From 379d5c437d25d6081b64553c346092f1526a2948 Mon Sep 17 00:00:00 2001 From: amy null Date: Fri, 24 Mar 2023 14:12:17 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feature:=200.5.0:=20`boxxy=20scan`!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 29 +- Cargo.toml | 4 +- README.md | 2 + data/hardcoded-applications.json | 1001 ++++++++++++++++++ data/partial-support-applications.json | 1330 ++++++++++++++++++++++++ src/main.rs | 88 +- src/scanner/mod.rs | 46 + 7 files changed, 2484 insertions(+), 16 deletions(-) create mode 100644 data/hardcoded-applications.json create mode 100644 data/partial-support-applications.json create mode 100644 src/scanner/mod.rs diff --git a/Cargo.lock b/Cargo.lock index c79291e..77af702 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ "path_abs", "semver", "serde", - "serde_yaml", + "serde_yaml 0.8.26", "syntect", "thiserror", "unicode-width", @@ -163,7 +163,7 @@ dependencies = [ [[package]] name = "boxxy" -version = "0.4.0" +version = "0.5.0" dependencies = [ "atty", "bat", @@ -183,6 +183,8 @@ dependencies = [ "regex", "rlimit", "serde", + "serde_json", + "serde_yaml 0.9.19", "shellexpand", "strum", "syscall-numbers", @@ -1213,9 +1215,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.92" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -1234,6 +1236,19 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "serde_yaml" +version = "0.9.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82e6c8c047aa50a7328632d067bcae6ef38772a79e28daf32f735e0e4f3dd10" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha2" version = "0.10.6" @@ -1506,6 +1521,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unsafe-libyaml" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad2024452afd3874bf539695e04af6732ba06517424dbf958fdb16a01f3bef6c" + [[package]] name = "url" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index 6cbbfbb..e3b2162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "boxxy" -version = "0.4.0" +version = "0.5.0" edition = "2021" repository = "https://github.com/queer/boxxy" @@ -25,6 +25,8 @@ pretty_env_logger = "0.4.0" regex = "1.7.2" rlimit = "0.9.1" serde = { version = "1.0.158", features = ["derive"] } +serde_json = "1.0.94" +serde_yaml = "0.9.19" shellexpand = "3.1.0" strum = { version = "0.24.1", features = ["derive"] } syscall-numbers = "3.0.0" diff --git a/README.md b/README.md index b1b397b..bf1fe7c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ force it to puts its data somewhere nice and proper. - minimal overhead - opt-in immutable fs outside of rule rewrites, ie only the files/directories you specify in rules are writable +- as of `0.5.0`, boxxy can scan your homedir to automatically suggest rules for + you! ![image of boxxy scan](https://cdn.mewna.xyz/2023/03/25/G6hrd3iQjEy65.png) ### potential drawbacks diff --git a/data/hardcoded-applications.json b/data/hardcoded-applications.json new file mode 100644 index 0000000..9e39a9e --- /dev/null +++ b/data/hardcoded-applications.json @@ -0,0 +1,1001 @@ +[ + { + "name": "adb & Android Studio", + "paths": [ + "~/.android/" + ], + "fixes": [ + "~/.android:~/.local/share/android" + ] + }, + { + "name": "aegisub", + "paths": [ + "~/.aegisub/" + ], + "fixes": [ + "~/.aegisub:~/.local/share/aegisub" + ] + }, + { + "name": "alpine", + "paths": [ + "~/.pinerc", + "~/.addressbook", + "~/.pine-debug[1-4]", + "~/.newsrc", + "~/.mailcap", + "~/.mime.types", + "~/.pine-interrupted-mail" + ], + "fixes": [ + "~/.pinerc:~/.config/alpine/pinerc", + "~/.addressbook:~/.config/alpine/addressbook", + "~/.newsrc:~/.config/alpine/newsrc", + "~/.mailcap:~/.config/alpine/mailcap", + "~/.mime.types:~/.config/alpine/mime.types", + "~/.pine-interrupted-mail:~/.config/alpine/pine-interrupted-mail" + ] + }, + { + "name": "aMule", + "paths": [ + "~/.aMule" + ], + "fixes": [ + "~/.aMule:~/.local/share/aMule" + ] + }, + { + "name": "anthy", + "paths": [ + "~/.anthy" + ], + "fixes": [ + "~/.anthy:~/.local/share/anthy" + ] + }, + { + "name": "Apache Directory Studio", + "paths": [ + "~/.ApacheDirectoryStudio" + ], + "fixes": [ + "~/.ApacheDirectoryStudio:~/.local/share/ApacheDirectoryStudio" + ] + }, + { + "name": "ARandR", + "paths": [ + "~/.screenlayout" + ], + "fixes": [ + "~/.screenlayout:~/.config/ARandR" + ] + }, + { + "name": "Arduino", + "paths": [ + "~/.arduino15", + "~/.jssc" + ], + "fixes": [ + "~/.arduino15:~/.local/share/arduino15", + "~/.jssc:~/.local/share/jssc" + ] + }, + { + "name": "arduino-cli", + "paths": [ + "~/.arduino15/" + ], + "fixes": [ + "~/.arduino15:~/.local/share/arduino15" + ] + }, + { + "name": "Avidemux", + "paths": [ + "~/.avidemux6" + ], + "fixes": [ + "~/.avidemux6:~/.local/share/avidemux6" + ] + }, + { + "name": "Berkshelf", + "paths": [ + "~/.berkshelf/" + ], + "fixes": [ + "~/.berkshelf:~/.local/share/berkshelf" + ] + }, + { + "name": "chatty", + "paths": [ + "~/.chatty/" + ], + "fixes": [ + "~/.chatty:~/.local/share/chatty" + ] + }, + { + "name": "cmake", + "paths": [ + "~/.cmake/" + ], + "fixes": [ + "~/.cmake:~/.local/share/cmake" + ] + }, + { + "name": "Cinnamon", + "paths": [ + "~/.cinnamon/" + ], + "fixes": [ + "~/.cinnamon:~/.local/share/cinnamon" + ] + }, + { + "name": "conan", + "paths": [ + "~/.conan/" + ], + "fixes": [ + "~/.conan:~/.local/share/conan" + ] + }, + { + "name": "cryptomator", + "paths": [ + "~/.Cryptomator" + ], + "fixes": [ + "~/.Cryptomator:~/.local/share/Cryptomator" + ] + }, + { + "name": "ctags (universial-ctags)", + "paths": [ + "~/.ctagsrc", + "~/.ctags.d" + ], + "fixes": [ + "~/.ctagsrc:~/.config/ctags/ctagsrc", + "~/.ctags.d:~/.config/ctags" + ] + }, + { + "name": "CUPS", + "paths": [ + "~/.cups/" + ], + "fixes": [ + "~/.cups:~/.local/share/cups" + ] + }, + { + "name": "cVim", + "paths": [ + "~/.cvimrc" + ], + "fixes": [ + "~/.cvimrc:~/.config/cVim/cvimrc" + ] + }, + { + "name": "darcs", + "paths": [ + "~/.darcs/" + ], + "fixes": [ + "~/.darcs:~/.local/share/darcs" + ] + }, + { + "name": "dart", + "paths": [ + "~/.dart", + "~/.dartServer" + ], + "fixes": [ + "~/.dart:~/.local/share/dart", + "~/.dartServer:~/.local/share/dartServer" + ] + }, + { + "name": "devede", + "paths": [ + "~/.devedeng" + ], + "fixes": [ + "~/.devedeng:~/.local/share/devedeng" + ] + }, + { + "name": "Dia", + "paths": [ + "~/.dia/" + ], + "fixes": [ + "~/.dia:~/.local/share/dia" + ] + }, + { + "name": "dotnet-sdk", + "paths": [ + "~/.dotnet/" + ], + "fixes": [ + "~/.dotnet:~/.local/share/dotnet" + ] + }, + { + "name": "dropbox", + "paths": [ + "~/.dropbox/" + ], + "fixes": [ + "~/.dropbox:~/.local/share/dropbox" + ] + }, + { + "name": "Eclipse", + "paths": [ + "~/.eclipse/" + ], + "fixes": [ + "~/.eclipse:~/.local/share/eclipse" + ] + }, + { + "name": "Fetchmail", + "paths": [ + "~/.fetchmailrc" + ], + "fixes": [ + "~/.fetchmailrc:~/.config/fetchmailrc" + ] + }, + { + "name": "Flatpak", + "paths": [ + "~/.var/" + ], + "fixes": [ + "~/.var:~/.local/share/var" + ] + }, + { + "name": "freesweep", + "paths": [ + "~/.sweeprc" + ], + "fixes": [ + "~/.sweeprc:~/.config/freesweep/sweeprc" + ] + }, + { + "name": "gftp", + "paths": [ + "~/.gftp/" + ], + "fixes": [ + "~/.gftp:~/.local/share/gftp" + ] + }, + { + "name": "gitkraken", + "paths": [ + "~/.gitkraken/" + ], + "fixes": [ + "~/.gitkraken:~/.local/share/gitkraken" + ] + }, + { + "name": "GoldenDict", + "paths": [ + "~/.goldendict/" + ], + "fixes": [ + "~/.goldendict:~/.local/share/goldendict" + ] + }, + { + "name": "gphoto2", + "paths": [ + "~/.gphoto" + ], + "fixes": [ + "~/.gphoto:~/.local/share/gphoto" + ] + }, + { + "name": "gramps", + "paths": [ + "~/.gramps/" + ], + "fixes": [ + "~/.gramps:~/.local/share/gramps" + ] + }, + { + "name": "groovy", + "paths": [ + "~/.groovy/" + ], + "fixes": [ + "~/.groovy:~/.local/share/groovy" + ] + }, + { + "name": "grsync", + "paths": [ + "~/.grsync/" + ], + "fixes": [ + "~/.grsync:~/.local/share/grsync" + ] + }, + { + "name": "google-cloud-cli", + "paths": [ + "~/.gsutil/" + ], + "fixes": [ + "~/.gsutil:~/.local/share/gsutil" + ] + }, + { + "name": "gtk-recordMyDesktop", + "paths": [ + "~/.gtk-recordmydesktop" + ], + "fixes": [ + "~/.gtk-recordmydesktop:~/.config/gtk-recordMyDesktop/gtk-recordmydesktop" + ] + }, + { + "name": "hplip", + "paths": [ + "~/.hplip/" + ], + "fixes": [ + "~/.hplip:~/.local/share/hplip" + ] + }, + { + "name": "hydrogen", + "paths": [ + "~/.hydrogen/" + ], + "fixes": [ + "~/.hydrogen:~/.local/share/hydrogen" + ] + }, + { + "name": "idris", + "paths": [ + "~/.idris" + ], + "fixes": [ + "~/.idris:~/.local/share/idris" + ] + }, + { + "name": "itch-setup-bin", + "paths": [ + "~/.itch" + ], + "fixes": [ + "~/.itch:~/.local/share/itch" + ] + }, + { + "name": "Jmol", + "paths": [ + "~/.jmol/" + ], + "fixes": [ + "~/.jmol:~/.local/share/jmol" + ] + }, + { + "name": "lbdb", + "paths": [ + "~/.lbdbrc", + "~/.lbdb/" + ], + "fixes": [ + "~/.lbdbrc:~/.config/lbdb/lbdbrc", + "~/.lbdb:~/.local/share/lbdb" + ] + }, + { + "name": "Java OpenJDK", + "paths": [ + "~/.java/fonts" + ], + "fixes": [ + "~/.java/fonts:~/.local/share/java/fonts" + ] + }, + { + "name": "Java OpenJFX", + "paths": [ + "~/.java/webview" + ], + "fixes": [ + "~/.java/webview:~/.local/share/java/webview" + ] + }, + { + "name": "jgmenu", + "paths": [ + "~/.jgmenu-lockfile" + ], + "fixes": [ + "~/.jgmenu-lockfile:~/.config/jgmenu/jgmenu-lockfile" + ] + }, + { + "name": "julia", + "paths": [ + "~/.juliarc.jl", + "~/.julia_history", + "~/.julia" + ], + "fixes": [ + "~/.juliarc.jl:~/.config/julia/juliarc.jl", + "~/.julia_history:~/.local/share/julia/julia_history", + "~/.julia:~/.local/share/julia" + ] + }, + { + "name": "kite", + "paths": [ + "~/.kite/" + ], + "fixes": [ + "~/.kite:~/.local/share/kite" + ] + }, + { + "name": "kotlin", + "paths": [ + "~/.kotlinc_history" + ], + "fixes": [ + "~/.kotlinc_history:~/.local/share/kotlinc/kotlinc_history" + ] + }, + { + "name": "Kubernetes", + "paths": [ + "~/.kube/" + ], + "fixes": [ + "~/.kube:~/.local/share/kube" + ] + }, + { + "name": "lldb", + "paths": [ + "~/.lldb", + "~/.lldbinit" + ], + "fixes": [ + "~/.lldb:~/.local/share/lldb", + "~/.lldbinit:~/.config/lldb/lldbinit" + ] + }, + { + "name": "LMMS", + "paths": [ + "~/.lmmsrc.xml" + ], + "fixes": [ + "~/.lmmsrc.xml:~/.config/lmms/lmmsrc.xml" + ] + }, + { + "name": "mathomatic", + "paths": [ + "~/.mathomaticrc", + "~/.matho_history" + ], + "fixes": [ + "~/.mathomaticrc:~/.config/mathomatic/mathomaticrc", + "~/.matho_history:~/.local/share/mathomatic/matho_history" + ] + }, + { + "name": "Minecraft", + "paths": [ + "~/.minecraft/" + ], + "fixes": [ + "~/.minecraft:~/.local/share/minecraft" + ] + }, + { + "name": "Minetest", + "paths": [ + "~/.minetest/" + ], + "fixes": [ + "~/.minetest:~/.local/share/minetest" + ] + }, + { + "name": "minicom", + "paths": [ + "~/.minirc.dfl" + ], + "fixes": [ + "~/.minirc.dfl:~/.config/minicom/minirc.dfl" + ] + }, + { + "name": "Mono", + "paths": [ + "~/.mono/" + ], + "fixes": [ + "~/.mono:~/.local/share/mono" + ] + }, + { + "name": "mongodb", + "paths": [ + "~/.mongorc.js", + "~/.dbshell" + ], + "fixes": [ + "~/.mongorc.js:~/.config/mongodb/mongorc.js", + "~/.dbshell:~/.config/mongodb/dbshell" + ] + }, + { + "name": "", + "paths": [ + "~/.netrc" + ], + "fixes": [ + "~/.netrc:~/.config/netrc" + ] + }, + { + "name": "nmcli", + "paths": [ + "~/.nmcli-history" + ], + "fixes": [ + "~/.nmcli-history:~/.local/share/nmcli/nmcli-history" + ] + }, + { + "name": "Networkmanager-openvpn", + "paths": [ + "~/.cert/nm-openvpn" + ], + "fixes": [ + "~/.cert/nm-openvpn:~/.local/share/cert/nm-openvpn" + ] + }, + { + "name": "ocaml-utop", + "paths": [ + "~/.utop-history" + ], + "fixes": [ + "~/.utop-history:~/.local/share/utop/utop-history" + ] + }, + { + "name": "parsec-bin", + "paths": [ + "~/.parsec" + ], + "fixes": [ + "~/.parsec:~/.local/share/parsec" + ] + }, + { + "name": "pcsxr", + "paths": [ + "~/.pcsxr" + ], + "fixes": [ + "~/.pcsxr:~/.local/share/pcsxr" + ] + }, + { + "name": "perf", + "paths": [ + "~/.debug" + ], + "fixes": [ + "~/.debug:~/.local/share/debug" + ] + }, + { + "name": "perl", + "paths": [ + "~/.cpan", + "~/perl5" + ], + "fixes": [ + "~/.cpan:~/.local/share/cpan", + "~/perl5:~/.local/share/perl5" + ] + }, + { + "name": "phoronix-test-suite", + "paths": [ + "~/.phoronix-test-suite" + ], + "fixes": [ + "~/.phoronix-test-suite:~/.local/share/phoronix-test-suite" + ] + }, + { + "name": "portfolio-performance-bin", + "paths": [ + "~/.PortfolioPerformance/" + ], + "fixes": [ + "~/.PortfolioPerformance:~/.local/share/PortfolioPerformance" + ] + }, + { + "name": "psensor", + "paths": [ + "~/.psensor" + ], + "fixes": [ + "~/.psensor:~/.local/share/psensor" + ] + }, + { + "name": "python", + "paths": [ + "~/.python_history" + ], + "fixes": [ + "~/.python_history:~/.local/share/python/python_history" + ] + }, + { + "name": "python-tensorflow", + "paths": [ + "~/.keras" + ], + "fixes": [ + "~/.keras:~/.local/share/keras" + ] + }, + { + "name": "qmmp", + "paths": [ + "~/.qmmp" + ], + "fixes": [ + "~/.qmmp:~/.local/share/qmmp" + ] + }, + { + "name": "Qt Designer", + "paths": [ + "~/.designer" + ], + "fixes": [ + "~/.designer:~/.local/share/designer" + ] + }, + { + "name": "RedNotebook", + "paths": [ + "~/.rednotebook" + ], + "fixes": [ + "~/.rednotebook:~/.local/share/rednotebook" + ] + }, + { + "name": "Remarkable", + "paths": [ + "~/.remarkable" + ], + "fixes": [ + "~/.remarkable:~/.local/share/remarkable" + ] + }, + { + "name": "renderdoc", + "paths": [ + "~/.renderdoc" + ], + "fixes": [ + "~/.renderdoc:~/.local/share/renderdoc" + ] + }, + { + "name": "Ren'Py", + "paths": [ + "~/.renpy" + ], + "fixes": [ + "~/.renpy:~/.local/share/renpy" + ] + }, + { + "name": "repo", + "paths": [ + "~/.repoconfig" + ], + "fixes": [ + "~/.repoconfig:~/.config/repo/repoconfig" + ] + }, + { + "name": "rpm", + "paths": [ + "~/.rpmrc", + "~/.rpmmacros" + ], + "fixes": [ + "~/.rpmrc:~/.config/rpm/rpmrc", + "~/.rpmmacros:~/.config/rpm/rpmmacros" + ] + }, + { + "name": "SANE", + "paths": [ + "~/.sane/" + ], + "fixes": [ + "~/.sane:~/.local/share/sane" + ] + }, + { + "name": "sbcl", + "paths": [ + "~/.sbclrc" + ], + "fixes": [ + "~/.sbclrc:~/.config/sbcl/sbclrc" + ] + }, + { + "name": "Solfege", + "paths": [ + "~/.solfege", + "~/.solfegerc", + "~/lessonfiles" + ], + "fixes": [ + "~/.solfege:~/.local/share/solfege", + "~/.solfegerc:~/.config/solfege/solfegerc", + "~/lessonfiles:~/.local/share/solfege/lessonfiles" + ] + }, + { + "name": "SpamAssassin", + "paths": [ + "~/.spamassassin" + ], + "fixes": [ + "~/.spamassassin:~/.local/share/spamassassin" + ] + }, + { + "name": "SQLite", + "paths": [ + "~/.sqlite_history", + "~/.sqliterc" + ], + "fixes": [ + "~/.sqlite_history:~/.local/share/sqlite/sqlite_history", + "~/.sqliterc:~/.config/sqlite/sqliterc" + ] + }, + { + "name": "python-streamlit", + "paths": [ + "~/.streamlit" + ], + "fixes": [ + "~/.streamlit:~/.local/share/streamlit" + ] + }, + { + "name": "TeamSpeak", + "paths": [ + "~/.ts3client" + ], + "fixes": [ + "~/.ts3client:~/.local/share/ts3client" + ] + }, + { + "name": "terraform", + "paths": [ + "~/.terraform.d/" + ], + "fixes": [ + "~/.terraform.d:~/.local/share/terraform" + ] + }, + { + "name": "texinfo", + "paths": [ + "~/.infokey" + ], + "fixes": [ + "~/.infokey:~/.config/info/infokey" + ] + }, + { + "name": "Thunderbird", + "paths": [ + "~/.thunderbird/" + ], + "fixes": [ + "~/.thunderbird:~/.local/share/thunderbird" + ] + }, + { + "name": "TigerVNC", + "paths": [ + "~/.vnc" + ], + "fixes": [ + "~/.vnc:~/.local/share/vnc" + ] + }, + { + "name": "tllocalmgr", + "paths": [ + "~/.texlive" + ], + "fixes": [ + "~/.texlive:~/.local/share/texlive" + ] + }, + { + "name": "urlview", + "paths": [ + "~/.urlview" + ], + "fixes": [ + "~/.urlview:~/.config/urlview/urlview" + ] + }, + { + "name": "vale", + "paths": [ + "~/.vale.ini" + ], + "fixes": [ + "~/.vale.ini:~/.config/vale/vale.ini" + ] + }, + { + "name": "vim", + "paths": [ + "~/.vim", + "~/.vimrc", + "~/.viminfo" + ], + "fixes": [ + "~/.vim:~/.local/share/vim", + "~/.vimrc:~/.config/vim/vimrc", + "~/.viminfo:~/.local/share/vim/viminfo" + ] + }, + { + "name": "vimperator", + "paths": [ + "~/.vimperatorrc" + ], + "fixes": [ + "~/.vimperatorrc:~/.config/vimperator/vimperatorrc" + ] + }, + { + "name": "visidata", + "paths": [ + "~/.visidata" + ], + "fixes": [ + "~/.visidata:~/.config/visidata/visidata" + ] + }, + { + "name": "wpa_cli", + "paths": [ + "~/.wpa_cli_history" + ], + "fixes": [ + "~/.wpa_cli_history:~/.local/share/wpa_cli/wpa_cli_history" + ] + }, + { + "name": "wego", + "paths": [ + "~/.wegorc" + ], + "fixes": [ + "~/.wegorc:~/.config/wego/wegorc" + ] + }, + { + "name": "x2goclient", + "paths": [ + "~/.x2goclient" + ], + "fixes": [ + "~/.x2goclient:~/.local/share/x2goclient" + ] + }, + { + "name": "xpdf", + "paths": [ + "~/.xpdfrc" + ], + "fixes": [ + "~/.xpdfrc:~/.config/xpdf/xpdfrc" + ] + }, + { + "name": "xrdp", + "paths": [ + "~/thinclient_drives" + ], + "fixes": [ + "~/thinclient_drives:~/.local/share/xrdp/thinclient_drives" + ] + }, + { + "name": "XVim2", + "paths": [ + "~/.xvimrc" + ], + "fixes": [ + "~/.xvimrc:~/.config/xvim/xvimrc" + ] + }, + { + "name": "YARD", + "paths": [ + "~/.yard" + ], + "fixes": [ + "~/.yard:~/.config/yard/yard" + ] + }, + { + "name": "zenmap nmap", + "paths": [ + "~/.zenmap" + ], + "fixes": [ + "~/.zenmap:~/.local/share/zenmap" + ] + }, + { + "name": "zotero-bin", + "paths": [ + "~/.zotero", + "~/Zotero" + ], + "fixes": [ + "~/.zotero:~/.local/share/zotero", + "~/Zotero:~/.local/share/zotero" + ] + } +] diff --git a/data/partial-support-applications.json b/data/partial-support-applications.json new file mode 100644 index 0000000..9ed8b48 --- /dev/null +++ b/data/partial-support-applications.json @@ -0,0 +1,1330 @@ +[ + { + "name": "abook", + "paths": [ + "~/.abook" + ], + "fixes": [ + "~/.abook:~/.config/abook" + ] + }, + { + "name": "ack", + "paths": [ + "~/.ackrc" + ], + "fixes": [ + "~/.ackrc:~/.config/ack/ackrc" + ] + }, + { + "name": "Ansible", + "paths": [ + "~/.ansible" + ], + "fixes": [ + "~/.ansible:~/.config/ansible" + ] + }, + { + "name": "asdf-vm", + "paths": [ + "~/.asdfrc", + "~/.asdf/" + ], + "fixes": [ + "~/.asdfrc:~/.config/asdf/asdfrc", + "~/.asdf/:~/.local/share/asdf" + ] + }, + { + "name": "aspell", + "paths": [ + "~/.aspell.conf" + ], + "fixes": [ + "~/.aspell.conf:~/.config/aspell/aspell.conf" + ] + }, + { + "name": "Atom", + "paths": [ + "~/.atom" + ], + "fixes": [ + "~/.atom:~/.local/share/atom" + ] + }, + { + "name": "aws-cli", + "paths": [ + "~/.aws" + ], + "fixes": [ + "~/.aws:~/.config/aws" + ] + }, + { + "name": "bashdb", + "paths": [ + "~/.bashdbinit", + "~/.bashdb_hist" + ], + "fixes": [ + "~/.bashdbinit:~/.config/bashdb/bashdbinit", + "~/.bashdb_hist:~/.local/share/bashdb/bashdb_hist" + ] + }, + { + "name": "bazaar", + "paths": [ + "~/.bazaar", + "~/.bzr.log" + ], + "fixes": [ + "~/.bzr.log:~/.local/share/bazaar/bzr.log", + "~/.bazaar:~/.config/bazaar" + ] + }, + { + "name": "bogofilter", + "paths": [ + "~/.bogofilter" + ], + "fixes": [ + "~/.bogofilter:~/.local/share/bogofilter" + ] + }, + { + "name": "btpd-git", + "paths": [ + "~/.btpd/" + ], + "fixes": [ + "~/.btpd/:~/.config/btpd" + ] + }, + { + "name": "calc", + "paths": [ + "~/.calc_history" + ], + "fixes": [ + "~/.calc_history:~/.cache/calc/calc_history" + ] + }, + { + "name": "Rust - Cargo", + "paths": [ + "~/.cargo" + ], + "fixes": [ + "~/.cargo:~/.local/share/cargo" + ] + }, + { + "name": "cataclysm-dda", + "paths": [ + "~/.cataclysm-dda" + ], + "fixes": [ + "~/.cataclysm-dda:~/.local/share/cataclysm-dda" + ] + }, + { + "name": "cd-bookmark", + "paths": [ + "~/.cdbookmark" + ], + "fixes": [ + "~/.cdbookmark:~/.config/cd-bookmark" + ] + }, + { + "name": "cgdb", + "paths": [ + "~/.cgdb" + ], + "fixes": [ + "~/.cgdb:~/.config/cgdb" + ] + }, + { + "name": "chez-scheme", + "paths": [ + "~/.chezscheme_history" + ], + "fixes": [ + "~/.chezscheme_history:~/.local/share/chez-scheme/chezscheme_history" + ] + }, + { + "name": "cinelerra", + "paths": [ + "~/.bcast5" + ], + "fixes": [ + "~/.bcast5:~/.local/share/cinelerra/bcast5" + ] + }, + { + "name": "conky", + "paths": [ + "~/.conkyrc" + ], + "fixes": [ + "~/.conkyrc:~/.config/conky/conkyrc" + ] + }, + { + "name": "claws-mail", + "paths": [ + "~/.claws-mail" + ], + "fixes": [ + "~/.claws-mail:~/.local/share/claws-mail" + ] + }, + { + "name": "coreutils", + "paths": [ + "~/.dircolors" + ], + "fixes": [ + "~/.dircolors:~/.config/coreutils/dircolors" + ] + }, + { + "name": "crawl", + "paths": [ + "~/.crawl" + ], + "fixes": [ + "~/.crawl:~/.local/share/crawl" + ] + }, + { + "name": "clusterssh", + "paths": [ + "~/.clusterssh/" + ], + "fixes": [ + "~/.clusterssh/:~/.config/clusterssh" + ] + }, + { + "name": "CUDA", + "paths": [ + "~/.nv" + ], + "fixes": [ + "~/.nv:~/.cache/cuda" + ] + }, + { + "name": "dict", + "paths": [ + "~/.dictrc" + ], + "fixes": [ + "~/.dictrc:~/.config/dict/dictrc" + ] + }, + { + "name": "Docker", + "paths": [ + "~/.docker" + ], + "fixes": [ + "~/.docker:~/.config/docker" + ] + }, + { + "name": "docker-machine", + "paths": [ + "~/.docker/machine" + ], + "fixes": [ + "~/.docker/machine:~/.local/share/docker/machine" + ] + }, + { + "name": "DOSBox", + "paths": [ + "~/.dosbox" + ], + "fixes": [ + "~/.dosbox:~/.config/dosbox" + ] + }, + { + "name": "dub", + "paths": [ + "~/.dub" + ], + "fixes": [ + "~/.dub:~/.local/share/dub" + ] + }, + { + "name": "Electrum Bitcoin Wallet", + "paths": [ + "~/.electrum" + ], + "fixes": [ + "~/.electrum:~/.local/share/electrum" + ] + }, + { + "name": "ELinks", + "paths": [ + "~/.elinks" + ], + "fixes": [ + "~/.elinks:~/.config/elinks" + ] + }, + { + "name": "elixir", + "paths": [ + "~/.mix" + ], + "fixes": [ + "~/.mix:~/.local/share/elixir" + ] + }, + { + "name": "Elm", + "paths": [ + "~/.elm" + ], + "fixes": [ + "~/.elm:~/.config/elm" + ] + }, + { + "name": "fceux", + "paths": [ + "~/.fceux/" + ], + "fixes": [ + "~/.fceux/:~/.config/fceux" + ] + }, + { + "name": "FFmpeg", + "paths": [ + "~/.ffmpeg" + ], + "fixes": [ + "~/.ffmpeg:~/.config/ffmpeg" + ] + }, + { + "name": "flutter", + "paths": [ + "~/.flutter", + "~/.flutter_settings", + "~/.flutter_tool_state", + "~/.pub-cache" + ], + "fixes": [ + "~/.flutter:~/.local/share/flutter", + "~/.flutter_settings:~/.config/flutter/flutter_settings", + "~/.flutter_tool_state:~/.config/flutter/flutter_tool_state", + "~/.pub-cache:~/.cache/flutter" + ] + }, + { + "name": "emscripten", + "paths": [ + "~/.emscripten", + "~/.emscripten_sanity", + "~/.emscripten_ports", + "~/.emscripten_cache__last_clear" + ], + "fixes": [ + "~/.emscripten:~/.config/emscripten/emscripten", + "~/.emscripten_sanity:~/.config/emscripten/emscripten_sanity", + "~/.emscripten_ports:~/.config/emscripten/emscripten_ports", + "~/.emscripten_cache__last_clear:~/.cache/emscripten/emscripten_cache__last_clear" + ] + }, + { + "name": "get_iplayer", + "paths": [ + "~/.get_iplayer" + ], + "fixes": [ + "~/.get_iplayer:~/.local/share/get_iplayer" + ] + }, + { + "name": "getmail", + "paths": [ + "~/.getmail" + ], + "fixes": [ + "~/.getmail:~/.config/getmail" + ] + }, + { + "name": "ghc", + "paths": [ + "~/.ghci" + ], + "fixes": [ + "~/.ghci:~/.config/ghc/ghci" + ] + }, + { + "name": "ghcup-hs-bin", + "paths": [ + "~/.ghcup" + ], + "fixes": [ + "~/.ghcup:~/.local/share/ghcup" + ] + }, + { + "name": "gliv", + "paths": [ + "~/.glivrc" + ], + "fixes": [ + "~/.glivrc:~/.config/gliv/glivrc" + ] + }, + { + "name": "gnuradio", + "paths": [ + "~/.gnuradio" + ], + "fixes": [ + "~/.gnuradio:~/.config/gnuradio" + ] + }, + { + "name": "GnuPG", + "paths": [ + "~/.gnupg" + ], + "fixes": [ + "~/.gnupg:~/.local/share/gnupg" + ] + }, + { + "name": "Go", + "paths": [ + "~/go" + ], + "fixes": [ + "~/go:~/.local/share/go" + ] + }, + { + "name": "Google Earth", + "paths": [ + "~/.googleearth" + ], + "fixes": [ + "~/.googleearth:~/.local/share/googleearth" + ] + }, + { + "name": "gopass", + "paths": [ + "~/.password-store" + ], + "fixes": [ + "~/.password-store:~/.local/share/password-store" + ] + }, + { + "name": "gpodder", + "paths": [ + "~/gPodder" + ], + "fixes": [ + "~/gPodder:~/.local/share/gpodder" + ] + }, + { + "name": "GQ LDAP client", + "paths": [ + "~/.gq", + "~/.gq-state" + ], + "fixes": [ + "~/.gq:~/.config/gq", + "~/.gq-state:~/.local/share/gq" + ] + }, + { + "name": "Gradle", + "paths": [ + "~/.gradle" + ], + "fixes": [ + "~/.gradle:~/.local/share/gradle" + ] + }, + { + "name": "GTK 1", + "paths": [ + "~/.gtkrc" + ], + "fixes": [ + "~/.gtkrc:~/.config/gtk-1.0/gtkrc" + ] + }, + { + "name": "GTK 2", + "paths": [ + "~/.gtkrc-2.0" + ], + "fixes": [ + "~/.gtkrc-2.0:~/.config/gtk-2.0/gtkrc" + ] + }, + { + "name": "hledger", + "paths": [ + "~/.hledger.journal" + ], + "fixes": [ + "~/.hledger.journal:~/.local/share/hledger/hledger.journal" + ] + }, + { + "name": "imapfilter", + "paths": [ + "~/.imapfilter" + ], + "fixes": [ + "~/.imapfilter:~/.config/imapfilter" + ] + }, + { + "name": "IPFS", + "paths": [ + "~/.ipfs" + ], + "fixes": [ + "~/.ipfs:~/.local/share/ipfs" + ] + }, + { + "name": "irb", + "paths": [ + "~/.irbrc" + ], + "fixes": [ + "~/.irbrc:~/.config/irb/irbrc" + ] + }, + { + "name": "irssi", + "paths": [ + "~/.irssi" + ], + "fixes": [ + "~/.irssi:~/.config/irssi" + ] + }, + { + "name": "isync", + "paths": [ + "~/.mbsyncrc" + ], + "fixes": [ + "~/.mbsyncrc:~/.config/isync/mbsyncrc" + ] + }, + { + "name": "Java - OpenJDK", + "paths": [ + "~/.java/.userPrefs" + ], + "fixes": [ + "~/.java/.userPrefs:~/.local/share/java/.userPrefs" + ] + }, + { + "name": "jupyter", + "paths": [ + "~/.jupyter" + ], + "fixes": [ + "~/.jupyter:~/.local/share/jupyter" + ] + }, + { + "name": "k9s", + "paths": [ + "~/.k9s" + ], + "fixes": [ + "~/.k9s:~/.config/k9s" + ] + }, + { + "name": "KDE", + "paths": [ + "~/.kde", + "~/.kde4" + ], + "fixes": [ + "~/.kde:~/.config/kde", + "~/.kde4:~/.config/kde4" + ] + }, + { + "name": "keychain", + "paths": [ + "~/.keychain" + ], + "fixes": [ + "~/.keychain:~/.local/share/keychain" + ] + }, + { + "name": "kodi", + "paths": [ + "~/.kodi" + ], + "fixes": [ + "~/.kodi:~/.local/share/kodi" + ] + }, + { + "name": "kscript", + "paths": [ + "~/.kscript" + ], + "fixes": [ + "~/.kscript:~/.cache/kscript" + ] + }, + { + "name": "ledger", + "paths": [ + "~/.ledgerrc", + "~/.pricedb" + ], + "fixes": [ + "~/.ledgerrc:~/.config/ledger/ledgerrc", + "~/.pricedb:~/.local/share/ledger/pricedb" + ] + }, + { + "name": "Leiningen", + "paths": [ + "~/.lein", + "~/.m2" + ], + "fixes": [ + "~/.lein:~/.local/share/lein", + "~/.m2:~/.local/share/m2" + ] + }, + { + "name": "libdvdcss", + "paths": [ + "~/.dvdcss" + ], + "fixes": [ + "~/.dvdcss:~/.local/share/dvdcss" + ] + }, + { + "name": "ltrace", + "paths": [ + "~/.ltrace.conf" + ], + "fixes": [ + "~/.ltrace.conf:~/.config/ltrace/ltrace.conf" + ] + }, + { + "name": "m17n-db", + "paths": [ + "~/.m17n.d" + ], + "fixes": [ + "~/.m17n.d:~/.local/share/m17n" + ] + }, + { + "name": "maptool-bin", + "paths": [ + "~/.maptool-rptools" + ], + "fixes": [ + "~/.maptool-rptools:~/.local/share/maptool-rptools" + ] + }, + { + "name": "maven", + "paths": [ + "~/.m2" + ], + "fixes": [ + "~/.m2:~/.local/share/m2" + ] + }, + { + "name": "Mathematica", + "paths": [ + "~/.Mathematica" + ], + "fixes": [ + "~/.Mathematica:~/.config/Mathematica" + ] + }, + { + "name": "maxima", + "paths": [ + "~/.maxima" + ], + "fixes": [ + "~/.maxima:~/.config/maxima" + ] + }, + { + "name": "mednafen", + "paths": [ + "~/.mednafen" + ], + "fixes": [ + "~/.mednafen:~/.config/mednafen" + ] + }, + { + "name": "minikube", + "paths": [ + "~/.minikube" + ], + "fixes": [ + "~/.minikube:~/.local/share/minikube" + ] + }, + { + "name": "mitmproxy", + "paths": [ + "~/.mitmproxy" + ], + "fixes": [ + "~/.mitmproxy:~/.config/mitmproxy" + ] + }, + { + "name": "MOC", + "paths": [ + "~/.moc" + ], + "fixes": [ + "~/.moc:~/.config/moc" + ] + }, + { + "name": "monero", + "paths": [ + "~/.bitmonero" + ], + "fixes": [ + "~/.bitmonero:~/.local/share/monero" + ] + }, + { + "name": "most", + "paths": [ + "~/.mostrc" + ], + "fixes": [ + "~/.mostrc:~/.config/most/mostrc" + ] + }, + { + "name": "MPlayer", + "paths": [ + "~/.mplayer" + ], + "fixes": [ + "~/.mplayer:~/.config/mplayer" + ] + }, + { + "name": "mypy", + "paths": [ + "~/.config/mypy/config", + "~/.mypy.ini", + "~/.mypy_cache" + ], + "fixes": [ + "~/.config/mypy/config:~/.config/mypy/config", + "~/.mypy.ini:~/.config/mypy/config", + "~/.mypy_cache:~/.cache/mypy" + ] + }, + { + "name": "MySQL", + "paths": [ + "~/.mysql_history", + "~/.my.cnf", + "~/.mylogin.cnf" + ], + "fixes": [ + "~/.mysql_history:~/.local/share/mysql_history", + "~/.my.cnf:~/.config/my.cnf", + "~/.mylogin.cnf:~/.config/mylogin.cnf" + ] + }, + { + "name": "mysql-workbench", + "paths": [ + "~/.mysql/workbench" + ], + "fixes": [ + "~/.mysql/workbench:~/.local/share/mysql/workbench" + ] + }, + { + "name": "ncurses", + "paths": [ + "~/.terminfo" + ], + "fixes": [ + "~/.terminfo:~/.local/share/terminfo" + ] + }, + { + "name": "n", + "paths": [ + "/usr/local/n" + ], + "fixes": [ + "/usr/local/n:~/.local/share/n" + ] + }, + { + "name": "ncmpc", + "paths": [ + "~/.ncmpc" + ], + "fixes": [ + "~/.ncmpc:~/.config/ncmpc" + ] + }, + { + "name": "Netbeans", + "paths": [ + "~/.netbeans" + ], + "fixes": [ + "~/.netbeans:~/.local/share/netbeans" + ] + }, + { + "name": "Node.js", + "paths": [ + "~/.node_repl_history" + ], + "fixes": [ + "~/.node_repl_history:~/.local/share/node_repl_history" + ] + }, + { + "name": "npm", + "paths": [ + "~/.npm", + "~/.npmrc" + ], + "fixes": [ + "~/.npm:~/.local/share/npm", + "~/.npmrc:~/.config/npm/npmrc" + ] + }, + { + "name": "opam", + "paths": [ + "~/.opam" + ], + "fixes": [ + "~/.opam:~/.local/share/opam" + ] + }, + { + "name": "pnpm", + "paths": [ + "~/.pnpm-store" + ], + "fixes": [ + "~/.pnpm-store:~/.local/share/pnpm-store" + ] + }, + { + "name": "PuTTY", + "paths": [ + "~/.putty/" + ], + "fixes": [ + "~/.putty/:~/.config/putty/" + ] + }, + { + "name": "nuget", + "paths": [ + "~/.nuget/packages" + ], + "fixes": [ + "~/.nuget/packages:~/.local/share/nuget/packages" + ] + }, + { + "name": "NVIDIA", + "paths": [ + "~/.nv" + ], + "fixes": [ + "~/.nv:~/.cache/nv" + ] + }, + { + "name": "nvidia-settings", + "paths": [ + "~/.nvidia-settings-rc" + ], + "fixes": [ + "~/.nvidia-settings-rc:~/.config/nvidia-settings-rc" + ] + }, + { + "name": "nvm", + "paths": [ + "~/.nvm" + ], + "fixes": [ + "~/.nvm:~/.local/share/nvm" + ] + }, + { + "name": "Octave", + "paths": [ + "~/octave", + "~/.octave_packages", + "~/.octave_hist" + ], + "fixes": [ + "~/octave:~/.local/share/octave", + "~/.octave_packages:~/.local/share/octave", + "~/.octave_hist:~/.local/share/octave" + ] + }, + { + "name": "openscad", + "paths": [ + "~/.OpenSCAD" + ], + "fixes": [ + "~/.OpenSCAD:~/.local/share/OpenSCAD" + ] + }, + { + "name": "parallel", + "paths": [ + "~/.parallel" + ], + "fixes": [ + "~/.parallel:~/.config/parallel" + ] + }, + { + "name": "pass", + "paths": [ + "~/.password-store" + ], + "fixes": [ + "~/.password-store:~/.local/share/password-store" + ] + }, + { + "name": "Pidgin", + "paths": [ + "~/.purple" + ], + "fixes": [ + "~/.purple:~/.local/share/pidgin" + ] + }, + { + "name": "PostgreSQL", + "paths": [ + "~/.psqlrc", + "~/.psql_history", + "~/.pgpass", + "~/.pg_service.conf" + ], + "fixes": [ + "~/.psqlrc:~/.config/psqlrc", + "~/.psql_history:~/.local/share/psql_history", + "~/.pgpass:~/.config/pgpass", + "~/.pg_service.conf:~/.config/pg_service.conf" + ] + }, + { + "name": "pyenv", + "paths": [ + "~/.pyenv" + ], + "fixes": [ + "~/.pyenv:~/.local/share/pyenv" + ] + }, + { + "name": "python-azure-cli", + "paths": [ + "~/.azure" + ], + "fixes": [ + "~/.azure:~/.config/azure" + ] + }, + { + "name": "python-grip", + "paths": [ + "~/.grip" + ], + "fixes": [ + "~/.grip:~/.config/grip" + ] + }, + { + "name": "python-setuptools", + "paths": [ + "~/.python-eggs" + ], + "fixes": [ + "~/.python-eggs:~/.cache/python-eggs" + ] + }, + { + "name": "racket", + "paths": [ + "~/.racketrc", + "~/.racket" + ], + "fixes": [ + "~/.racketrc:~/.config/racketrc", + "~/.racket:~/.local/share/racket" + ] + }, + { + "name": "rbenv", + "paths": [ + "~/.rbenv" + ], + "fixes": [ + "~/.rbenv:~/.local/share/rbenv" + ] + }, + { + "name": "nodenv", + "paths": [ + "~/.nodenv" + ], + "fixes": [ + "~/.nodenv:~/.local/share/nodenv" + ] + }, + { + "name": "readline", + "paths": [ + "~/.inputrc" + ], + "fixes": [ + "~/.inputrc:~/.config/inputrc" + ] + }, + { + "name": "recoll", + "paths": [ + "~/.recoll" + ], + "fixes": [ + "~/.recoll:~/.config/recoll" + ] + }, + { + "name": "redis", + "paths": [ + "~/.rediscli_history", + "~/.redisclirc" + ], + "fixes": [ + "~/.rediscli_history:~/.local/share/rediscli_history", + "~/.redisclirc:~/.config/redisclirc" + ] + }, + { + "name": "ruby-solargraph", + "paths": [ + "~/.solargraph/cache/" + ], + "fixes": [ + "~/.solargraph/cache/:~/.cache/solargraph" + ] + }, + { + "name": "Rust#Rustup", + "paths": [ + "~/.rustup" + ], + "fixes": [ + "~/.rustup:~/.local/share/rustup" + ] + }, + { + "name": "sbt", + "paths": [ + "~/.sbt", + "~/.ivy2" + ], + "fixes": [ + "~/.sbt:~/.config/sbt", + "~/.ivy2:~/.cache/ivy2" + ] + }, + { + "name": "SageMath", + "paths": [ + "~/.sage" + ], + "fixes": [ + "~/.sage:~/.local/share/sage" + ] + }, + { + "name": "GNU Screen", + "paths": [ + "~/.screenrc" + ], + "fixes": [ + "~/.screenrc:~/.config/screenrc" + ] + }, + { + "name": "simplescreenrecorder", + "paths": [ + "~/.ssr/" + ], + "fixes": [ + "~/.ssr/:~/.local/share/ssr" + ] + }, + { + "name": "spacemacs", + "paths": [ + "~/.spacemacs", + "~/.spacemacs.d" + ], + "fixes": [ + "~/.spacemacs:~/.config/spacemacs/init.el", + "~/.spacemacs.d:~/.config/spacemacs.d" + ] + }, + { + "name": "Haskell - Stack", + "paths": [ + "~/.stack" + ], + "fixes": [ + "~/.stack:~/.local/share/stack" + ] + }, + { + "name": "subversion", + "paths": [ + "~/.subversion" + ], + "fixes": [ + "~/.subversion:~/.config/subversion" + ] + }, + { + "name": "Local TeX Live TeXmf tree, TeXmf caches and config", + "paths": [ + "~/texmf", + "~/.texlive/texmf-var", + "~/.texlive/texmf-config" + ], + "fixes": [ + "~/.texlive/texmf-var:~/.cache/texlive/texmf-var", + "~/.texlive/texmf-config:~/.config/texlive/texmf-config", + "~/texmf:~/.local/share/texmf" + ] + }, + { + "name": "TeXmacs", + "paths": [ + "~/.TeXmacs" + ], + "fixes": [ + "~/.TeXmacs:~/.local/state/texmacs" + ] + }, + { + "name": "tiptop", + "paths": [ + "~/.tiptoprc" + ], + "fixes": [ + "~/.tiptoprc:~/.config/tiptop/tiptoprc" + ] + }, + { + "name": "ruby-travis", + "paths": [ + "~/.travis/" + ], + "fixes": [ + "~/.travis:~/.config/travis" + ] + }, + { + "name": "uncrustify", + "paths": [ + "~/.uncrustify.cfg" + ], + "fixes": [ + "~/.uncrustify.cfg:~/.config/uncrustify/uncrustify.cfg" + ] + }, + { + "name": "Unison", + "paths": [ + "~/.unison" + ], + "fixes": [ + "~/.unison:~/.local/share/unison" + ] + }, + { + "name": "units", + "paths": [ + "~/.units_history" + ], + "fixes": [ + "~/.units_history:~/.cache/units_history" + ] + }, + { + "name": "urxvtd", + "paths": [ + "~/.urxvt/urxvtd-hostname" + ], + "fixes": [ + "~/.urxvt/urxvtd-hostname:~/.local/state/urxvt/urxvtd-hostname" + ] + }, + { + "name": "Vagrant", + "paths": [ + "~/.vagrant.d", + "~/.vagrant.d/aliases" + ], + "fixes": [ + "~/.vagrant.d/aliases:~/.config/vagrant.d/aliases", + "~/.vagrant.d:~/.local/share/vagrant.d" + ] + }, + { + "name": "virtualenv", + "paths": [ + "~/.virtualenvs" + ], + "fixes": [ + "~/.virtualenvs:~/.local/share/virtualenvs" + ] + }, + { + "name": "Visual Studio Code", + "paths": [ + "~/.vscode-oss/" + ], + "fixes": [ + "~/.vscode-oss:~/.local/share/vscode-oss" + ] + }, + { + "name": "VSCodium", + "paths": [ + "~/.vscode-oss/" + ], + "fixes": [ + "~/.vscode-oss:~/.local/share/vscodium" + ] + }, + { + "name": "w3m", + "paths": [ + "~/.w3m" + ], + "fixes": [ + "~/.w3m:~/.config/w3m" + ] + }, + { + "name": "wget", + "paths": [ + "~/.wgetrc", + "~/.wget-hsts" + ], + "fixes": [ + "~/.wgetrc:~/.config/wget/wgetrc", + "~/.wget-hsts:~/.local/share/wget-hsts" + ] + }, + { + "name": "wine", + "paths": [ + "~/.wine" + ], + "fixes": [ + "~/.wine:~/.local/share/wineprefixes/default" + ] + }, + { + "name": "xbindkeys", + "paths": [ + "~/.xbindkeysrc" + ], + "fixes": [ + "~/.xbindkeysrc:~/.config/xbindkeys/config" + ] + }, + { + "name": "z", + "paths": [ + "~/.z" + ], + "fixes": [ + "~/.z:~/.local/share/z/z" + ] + }, + { + "name": "yarn", + "paths": [ + "~/.yarnrc", + "~/.yarn/", + "~/.yarncache/", + "~/.yarn-config/" + ], + "fixes": [ + "~/.yarnrc:~/.config/yarn/yarnrc", + "~/.yarn/:~/.config/yarn/global", + "~/.yarncache/:~/.cache/yarn", + "~/.yarn-config/:~/.config/yarn/local" + ] + } +] diff --git a/src/main.rs b/src/main.rs index 656b53f..1b0a2e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,9 +9,11 @@ use config::{Config, FileFormat}; use log::*; use which::which; -use crate::enclosure::rule::BoxxyConfig; +use crate::enclosure::rule::{BoxxyConfig, Rule, RuleMode}; +use crate::scanner::Scanner; pub mod enclosure; +pub mod scanner; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -22,6 +24,7 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); about = "Put bad programs in a box with only their files.", long_about = "boxxy forces bad programs to put their files somewhere else via Linux user namespaces.", version = VERSION, + subcommand_negates_reqs = true, )] pub struct Args { #[arg( @@ -59,13 +62,21 @@ pub struct Args { } #[derive(Subcommand)] -#[command( - name = "config", - about = "View the config file.", - subcommand_negates_reqs = true -)] pub enum BoxxySubcommand { + #[command( + name = "config", + about = "View the config file.", + subcommand_negates_reqs = true, + aliases = &["cfg", "conf", "c"] + )] Config, + #[command( + name = "scan", + about = "Scan your homedir for applications that may benefit from boxxy.", + subcommand_negates_reqs = true, + aliases = &["s"] + )] + Scan, } fn main() -> Result<()> { @@ -74,12 +85,67 @@ fn main() -> Result<()> { let self_exe = std::env::args().next().unwrap(); setup_logging(&cfg, &self_exe)?; - if let Some(BoxxySubcommand::Config) = cfg.command { - let config_path = config_file_path(&self_exe)?; - let mut printer = bat::PrettyPrinter::new(); - printer.input_file(config_path).print()?; + if let Some(cmd) = cfg.command { + match cmd { + BoxxySubcommand::Config => { + let config_path = config_file_path(&self_exe)?; + let mut printer = bat::PrettyPrinter::new(); + printer.input_file(config_path).print()?; - return Ok(()); + return Ok(()); + } + BoxxySubcommand::Scan => { + let apps = Scanner::new().scan()?; + if !apps.is_empty() { + info!( + "found {} applications that might be boxxable! generating config...", + apps.len() + ); + let mut rules = vec![]; + for app in apps { + for fix in app.fixes { + let (old, new) = fix.split_once(':').unwrap(); + let path = PathBuf::from(old); + let mode = if path.is_dir() { + RuleMode::Directory + } else { + RuleMode::File + }; + rules.push(Rule { + name: app.name.clone(), + target: old.into(), + rewrite: new.into(), + mode, + context: vec![], + only: vec![], + }); + } + } + let config = BoxxyConfig { + rules: rules.clone(), + }; + let config = &serde_yaml::to_string(&config)?; + let mut printer = bat::PrettyPrinter::new(); + println!(); + printer + .input_from_bytes(config.as_bytes()) + .language("yaml") + .print() + .expect("failed to print config"); + println!(); + warn!("!!! BE CAREFUL WITH THIS CONFIG !!!"); + warn!("SAFETY IS NOT GUARANTEED!!!"); + warn!("this config was automatically generated and may not be correct."); + warn!("please review the config before using it!"); + info!("rules generated: {}", rules.len()); + info!( + "put relevant rules in your config file: {}", + config_file_path(&self_exe)?.display() + ); + } + return Ok(()); + } + } } // Load rules diff --git a/src/scanner/mod.rs b/src/scanner/mod.rs new file mode 100644 index 0000000..b7bec99 --- /dev/null +++ b/src/scanner/mod.rs @@ -0,0 +1,46 @@ +use std::path::PathBuf; + +use color_eyre::Result; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct App { + pub name: String, + pub paths: Vec, + pub fixes: Vec, +} + +pub struct Scanner { + pub apps: Vec, +} + +const HARDCODED_APPS_JSON: &str = include_str!("../../data/hardcoded-applications.json"); +const PARTIAL_APPS_JSON: &str = include_str!("../../data/partial-support-applications.json"); + +impl Scanner { + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + let mut hardcoded = serde_json::from_str::>(HARDCODED_APPS_JSON).unwrap(); + let mut partial = serde_json::from_str::>(PARTIAL_APPS_JSON).unwrap(); + let mut apps = vec![]; + apps.append(&mut hardcoded); + apps.append(&mut partial); + + Self { apps } + } + + pub fn scan(&mut self) -> Result> { + let mut out = vec![]; + + for app in &self.apps { + for path in &app.paths { + let path = shellexpand::full(&path)?.to_string(); + if PathBuf::from(path).exists() { + out.push(app.clone()); + } + } + } + + Ok(out) + } +}