about summary refs log tree commit diff
path: root/users/wpcarro/tools/symlinkManager
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-12-13T22·51+0300
committerVincent Ambo <mail@tazj.in>2021-12-13T23·15+0300
commit019f8fd2113df4c5247c3969c60fd4f0e08f91f7 (patch)
tree76a857f61aa88f62a30e854651e8439db77fd0ea /users/wpcarro/tools/symlinkManager
parent464bbcb15c09813172c79820bcf526bb10cf4208 (diff)
parent6123e976928ca3d8d93f0b2006b10b5f659eb74d (diff)
subtree(users/wpcarro): docking briefcase at '24f5a642' r/3226
git-subtree-dir: users/wpcarro
git-subtree-mainline: 464bbcb15c09813172c79820bcf526bb10cf4208
git-subtree-split: 24f5a642af3aa1627bbff977f0a101907a02c69f
Change-Id: I6105b3762b79126b3488359c95978cadb3efa789
Diffstat (limited to 'users/wpcarro/tools/symlinkManager')
-rw-r--r--users/wpcarro/tools/symlinkManager/README.md14
-rw-r--r--users/wpcarro/tools/symlinkManager/default.nix11
-rw-r--r--users/wpcarro/tools/symlinkManager/main.go82
3 files changed, 107 insertions, 0 deletions
diff --git a/users/wpcarro/tools/symlinkManager/README.md b/users/wpcarro/tools/symlinkManager/README.md
new file mode 100644
index 000000000000..b0fc58c8e989
--- /dev/null
+++ b/users/wpcarro/tools/symlinkManager/README.md
@@ -0,0 +1,14 @@
+# Dotfile Symlink Manager
+
+Find and delete all symlinks to the dotfiles defined in `$BRIEFCASE`.
+
+Oftentimes I corrupt the state of my configuration files. The intention with
+this script is to help me clean things up when this happens. An example workflow
+might look like:
+
+```shell
+> symlink-mgr --audit
+> symlink-mgr --seriously
+> briefcase # changes directory to $BRIEFCASE
+> make install
+```
diff --git a/users/wpcarro/tools/symlinkManager/default.nix b/users/wpcarro/tools/symlinkManager/default.nix
new file mode 100644
index 000000000000..16bb26bb3c2e
--- /dev/null
+++ b/users/wpcarro/tools/symlinkManager/default.nix
@@ -0,0 +1,11 @@
+{ depot, briefcase, ... }:
+
+depot.buildGo.program {
+  name = "symlink-mgr";
+  srcs = [
+    ./main.go
+  ];
+  deps = with briefcase.gopkgs; [
+    utils
+  ];
+}
diff --git a/users/wpcarro/tools/symlinkManager/main.go b/users/wpcarro/tools/symlinkManager/main.go
new file mode 100644
index 000000000000..e682867fb850
--- /dev/null
+++ b/users/wpcarro/tools/symlinkManager/main.go
@@ -0,0 +1,82 @@
+package main
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+	"utils"
+)
+
+var hostnames = map[string]string{
+	os.Getenv("DESKTOP"): "desktop",
+	os.Getenv("LAPTOP"):  "work_laptop",
+}
+
+func main() {
+	audit := flag.Bool("audit", false, "Output all symlinks that would be deleted. This is the default behavior. This option is mutually exclusive with the --seriously option.")
+	seriously := flag.Bool("seriously", false, "Actually delete the symlinks. This option is mutually exclusive with the --audit option.")
+	repoName := flag.String("repo-name", "briefcase", "The name of the repository.")
+	deviceOnly := flag.Bool("device-only", false, "Only output the device-specific dotfiles.")
+	flag.Parse()
+
+	if !*audit && !*seriously {
+		log.Fatal(errors.New("Either -audit or -seriously needs to be set."))
+	}
+	if *audit == *seriously {
+		log.Fatal(errors.New("Arguments -audit and -seriously are mutually exclusive"))
+	}
+
+	home, err := os.UserHomeDir()
+	utils.FailOn(err)
+	count := 0
+
+	err = filepath.Walk(home, func(path string, info os.FileInfo, err error) error {
+		if utils.IsSymlink(info.Mode()) {
+			dest, err := os.Readlink(path)
+			utils.FailOn(err)
+
+			var predicate func(string) bool
+
+			if *deviceOnly {
+				predicate = func(dest string) bool {
+					var hostname string
+					hostname, err = os.Hostname()
+					utils.FailOn(err)
+					seeking, ok := hostnames[hostname]
+					if !ok {
+						log.Fatal(fmt.Sprintf("Hostname \"%s\" not supported in the hostnames map.", hostname))
+					}
+					return strings.Contains(dest, *repoName) && strings.Contains(dest, seeking)
+				}
+			} else {
+				predicate = func(dest string) bool {
+					return strings.Contains(dest, *repoName)
+				}
+			}
+
+			if predicate(dest) {
+				if *audit {
+					fmt.Printf("%s -> %s\n", path, dest)
+				} else if *seriously {
+					fmt.Printf("rm %s\n", path)
+					err = os.Remove(path)
+					utils.FailOn(err)
+				}
+				count += 1
+			}
+		}
+		return nil
+	})
+	utils.FailOn(err)
+	if *audit {
+		fmt.Printf("Would have deleted %d symlinks.\n", count)
+	} else if *seriously {
+		fmt.Printf("Successfully deleted %d symlinks.\n", count)
+	}
+
+	os.Exit(0)
+}