diff --git a/flake-modules/devshells.nix b/flake-modules/devshells.nix index 962c4bf..c387269 100644 --- a/flake-modules/devshells.nix +++ b/flake-modules/devshells.nix @@ -6,6 +6,7 @@ _: { buildInputs = [ pkgs.just self'.packages.nvim + pkgs.uv ]; QEMU_OPTS_WL = "-enable-kvm -nodefaults -m 4G -cpu host -smp 4 -device virtio-gpu"; }; diff --git a/scripts/default.nix b/scripts/default.nix index 534f1e9..0152c68 100644 --- a/scripts/default.nix +++ b/scripts/default.nix @@ -30,19 +30,19 @@ let callRustPackage = pkgs: pname: nixSrc: pkgs.callPackage nixSrc { cleanRustSrc = cleanRustSrc pname; }; - packages = { - jpassmenu = ./jpassmenu/package.nix; - audiomenu = ./audiomenu/package.nix; + packages = pkgs: { + jpassmenu = pkgs.callPackage ./jpassmenu/package.nix { }; + audiomenu = callRustPackage pkgs "audiomenu" ./audiomenu/package.nix; }; in { # Add scripts to overlay - flake.overlays.scripts = _final: prev: builtins.mapAttrs (callRustPackage prev) packages; + flake.overlays.scripts = _final: packages; # Add scripts to packages perSystem = { pkgs, ... }: { - packages = builtins.mapAttrs (callRustPackage pkgs) packages; + packages = packages pkgs; }; } diff --git a/scripts/jpassmenu/.envrc b/scripts/jpassmenu/.envrc new file mode 100644 index 0000000..729d54f --- /dev/null +++ b/scripts/jpassmenu/.envrc @@ -0,0 +1,2 @@ +source_up +source .venv/bin/activate diff --git a/scripts/jpassmenu/.gitignore b/scripts/jpassmenu/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/scripts/jpassmenu/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/scripts/jpassmenu/.python-version b/scripts/jpassmenu/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/scripts/jpassmenu/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/scripts/jpassmenu/Cargo.lock b/scripts/jpassmenu/Cargo.lock deleted file mode 100644 index eb6f737..0000000 --- a/scripts/jpassmenu/Cargo.lock +++ /dev/null @@ -1,728 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anstyle-parse" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" -dependencies = [ - "anstyle", - "once_cell", - "windows-sys", -] - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "backtrace-ext" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" -dependencies = [ - "backtrace", -] - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "bstr" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.5.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "duct" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6ce170a0e8454fa0f9b0e5ca38a6ba17ed76a50916839d217eb5357e05cdfde" -dependencies = [ - "libc", - "os_pipe", - "shared_child", - "shared_thread", -] - -[[package]] -name = "env_filter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "globset" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "ignore" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "is_ci" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "jiff" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde", -] - -[[package]] -name = "jiff-static" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "jpassmenu" -version = "0.1.0" -dependencies = [ - "clap", - "duct", - "env_logger", - "ignore", - "log", - "miette", -] - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miette" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" -dependencies = [ - "backtrace", - "backtrace-ext", - "cfg-if", - "miette-derive", - "owo-colors", - "supports-color", - "supports-hyperlinks", - "supports-unicode", - "terminal_size", - "textwrap", - "unicode-width 0.1.14", -] - -[[package]] -name = "miette-derive" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "os_pipe" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "owo-colors" -version = "4.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec" - -[[package]] -name = "portable-atomic" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shared_child" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e297bd52991bbe0686c086957bee142f13df85d1e79b0b21630a99d374ae9dc" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "shared_thread" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a6f98357c6bb0ebace19b22220e5543801d9de90ffe77f8abb27c056bac064" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "supports-color" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" -dependencies = [ - "is_ci", -] - -[[package]] -name = "supports-hyperlinks" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" - -[[package]] -name = "supports-unicode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" - -[[package]] -name = "syn" -version = "2.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "terminal_size" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" -dependencies = [ - "rustix", - "windows-sys", -] - -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" -dependencies = [ - "unicode-linebreak", - "unicode-width 0.2.0", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/scripts/jpassmenu/Cargo.toml b/scripts/jpassmenu/Cargo.toml deleted file mode 100644 index 68c2cad..0000000 --- a/scripts/jpassmenu/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "jpassmenu" -description = "A simple program that uses dmenu compatible menu to select a password to type/copy" -version = "0.1.0" -edition = "2021" - -[dependencies] -clap = { version = "4.5.23", features = ["derive", "env"] } -duct = "1.0.0" -env_logger = "0.11.5" -ignore = "0.4.23" -log = "0.4.22" -miette = { version = "7.4.0", features = ["fancy"] } - -[profile.release] -lto = true -opt-level = "s" -panic = "abort" -strip = true diff --git a/scripts/jpassmenu/README.md b/scripts/jpassmenu/README.md new file mode 100644 index 0000000..2c28fb8 --- /dev/null +++ b/scripts/jpassmenu/README.md @@ -0,0 +1,3 @@ +# jpassmenu + +My own implementation of the `passmenu` `dmenu` script, this one uses `fuzzel` by default and types passwords with `ydotool`. diff --git a/scripts/jpassmenu/jpassmenu.py b/scripts/jpassmenu/jpassmenu.py new file mode 100644 index 0000000..f446412 --- /dev/null +++ b/scripts/jpassmenu/jpassmenu.py @@ -0,0 +1,111 @@ +from os import environ +from pathlib import Path +import subprocess +import click + + +def select(options: list[str]) -> int | None: + menu_output = subprocess.run( + ["fuzzel", "--dmenu"], + input="\n".join(options), + encoding="UTF-8", + capture_output=True, + ) + if menu_output.returncode == 2: + return None + menu_output.check_returncode() + selected = menu_output.stdout.rstrip() + return options.index(selected) + + +@click.command( + "jpassmenu", context_settings={"show_default": True, "max_content_width": 120} +) +@click.option( + "--type", + "typeit", + help="Type the password using ydotool instead of copying it to the clipboard", +) +@click.option( + "--store-dir", + type=click.Path(exists=True, file_okay=False, path_type=Path), + envvar="PASSWORD_STORE_DIR", + default=Path("~/.password-store"), +) +@click.option( + "--pass-bin", + default="pass", + help="Path to the pass binary\n\nNeeds to support `pass show` and `pass show --clip`", +) +@click.option( + "--menu-bin", default="fuzzel", help="Path to the dmenu compatible menu binary" +) +@click.argument("menu_args", nargs=-1) +def main( + typeit: bool, store_dir: Path, pass_bin: str, menu_bin: str, menu_args: list[str] +) -> None: + menu_args = ( + ["--dmenu"] if not menu_args and menu_bin.endswith("fuzzel") else menu_args + ) + store_dir = store_dir.expanduser().absolute() + # Get all files in store_dir + secrets = ( + dirpath / fname + for dirpath, _dirnames, filenames in store_dir.walk() + for fname in filenames + ) + # Filter for files ending in .gpg and strip the extension + secrets = ( + secret.with_suffix("") + for secret in secrets + if secret.is_file() and secret.suffix == ".gpg" + ) + # Make the paths relative to store_dir and turn to strings + secrets = sorted(str(secret.relative_to(store_dir)) for secret in secrets) + + if not secrets: + click.secho(f"No valid entries found in {store_dir}", err=True, fg="red") + + selected = select(secrets) + if selected is None: + click.echo("No secret selected") + return + selected = secrets[selected] + + # If PASSWORD_STORE_DIR and --store-dir disagree, set PASSWORD_STORE_DIR to --store-dir + env_store = ( + Path(environ.get("PASSWORD_STORE_DIR", default="~/.password-store")) + .expanduser() + .absolute() + ) + if store_dir != env_store: + environ["PASSWORD_STORE_DIR"] = str(store_dir) + + pass_cmd = ( + [pass_bin, "show", selected] + if typeit + else [pass_bin, "show", "--clip", selected] + ) + + pass_output = subprocess.run( + pass_cmd, + encoding="UTF-8", + check=True, + capture_output=typeit, + ) + if not typeit: + return + + pass_entry = pass_output.stdout + secret = pass_entry.splitlines()[0].strip() + + _ = subprocess.run( + ["ydotool", "type", "--file", "-"], + input=secret, + encoding="UTF-8", + check=True, + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/jpassmenu/package.nix b/scripts/jpassmenu/package.nix index ceb495b..b74c27e 100644 --- a/scripts/jpassmenu/package.nix +++ b/scripts/jpassmenu/package.nix @@ -1,22 +1,6 @@ -{ - lib, - rustPlatform, - cleanRustSrc, -}: -let - cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); - inherit (cargoToml.package) name version description; - pname = name; - src = cleanRustSrc ./.; -in -rustPlatform.buildRustPackage { - inherit pname version src; - cargoLock.lockFile = ./Cargo.lock; - useNextest = true; - meta = { - inherit description; - license = lib.licenses.mit; - homepage = "https://github.com/jalil-salame/configuration.nix"; - mainProgram = name; - }; -} +{ writers, python3Packages }: +writers.writePython3 "jpassmenu" { + libraries = [ python3Packages.click ]; + # line too long, but I like my code well documented + flakeIgnore = [ "E501" ]; +} ./jpassmenu.py diff --git a/scripts/jpassmenu/pyproject.toml b/scripts/jpassmenu/pyproject.toml new file mode 100644 index 0000000..5cfa6aa --- /dev/null +++ b/scripts/jpassmenu/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "jpassmenu" +version = "0.1.0" +description = "A simple program that uses dmenu compatible menu to select a password to type/copy" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "click>=8.1.7", +] diff --git a/scripts/jpassmenu/src/main.rs b/scripts/jpassmenu/src/main.rs deleted file mode 100644 index 279dbdc..0000000 --- a/scripts/jpassmenu/src/main.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::{ - ffi::OsStr, - fmt::Write as _, - path::{Path, PathBuf}, -}; - -use clap::Parser; -use duct::cmd; -use miette::{bail, ensure, Context, IntoDiagnostic, Result}; - -fn main() -> Result<()> { - miette::set_panic_hook(); - env_logger::builder() - .filter_level(log::LevelFilter::Info) - .parse_default_env() - .try_init() - .into_diagnostic()?; - Opts::parse().run() -} - -impl Opts { - fn run(self) -> Result<()> { - log::debug!("parsed opts {self:?}"); - let Self { - typeit, - store_dir, - pass_bin, - menu_bin, - menu_args, - } = self; - let store_dir = resolve_home(store_dir); - // Search paths - log::info!("looking for entries in {}", store_dir.display()); - let mut paths = ignore::Walk::new(&store_dir) - .filter_map(|entry| { - let entry = entry.ok()?; - if entry.file_type()?.is_file() - && entry.path().extension() == Some(OsStr::new("gpg")) - { - let path = entry.path(); - Some( - path.strip_prefix(&store_dir) - .unwrap_or(path) - .with_extension("") - .into_boxed_path(), - ) - } else { - None - } - }) - .collect::>>(); - paths.sort_unstable(); - ensure!( - !paths.is_empty(), - "failed to find entries in {}", - store_dir.display() - ); - log::debug!("found entries: {paths:#?}"); - // Concatenate all paths - let paths = paths - .into_iter() - .try_fold(String::new(), |mut acc, it| { - writeln!(acc, "{}", it.display()).map(|_| acc) - }) - .into_diagnostic() - .wrap_err("preparing paths")?; - // Show dynamic menu - let selected = cmd(menu_bin, menu_args) - .stdin_bytes(paths.as_bytes()) - .read() - .into_diagnostic() - .wrap_err("failed to run menu and retrieve the selected entry")?; - let selected = selected.trim(); - if selected.is_empty() { - bail!("no password entry selected"); - } - // Prepare env dir - let env_store = std::env::var_os("PASSWORD_STORE_DIR"); - let set_env = if let Some(env_store) = env_store { - if store_dir != env_store { - Some(store_dir) - } else { - None - } - } else if store_dir == Path::new("~/.password-store") { - None - } else { - Some(store_dir) - }; - // Prepare pass command - let args = if typeit { - vec!["show", selected] - } else { - vec!["show", "-c", selected] - }; - let pass = cmd(pass_bin, args); - let pass = if let Some(env) = set_env { - pass.env("PASSWORD_STORE_DIR", env) - } else { - pass - }; - // Copy password to clipboard - if !typeit { - pass.run() - .into_diagnostic() - .wrap_err("failed to copy password to clipboard")?; - return Ok(()); - } - // Retrieve password - let pass_entry = pass - .read() - .into_diagnostic() - .wrap_err("failed to retrieve password")?; - let Some(password) = pass_entry.lines().next() else { - bail!("failed to retrieve password or entry was empty"); - }; - // Type password with ydotool - cmd("ydotool", &["type", "--file", "-"]) - .stdin_bytes(password.as_bytes()) - .run() - .into_diagnostic() - .wrap_err("failed to type password with ydotool")?; - Ok(()) - } -} - -#[derive(Debug, Parser)] -struct Opts { - /// Type the password instead of copying it to the clipboard - #[arg(long("type"))] - typeit: bool, - #[arg(long, env("PASSWORD_STORE_DIR"), default_value = "~/.password-store")] - store_dir: PathBuf, - /// Path to the pass binary - /// - /// Needs to support `pass show` and `pass show -c` - #[arg(long, default_value = "pass")] - pass_bin: String, - /// Path to the dynamic menu binary - #[arg(long, default_value = "fuzzel")] - menu_bin: String, - /// Args to the dynamic menu - #[arg(long, default_value = "--dmenu")] - menu_args: Vec, -} - -fn resolve_home(path: PathBuf) -> PathBuf { - if let Ok(path) = path.strip_prefix("~") { - if let Some(home) = std::env::var_os("HOME") { - let mut home = PathBuf::from(home); - home.push(path); - return home; - } - } - path -} diff --git a/scripts/jpassmenu/uv.lock b/scripts/jpassmenu/uv.lock new file mode 100644 index 0000000..55d4696 --- /dev/null +++ b/scripts/jpassmenu/uv.lock @@ -0,0 +1,34 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "click" +version = "8.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/0f/62ca20172d4f87d93cf89665fbaedcd560ac48b465bd1d92bfc7ea6b0a41/click-8.2.0.tar.gz", hash = "sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d", size = 235857 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/58/1f37bf81e3c689cc74ffa42102fa8915b59085f54a6e4a80bc6265c0f6bf/click-8.2.0-py3-none-any.whl", hash = "sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c", size = 102156 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "jpassmenu" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "click" }, +] + +[package.metadata] +requires-dist = [{ name = "click", specifier = ">=8.2.0" }]