From 368cb6b0d25db2ae23be42ad51584de059997e51 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Mon, 20 May 2024 16:10:21 +0200 Subject: refactor(sys): Modularize and move to `modules/system` or `pkgs` --- modules/system/boot/boot_pictures/gnu.png | Bin 0 -> 327518 bytes modules/system/boot/boot_pictures/gnulin_emb_1.png | Bin 0 -> 207444 bytes modules/system/boot/boot_pictures/gnulin_emb_2.png | Bin 0 -> 208347 bytes modules/system/boot/default.nix | 129 + modules/system/boot/iso_entry/archlive_iso.nix | 77 + modules/system/boot/iso_entry/signing_key.nix | 18 + modules/system/cleanup/default.nix | 18 + modules/system/default.nix | 26 + modules/system/disks/default.nix | 133 + modules/system/disks/fstrim.nix | 42 + modules/system/disks/hibernate.nix | 45 + modules/system/documentation/default.nix | 24 + modules/system/fonts/default.nix | 55 + modules/system/fonts/emoji_font.xml | 22 + modules/system/hardware/default.nix | 68 + modules/system/impermanence/default.nix | 55 + modules/system/libvirtd/default.nix | 27 + modules/system/locale/default.nix | 57 + modules/system/locale/keymaps/dvorak_modified.xkb | 15 + modules/system/locale/keymaps/us_modified.xkb | 9 + modules/system/networking/default.nix | 81 + modules/system/polkit/default.nix | 14 + modules/system/power/default.nix | 33 + modules/system/secrets/default.nix | 82 + modules/system/secrets/lf/cd_paths | 4190 ++++++++++++++++++++ modules/system/secrets/nheko/conf.apzu | 45 + modules/system/secrets/nheko/conf.isimud | 47 + modules/system/secrets/nheko/conf.tiamat | 45 + modules/system/secrets/secrets.nix | 22 + modules/system/secrets/serverphone/ca.key | 19 + modules/system/secrets/serverphone/server.key | 19 + modules/system/secrets/taskserver/ca.cert | 92 + modules/system/secrets/taskserver/credentials | 15 + modules/system/secrets/taskserver/private.key | 450 +++ modules/system/secrets/taskserver/public.cert | 83 + modules/system/secrets/update.sh | 37 + modules/system/services/adb/default.nix | 22 + modules/system/services/backup/default.nix | 49 + modules/system/services/dconf/default.nix | 7 + modules/system/services/default.nix | 19 + modules/system/services/fwupd/default.nix | 14 + modules/system/services/issue_file/default.nix | 38 + modules/system/services/nix/default.nix | 53 + modules/system/services/openssh/default.nix | 15 + modules/system/services/postgresql/default.nix | 17 + modules/system/services/printing/default.nix | 45 + modules/system/services/scanning/default.nix | 25 + .../services/serverphone/certificates/ca.crt | 10 + .../services/serverphone/certificates/server.crt | 10 + modules/system/services/serverphone/default.nix | 49 + modules/system/services/serverphone/keys/key_1 | 1 + modules/system/services/serverphone/keys/key_2 | 1 + modules/system/services/snapper/default.nix | 53 + modules/system/services/steam/default.nix | 23 + modules/system/services/swaylock/default.nix | 4 + modules/system/services/xdg/default.nix | 58 + modules/system/services/xdg/scripts/lf_wrapper.sh | 79 + .../system/services/xdg/scripts/ranger_wrapper.sh | 68 + modules/system/sound/default.nix | 38 + modules/system/tempfiles/default.nix | 20 + modules/system/users/default.nix | 50 + modules/system/version/default.nix | 19 + modules/system/waydroid/default.nix | 5 + pkgs/default.nix | 24 + pkgs/sources/comments/.envrc | 4 + pkgs/sources/comments/.gitignore | 3 + pkgs/sources/comments/Cargo.lock | 446 +++ pkgs/sources/comments/Cargo.toml | 16 + pkgs/sources/comments/comments.nix | 25 + pkgs/sources/comments/default.nix | 18 + pkgs/sources/comments/flake.lock | 61 + pkgs/sources/comments/flake.nix | 31 + pkgs/sources/comments/src/info_json.rs | 223 ++ pkgs/sources/comments/src/main.rs | 322 ++ pkgs/sources/comments/update.sh | 8 + pkgs/sources/default.nix | 27 + pkgs/sources/generate_moz_extension/.envrc | 1 + pkgs/sources/generate_moz_extension/.gitignore | 3 + pkgs/sources/generate_moz_extension/Cargo.lock | 1275 ++++++ pkgs/sources/generate_moz_extension/Cargo.toml | 14 + pkgs/sources/generate_moz_extension/default.nix | 16 + .../examples/generate_extensions.sh | 17 + pkgs/sources/generate_moz_extension/flake.lock | 106 + pkgs/sources/generate_moz_extension/flake.nix | 75 + .../generate_firefox_extensions.nix | 20 + .../res/generate_extensions.py | 44 + .../generate_moz_extension/res/reference.json | 30 + pkgs/sources/generate_moz_extension/res/test.json | 30 + pkgs/sources/generate_moz_extension/src/main.rs | 138 + pkgs/sources/generate_moz_extension/src/types.rs | 71 + pkgs/sources/generate_moz_extension/update.sh | 8 + pkgs/sources/lf-make-map/.envrc | 11 + pkgs/sources/lf-make-map/.gitignore | 6 + pkgs/sources/lf-make-map/Cargo.lock | 505 +++ pkgs/sources/lf-make-map/Cargo.toml | 14 + pkgs/sources/lf-make-map/README.md | 12 + pkgs/sources/lf-make-map/default.nix | 12 + pkgs/sources/lf-make-map/flake.lock | 147 + pkgs/sources/lf-make-map/flake.nix | 125 + pkgs/sources/lf-make-map/lf_make_map.nix | 10 + pkgs/sources/lf-make-map/src/cli.rs | 49 + pkgs/sources/lf-make-map/src/main.rs | 229 ++ .../lf-make-map/src/mapping/map_tree/display.rs | 91 + .../lf-make-map/src/mapping/map_tree/iterator.rs | 53 + .../lf-make-map/src/mapping/map_tree/lf_mapping.rs | 19 + .../lf-make-map/src/mapping/map_tree/mod.rs | 402 ++ pkgs/sources/lf-make-map/src/mapping/mod.rs | 156 + pkgs/sources/lf-make-map/update.sh | 6 + pkgs/sources/plgs-pkgs/README.md | 92 + pkgs/sources/plgs-pkgs/check.nix | 37 + pkgs/sources/plgs-pkgs/default.nix | 15 + pkgs/sources/plgs-pkgs/overrides.nix | 34 + pkgs/sources/plgs-pkgs/plugins/.plugins.json | 7 + pkgs/sources/plgs-pkgs/plugins/blacklist.txt | 1 + pkgs/sources/plgs-pkgs/plugins/default.nix | 55 + pkgs/sources/plgs-pkgs/plugins/manifest.txt | 3 + pkgs/sources/plgs-pkgs/plugins/plugins.md | 7 + pkgs/sources/plgs-pkgs/plugins/whitelist.txt | 0 pkgs/sources/plgs-pkgs/update.sh | 27 + pkgs/sources/scripts/default.nix | 412 ++ pkgs/sources/scripts/source/apps/aumo.sh | 28 + pkgs/sources/scripts/source/apps/con2pdf.sh | 234 ++ pkgs/sources/scripts/source/apps/fupdate.1.md | 70 + pkgs/sources/scripts/source/apps/fupdate.sh | 197 + pkgs/sources/scripts/source/apps/git-edit-index.sh | 98 + .../scripts/source/small_functions/brightness.sh | 80 + .../sources/scripts/source/small_functions/nato.py | 106 + .../small_functions/screenshot_persistent.sh | 22 + .../source/small_functions/screenshot_temporary.sh | 8 + .../scripts/source/small_functions/update-sys.sh | 85 + .../source/specific/neorg/neorg_id_function.sh | 16 + .../source/specific/neorg/sh/functions/add.sh | 23 + .../source/specific/neorg/sh/functions/context.sh | 43 + .../source/specific/neorg/sh/functions/dmenu.sh | 14 + .../source/specific/neorg/sh/functions/f_start.sh | 7 + .../source/specific/neorg/sh/functions/f_stop.sh | 7 + .../source/specific/neorg/sh/functions/list.sh | 8 + .../source/specific/neorg/sh/functions/project.sh | 41 + .../source/specific/neorg/sh/functions/review.sh | 12 + .../source/specific/neorg/sh/functions/utils.sh | 40 + .../specific/neorg/sh/functions/workspace.sh | 9 + .../scripts/source/specific/neorg/sh/main.sh | 164 + .../scripts/source/specific/spodi/sh/download.sh | 58 + .../scripts/source/specific/spodi/sh/update.sh | 52 + .../sources/scripts/source/specific/spodi/spodi.sh | 71 + .../scripts/source/specific/ytcc/description.sh | 8 + pkgs/sources/scripts/source/wrappers/battery.sh | 11 + pkgs/sources/scripts/source/wrappers/hibernate.sh | 15 + pkgs/sources/scripts/source/wrappers/ll.sh | 14 + pkgs/sources/scripts/source/wrappers/lock.sh | 18 + pkgs/sources/scripts/source/wrappers/lyrics.sh | 11 + pkgs/sources/scripts/source/wrappers/mpc-fav.sh | 16 + pkgs/sources/scripts/source/wrappers/mpc-rm.sh | 10 + pkgs/sources/scripts/source/wrappers/mpc.sh | 20 + pkgs/sources/scripts/source/wrappers/show.sh | 9 + pkgs/sources/scripts/source/wrappers/sort_song.sh | 34 + pkgs/sources/scripts/source/wrappers/virsh-del.sh | 10 + pkgs/sources/scripts/source/wrappers/yti.sh | 33 + pkgs/sources/snap-sync-forked/default.nix | 24 + pkgs/sources/snap-sync-forked/snap-sync-forked.sh | 534 +++ pkgs/sources/tree-sitter-yts/.editorconfig | 21 + pkgs/sources/tree-sitter-yts/.envrc | 1 + pkgs/sources/tree-sitter-yts/.gitignore | 3 + pkgs/sources/tree-sitter-yts/Cargo.toml | 21 + pkgs/sources/tree-sitter-yts/binding.gyp | 19 + .../tree-sitter-yts/bindings/node/binding.cc | 33 + .../sources/tree-sitter-yts/bindings/node/index.js | 19 + .../sources/tree-sitter-yts/bindings/rust/build.rs | 40 + pkgs/sources/tree-sitter-yts/bindings/rust/lib.rs | 52 + pkgs/sources/tree-sitter-yts/corpus/comments.txt | 51 + .../tree-sitter-yts/corpus/comments_correct.txt | 27 + pkgs/sources/tree-sitter-yts/corpus/duration.txt | 84 + pkgs/sources/tree-sitter-yts/corpus/url.txt | 84 + pkgs/sources/tree-sitter-yts/default.nix | 11 + pkgs/sources/tree-sitter-yts/flake.lock | 97 + pkgs/sources/tree-sitter-yts/flake.nix | 82 + pkgs/sources/tree-sitter-yts/grammar.js | 26 + pkgs/sources/tree-sitter-yts/highlight.yts | 4 + pkgs/sources/tree-sitter-yts/package.json | 31 + pkgs/sources/tree-sitter-yts/package.nix | 63 + .../sources/tree-sitter-yts/queries/highlights.scm | 11 + pkgs/sources/tree-sitter-yts/src/grammar.json | 238 ++ pkgs/sources/tree-sitter-yts/src/node-types.json | 200 + pkgs/sources/tree-sitter-yts/src/parser.c | 1108 ++++++ .../tree-sitter-yts/src/tree_sitter/parser.h | 241 ++ pkgs/sources/tree-sitter-yts/treefmt.toml | 35 + pkgs/sources/update_pkgs.sh | 25 + pkgs/sources/update_vim_plugins/.envrc | 1 + .../sources/update_vim_plugins/check-duplicates.sh | 43 + pkgs/sources/update_vim_plugins/default.nix | 17 + pkgs/sources/update_vim_plugins/flake.lock | 61 + pkgs/sources/update_vim_plugins/flake.nix | 24 + pkgs/sources/update_vim_plugins/package.nix | 47 + pkgs/sources/update_vim_plugins/poetry.lock | 680 ++++ pkgs/sources/update_vim_plugins/pyproject.toml | 45 + pkgs/sources/update_vim_plugins/update.sh | 5 + .../update_vim_plugins/__init__.py | 0 .../update_vim_plugins/__main__.py | 15 + .../update_vim_plugins/cleanup.py | 100 + .../update_vim_plugins/helpers.py | 61 + .../update_vim_plugins/update_vim_plugins/nix.py | 121 + .../update_vim_plugins/plugin.py | 182 + .../update_vim_plugins/update_vim_plugins/spec.py | 143 + .../update_vim_plugins/tests/__init__.py | 0 .../update_vim_plugins/tests/fixtures.py | 44 + .../update_vim_plugins/tests/test_nix.py | 32 + .../update_vim_plugins/tests/test_plugin.py | 144 + .../update_vim_plugins/tests/test_spec.py | 136 + .../update_vim_plugins/update.py | 212 + pkgs/sources/yt/.env | 3 + pkgs/sources/yt/.envrc | 1 + pkgs/sources/yt/.gitignore | 3 + pkgs/sources/yt/Cargo.lock | 640 +++ pkgs/sources/yt/Cargo.toml | 35 + pkgs/sources/yt/default.nix | 51 + pkgs/sources/yt/flake.lock | 61 + pkgs/sources/yt/flake.nix | 30 + pkgs/sources/yt/src/bin/yt/main.rs | 91 + pkgs/sources/yt/src/bin/ytc/args.rs | 26 + pkgs/sources/yt/src/bin/ytc/main.rs | 77 + pkgs/sources/yt/src/bin/yts/args.rs | 41 + pkgs/sources/yt/src/bin/yts/main.rs | 91 + pkgs/sources/yt/src/constants.rs | 51 + pkgs/sources/yt/src/downloader.rs | 212 + pkgs/sources/yt/src/help.str | 8 + pkgs/sources/yt/src/lib.rs | 185 + pkgs/sources/yt/todo | 1 + pkgs/sources/yt/update.sh | 8 + pkgs/sources/yt/yt.nix | 29 + pkgs/sources/yt/ytc.nix | 29 + pkgs/sources/yt/yts.nix | 27 + sys/boot/archlive_iso.nix | 77 - sys/boot/boot_pictures/gnu.png | Bin 327518 -> 0 bytes sys/boot/boot_pictures/gnulin_emb_1.png | Bin 207444 -> 0 bytes sys/boot/boot_pictures/gnulin_emb_2.png | Bin 208347 -> 0 bytes sys/boot/default.nix | 117 - sys/boot/signing_key.nix | 18 - sys/default.nix | 28 - sys/disks/default.nix | 137 - sys/disks/fstrim.nix | 42 - sys/disks/hibernate.nix | 44 - sys/documentation/default.nix | 15 - sys/font/default.nix | 38 - sys/font/font.xml | 22 - sys/git_revision/default.nix | 8 - sys/hardware/default.nix | 44 - sys/impermanence/default.nix | 41 - sys/libvirtd/default.nix | 27 - sys/locale/default.nix | 49 - sys/locale/keymaps/dvorak_modified.xkb | 15 - sys/locale/keymaps/us_modified.xkb | 9 - sys/network/default.nix | 51 - sys/nixpkgs/default.nix | 23 - sys/nixpkgs/pkgs/comments/.envrc | 4 - sys/nixpkgs/pkgs/comments/.gitignore | 3 - sys/nixpkgs/pkgs/comments/Cargo.lock | 446 --- sys/nixpkgs/pkgs/comments/Cargo.toml | 16 - sys/nixpkgs/pkgs/comments/comments.nix | 25 - sys/nixpkgs/pkgs/comments/default.nix | 18 - sys/nixpkgs/pkgs/comments/flake.lock | 61 - sys/nixpkgs/pkgs/comments/flake.nix | 31 - sys/nixpkgs/pkgs/comments/src/info_json.rs | 223 -- sys/nixpkgs/pkgs/comments/src/main.rs | 322 -- sys/nixpkgs/pkgs/comments/update.sh | 8 - sys/nixpkgs/pkgs/default.nix | 26 - sys/nixpkgs/pkgs/generate_moz_extension/.envrc | 1 - sys/nixpkgs/pkgs/generate_moz_extension/.gitignore | 3 - sys/nixpkgs/pkgs/generate_moz_extension/Cargo.lock | 1275 ------ sys/nixpkgs/pkgs/generate_moz_extension/Cargo.toml | 14 - .../pkgs/generate_moz_extension/default.nix | 16 - .../examples/generate_extensions.sh | 17 - sys/nixpkgs/pkgs/generate_moz_extension/flake.lock | 106 - sys/nixpkgs/pkgs/generate_moz_extension/flake.nix | 75 - .../generate_firefox_extensions.nix | 20 - .../res/generate_extensions.py | 44 - .../pkgs/generate_moz_extension/res/reference.json | 30 - .../pkgs/generate_moz_extension/res/test.json | 30 - .../pkgs/generate_moz_extension/src/main.rs | 138 - .../pkgs/generate_moz_extension/src/types.rs | 71 - sys/nixpkgs/pkgs/generate_moz_extension/update.sh | 8 - sys/nixpkgs/pkgs/lf-make-map/.envrc | 11 - sys/nixpkgs/pkgs/lf-make-map/.gitignore | 6 - sys/nixpkgs/pkgs/lf-make-map/Cargo.lock | 505 --- sys/nixpkgs/pkgs/lf-make-map/Cargo.toml | 14 - sys/nixpkgs/pkgs/lf-make-map/README.md | 12 - sys/nixpkgs/pkgs/lf-make-map/default.nix | 12 - sys/nixpkgs/pkgs/lf-make-map/flake.lock | 147 - sys/nixpkgs/pkgs/lf-make-map/flake.nix | 125 - sys/nixpkgs/pkgs/lf-make-map/lf_make_map.nix | 10 - sys/nixpkgs/pkgs/lf-make-map/src/cli.rs | 49 - sys/nixpkgs/pkgs/lf-make-map/src/main.rs | 229 -- .../lf-make-map/src/mapping/map_tree/display.rs | 91 - .../lf-make-map/src/mapping/map_tree/iterator.rs | 53 - .../lf-make-map/src/mapping/map_tree/lf_mapping.rs | 19 - .../pkgs/lf-make-map/src/mapping/map_tree/mod.rs | 402 -- sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs | 156 - sys/nixpkgs/pkgs/lf-make-map/update.sh | 6 - sys/nixpkgs/pkgs/plgs-pkgs/README.md | 92 - sys/nixpkgs/pkgs/plgs-pkgs/check.nix | 37 - sys/nixpkgs/pkgs/plgs-pkgs/default.nix | 15 - sys/nixpkgs/pkgs/plgs-pkgs/overrides.nix | 34 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/.plugins.json | 7 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/blacklist.txt | 1 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/default.nix | 55 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/manifest.txt | 3 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/plugins.md | 7 - sys/nixpkgs/pkgs/plgs-pkgs/plugins/whitelist.txt | 0 sys/nixpkgs/pkgs/plgs-pkgs/update.sh | 27 - sys/nixpkgs/pkgs/scripts/default.nix | 392 -- sys/nixpkgs/pkgs/scripts/source/apps/aumo.sh | 28 - sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh | 234 -- sys/nixpkgs/pkgs/scripts/source/apps/fupdate.1.md | 70 - sys/nixpkgs/pkgs/scripts/source/apps/fupdate.sh | 197 - .../pkgs/scripts/source/apps/git-edit-index.sh | 98 - .../pkgs/scripts/source/small_functions/nato.py | 106 - .../small_functions/screenshot_persistent.sh | 22 - .../source/small_functions/screenshot_temporary.sh | 8 - .../scripts/source/small_functions/update-sys.sh | 85 - .../source/specific/neorg/neorg_id_function.sh | 16 - .../source/specific/neorg/sh/functions/add.sh | 23 - .../source/specific/neorg/sh/functions/context.sh | 43 - .../source/specific/neorg/sh/functions/dmenu.sh | 14 - .../source/specific/neorg/sh/functions/f_start.sh | 7 - .../source/specific/neorg/sh/functions/f_stop.sh | 7 - .../source/specific/neorg/sh/functions/list.sh | 8 - .../source/specific/neorg/sh/functions/project.sh | 41 - .../source/specific/neorg/sh/functions/review.sh | 12 - .../source/specific/neorg/sh/functions/utils.sh | 40 - .../specific/neorg/sh/functions/workspace.sh | 9 - .../pkgs/scripts/source/specific/neorg/sh/main.sh | 164 - .../scripts/source/specific/spodi/sh/download.sh | 58 - .../scripts/source/specific/spodi/sh/update.sh | 52 - .../pkgs/scripts/source/specific/spodi/spodi.sh | 71 - .../scripts/source/specific/ytcc/description.sh | 8 - .../pkgs/scripts/source/wrappers/battery.sh | 11 - .../pkgs/scripts/source/wrappers/hibernate.sh | 15 - sys/nixpkgs/pkgs/scripts/source/wrappers/ll.sh | 14 - sys/nixpkgs/pkgs/scripts/source/wrappers/lock.sh | 18 - sys/nixpkgs/pkgs/scripts/source/wrappers/lyrics.sh | 11 - .../pkgs/scripts/source/wrappers/mpc-fav.sh | 16 - sys/nixpkgs/pkgs/scripts/source/wrappers/mpc-rm.sh | 10 - sys/nixpkgs/pkgs/scripts/source/wrappers/mpc.sh | 20 - sys/nixpkgs/pkgs/scripts/source/wrappers/show.sh | 9 - .../pkgs/scripts/source/wrappers/sort_song.sh | 34 - .../pkgs/scripts/source/wrappers/virsh-del.sh | 10 - sys/nixpkgs/pkgs/scripts/source/wrappers/yti.sh | 33 - sys/nixpkgs/pkgs/snap-sync-forked/default.nix | 24 - .../pkgs/snap-sync-forked/snap-sync-forked.sh | 534 --- sys/nixpkgs/pkgs/tree-sitter-yts/.editorconfig | 21 - sys/nixpkgs/pkgs/tree-sitter-yts/.envrc | 1 - sys/nixpkgs/pkgs/tree-sitter-yts/.gitignore | 3 - sys/nixpkgs/pkgs/tree-sitter-yts/Cargo.toml | 21 - sys/nixpkgs/pkgs/tree-sitter-yts/binding.gyp | 19 - .../pkgs/tree-sitter-yts/bindings/node/binding.cc | 33 - .../pkgs/tree-sitter-yts/bindings/node/index.js | 19 - .../pkgs/tree-sitter-yts/bindings/rust/build.rs | 40 - .../pkgs/tree-sitter-yts/bindings/rust/lib.rs | 52 - .../pkgs/tree-sitter-yts/corpus/comments.txt | 51 - .../tree-sitter-yts/corpus/comments_correct.txt | 27 - .../pkgs/tree-sitter-yts/corpus/duration.txt | 84 - sys/nixpkgs/pkgs/tree-sitter-yts/corpus/url.txt | 84 - sys/nixpkgs/pkgs/tree-sitter-yts/default.nix | 11 - sys/nixpkgs/pkgs/tree-sitter-yts/flake.lock | 97 - sys/nixpkgs/pkgs/tree-sitter-yts/flake.nix | 82 - sys/nixpkgs/pkgs/tree-sitter-yts/grammar.js | 26 - sys/nixpkgs/pkgs/tree-sitter-yts/highlight.yts | 4 - sys/nixpkgs/pkgs/tree-sitter-yts/package.json | 31 - sys/nixpkgs/pkgs/tree-sitter-yts/package.nix | 63 - .../pkgs/tree-sitter-yts/queries/highlights.scm | 11 - sys/nixpkgs/pkgs/tree-sitter-yts/src/grammar.json | 238 -- .../pkgs/tree-sitter-yts/src/node-types.json | 200 - sys/nixpkgs/pkgs/tree-sitter-yts/src/parser.c | 1108 ------ .../pkgs/tree-sitter-yts/src/tree_sitter/parser.h | 241 -- sys/nixpkgs/pkgs/tree-sitter-yts/treefmt.toml | 35 - sys/nixpkgs/pkgs/update_pkgs.sh | 25 - sys/nixpkgs/pkgs/update_vim_plugins/.envrc | 1 - .../pkgs/update_vim_plugins/check-duplicates.sh | 43 - sys/nixpkgs/pkgs/update_vim_plugins/default.nix | 17 - sys/nixpkgs/pkgs/update_vim_plugins/flake.lock | 61 - sys/nixpkgs/pkgs/update_vim_plugins/flake.nix | 24 - sys/nixpkgs/pkgs/update_vim_plugins/package.nix | 47 - sys/nixpkgs/pkgs/update_vim_plugins/poetry.lock | 680 ---- sys/nixpkgs/pkgs/update_vim_plugins/pyproject.toml | 45 - sys/nixpkgs/pkgs/update_vim_plugins/update.sh | 5 - .../update_vim_plugins/__init__.py | 0 .../update_vim_plugins/__main__.py | 15 - .../update_vim_plugins/cleanup.py | 100 - .../update_vim_plugins/helpers.py | 61 - .../update_vim_plugins/update_vim_plugins/nix.py | 121 - .../update_vim_plugins/plugin.py | 182 - .../update_vim_plugins/update_vim_plugins/spec.py | 143 - .../update_vim_plugins/tests/__init__.py | 0 .../update_vim_plugins/tests/fixtures.py | 44 - .../update_vim_plugins/tests/test_nix.py | 32 - .../update_vim_plugins/tests/test_plugin.py | 144 - .../update_vim_plugins/tests/test_spec.py | 136 - .../update_vim_plugins/update.py | 212 - sys/nixpkgs/pkgs/yt/.env | 3 - sys/nixpkgs/pkgs/yt/.envrc | 1 - sys/nixpkgs/pkgs/yt/.gitignore | 3 - sys/nixpkgs/pkgs/yt/Cargo.lock | 640 --- sys/nixpkgs/pkgs/yt/Cargo.toml | 35 - sys/nixpkgs/pkgs/yt/default.nix | 51 - sys/nixpkgs/pkgs/yt/flake.lock | 61 - sys/nixpkgs/pkgs/yt/flake.nix | 30 - sys/nixpkgs/pkgs/yt/src/bin/yt/main.rs | 91 - sys/nixpkgs/pkgs/yt/src/bin/ytc/args.rs | 26 - sys/nixpkgs/pkgs/yt/src/bin/ytc/main.rs | 77 - sys/nixpkgs/pkgs/yt/src/bin/yts/args.rs | 41 - sys/nixpkgs/pkgs/yt/src/bin/yts/main.rs | 91 - sys/nixpkgs/pkgs/yt/src/constants.rs | 51 - sys/nixpkgs/pkgs/yt/src/downloader.rs | 212 - sys/nixpkgs/pkgs/yt/src/help.str | 8 - sys/nixpkgs/pkgs/yt/src/lib.rs | 185 - sys/nixpkgs/pkgs/yt/update.sh | 8 - sys/nixpkgs/pkgs/yt/yt.nix | 29 - sys/nixpkgs/pkgs/yt/ytc.nix | 29 - sys/nixpkgs/pkgs/yt/yts.nix | 27 - sys/options/default.nix | 26 - sys/options/secret.nix | Bin 25 -> 0 bytes sys/polkit/default.nix | 3 - sys/power/default.nix | 19 - sys/secrets/default.nix | 77 - sys/secrets/lf/cd_paths | 4190 -------------------- sys/secrets/nheko/conf.apzu | 45 - sys/secrets/nheko/conf.isimud | 47 - sys/secrets/nheko/conf.tiamat | 45 - sys/secrets/secrets.nix | 22 - sys/secrets/serverphone/ca.key | 19 - sys/secrets/serverphone/server.key | 19 - sys/secrets/taskserver/ca.cert | 92 - sys/secrets/taskserver/credentials | 15 - sys/secrets/taskserver/private.key | 450 --- sys/secrets/taskserver/public.cert | 83 - sys/secrets/update.sh | 37 - sys/sound/default.nix | 26 - sys/svcs/adb/default.nix | 22 - sys/svcs/backup/default.nix | 46 - sys/svcs/dconf/default.nix | 10 - sys/svcs/default.nix | 19 - sys/svcs/fwupd/default.nix | 3 - sys/svcs/getty/default.nix | 41 - sys/svcs/nix/default.nix | 52 - sys/svcs/openssh/default.nix | 15 - sys/svcs/postgresql/default.nix | 5 - sys/svcs/printing/default.nix | 31 - sys/svcs/scanning/default.nix | 12 - sys/svcs/serverphone/certificates/ca.crt | 10 - sys/svcs/serverphone/certificates/server.crt | 10 - sys/svcs/serverphone/default.nix | 49 - sys/svcs/serverphone/keys/key_1 | 1 - sys/svcs/serverphone/keys/key_2 | 1 - sys/svcs/snapper/default.nix | 41 - sys/svcs/steam/default.nix | 23 - sys/svcs/swaylock/default.nix | 4 - sys/svcs/xdg/default.nix | 58 - sys/svcs/xdg/scripts/lf_wrapper.sh | 79 - sys/svcs/xdg/scripts/ranger_wrapper.sh | 68 - sys/tempfiles/default.nix | 6 - sys/users/default.nix | 45 - sys/waydroid/default.nix | 4 - 461 files changed, 21179 insertions(+), 20842 deletions(-) create mode 100755 modules/system/boot/boot_pictures/gnu.png create mode 100755 modules/system/boot/boot_pictures/gnulin_emb_1.png create mode 100755 modules/system/boot/boot_pictures/gnulin_emb_2.png create mode 100644 modules/system/boot/default.nix create mode 100644 modules/system/boot/iso_entry/archlive_iso.nix create mode 100644 modules/system/boot/iso_entry/signing_key.nix create mode 100644 modules/system/cleanup/default.nix create mode 100644 modules/system/default.nix create mode 100644 modules/system/disks/default.nix create mode 100644 modules/system/disks/fstrim.nix create mode 100644 modules/system/disks/hibernate.nix create mode 100644 modules/system/documentation/default.nix create mode 100644 modules/system/fonts/default.nix create mode 100644 modules/system/fonts/emoji_font.xml create mode 100644 modules/system/hardware/default.nix create mode 100644 modules/system/impermanence/default.nix create mode 100644 modules/system/libvirtd/default.nix create mode 100644 modules/system/locale/default.nix create mode 100644 modules/system/locale/keymaps/dvorak_modified.xkb create mode 100644 modules/system/locale/keymaps/us_modified.xkb create mode 100644 modules/system/networking/default.nix create mode 100644 modules/system/polkit/default.nix create mode 100644 modules/system/power/default.nix create mode 100644 modules/system/secrets/default.nix create mode 100644 modules/system/secrets/lf/cd_paths create mode 100644 modules/system/secrets/nheko/conf.apzu create mode 100644 modules/system/secrets/nheko/conf.isimud create mode 100644 modules/system/secrets/nheko/conf.tiamat create mode 100644 modules/system/secrets/secrets.nix create mode 100644 modules/system/secrets/serverphone/ca.key create mode 100644 modules/system/secrets/serverphone/server.key create mode 100644 modules/system/secrets/taskserver/ca.cert create mode 100644 modules/system/secrets/taskserver/credentials create mode 100644 modules/system/secrets/taskserver/private.key create mode 100644 modules/system/secrets/taskserver/public.cert create mode 100755 modules/system/secrets/update.sh create mode 100644 modules/system/services/adb/default.nix create mode 100644 modules/system/services/backup/default.nix create mode 100644 modules/system/services/dconf/default.nix create mode 100644 modules/system/services/default.nix create mode 100644 modules/system/services/fwupd/default.nix create mode 100644 modules/system/services/issue_file/default.nix create mode 100644 modules/system/services/nix/default.nix create mode 100644 modules/system/services/openssh/default.nix create mode 100644 modules/system/services/postgresql/default.nix create mode 100644 modules/system/services/printing/default.nix create mode 100644 modules/system/services/scanning/default.nix create mode 100644 modules/system/services/serverphone/certificates/ca.crt create mode 100644 modules/system/services/serverphone/certificates/server.crt create mode 100644 modules/system/services/serverphone/default.nix create mode 120000 modules/system/services/serverphone/keys/key_1 create mode 120000 modules/system/services/serverphone/keys/key_2 create mode 100644 modules/system/services/snapper/default.nix create mode 100644 modules/system/services/steam/default.nix create mode 100644 modules/system/services/swaylock/default.nix create mode 100644 modules/system/services/xdg/default.nix create mode 100755 modules/system/services/xdg/scripts/lf_wrapper.sh create mode 100755 modules/system/services/xdg/scripts/ranger_wrapper.sh create mode 100644 modules/system/sound/default.nix create mode 100644 modules/system/tempfiles/default.nix create mode 100644 modules/system/users/default.nix create mode 100644 modules/system/version/default.nix create mode 100644 modules/system/waydroid/default.nix create mode 100644 pkgs/default.nix create mode 100644 pkgs/sources/comments/.envrc create mode 100644 pkgs/sources/comments/.gitignore create mode 100644 pkgs/sources/comments/Cargo.lock create mode 100644 pkgs/sources/comments/Cargo.toml create mode 100644 pkgs/sources/comments/comments.nix create mode 100644 pkgs/sources/comments/default.nix create mode 100644 pkgs/sources/comments/flake.lock create mode 100644 pkgs/sources/comments/flake.nix create mode 100644 pkgs/sources/comments/src/info_json.rs create mode 100644 pkgs/sources/comments/src/main.rs create mode 100755 pkgs/sources/comments/update.sh create mode 100644 pkgs/sources/default.nix create mode 100644 pkgs/sources/generate_moz_extension/.envrc create mode 100644 pkgs/sources/generate_moz_extension/.gitignore create mode 100644 pkgs/sources/generate_moz_extension/Cargo.lock create mode 100644 pkgs/sources/generate_moz_extension/Cargo.toml create mode 100644 pkgs/sources/generate_moz_extension/default.nix create mode 100755 pkgs/sources/generate_moz_extension/examples/generate_extensions.sh create mode 100644 pkgs/sources/generate_moz_extension/flake.lock create mode 100644 pkgs/sources/generate_moz_extension/flake.nix create mode 100644 pkgs/sources/generate_moz_extension/generate_firefox_extensions.nix create mode 100644 pkgs/sources/generate_moz_extension/res/generate_extensions.py create mode 100644 pkgs/sources/generate_moz_extension/res/reference.json create mode 100644 pkgs/sources/generate_moz_extension/res/test.json create mode 100644 pkgs/sources/generate_moz_extension/src/main.rs create mode 100644 pkgs/sources/generate_moz_extension/src/types.rs create mode 100755 pkgs/sources/generate_moz_extension/update.sh create mode 100644 pkgs/sources/lf-make-map/.envrc create mode 100644 pkgs/sources/lf-make-map/.gitignore create mode 100644 pkgs/sources/lf-make-map/Cargo.lock create mode 100644 pkgs/sources/lf-make-map/Cargo.toml create mode 100644 pkgs/sources/lf-make-map/README.md create mode 100644 pkgs/sources/lf-make-map/default.nix create mode 100644 pkgs/sources/lf-make-map/flake.lock create mode 100644 pkgs/sources/lf-make-map/flake.nix create mode 100644 pkgs/sources/lf-make-map/lf_make_map.nix create mode 100644 pkgs/sources/lf-make-map/src/cli.rs create mode 100644 pkgs/sources/lf-make-map/src/main.rs create mode 100644 pkgs/sources/lf-make-map/src/mapping/map_tree/display.rs create mode 100644 pkgs/sources/lf-make-map/src/mapping/map_tree/iterator.rs create mode 100644 pkgs/sources/lf-make-map/src/mapping/map_tree/lf_mapping.rs create mode 100644 pkgs/sources/lf-make-map/src/mapping/map_tree/mod.rs create mode 100644 pkgs/sources/lf-make-map/src/mapping/mod.rs create mode 100755 pkgs/sources/lf-make-map/update.sh create mode 100644 pkgs/sources/plgs-pkgs/README.md create mode 100644 pkgs/sources/plgs-pkgs/check.nix create mode 100644 pkgs/sources/plgs-pkgs/default.nix create mode 100644 pkgs/sources/plgs-pkgs/overrides.nix create mode 100644 pkgs/sources/plgs-pkgs/plugins/.plugins.json create mode 100644 pkgs/sources/plgs-pkgs/plugins/blacklist.txt create mode 100644 pkgs/sources/plgs-pkgs/plugins/default.nix create mode 100644 pkgs/sources/plgs-pkgs/plugins/manifest.txt create mode 100644 pkgs/sources/plgs-pkgs/plugins/plugins.md create mode 100644 pkgs/sources/plgs-pkgs/plugins/whitelist.txt create mode 100755 pkgs/sources/plgs-pkgs/update.sh create mode 100644 pkgs/sources/scripts/default.nix create mode 100755 pkgs/sources/scripts/source/apps/aumo.sh create mode 100755 pkgs/sources/scripts/source/apps/con2pdf.sh create mode 100644 pkgs/sources/scripts/source/apps/fupdate.1.md create mode 100755 pkgs/sources/scripts/source/apps/fupdate.sh create mode 100755 pkgs/sources/scripts/source/apps/git-edit-index.sh create mode 100755 pkgs/sources/scripts/source/small_functions/brightness.sh create mode 100755 pkgs/sources/scripts/source/small_functions/nato.py create mode 100755 pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh create mode 100755 pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh create mode 100755 pkgs/sources/scripts/source/small_functions/update-sys.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh create mode 100755 pkgs/sources/scripts/source/specific/neorg/sh/main.sh create mode 100755 pkgs/sources/scripts/source/specific/spodi/sh/download.sh create mode 100755 pkgs/sources/scripts/source/specific/spodi/sh/update.sh create mode 100755 pkgs/sources/scripts/source/specific/spodi/spodi.sh create mode 100755 pkgs/sources/scripts/source/specific/ytcc/description.sh create mode 100755 pkgs/sources/scripts/source/wrappers/battery.sh create mode 100755 pkgs/sources/scripts/source/wrappers/hibernate.sh create mode 100755 pkgs/sources/scripts/source/wrappers/ll.sh create mode 100755 pkgs/sources/scripts/source/wrappers/lock.sh create mode 100755 pkgs/sources/scripts/source/wrappers/lyrics.sh create mode 100755 pkgs/sources/scripts/source/wrappers/mpc-fav.sh create mode 100755 pkgs/sources/scripts/source/wrappers/mpc-rm.sh create mode 100755 pkgs/sources/scripts/source/wrappers/mpc.sh create mode 100755 pkgs/sources/scripts/source/wrappers/show.sh create mode 100755 pkgs/sources/scripts/source/wrappers/sort_song.sh create mode 100755 pkgs/sources/scripts/source/wrappers/virsh-del.sh create mode 100755 pkgs/sources/scripts/source/wrappers/yti.sh create mode 100644 pkgs/sources/snap-sync-forked/default.nix create mode 100755 pkgs/sources/snap-sync-forked/snap-sync-forked.sh create mode 100644 pkgs/sources/tree-sitter-yts/.editorconfig create mode 100644 pkgs/sources/tree-sitter-yts/.envrc create mode 100644 pkgs/sources/tree-sitter-yts/.gitignore create mode 100644 pkgs/sources/tree-sitter-yts/Cargo.toml create mode 100644 pkgs/sources/tree-sitter-yts/binding.gyp create mode 100644 pkgs/sources/tree-sitter-yts/bindings/node/binding.cc create mode 100644 pkgs/sources/tree-sitter-yts/bindings/node/index.js create mode 100644 pkgs/sources/tree-sitter-yts/bindings/rust/build.rs create mode 100644 pkgs/sources/tree-sitter-yts/bindings/rust/lib.rs create mode 100644 pkgs/sources/tree-sitter-yts/corpus/comments.txt create mode 100644 pkgs/sources/tree-sitter-yts/corpus/comments_correct.txt create mode 100644 pkgs/sources/tree-sitter-yts/corpus/duration.txt create mode 100644 pkgs/sources/tree-sitter-yts/corpus/url.txt create mode 100644 pkgs/sources/tree-sitter-yts/default.nix create mode 100644 pkgs/sources/tree-sitter-yts/flake.lock create mode 100644 pkgs/sources/tree-sitter-yts/flake.nix create mode 100644 pkgs/sources/tree-sitter-yts/grammar.js create mode 100644 pkgs/sources/tree-sitter-yts/highlight.yts create mode 100644 pkgs/sources/tree-sitter-yts/package.json create mode 100644 pkgs/sources/tree-sitter-yts/package.nix create mode 100644 pkgs/sources/tree-sitter-yts/queries/highlights.scm create mode 100644 pkgs/sources/tree-sitter-yts/src/grammar.json create mode 100644 pkgs/sources/tree-sitter-yts/src/node-types.json create mode 100644 pkgs/sources/tree-sitter-yts/src/parser.c create mode 100644 pkgs/sources/tree-sitter-yts/src/tree_sitter/parser.h create mode 100644 pkgs/sources/tree-sitter-yts/treefmt.toml create mode 100755 pkgs/sources/update_pkgs.sh create mode 100644 pkgs/sources/update_vim_plugins/.envrc create mode 100755 pkgs/sources/update_vim_plugins/check-duplicates.sh create mode 100644 pkgs/sources/update_vim_plugins/default.nix create mode 100644 pkgs/sources/update_vim_plugins/flake.lock create mode 100644 pkgs/sources/update_vim_plugins/flake.nix create mode 100644 pkgs/sources/update_vim_plugins/package.nix create mode 100644 pkgs/sources/update_vim_plugins/poetry.lock create mode 100644 pkgs/sources/update_vim_plugins/pyproject.toml create mode 100755 pkgs/sources/update_vim_plugins/update.sh create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/__init__.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/__main__.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/cleanup.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/helpers.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/nix.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/plugin.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/spec.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/tests/__init__.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/tests/fixtures.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_nix.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_plugin.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_spec.py create mode 100644 pkgs/sources/update_vim_plugins/update_vim_plugins/update.py create mode 100755 pkgs/sources/yt/.env create mode 100644 pkgs/sources/yt/.envrc create mode 100644 pkgs/sources/yt/.gitignore create mode 100644 pkgs/sources/yt/Cargo.lock create mode 100644 pkgs/sources/yt/Cargo.toml create mode 100644 pkgs/sources/yt/default.nix create mode 100644 pkgs/sources/yt/flake.lock create mode 100644 pkgs/sources/yt/flake.nix create mode 100644 pkgs/sources/yt/src/bin/yt/main.rs create mode 100644 pkgs/sources/yt/src/bin/ytc/args.rs create mode 100644 pkgs/sources/yt/src/bin/ytc/main.rs create mode 100644 pkgs/sources/yt/src/bin/yts/args.rs create mode 100644 pkgs/sources/yt/src/bin/yts/main.rs create mode 100644 pkgs/sources/yt/src/constants.rs create mode 100644 pkgs/sources/yt/src/downloader.rs create mode 100644 pkgs/sources/yt/src/help.str create mode 100644 pkgs/sources/yt/src/lib.rs create mode 100644 pkgs/sources/yt/todo create mode 100755 pkgs/sources/yt/update.sh create mode 100644 pkgs/sources/yt/yt.nix create mode 100644 pkgs/sources/yt/ytc.nix create mode 100644 pkgs/sources/yt/yts.nix delete mode 100644 sys/boot/archlive_iso.nix delete mode 100755 sys/boot/boot_pictures/gnu.png delete mode 100755 sys/boot/boot_pictures/gnulin_emb_1.png delete mode 100755 sys/boot/boot_pictures/gnulin_emb_2.png delete mode 100644 sys/boot/default.nix delete mode 100644 sys/boot/signing_key.nix delete mode 100644 sys/default.nix delete mode 100644 sys/disks/default.nix delete mode 100644 sys/disks/fstrim.nix delete mode 100644 sys/disks/hibernate.nix delete mode 100644 sys/documentation/default.nix delete mode 100644 sys/font/default.nix delete mode 100644 sys/font/font.xml delete mode 100644 sys/git_revision/default.nix delete mode 100644 sys/hardware/default.nix delete mode 100644 sys/impermanence/default.nix delete mode 100644 sys/libvirtd/default.nix delete mode 100644 sys/locale/default.nix delete mode 100644 sys/locale/keymaps/dvorak_modified.xkb delete mode 100644 sys/locale/keymaps/us_modified.xkb delete mode 100644 sys/network/default.nix delete mode 100644 sys/nixpkgs/default.nix delete mode 100644 sys/nixpkgs/pkgs/comments/.envrc delete mode 100644 sys/nixpkgs/pkgs/comments/.gitignore delete mode 100644 sys/nixpkgs/pkgs/comments/Cargo.lock delete mode 100644 sys/nixpkgs/pkgs/comments/Cargo.toml delete mode 100644 sys/nixpkgs/pkgs/comments/comments.nix delete mode 100644 sys/nixpkgs/pkgs/comments/default.nix delete mode 100644 sys/nixpkgs/pkgs/comments/flake.lock delete mode 100644 sys/nixpkgs/pkgs/comments/flake.nix delete mode 100644 sys/nixpkgs/pkgs/comments/src/info_json.rs delete mode 100644 sys/nixpkgs/pkgs/comments/src/main.rs delete mode 100755 sys/nixpkgs/pkgs/comments/update.sh delete mode 100644 sys/nixpkgs/pkgs/default.nix delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/.envrc delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/.gitignore delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/Cargo.lock delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/Cargo.toml delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/default.nix delete mode 100755 sys/nixpkgs/pkgs/generate_moz_extension/examples/generate_extensions.sh delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/flake.lock delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/flake.nix delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/generate_firefox_extensions.nix delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/res/generate_extensions.py delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/res/reference.json delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/res/test.json delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/src/main.rs delete mode 100644 sys/nixpkgs/pkgs/generate_moz_extension/src/types.rs delete mode 100755 sys/nixpkgs/pkgs/generate_moz_extension/update.sh delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/.envrc delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/.gitignore delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/Cargo.lock delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/Cargo.toml delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/README.md delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/default.nix delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/flake.lock delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/flake.nix delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/lf_make_map.nix delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/cli.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/main.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/display.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/iterator.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/lf_mapping.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/mod.rs delete mode 100644 sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs delete mode 100755 sys/nixpkgs/pkgs/lf-make-map/update.sh delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/README.md delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/check.nix delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/default.nix delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/overrides.nix delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/.plugins.json delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/blacklist.txt delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/default.nix delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/manifest.txt delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/plugins.md delete mode 100644 sys/nixpkgs/pkgs/plgs-pkgs/plugins/whitelist.txt delete mode 100755 sys/nixpkgs/pkgs/plgs-pkgs/update.sh delete mode 100644 sys/nixpkgs/pkgs/scripts/default.nix delete mode 100755 sys/nixpkgs/pkgs/scripts/source/apps/aumo.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh delete mode 100644 sys/nixpkgs/pkgs/scripts/source/apps/fupdate.1.md delete mode 100755 sys/nixpkgs/pkgs/scripts/source/apps/fupdate.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/apps/git-edit-index.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/small_functions/nato.py delete mode 100755 sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_persistent.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_temporary.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/small_functions/update-sys.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/neorg_id_function.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/add.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/context.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/dmenu.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_start.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_stop.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/list.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/project.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/review.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/utils.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/workspace.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/main.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/download.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/update.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/spodi/spodi.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/specific/ytcc/description.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/battery.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/hibernate.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/ll.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/lock.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/lyrics.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/mpc-fav.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/mpc-rm.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/mpc.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/show.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/sort_song.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/virsh-del.sh delete mode 100755 sys/nixpkgs/pkgs/scripts/source/wrappers/yti.sh delete mode 100644 sys/nixpkgs/pkgs/snap-sync-forked/default.nix delete mode 100755 sys/nixpkgs/pkgs/snap-sync-forked/snap-sync-forked.sh delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/.editorconfig delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/.envrc delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/.gitignore delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/Cargo.toml delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/binding.gyp delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/bindings/node/binding.cc delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/bindings/node/index.js delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/build.rs delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/lib.rs delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments.txt delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments_correct.txt delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/corpus/duration.txt delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/corpus/url.txt delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/default.nix delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/flake.lock delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/flake.nix delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/grammar.js delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/highlight.yts delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/package.json delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/package.nix delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/queries/highlights.scm delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/src/grammar.json delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/src/node-types.json delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/src/parser.c delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/src/tree_sitter/parser.h delete mode 100644 sys/nixpkgs/pkgs/tree-sitter-yts/treefmt.toml delete mode 100755 sys/nixpkgs/pkgs/update_pkgs.sh delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/.envrc delete mode 100755 sys/nixpkgs/pkgs/update_vim_plugins/check-duplicates.sh delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/default.nix delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/flake.lock delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/flake.nix delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/package.nix delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/poetry.lock delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/pyproject.toml delete mode 100755 sys/nixpkgs/pkgs/update_vim_plugins/update.sh delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__init__.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__main__.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/cleanup.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/helpers.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/nix.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/plugin.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/spec.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/__init__.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/fixtures.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_nix.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_plugin.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_spec.py delete mode 100644 sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/update.py delete mode 100755 sys/nixpkgs/pkgs/yt/.env delete mode 100644 sys/nixpkgs/pkgs/yt/.envrc delete mode 100644 sys/nixpkgs/pkgs/yt/.gitignore delete mode 100644 sys/nixpkgs/pkgs/yt/Cargo.lock delete mode 100644 sys/nixpkgs/pkgs/yt/Cargo.toml delete mode 100644 sys/nixpkgs/pkgs/yt/default.nix delete mode 100644 sys/nixpkgs/pkgs/yt/flake.lock delete mode 100644 sys/nixpkgs/pkgs/yt/flake.nix delete mode 100644 sys/nixpkgs/pkgs/yt/src/bin/yt/main.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/bin/ytc/args.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/bin/ytc/main.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/bin/yts/args.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/bin/yts/main.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/constants.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/downloader.rs delete mode 100644 sys/nixpkgs/pkgs/yt/src/help.str delete mode 100644 sys/nixpkgs/pkgs/yt/src/lib.rs delete mode 100755 sys/nixpkgs/pkgs/yt/update.sh delete mode 100644 sys/nixpkgs/pkgs/yt/yt.nix delete mode 100644 sys/nixpkgs/pkgs/yt/ytc.nix delete mode 100644 sys/nixpkgs/pkgs/yt/yts.nix delete mode 100644 sys/options/default.nix delete mode 100644 sys/options/secret.nix delete mode 100644 sys/polkit/default.nix delete mode 100644 sys/power/default.nix delete mode 100644 sys/secrets/default.nix delete mode 100644 sys/secrets/lf/cd_paths delete mode 100644 sys/secrets/nheko/conf.apzu delete mode 100644 sys/secrets/nheko/conf.isimud delete mode 100644 sys/secrets/nheko/conf.tiamat delete mode 100644 sys/secrets/secrets.nix delete mode 100644 sys/secrets/serverphone/ca.key delete mode 100644 sys/secrets/serverphone/server.key delete mode 100644 sys/secrets/taskserver/ca.cert delete mode 100644 sys/secrets/taskserver/credentials delete mode 100644 sys/secrets/taskserver/private.key delete mode 100644 sys/secrets/taskserver/public.cert delete mode 100755 sys/secrets/update.sh delete mode 100644 sys/sound/default.nix delete mode 100644 sys/svcs/adb/default.nix delete mode 100644 sys/svcs/backup/default.nix delete mode 100644 sys/svcs/dconf/default.nix delete mode 100644 sys/svcs/default.nix delete mode 100644 sys/svcs/fwupd/default.nix delete mode 100644 sys/svcs/getty/default.nix delete mode 100644 sys/svcs/nix/default.nix delete mode 100644 sys/svcs/openssh/default.nix delete mode 100644 sys/svcs/postgresql/default.nix delete mode 100644 sys/svcs/printing/default.nix delete mode 100644 sys/svcs/scanning/default.nix delete mode 100644 sys/svcs/serverphone/certificates/ca.crt delete mode 100644 sys/svcs/serverphone/certificates/server.crt delete mode 100644 sys/svcs/serverphone/default.nix delete mode 120000 sys/svcs/serverphone/keys/key_1 delete mode 120000 sys/svcs/serverphone/keys/key_2 delete mode 100644 sys/svcs/snapper/default.nix delete mode 100644 sys/svcs/steam/default.nix delete mode 100644 sys/svcs/swaylock/default.nix delete mode 100644 sys/svcs/xdg/default.nix delete mode 100755 sys/svcs/xdg/scripts/lf_wrapper.sh delete mode 100755 sys/svcs/xdg/scripts/ranger_wrapper.sh delete mode 100644 sys/tempfiles/default.nix delete mode 100644 sys/users/default.nix delete mode 100644 sys/waydroid/default.nix diff --git a/modules/system/boot/boot_pictures/gnu.png b/modules/system/boot/boot_pictures/gnu.png new file mode 100755 index 00000000..d07dee3e Binary files /dev/null and b/modules/system/boot/boot_pictures/gnu.png differ diff --git a/modules/system/boot/boot_pictures/gnulin_emb_1.png b/modules/system/boot/boot_pictures/gnulin_emb_1.png new file mode 100755 index 00000000..483f2681 Binary files /dev/null and b/modules/system/boot/boot_pictures/gnulin_emb_1.png differ diff --git a/modules/system/boot/boot_pictures/gnulin_emb_2.png b/modules/system/boot/boot_pictures/gnulin_emb_2.png new file mode 100755 index 00000000..48cd6ad7 Binary files /dev/null and b/modules/system/boot/boot_pictures/gnulin_emb_2.png differ diff --git a/modules/system/boot/default.nix b/modules/system/boot/default.nix new file mode 100644 index 00000000..1e6fa99b --- /dev/null +++ b/modules/system/boot/default.nix @@ -0,0 +1,129 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.boot; +in { + options.soispha.boot = { + enable = lib.mkEnableOption "Bootloader configuration"; + # TODO: Add this option <2024-05-16> + # enableIsoEntry = lib.mkEnableOption "an tails iso boot entry"; + }; + + config = lib.mkIf cfg.enable ( + # let + # cfg = config.boot.loader.systemd-boot; + # inherit (config.boot.loader) efi; + # + # esa = n: lib.strings.escapeShellArg n; + # + # bootMountPoint = + # if cfg.xbootldrMountPoint != null + # then cfg.xbootldrMountPoint + # else efi.efiSysMountPoint; + # + # nixosDir = "/EFI/nixos"; + # + # # FIXME: This system has two big problems: + # # 1. It does not updated files, which still have the same name + # # 2. It forgets about files, which were 'deleted' in this configuration (these just + # # stay on disk forever) <2024-05-11> + # copyExtraFiles = '' + # echo "[systemd-boot] copying files to ${bootMountPoint}" + # empty_file=$(mktemp) + # + # ${lib.concatStrings (lib.mapAttrsToList (n: v: + # /* + # bash + # */ + # '' + # if ! [ -e ${esa "${bootMountPoint}/${n}"} ]; then + # install -Dp "${v}" ${esa "${bootMountPoint}/${n}"} + # install -D "$empty_file" ${esa "${bootMountPoint}/${nixosDir}/.extra-files/${n}"} + # fi + # '') + # cfg.extraFiles)} + # + # ${lib.concatStrings (lib.mapAttrsToList (n: v: + # /* + # bash + # */ + # '' + # # if ! [ -e ${esa "${bootMountPoint}/loader/entries/${n}"} ]; then + # install -Dp "${pkgs.writeText n v}" ${esa "${bootMountPoint}/loader/entries/${n}"} + # install -D "$empty_file" ${esa "${bootMountPoint}/${nixosDir}/.extra-files/loader/entries/${n}"} + # # fi + # '') + # cfg.extraEntries)} + # ''; + # in + { + # FIXME: Reactviate this whole iso thing when a disko redeploy is done. + # (and switch to tails instead of arch) <2024-05-12> + # + # system.activationScripts = { + # copyExtraFilesForBoot = copyExtraFiles; + # }; + + boot = { + initrd = { + kernelModules = ["nvme" "btrfs"]; + }; + + kernelPackages = pkgs.linuxPackages_latest; + + lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + + settings = { + # Disable editing the kernel command line (which could allow someone to become root) + editor = false; + }; + }; + + loader = { + systemd-boot = { + # Lanzaboote currently replaces the systemd-boot module. + # This setting is usually set to true in configuration.nix + # generated at installation time. So we force it to false + # for now. + enable = false; + + # extraEntries = { + # "live.conf" = '' + # title Archlinux Live ISO + # linux /live/vmlinuz-linux + # initrd /live/initramfs-linux.img + # options img_dev=${config.soispha.disks.disk} img_loop=/archlinux.iso copytoram + # ''; + # }; + # + # extraFiles = let + # iso = import ./archlive_iso.nix {inherit pkgs;}; + # in { + # "archlinux.iso" = "${iso}/archlinux.iso"; + # "live/initramfs-linux.img" = "${iso}/live/initramfs-linux.img"; + # "live/vmlinuz-linux" = "${iso}/live/vmlinuz-linux"; + # }; + }; + + grub = { + enable = false; + # theme = pkgs.nixos-grub2-theme; + splashImage = ./boot_pictures/gnu.png; + efiSupport = true; + device = "nodev"; # only for efi + }; + + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot"; + }; + }; + }; + } + ); +} diff --git a/modules/system/boot/iso_entry/archlive_iso.nix b/modules/system/boot/iso_entry/archlive_iso.nix new file mode 100644 index 00000000..d19a4a87 --- /dev/null +++ b/modules/system/boot/iso_entry/archlive_iso.nix @@ -0,0 +1,77 @@ +{pkgs ? (builtins.getFlake "nixpkgs").legacyPackages."x86_64-linux"}: let + signing_key = import ./signing_key.nix {inherit pkgs;}; + + checked_iso = pkgs.stdenv.mkDerivation { + pname = "archlinux-iso"; + version = "2024.05.01"; + + srcs = [ + (pkgs.fetchurl { + url = "https://archlinux.org/iso/2024.05.01/archlinux-2024.05.01-x86_64.iso.sig"; + hash = "sha256-QOGYng6a7zA5EJKGotDccJ7fD2MmPPXQEdVr1kjJvi4="; + }) + (pkgs.fetchurl { + url = "https://mirror.informatik.tu-freiberg.de/arch/iso/latest/archlinux-2024.05.01-x86_64.iso"; + hash = "sha256-G0oE74pzUIUqEwcO5JhEKwh6YHoYhAtN19mYZ+tfakw="; + }) + (pkgs.fetchurl { + url = "https://archlinux.org/iso/2024.05.01/b2sums.txt"; + hash = "sha256-HSMS13hHXFKKQsCA8spa7XtirHCBTmePwhOsStVPbHw="; + }) + ]; + + dontUnpack = true; + + nativeBuildInputs = with pkgs; [ + sequoia-sq + ]; + + buildPhase = + /* + bash + */ + '' + cp -r "${signing_key}" ./release-key.pgp + for src in $srcs; do + cp -r "$src" "$(stripHash "$src")" + done + + sed '2d;3d;4d' b2sums.txt > b2sums_clean.txt + + # As per the directions from: https://archlinux.org/download/ + + # blake hash check + b2sum -c ./b2sums_clean.txt + + # pgp signature check + sq verify --signer-file release-key.pgp --detached archlinux-2024.05.01-x86_64.iso.sig archlinux-2024.05.01-x86_64.iso + ''; + + installPhase = '' + cp archlinux-2024.05.01-x86_64.iso "$out"; + ''; + }; +in + pkgs.stdenv.mkDerivation { + name = "live_iso_boot_entry"; + + src = checked_iso; + + dontUnpack = true; + + nativeBuildInputs = with pkgs; [ + libarchive # for bsdtar + ]; + + buildPhase = '' + mkdir iso + bsdtar -xf "$src" -C iso + ''; + + installPhase = '' + install -D ./iso/arch/boot/x86_64/initramfs-linux.img "$out/live/initramfs-linux.img" + install -D ./iso/arch/boot/x86_64/vmlinuz-linux "$out/live/vmlinuz-linux" + + install -D "$src" "$out/archlinux.iso" + ''; + } diff --git a/modules/system/boot/iso_entry/signing_key.nix b/modules/system/boot/iso_entry/signing_key.nix new file mode 100644 index 00000000..788447be --- /dev/null +++ b/modules/system/boot/iso_entry/signing_key.nix @@ -0,0 +1,18 @@ +{pkgs ? (builtins.getFlake "nixpkgs").legacyPackages."x86_64-linux"}: +pkgs.stdenv.mkDerivation { + name = "archlinux_signing_keys"; + + outputHash = "sha256-evGWzkxMaZw3rlixKsyWCS/ZvNuZ+OfXQb6sgiHz9XY="; + outputHashAlgo = "sha256"; + NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + + nativeBuildInputs = with pkgs; [ + sequoia-sq + ]; + + dontUnpack = true; + + buildPhase = '' + sq --verbose --no-cert-store --no-key-store network wkd fetch pierre@archlinux.org --output "$out" + ''; +} diff --git a/modules/system/cleanup/default.nix b/modules/system/cleanup/default.nix new file mode 100644 index 00000000..4e192f7d --- /dev/null +++ b/modules/system/cleanup/default.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.cleanup; +in { + # remove all the bloat, which NixOS installs by default + options.soispha.cleanup = { + enable = lib.mkEnableOption "avoiding of nixos' default installed packages"; + }; + + config = lib.mkIf cfg.enable { + environment = { + defaultPackages = lib.mkForce []; + }; + }; +} diff --git a/modules/system/default.nix b/modules/system/default.nix new file mode 100644 index 00000000..0eef0b7f --- /dev/null +++ b/modules/system/default.nix @@ -0,0 +1,26 @@ +{config, ...}: let + cfg = config.soispha; +in { + imports = [ + ./boot + ./cleanup + ./disks + ./documentation + ./fonts + ./hardware + ./impermanence + ./locale + ./networking + ./polkit + ./power + ./secrets + ./services + ./sound + ./tempfiles + ./users + ./version + ./waydroid + ]; + options = {}; + config = {}; +} diff --git a/modules/system/disks/default.nix b/modules/system/disks/default.nix new file mode 100644 index 00000000..c0e5bcfd --- /dev/null +++ b/modules/system/disks/default.nix @@ -0,0 +1,133 @@ +{ + config, + lib, + pkgs, + ... +}: let + # FIXME: The iso redeploy requires a bigger efi partition <2024-05-12> + cfg = config.soispha.disks; + defaultMountOptions = [ + "compress-force=zstd:15" # This saves disk space, at a performance cost + "noatime" # should have some performance upsides, and I don't use it anyways + "lazytime" # make time changes in memory + ]; +in { + options.soispha.disks = { + enable = lib.mkEnableOption "disk setup with disko"; + + disk = lib.mkOption { + type = lib.types.path; + example = lib.literalExpression "/dev/disk/by-uuid/0442cb6d-f13a-4635-b487-fa76189774c5"; + description = "The disk used for installing the OS."; + }; + + ssd = lib.mkEnableOption "ssd specific improvements, like trim"; + + swap = { + uuid = lib.mkOption { + type = lib.types.str; + example = lib.literalExpression "d1d20ae7-3d8a-44da-86da-677dbbb10c89"; + description = "The uuid of the swapfile"; + }; + resumeOffset = lib.mkOption { + type = lib.types.str; + example = lib.literalExpression "134324224"; + description = "The resume offset of the swapfile"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd = lib.recursiveUpdate (import ./hibernate.nix {inherit pkgs;}) (import ./fstrim.nix {inherit pkgs lib cfg;}); + + disko.devices = { + disk = { + main = { + device = cfg.disk; + content = { + type = "gpt"; + partitions = { + root = { + size = "100%"; + name = "root"; + content = { + type = "luks"; + name = "nixos"; + extraOpenArgs = ["--allow-discards"]; + content = { + type = "btrfs"; + extraArgs = ["-f" "--label nixos"]; # Override existing partitions + subvolumes = { + "nix" = { + mountpoint = "/nix"; + mountOptions = defaultMountOptions; + }; + "persistent-storage" = { + mountpoint = "/srv"; + mountOptions = defaultMountOptions; + }; + "persistent-storage@snapshots" = { + mountpoint = "/srv/.snapshots"; + mountOptions = defaultMountOptions; + }; + "swap" = { + mountpoint = "/swap"; + mountOptions = defaultMountOptions; + }; + }; + }; + }; + }; + boot = { + type = "EF00"; + size = "512M"; + name = "boot"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + }; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = ["defaults" "size=4G" "mode=755"]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = ["defaults" "size=16G" "mode=755"]; + }; + }; + }; + fileSystems = { + "/srv" = { + neededForBoot = true; + }; + "/swap" = { + neededForBoot = true; + }; + }; + swapDevices = [ + #{ + # device = "/swap/swapfile"; + # priority = 1; # lower than zramSwap, just in case + # # size = 2048; # TODO: can nixos create a btrfs swapfile correctly? + #} + ]; + zramSwap = { + enable = true; + priority = 10; # needs to be higher than hardware-swap + }; + boot = { + kernelParams = [ + "resume_offset=${cfg.swap.resumeOffset}" + "zswap.enabled=0" # zswap and zram are not really compatible + ]; + resumeDevice = "/dev/disk/by-uuid/${cfg.swap.uuid}"; + }; + }; +} diff --git a/modules/system/disks/fstrim.nix b/modules/system/disks/fstrim.nix new file mode 100644 index 00000000..6daeb65e --- /dev/null +++ b/modules/system/disks/fstrim.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + cfg, +}: { + timers.fstrim = lib.mkIf cfg.ssd { + wantedBy = ["timers.target"]; + wants = ["fstrim.service"]; + unitConfig = { + Description = "Discard unused blocks once a week"; + Documentation = "man:fstrim"; + ConditionVirtualization = "!container"; + ConditionPathExists = "!/etc/initrd-release"; + }; + timerConfig = { + OnCalendar = "weekly"; + AccuracySec = "1h"; + Persistent = "true"; + RandomizedDelaySec = "6000"; + }; + }; + services.fstrim = lib.mkIf cfg.ssd { + wantedBy = lib.mkForce []; + unitConfig = { + Description = "Discard unused blocks on filesystems from /etc/fstab"; + Documentation = "man:fstrim(8)"; + ConditionVirtualization = "!container"; + }; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.util-linux}/bin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported"; + PrivateDevices = "no"; + PrivateNetwork = "yes"; + PrivateUsers = "no"; + ProtectKernelTunables = "yes"; + ProtectKernelModules = "yes"; + ProtectControlGroups = "yes"; + MemoryDenyWriteExecute = "yes"; + SystemCallFilter = "@default @file-system @basic-io @system-service"; + }; + }; +} diff --git a/modules/system/disks/hibernate.nix b/modules/system/disks/hibernate.nix new file mode 100644 index 00000000..a50e5b57 --- /dev/null +++ b/modules/system/disks/hibernate.nix @@ -0,0 +1,45 @@ +{pkgs}: { + services = { + hibernate-preparation = { + wantedBy = ["systemd-hibernate.service"]; + unitConfig = { + Description = "Enable swap file and disable zram before hibernate"; + Before = "systemd-hibernate.service"; + }; + serviceConfig = { + Type = "oneshot"; + User = "root"; + ExecStart = "${pkgs.bash}/bin/bash -c \"${pkgs.util-linux}/bin/swapon /swap/swapfile && ${pkgs.util-linux}/bin/swapoff /dev/zram0\""; + }; + }; + + hibernate-resume = { + wantedBy = ["systemd-hibernate.service"]; + unitConfig = { + Description = "Disable swap after resuming from hibernation"; + After = "hibernate.target"; + }; + serviceConfig = { + Type = "oneshot"; + User = "root"; + ExecStart = "${pkgs.util-linux}/bin/swapoff /swap/swapfile"; + }; + }; + # swapoff-start = { + # wantedBy = ["multi-user.target"]; + # unitConfig = { + # Description = "Disable hardware swap after booting"; + # }; + # serviceConfig = { + # Type = "oneshot"; + # User = "root"; + # ExecStart = "${pkgs.util-linux}/bin/swapoff /swap/swapfile"; + # }; + # }; + systemd-hibernate.serviceConfig.Environment = "SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"; + systemd-logind.serviceConfig.Environment = "SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"; + }; + sleep.extraConfig = '' + HibernateDelaySec=5m + ''; +} diff --git a/modules/system/documentation/default.nix b/modules/system/documentation/default.nix new file mode 100644 index 00000000..0e998d6c --- /dev/null +++ b/modules/system/documentation/default.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.documentation; +in { + options.soispha.documentation = { + enable = lib.mkEnableOption "documentation"; + }; + config = lib.mkIf cfg.enable { + documentation = { + nixos = { + includeAllModules = true; + + enable = true; + }; + dev = { + # Add man pages aimed at developers (I guess c library stuff, and the like) + enable = true; + }; + }; + }; +} diff --git a/modules/system/fonts/default.nix b/modules/system/fonts/default.nix new file mode 100644 index 00000000..fa99c1f3 --- /dev/null +++ b/modules/system/fonts/default.nix @@ -0,0 +1,55 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.fonts; +in { + options.soispha.fonts = { + enable = lib.mkEnableOption "fonts"; + + fonts = lib.mkOption { + type = lib.types.listOf lib.types.path; + example = lib.literalExpression ''["SourceCodePro" "Overpass" "FiraCode"]''; + default = [ + "SourceCodePro" + "Overpass" + ]; + description = "The nerd-fonts to install"; + }; + + enableEmoji = lib.mkEnableOpiton "emoji font support"; + }; + + config = lib.mkIf cfg.enable { + fonts = { + packages = let + nerdFont = pkgs.nerdfonts.override { + inherit (cfg) fonts; + }; + in + [ + nerdFont + ] + ++ (with pkgs; [liberation_ttf]) + ++ lib.optional cfg.enableEmoji pkgs.noto-fonts-emoji; + + fontconfig = { + # NOTE: This is responsible for color emoji support <2023-08-28> + # WARNING: This could lead to broken font rendering, if the emoji font is used as + # a fallback for normal characters <2024-05-16> + localConf = lib.mkIf cfg.enableEmoji (builtins.readFile ./emoji_font.xml); + + defaultFonts = { + serif = lib.mkForce ["Liberation Serif"] ++ lib.optional cfg.enableEmoji "Noto Color Emoji"; + sansSerif = lib.mkForce ["Overpass Nerd Font Propo"] ++ lib.optional cfg.enableEmoji "Noto Color Emoji"; + monospace = lib.mkForce ["SauceCodePro Nerd Font Mono"] ++ lib.optional cfg.enableEmoji "Noto Color Emoji"; + emoji = lib.mkIf cfg.enableEmoji (lib.mkForce ["Noto Color Emoji"]); + }; + allowType1 = false; + allowBitmaps = false; + }; + }; + }; +} diff --git a/modules/system/fonts/emoji_font.xml b/modules/system/fonts/emoji_font.xml new file mode 100644 index 00000000..f3f6bb3e --- /dev/null +++ b/modules/system/fonts/emoji_font.xml @@ -0,0 +1,22 @@ + + + + + monospace + + emoji + + + + sans-serif + + emoji + + + + serif + + emoji + + + diff --git a/modules/system/hardware/default.nix b/modules/system/hardware/default.nix new file mode 100644 index 00000000..acf9fb2e --- /dev/null +++ b/modules/system/hardware/default.nix @@ -0,0 +1,68 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.hardware; +in { + options.soispha.hardware = { + enable = lib.mkEnableOption "udev rules for devices I use"; + moonlander = { + enableLiveTraining = lib.mkEnableOption "udev rules for live training"; + enableFlashing = lib.mkEnableOption "udev rules for firmware flashing"; + }; + }; + + config = lib.mkIf cfg.enable { + hardware = { + keyboard.zsa.enable = false; + nitrokey.enable = true; + + # TODO: Remove this once I know, that it is no longer necessary <2024-05-16> + onlykey.enable = true; + + opengl = { + enable = true; + extraPackages = builtins.attrValues { + inherit + (pkgs) + vaapiVdpau + libvdpau-va-gl + ; + }; + }; + }; + + # TODO: Remove the support for the old keyboards <2024-05-16> + services.udev.extraRules = + lib.mkIf cfg.moonlander.enableLiveTraining '' + # Rules for Oryx web flashing and live training + KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev" + KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev" + + # Legacy rules for live training over webusb (Not needed for firmware v21+) + # Rule for all ZSA keyboards + SUBSYSTEM=="usb", ATTR{idVendor}=="3297", GROUP="plugdev" + # Rule for the Moonlander + SUBSYSTEM=="usb", ATTR{idVendor}=="3297", ATTR{idProduct}=="1969", GROUP="plugdev" + # Rule for the Ergodox EZ + SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="1307", GROUP="plugdev" + # Rule for the Planck EZ + SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="6060", GROUP="plugdev" + '' + + lib.mkIf cfg.moonlander.enableFlashing + '' + # Wally Flashing rules for the Ergodox EZ + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1" + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" + KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" + + # Wally Flashing rules for the Moonlander and Planck EZ + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", \ + MODE:="0666", \ + SYMLINK+="stm32_dfu" + ''; + }; +} diff --git a/modules/system/impermanence/default.nix b/modules/system/impermanence/default.nix new file mode 100644 index 00000000..dca30083 --- /dev/null +++ b/modules/system/impermanence/default.nix @@ -0,0 +1,55 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.impermanence; +in { + options.soispha.impermanence = { + enable = lib.mkEnableOption "persisting directories and files with impermanence"; + + directories = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = + [ + "/etc/nixos" + "/var/log" + "/var/lib/systemd" + ] + ++ lib.optional config.networking.networkmanager.enable "/etc/NetworkManager" + ++ lib.optional config.boot.lanzaboote.enable "/etc/secureboot" + ++ lib.optional config.hardware.bluetooth.enable "/var/lib/bluetooth" + ++ lib.optional config.virtualisation.waydroid.enable "/var/lib/waydroid" + ++ lib.optional config.services.postgresql.enable "/var/lib/postgresql"; + + defaultText = lib.literalExpression '' + [ + "/etc/nixos" + "/var/log" + "/var/lib/systemd" + ] + ++ lib.optional config.networking.networkmanager.enable "/etc/NetworkManager" + ++ lib.optional config.boot.lanzaboote.enable "/etc/secureboot" + ++ lib.optional config.hardware.bluetooth.enable "/var/lib/bluetooth" + ++ lib.optional config.virtualisation.waydroid.enable "/var/lib/waydroid" + ++ lib.optional config.services.postgresql.enable "/var/lib/postgresql" + ''; + description = "The directories to persist"; + }; + }; + + config = lib.mkIf cfg.enable { + # needed for the hm impermanence config + programs.fuse.userAllowOther = true; + + environment.persistence = { + "/srv" = { + hideMounts = true; + inherit (cfg) directories; + files = [ + "/etc/machine-id" + ]; + }; + }; + }; +} diff --git a/modules/system/libvirtd/default.nix b/modules/system/libvirtd/default.nix new file mode 100644 index 00000000..5c519550 --- /dev/null +++ b/modules/system/libvirtd/default.nix @@ -0,0 +1,27 @@ +{pkgs, ...}: { + # virtualisation = { + # spiceUSBRedirection.enable = true; # TODO: this allows usb access to any user, which shouldn't be that bad + # cores = 8; + # diskSize = 25000; + # useEFIBoot = true; + # resolution = { + # x = 1920; + # y = 1080; + # }; + # memorySize = 8024; + # sharedDirectories = {}; # TODO: add some + # libvirtd = { + # enable = true; + # qemu = { + # package = pkgs.qemu_full; + # ovmf = { + # enable = true; + # packages = [pkgs.OVMFFull.fd]; + # }; + # }; + # }; + # }; + # users.users.soispha.extraGroups = [ + # "libvirtd" # to run libvirt stuff as this user + # ]; +} diff --git a/modules/system/locale/default.nix b/modules/system/locale/default.nix new file mode 100644 index 00000000..10569216 --- /dev/null +++ b/modules/system/locale/default.nix @@ -0,0 +1,57 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.locale; +in { + options.soispha.locale = { + enable = lib.mkEnableOption "locale setup"; + + keyMap = lib.mkOption { + type = lib.types.str; + example = "us"; + default = "dvorak"; + description = "The console key map language to use"; + }; + + timeZone = lib.mkOption { + type = lib.types.str; + default = "Europe/Berlin"; + description = "The time zone to use"; + }; + }; + + config = lib.mkIf cfg.enable { + time = { + inherit (cfg) timeZone; + }; + + i18n = { + defaultLocale = "en_CA.UTF-8"; + extraLocaleSettings = { + LANGUAGE = "en_CA:en_US:en"; + LC_TIME = "en_DK.UTF-8"; + LC_COLLATE = "C.UTF-8"; + }; + }; + + # Layout + console = { + inherit (cfg) keyMap; + }; + + services.xserver.xkb.extraLayouts = { + "us-modified" = { + description = "standard us with caps as compose key."; + languages = ["eng" "swe" "deu"]; + symbolsFile = ./keymaps/us_modified.xkb; + }; + "dvorak-modified" = { + description = "standard dvorak english with german and swedish extra chars."; + languages = ["eng" "swe" "deu"]; + symbolsFile = ./keymaps/dvorak_modified.xkb; + }; + }; + }; +} diff --git a/modules/system/locale/keymaps/dvorak_modified.xkb b/modules/system/locale/keymaps/dvorak_modified.xkb new file mode 100644 index 00000000..63f5d4fb --- /dev/null +++ b/modules/system/locale/keymaps/dvorak_modified.xkb @@ -0,0 +1,15 @@ +partial alphanumeric_keys +xkb_symbols "dvorak-modified" { + name[Group1]= "Dvorak English with additional keys"; + + key {[ o, O, odiaeresis, Odiaeresis]}; + key {[ u, U, udiaeresis, Udiaeresis]}; + key {type[Group1]="EIGHT_LEVEL", + [ a, A, adiaeresis, Adiaeresis, aring, Aring]}; + + + include "us(dvorak)" + include "level3(caps_switch)" + include "level5(ralt_switch)" +}; +// vim: ft=xkb diff --git a/modules/system/locale/keymaps/us_modified.xkb b/modules/system/locale/keymaps/us_modified.xkb new file mode 100644 index 00000000..6299a5e9 --- /dev/null +++ b/modules/system/locale/keymaps/us_modified.xkb @@ -0,0 +1,9 @@ +partial alphanumeric_keys +xkb_symbols "us-modified" { + name[Group1]= "US English with caps lock key as compose key"; + + + include "us(basic)" + include "compose(caps)" +}; +// vim: ft=xkb diff --git a/modules/system/networking/default.nix b/modules/system/networking/default.nix new file mode 100644 index 00000000..aaaab782 --- /dev/null +++ b/modules/system/networking/default.nix @@ -0,0 +1,81 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.networking; +in { + options.soispha.networking = { + enable = lib.mkEnableOption "networking"; + + networkManager = { + enable = lib.mkEnableOption "NetworkManager"; + }; + + hostName = lib.mkOption { + type = lib.types.str; + example = "apzu"; + description = "The name of the host"; + }; + }; + + config = + lib.mkIf cfg.enable { + systemd.network = { + networks = { + "tap0" = { + name = "tap0"; + bridge = [ + "virbr0" + ]; + }; + "enp4s0" = { + name = "enp4s0"; + networkConfig = { + DHCP = "yes"; + DNSOverTLS = "yes"; + DNSSEC = "yes"; + }; + bridge = [ + "virbr0" + ]; + }; + }; + + netdevs = { + "tap0" = { + netdevConfig = { + Name = "tap0"; + Kind = "tap"; + }; + tapConfig = { + User = "${config.users.users.soispha.uid}"; + Group = "libvirtd"; + }; + }; + "virbr0" = { + netdevConfig = { + Name = "br0"; + Kind = "bridge"; + }; + }; + }; + }; + } + // lib.mkIf cfg.networkManager.enable { + networking = { + networkmanager = { + enable = true; + dns = "default"; + wifi = { + powersave = true; + }; + }; + inherit (cfg) hostName; + }; + + users.users.soispha.extraGroups = [ + "networkmanager" # allows to configure networkmanager as this user + ]; + }; +} diff --git a/modules/system/polkit/default.nix b/modules/system/polkit/default.nix new file mode 100644 index 00000000..fb13505b --- /dev/null +++ b/modules/system/polkit/default.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.polkit; +in { + options.soispha.polkit = { + enable = lib.mkEnableOption "polkit"; + }; + config = lib.mkIf cfg.enable { + security.polkit.enable = true; + }; +} diff --git a/modules/system/power/default.nix b/modules/system/power/default.nix new file mode 100644 index 00000000..13013879 --- /dev/null +++ b/modules/system/power/default.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.power; +in { + options.soispha.power = { + enable = lib.mkEnableOption "power optimizations"; + }; + + config = lib.mkIf cfg.enable { + # see this for reference: https://github.com/NixOS/nixpkgs/issues/211345 + services = { + # conflicts with tlp + power-profiles-daemon.enable = false; + + thermald.enable = true; + + tlp = { + enable = true; + settings = { + CPU_BOOST_ON_AC = 1; + CPU_BOOST_ON_BAT = 0; + CPU_SCALING_GOVERNOR_ON_AC = "performance"; + CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; + SATA_LINKPWR_ON_AC = "max_performance"; + SATA_LINKPWR_ON_BAT = "min_power"; + }; + }; + }; + }; +} diff --git a/modules/system/secrets/default.nix b/modules/system/secrets/default.nix new file mode 100644 index 00000000..bbfaf9c1 --- /dev/null +++ b/modules/system/secrets/default.nix @@ -0,0 +1,82 @@ +{ + config, + lib, + ... +}: let + inherit (config.networking) hostName; + # mkFakeSecret = secretName: { + # name = secretName; + # value = { + # path = "/dev/null"; + # }; + # }; + # fakeSecrets = + # builtins.listToAttrs (lib.debug.traceValSeqN 2 (builtins.map mkFakeSecret + # (lib.debug.traceValSeqN 2 (builtins.attrNames secrets)))); + cfg = config.soispha.secrets; +in { + options.soispha.secrets = { + enable = lib.mkEnableOption "secrets through agenix"; + }; + + config = lib.mkIf cfg.enable { + age = { + secrets = { + # TODO: Remove this, as I'm no longer using nheko <2024-05-16> + nheko = { + file = ./nheko/conf. + hostName; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + + lf_cd_paths = { + file = ./lf/cd_paths; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + + # FIXME: Reactive when serverphone is merged in tree again <2024-05-11> + # + # serverphoneCa = { + # file = ./serverphone/ca.key; + # mode = "700"; + # owner = "serverphone"; + # group = "serverphone"; + # }; + # serverphoneServer = { + # file = ./serverphone/server.key; + # mode = "700"; + # owner = "serverphone"; + # group = "serverphone"; + # }; + + taskserverPrivate = { + file = ./taskserver/private.key; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + taskserverPublic = { + file = ./taskserver/public.cert; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + taskserverCA = { + file = ./taskserver/ca.cert; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + taskserverCredentials = { + file = ./taskserver/credentials; + mode = "700"; + owner = "soispha"; + group = "users"; + }; + }; + }; + }; +} diff --git a/modules/system/secrets/lf/cd_paths b/modules/system/secrets/lf/cd_paths new file mode 100644 index 00000000..fff32c61 --- /dev/null +++ b/modules/system/secrets/lf/cd_paths @@ -0,0 +1,4190 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrVzR4V1ZkdlNxNEwwbE9J +RkFtS1VFTFYvVi9mYTVRVTFNTWovMVRlaUNBClBoMzBYTDNrREMrZGNoSTlDNVZr +YVIxaVVFRkxVK2c3WHNidE1haHBCQkEKLT4gc3NoLWVkMjU1MTkgelpFb25nIDho +T21PTHAwRGJwRGlPNWE2YndnOC8wNVNhTi9nY0kzMzZlZ0JkdGxrUVUKVStHMzlN +bnB4VXRHSFpZY3IrUis2dEtwRUFyZnJIN0Rpc2RkcnlGTFhPcwotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgV2tKamE4T2Z3UGVVdXAzL2N2OGdsT1BqWld2cEhCTnBEQ2sr +QVR6QjFDOAp6YW5mQkVtOHdId1JJTVB2NW5YUGE1QURWS1haUVRHdmIzT1pXc1VV +aXdBCi0tLSB1VWRLVzNvbDIrSmswcUpqSGFsc3lnVFBpckZ5M0MxdVIxNEdGcmZa +U000Cofv00o3Z8wl2SaMdgZg2frL82hEazXauOvHejiYd0nEL/uWxf0+8KEKXMjm +HKCtoTMq3Ub9TF4WV8YYj2Y3EiJV5+Jv1LvefGto8qX/8YZw4nvNoziWWVLb6uWp +8cpZAQS3uKYoFb40pL0/ovdrQjHSsmJYdwLU6DtJEzXQPp1Log2L5pLN47+vT+y0 +J9ouYaYeB9GclvyTSo9/D36thjrAINy4elvQ7fI7maJ0Vnvi/BHm06jFAG5tWvsn +zgnXNNJrT5dF1pyKnT1gDOQupbI08arNA7p/WNzBw5Z52d8a09Y3plZ9P0cl7WVj +OJUkm0jIiqVSRcKH/gc/YYeSzeceVhbhiP9ZDPTS+1FRJMEOJGnz8VPit90RIFKj +dXTTEYqFnkVUcjSYLvtO/t66N1AMGrLVAj04ebFWMC6Tom1LQjNycZ4vGsoL5a0X +zBICK1Z+k1ABJgWe1L70hGyut8WFIZ5oRu24MQQtfRru4fnDS7tz3YM65bJdlMl1 +HZYocbs2ETdpDaAgcyHFvD8gjjrVJVWyZ/K/gTZPMuWXPxUEgLbP9bsrBN6i9Yiu +p7wolpsVWTaPjloBxGk7yyPXHIopyGDYl+9Jvv6w3CUTJxXn++Ym/SMF9hj+OCSt +0D67OyHK6JqZJh62HBMzcrwEN9j7tzs45CpGpr1TTHtlBpRrxPGi/imf+mjczVVt +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 +to20Jkr+r4i94inTPVNyz8ws1J8inZ/S21zYTHyCbJ5noCTkSzAgsi8OO4rwfOdY +BhY/UxdINZ0Cey0GBgKGxHduGgzIWZJ9mlhepOelzu3O9lvYZtb+R/RHnJpZq4+D +wxrc5GY0YjW8k/zlVBDY/8m+1lPNXCIJyc/ckcWLc46tHp96pvCRLvYDBv/9KZUj +D63vdaUnEnQndZgoTfk1J4ZTuyfzBWQCcWSLifKe/e0SOG+F69pIiKka7koWnQiM +UtN1xJ68IgiqTsX+dEQQxG2Z2p+6DKb2Gq1RF0Sce8zfdw3YpeKKT3E+ioDS334r +utNPm+ZYOLq/mG9EFlEFwwN2Fw6qZx5cnhJmIcMJvdXGM0F6kuoOLpx/9eIe81Wj +yi5PDkqRaKsTR2LtEtccPM8qZ5yI/GbGeUAHN/79LoHrKHqdk/MxA7Jtc0CaCA6O +tDscBTC6/IB7GAe3NXOLrVqWuZA2ntlmoGB2/qh+ADLidwTgcAAt0rUwRcH2wrwk +S4/eATCsdI7MXmZ3keCrR1bv+T4TO5/IyFl1kGTp7vKEWqm1QbqwbBp4dVRVjCph +CoVj8vXI2xf6D7dD2Th90K+FvMnf6rvsJNSjWkWm/wbNbyvo2ThYmLT/SnOHxv1p +FpTPoc3hx8VTMn7vk5v79LNERSeW0BSpAoVxLONdgT2phMn6fOf+CB57nl+p+sp0 +clC8Ru4XpfBx6TQvdETffKb6qvk8FBkq3+gAKw4Vkau3e3+HKHYxR7q5FkwEz0Zl +rgr0YXjWp50WsLSDc6P3PXbnqJDpqAFc4/R7S+ihPmttvesT8+aCTLZay3AYIXyf +E4RfgWLiBzfxhS4qQHBtrxMVTICueLpT2cvGXIi1ioVGsC/buzB1Nld+Qfk9LwnF +ZIMXQ5JpsgoFqB/ISvxH75n9Bw9zyvhEziVdQ7Xqkd+fqI72xuB21VhREBXjAqzp +UkbVG6mOiAV/WoE5xlWAx1FU5F29xkbBHB7dsvZVFJNNc7mptwYDE6wofKzhfQjw +THaX8H63JLdMpi2lsZUiVZcRYG9vP0AD1DfgvYm/kP13YXPHmLsN+lV+M8O0uuEi +HAgWHfihjx4qhZoMjVnl413PtGOF+Dp4p6+cffK6ee8AYzHXPIXoIHfAOd/hhoRW +fjgpAwUVCbkVztRBZKxFFzR7fGKf3slqieDWDs9z1jtFUAmhAoA+y3HaMaQNbQCk +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 +gQ== +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/nheko/conf.apzu b/modules/system/secrets/nheko/conf.apzu new file mode 100644 index 00000000..a4f704ea --- /dev/null +++ b/modules/system/secrets/nheko/conf.apzu @@ -0,0 +1,45 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYUVBnV3NkVlZuN0IrdzdZ +UmlXZUF5cmFvd1pzOGFZNlJuRzdFY3pWV25vCjVVNksrYjhPRi9ZTy9DOXA4anY2 +N3AxWXJTT0dZZU0zOEFCSUo2dUZhK0EKLT4gc3NoLWVkMjU1MTkgN0hmRlV3IC9U +UUhPY29BU2tVY2Z3YTJicjVwZjc0dVVRVHd5bzlqS3pKMDlDc1hjM3MKVmRxc3c2 +SkZvdk9nTzhSdkV2OEdrRjFqT3gyOTFZN3BRT1pZb09nQUg1SQotPiBiLWdyZWFz +ZSBsR0txeUoKanFDNm5BCi0tLSBqWCtNdWk2cWh6WDFXRTBsTjBHaXNRdDVlY2ps +dENOeVc1YmZnNEpZVWRrCpj1HsID0+Oi3IoVUCsFVPIxeKsvptv+8T+Zycu8tmfS +gZZm0XHdJHJFh81d75YyHRBhAhuq/Rg5sR5Wdu9UAAo0NqDIlKICFfKmdrbxEj8D +QL/W6TThKeR/rDZNy2E8Y1hRgQz5y1YG91kjoZpUQReNZBugaq5P0n1UiI4YYa2Y +Dp2E0S53pnLfd3f8UyVkli8fxciFCD0l3h+pueRhEalpaJlJAublyMLXO1rPFvw5 +MiqeP77+kcEtXWC3icfPwNdVhQJEIdOHNsUh6CdD37WORZmg8Kwq2vN0cO+xlZt0 +5zRe3pcBFSzqVmVC8BYRfeJPyygEo70kqbqd5JmnC4wcqvwbHyB8JNBspqkVc0Kh ++u2iYGFjtz6hN6wCxssIOxKLhgqmY5mS0qC21stDa3MrH83cAthtTWEf4IIHduHC +qDnmcpD4dJtB5fboxBrgZ4K3TxMPgRx7J+2tqY3wtxZUEonFFH1L7MyEGmJ6cFiU +RV1cbJRwOYH5nesA4nqAP7/d42vB0unbeTrkYOpTaUSa/hOXfycCtqhtHWFB5378 +2I5wvDdZeTzt+FmQO12Qj01Pqy19FbjMmUeQtKfAiBgOSdvdGOKBA7VmFlG1sow2 +vsU09JluQok/cuDEqunun4cHxLlzTJtH9eGAKceXx3trnKz/zyzbWw55G7VQqM7a +snpi0rsikr+7i0/oxAcrMoBOEX6EDShS6Vio6IIz8KNU5zUPQW5tNbbkfMQW1GM7 +rlZScSlk4N2CmR34BwtEUbAEKzPuNZU3zOX/urDd7rN6gjqwTwa8AGH8bCItMWSI +xxzPq00znHsf2hQkLOI40ENrs84/9ZiW4X3lJSPGaT/t1plzjiPUiIb37hSA6rhR +95zo5qzsjhVJqLB5V4S9wkWJ2vN5Yc4CY6hgoRnZz3n4XoxRed/rdXZ5eUQr2kg8 +h07CNpzeCUfx73kzsrFFIkBiNe0pd3ss2UXR8ilKyY2qMjqQc9Ypd0dLFU34nK+J +t8rQShs+288ni6kXu4PgBVzT891LRuwSxzv8lIZGHtUQ7XJFSJaeFBl+jIGo3iP2 +bdxlFuikGkhyvo+H/RFrAsmxHKgVs4y+ccCkMoapyUiVRvHA2X+LK935EEbGdTI/ +wNmUTPNmB3xlnIsrPxjqw4iUCf3OXZGFd1tSGc4C+5+IYryPPX4rln8fEnmYWq8f +mbHwIjri7YOuC/dVmI+fh74M0tqL7qGtTm8j//AYo1U1a0kgOPItiRzJRLX1TZ7M +JnjQbCmyPX17liRAVbeTJGLAorYIHhCXMRSf7TYwBGgOFHGcdQteFYms2eh9asDe +Zt6Zlmk5yJxz1je+ayWFzp7rms/wEkHR3kZ9dKUMtvAtLzusWcLL4A0zuBU9+GpW +thA+tcskvhX+UR8sYLT3d71JjGPqXujdHFpp4kM/RN+vdpdF+tOm0HVIn/ZuVcNV +pvGdAcKddXH9NXrc/5EDfQWfHbUrjgdHdZVo+BcD/4EZ/k7pQ4Q8EP9IXDvYmORU +5buuZsphAs8JFnuAu0FkwOuQQHX1NjVv0XGjwWMJsTDtRpZTfTL1wJmIdolqJRcZ +5EvhzViERXdZaOOXvUzy5N2BeZA/lX8Ls5P9ygOiCfF5rDajfk6CZLqrvJ+czW6m +07lkpfCo1CsxYGQPcNWlVQOnvO9lW7EtErEOcjdt1VcWJEm462O4FiILVm6Ef0Ax +/qDJUPwFd1NjmvW9e+GkHMXHDnADKxNxQU/KJJsLVdUyZVX4BzQ3W86N/kMyyWQd +1kgAzH1Aba1XyjDGyBAwC0ll0jwemqsD1F5Wzsvmm1dHMWev9y8P/jnQ3hsZ2j1c +n91KbPiZSaqK8ARRROzaVwJMGJIqnGAtqlwD/h1dE1cfHly/OxBHoo5VXPX8R9r7 +W31vHWjKrH7ZlZUa095f3X3xxUvhhnlFFhAwXluWc+FO5IlcqWMdfaeZKYORANdR +sB/moDP0n9WDQZrql15gfca+TQZMNcba8bsa9xnnkow+Gnl3LXE8SPTCE/nWK7lr +gXczbdNe7hpj4cK4lpQMlfk4iMeHYj47k8FFBEh0dbkAz9EpZQcRTjwJScybD51S +XhcOtSD1DJsNcl4RlaraDI4LRlfPqkTGbdmWfxaBmxgSupezF3wa9IC7iXmZeCt+ +doPKlB4LGmrr9ZHX0mDEJZtdrLT1x3xR80afZPlHCI4p3bKIgcmIKyxKxDpoKCou +OPpi0J2mtDZRG7M+u4dDJhiTiYPnhWxOmlL3yHGgN09xb2ZlmO6PhH5yL7eqiItS +n/iJA0bOZE/wT19+D5DofKzs2yjGTx4L+W4= +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/nheko/conf.isimud b/modules/system/secrets/nheko/conf.isimud new file mode 100644 index 00000000..ef6c52b6 --- /dev/null +++ b/modules/system/secrets/nheko/conf.isimud @@ -0,0 +1,47 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwa0Fvb0p0aU5yRGFCSm5h +d1lNSWc3aWl1NS9FcXpsalVVVGpuZGNRMnlrClVBM2R3aXpSa3pjZFpQbEV0Njcv +QUkySlJRNkV3THBjYUt3RWY3ZWRtaTgKLT4gc3NoLWVkMjU1MTkgN0hmRlV3IHda +dUU2WEwxdjNIZ0R2Wi9rbFQyb1l1TlFBZUJMWlFuMXZNSWZaZFIza2MKVGwyOExv +cW5GK0JsOFVRLzloaVUyQjhvYzR5QnNIc1RTaStISXdnT003ZwotPiBjejctZ3Jl +YXNlIFR9UFRJZyAwTjpdfCBrXlc4TXVnCmlHWTBMOUhPWU4vTzV1ZWFZVTVzTTRC +aitrNHJMQlBrMm85bWhBU29ONHpvSnkvSEFzcnZOTk5Ma1FNM20yVDUKMGF0M25C +UzR5RDdrN3cKLS0tIFNUQk1jU05lSStkQXdYMkttYjY2UVczMi9xZkhZYkdIQWw1 +RkpIOTBvWncKIACBrSaYzKJ84Kjpj57B/WC2vjIvvDAfy3TF1gVEWFOUgYkCpO52 +4sjWpd3JVpdLzsJczS7Ty0HZYBlmz3Qtejf7x6b4xftJSari5WUK6loGtmGKbgJW +lk2LZonpTsnyyALFavanlQKkv1isR9jqWxRe0KZu76zbX/QTUVfHyjV+4m6kleUI +ZJj1mLUKxYdJn2aGyTr4kwTfbLYR8/xxJYGqPUmCrFrLhsr7qy/yBXvPyIfJ+sd/ +ab2/Qz2U8wE8d0JRiwoguFaRTbrIKBzliF84CrbDznJtLQjn02zbc78lzn4n/7MV +3VArXkqw1pICkbrfLl1+own3Mw6ge73tDnSunzgJWBKSOFOrs/b/J1uMMjoiTGWi +THy8+asIFw/zZTmrUnlfmm0gE20nm/HYTJ+428nGrMwdh++LqgocxqX+CNcNTT56 +QhXwR3JuliST8jptRaFo8fzoJUImclSj+o3X2/KORm4fS8u67lcDA6KB/lw6WOie +UE09CVsrkR4X7ACe5Y7PYr0fWYNh1PrYxIabYttQq3aus5SunfkrCX+/+xtbMNsm +FX0TxMintrp3UV4eWEZzsHNz18PaXtyZTFCF4sTmnxjfP7TelZRTHNh/LbKLFrqL +kna9ChqIUiHIEYbugkZsSWUICWMbEGBWQxD4CT6DfGuve4vOgw5FWtqdvHz43f0j +9Agjvab5H+fBvDJTbJiHOFn681Wl219hR4z1plM1eVu+59JIFECVeEePoDrjGy9n +K50HUNs5Vq0p8RFus2BbjTuECmggkzd0P7mZb34bVo6K/89lCny21WeGyhwim8Hr +KKBmpm+hCh7gikBKXP0tnpmt4A5sPg30+YxePgaKCNtUjLLnN4moEGzzAsks1qsJ +GYvzSZv7AmTfyww2cjVm9ZSrlo4EHL5dMPEVBHpy6pcSV6WotkZiDklYPD4g0ZO2 +wgbLU5/YDhve9FOKoP7Y4wocP18O6ffjiPVeCg9XDUmoKq5Y/Ea1d317q973G2hf +YxUD8z9I8+fGlfqmgIjJZx8/0wTFlrCxI1oam6xPDmbSjrdVI+nr/2lfNqy/VOYN +SQMr/Po7DcAwB5SS4ItxYXKYo9FAFyoHAljYhV156l7dveqehZDKaqBzBF+pCefQ +BfiwvYg3by/R9jtMdh6MwfMeF1Z0siJdrPouIKmsuITLexuj85GkzPzSPDa69H2s +iInDepGDX2YvH2BUsUi8QPwoxRXROFwDqaIpA/aaPf224YN7D46TzU+a2HQzlpmV +xWqh/pBEwKdTpbgtdoG9GLrETDD5/2FV9FiQXxQgvV8934nlOAvdwHEJqGMlNIT2 +mlNhZyx49lOfx8BFP+NXb2adUY49Aahkdx4/uB6fN0H/RyNh39R74DCbjvIQUxRV +OUKyWZ2a2wSbZbA6tNmB5sXYtfCUOZLfE8mUwJgUSVrEccQ7UlSlEy9+gZDiHjS+ +OYnTBdRdG2AjPy3mBAdfqooTdzQwT5HNnFskg7Q3wnWRf230yZ6Qr2lBOyBgtnm1 +Hj8fI9VrACfAtYMIWUarBAnnoWHB1pHfoZOui6Zr4jtqlH7lgOAUFx/b60g4SsSF +jAJnRCFyUYbTv53GefabjkDg3WkCiyxrNhr7gS7oONa1qHai/1TQeWPCe9zj9kaR +nMRZQKI1/wmK8szhH7sA+tShtM3ktqkNlIWXuwId3OJ8ne2vcES92NRfyUI8qY39 +atndXRUg47+2MubBZhP1pnLEdxpvdOQVgDIzoNx3mu0mWkSi2K3Dy/Y4mZGVaee/ +K98cPo3S42eKEulsN/iyTWD1nJpaDNp4fWDCDMSK8dy7vSWYcT3htzzR3a4WIlLk +PV3/7l99y/HLjlJmqUwRri1hydRdC74Lk3FSV6gc6snn54WnaLUCVOpCIgHefNVr +zYmUR+4I6zioxp9540zrD8YvrK8YSSs47PtbpDYI8E9O4L7+uy7gujwJtSupZVRc +BP48+5NddK3gpQt4BagYj6CO/vENwDmUiA+kUM9WdQbnV/lmeNPdqm2VjVbxNObZ +5xHlXODOOCVg+LSpFybFT+3A2MNA/jRKGID5Kai0a9c7jY/XIrUdIaCpyVylj2dX +4JDC6AsRb1VXu7FaqhLhOabZZzW+o8m94ZjayWA2BT3IMf5Kd6eq+v9zh5RPlvtu +vcoLBTEsLPZeAyERpaTto431yRqzSKMvDQ6nwpXbdIcHLIvbp+utRoaqtel2JGO4 +PBz21qEI/ACc6sDhyUHHLz+MybEQilTSrBJ+jYSohFfm0DEpG8cThgm6mMSDUMEM +6ehgKHIYdlMa7YIBcIpJBsl8Xs6If2+FA7cbeh6xqbw= +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/nheko/conf.tiamat b/modules/system/secrets/nheko/conf.tiamat new file mode 100644 index 00000000..51cab7df --- /dev/null +++ b/modules/system/secrets/nheko/conf.tiamat @@ -0,0 +1,45 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCUDQ4ZUtkcEVTVWpTQ0Zy +Yi9naWRDaDJFYm9GR0k1QVhJR3V2Rmc0a2hNClNxeTQ2YmFHRkxRWnhlc3IrKzJE +eHpWNGFSTEV2WDR0OHNwTEZiMGdxOFEKLT4gc3NoLWVkMjU1MTkgelpFb25nIDFH +M3orVXZFMndGc0hPN1hWY0xyeXJuYmFLVks4bFVqdHFQVEN5eUhNRmcKUWlZdjlH +ZWtrcGlnZ2ZGVHBwNEZrM29CT3c0MERBNm5SVjhMdWxGbEgvbwotPiBULWdyZWFz +ZSBoOGYKdzBOVGpYNVJFdXoxK1dZdU9rdG5jU21UbUp4UjJYZXRoTTJqNnJvCi0t +LSBwZTJaUS9XRVRINmpNVFhxMnkvdGxkVTJaNkZTZG1PUGVZN0F5QmpJWkxrCohN +YfE5W/OxshJPerGCFWpYkFcQhJaz/HEknz13rCqH4yXfp3M7uoHWKfEFi1uzFdZs +H9MnIKS5NN8bLW4xssBaogalqCAigEUDuLPKmep8224Y4h9i+7fWOMBhgHjU322N +7iJCjnHiKT2tM4uv95c9Fa676xHcfZwzaCFDxbasQZmZL3G3U1wDseSK7EHCZ78R +sXqqd54ApUQyAwdSLPFVvX/YlhOIL6MMUWvhmmgHcNRYa71cQcoojleJI28fu53w +6X0qez81+/D8txyCEtF07m7ckCtYTe7oKT+mF5cvT99lHqEJBJzq/PxUIQt2dA2y +AQr09/7LJ5h8RYVG8emwlqzBasvCdLFXwtCNRMQGb5kDJ5CcZKy50SIpYvDdj269 +Ap4Lq/luQIeOMXQudbc+ECToxbrRKy4gcG8oKsvIXytIOszA8x4WjR14zSBTNunx +Z4mOb0zDy1GdKWsgPcyYdiOBIKzEpTLvjCbWYWJunGSPIlsksBvAAP6MsCbV0WQo +brp48ds24jlCjtqW+AdSIvo5+YVdyCEho8Gdw7k134cIhjoC0SU1vmNNzh1swoW0 +yRKG8ql2Tj6myIDcLM/KDozsgu/gNC2ugRwTCDv+gcApZBmKUXN2w0abhI2UMksH +FEw2ITrWDhPE87bXWNua+vdaBa619lg43xoJTGeJHqF5gXEV3blZ5bTvVjT2H7Dy +uBfCk+XQ4G51Dwh5iyjrQyWxCkYS0FJGD6WUTBU0nrxc6d9UERcxVurtPr7I9Tmf +IVdl6jkrjpfVIL/Imo+YgfdG9CvhyEl/x50c4umDsLxEi67v8TE/yEBhY+o5RnKD +EU0NjdHDIgtI9+Fa0KujnkIN6DqJ0V+QHKv7K8yiR8BScIq2YD1LOOApb6pom7+4 +440vZwmo4NgPsPyM/GgGUIyTeR4tU42BPyMTPjKEuN97ZwWZqIFreUl+nyLzViK/ +bGLYcRfVjjHTJPIeZRosYUo0ZMFggXAuslx5trQcb1B4iHvL7k2jjnMRJmyYZX2d +CWohscc+7+1iFNdH++tefcED8T8HCGpM1RxSM31kfpnKnINeBdo9E9ZDmNCElZm+ +nds5fgTm/MLKsuC/t+MecVdfeHTufc/Akh343DMdIMNmZ35xLcpNLmxTJ+iCALS7 +nheIWAFUaTh6GB6IGocSSjQ0RwS0wIftka4QdW+UEtEjnvB0D/CjwDLSO3pUl0mj +44r8fH8IZVcQcnqhuEsFoih/XOlH3N95O0HxXCvUcI13/HaSpUKdJqyAIn8w/jBM +FL/boJVA1zOH5sIY0AD2IMavuS5b/ZgJtPsESrc0LUiL4nztDVdAEtpHUM0OEzb9 +tSAIN888UKTC8MFSIwA+4cXIyCEpxXP3HbSNaar5gp75oG5/BqOu1aF5sC0kKpmn +9C9+z9sLTDigzV1GKlPpUGd9lVOeH2JpAY8ZUyn2gxh7C6IHwwUbWUclEPy2siYd +HcAMneEwXpm6DfJevMi2o0wOdVakcpN+YUNzIgferM/IU5FbgtC8gNBpDCBo2yLe +X7ERSzP177QWwXLIF2WhZeG4Cvszj4tySYsRJhoZPc9jpRjiK/ccOoNo8A1UKbJC +H/836MNskBmmbNoPsS979mLv8ijpRzvjnwbWn+ZlCo3gZAKVM7PcXuTODcWfoAJ4 +2ugEHCAiOobGQtGUp5HOhXYfAK2Wene0a9RmSAT3SgPmx95u1Fy8n+m/PDK2opIe +REpj9UTcoT0+5aHIwp2gqLVpQH2953Prd0qaNfc1t6gQKwDXDDU+b+QmxAaPBwpu +0TEIEYKsx237lX314XSaq+Nt7Ko1OPABR4gkz/ELL4WOKwFbf7oAAV3UiNPwweY8 +R3cpVvQ70y+M2Nnwepxf7wSruo+FDtgsic9vtobdpwBViPC+AG2QbI1hTD3uhslE +KunFtbO08ARcTMeMgZ0BE3XXnrgxdKjXmPEybQiyObFxDGbV1EX/2i1MKArQdQzs +MxCpKOzDi5axr3Qd/W6Y/foMZWfRYgb+0xITHU7haR8QRD80uTbt9TfsqK98H1A1 +UMosMKhkzKG70qdNvTiEh+OqBAIbUL42IKNn4SCiZt7ZCQ6/QqwcCi6ND0w8+dO1 +u8vZdRF+r/3AAPpa3W7BiIiLUmmU8IUI8A/72cCrY6PyrjaomXnpVWlZjQ616i9Q +TU9IwBahMa2j/a4317pv/7ltQQCpCkRs/HweQy5CQS+yFuOcoOVikL0ZHd9XC4YX +QJ/T6R5+OngxkJgoPRtJ +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/secrets.nix b/modules/system/secrets/secrets.nix new file mode 100644 index 00000000..cd6447b7 --- /dev/null +++ b/modules/system/secrets/secrets.nix @@ -0,0 +1,22 @@ +let + soispha = "age1mshh4ynzhhzhff25tqwkg4j054g3xwrfznh98ycchludj9wjj48qn2uffn"; + + tiamat = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMD87QQIUXdEv3TaNRrI9clD9VgpsuVLFg2CrNGa5lVB"; + apzu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBivF5b6PyxsR/t+4Qg4IEDXHVXrjmZpslTUNXpvcVbO"; +in { + "nheko/conf.tiamat".publicKeys = [soispha tiamat]; + "nheko/conf.apzu".publicKeys = [soispha apzu]; + + # only here to satisfy the nix evaluation + "nheko/conf.isimud".publicKeys = [soispha]; + + "lf/cd_paths".publicKeys = [soispha tiamat apzu]; + + "serverphone/ca.key".publicKeys = [soispha tiamat apzu]; + "serverphone/server.key".publicKeys = [soispha tiamat apzu]; + + "taskserver/private.key".publicKeys = [soispha tiamat apzu]; + "taskserver/public.cert".publicKeys = [soispha tiamat apzu]; + "taskserver/ca.cert".publicKeys = [soispha tiamat apzu]; + "taskserver/credentials".publicKeys = [soispha tiamat apzu]; +} diff --git a/modules/system/secrets/serverphone/ca.key b/modules/system/secrets/serverphone/ca.key new file mode 100644 index 00000000..d49c5395 --- /dev/null +++ b/modules/system/secrets/serverphone/ca.key @@ -0,0 +1,19 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyaGJNQkRRVy9MRXZ3b2tJ +Q2R1NUcrYUNGRE5uQkNyUDdkSm5rUWYxaXpjCjduMG1FSG1VamozdnJoVFFZUDYz +T2pyK1k3ekZ4RnFMaDFKdUZPWVNuR3MKLT4gc3NoLWVkMjU1MTkgelpFb25nIEpP +d0xwS3Nia3AwNmppRjZhODdzNXhEcnRsZW5rUzBQcTN6NWhWeTNiQ0EKTkpUZ1Jk +NHE3WVRzVEhpMnJGaVFpdkFBVW5QNThCSUdFSHVQR1RrQUJsZwotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgdjJKUUtlRjE5UFEyR2tBOWhEbHNMVlNSOUMyZ1dkYkhYZWRW +by9QZ2UxTQpVSnhJcFFYay9LSStrSFFJcXJPWUxydXNGbUNXRVpLcHJibjM2TDlw +RnlVCi0+IGNHPjMiSyQtZ3JlYXNlIGcgdWZkbApmY0YzMmhDdzBWT0RKaWlUUmZP +bmRPOExuRVJ3Yk5mMFhYSnhlRENqWXJxK1VWdnBibUxzNWV1NHMyNVNXN054CmR0 +VFAzYUR0RHVaZUpOTlB3USt2TXVDcXdLOGtpZwotLS0gaTliQzBjbjdUYkVidURX +em9wcU04cDhNMHB6KzNBSVMyMmtSRERKS240SQryB70ZEgDQ4eJ/pjIWh6MBEUQr +iAx2i+J+XJu+74bC9DfB5rWpR4/HAdp8EF6wmi05TuEPUpG9brwm/mHi+FB/Drpu +00viGfM3dlCyALz1jB2W/MbruouK85o2L3RWDCgc+eT1gA+u2C7ZxO6iYA3aP4lu +ShDcSHlsKkh9lx4cRsNTua/8N+GQZLciSC7iMDroruxWj1HET9IxeeVN+VSuqcjW +ocX3LU2uU8vP9WT9zT1lbQB5Z0EM7W+ez61SjGpzrpXB2mpmi+SHOIWF3VdG1H8R +18BIyRjKIj5Op+8XD7qAe6nl9SSCnMURH+arc7yjNMgEbzFykfldfug2ibI2G/kW +OxeiEBoSFlC+V8ivS6I= +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/serverphone/server.key b/modules/system/secrets/serverphone/server.key new file mode 100644 index 00000000..a2720406 --- /dev/null +++ b/modules/system/secrets/serverphone/server.key @@ -0,0 +1,19 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJZnBXSzF4K0ljR3B1Rkk1 +M0lSSkVmVlA2Tjcrd0JCRmhHWDY4bzNoYnhjCmsvQjJmYU5vNVh1Umw0dzhCQjNF +WVRhVHpUTUIzRVBxaXhFWHpuenZHN0kKLT4gc3NoLWVkMjU1MTkgelpFb25nIHAz +aG02dkxiNVRreVNadXJjbnc0bXBtSFRSNDhrYjljanUrNldwVFlabXcKU2c2L25r +VlNjeDFENUdQeWllenRGWlRqRW53UU5VNEdCaUZsbHpaL1ZFTQotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgZytvUUhZSXhwQ01mQmtkZmhzdHJUd2tlQS9yYkxCdTBYZ2pJ +UEd4WEF4SQp4WVh2UEJReDVES2tCWlpqQS9aanQzRGRsSTA4S0VXSWZxZ2hoKzZq +YllzCi0+IEc4eC1ncmVhc2UgaGQhIGFydERoaS4gLERUcQprczdDdHhaOXpmN1VU +MDlHNlYzVmMxY09Oa2xzTVN6M0ZyYnpRSzJEMS9nMmlqRVo4Wk1qN1lKZnp0N0RT +UStuCm51L01Rb3ZxNUhEa0c5Z3orYlp0YmlXMkhpeHVJMjNkRFZYWmR3QmV2Zwot +LS0gdWJDeHZvc0xOMU9uUjUyMlRGUnlGSW9PZzVKWWNoa3pWbVM1OE9LdFk2NAo+ +WS82jL1us5iVw+xWVI80luHMs31hxZfQgJDBuFbtpY0nKkM97U7rusl6t8P+s93c +R0IYBEUuz6n33GTeVOLipDqkZftlOOvSZkFneZ766+GpEO01dCjeSW9KViDC1jI/ +721IXq9TQNZw0Ou3Vf5E0nDypsfG0UhEoLCy6QZL9YCIyl5s//kyFFnpQjyaGT/P +pRHGhD0BxZa2ib07WDWzBpsTFtVemwcn9lqAx7DlYV2X3UwCT3qVOVjDuA/j6qUt +8bCDoXs4/dWleHNHzpwRhe+j2W4OWDKp7o0zYqxkUuPpEWXL7+A+B/+/08nAtZQk +ZvJyaZSL5wicIPAjLxrD00z2QcE/ZPyUrXsi0gOovuk= +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/taskserver/ca.cert b/modules/system/secrets/taskserver/ca.cert new file mode 100644 index 00000000..203d62a8 --- /dev/null +++ b/modules/system/secrets/taskserver/ca.cert @@ -0,0 +1,92 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5c0xqVmk5MzZrUmhqTkUv +YUdRamtpQTdvZ2N1QUM4MWNiWWlYbmwvWURvCnhLYzJuSGM5dkhGbmZGaWNpNVhn +L3hSTU9xb0cwc1FSZHJpYUFqTE1NZlUKLT4gc3NoLWVkMjU1MTkgelpFb25nIFhv +N2dOR2xleGVRUWU1cTd5Q1RnQjVtZElJOVdaS2EzTGtVbmswNXdiRWMKa0hubkRD +bFE0NXp6R2QvcHpCUTZjblk1RVpIMmJ1TFhyajM0N1lYRy80UQotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgOFpvTm1tN21pemJFUXVYYzREcE1aZ3dnMU5TLzVxLzFjdWI2 +eENGWXR4QQpwcHFLMS9WNDRiNFZxSThRUk85RVZhS2hyQnptL2FHdHo5OCt3dHF0 +amZZCi0+IGctZ3JlYXNlIDttPFJBT3FfIDZeMT91Ois3IEx0CkFTbFYxZzloWlJZ +WndXZGx3WHI0aXh0U09la3BmblZmcDRIb3RRYjdhL3drQnhQRWNrNUZabzE4R0Q0 +bnpqZGcKVy8xbWV2TXV4blpRNFg3czZHWExOZllLR20yU3hrdlltZwotLS0gUjQv +QXQ1L2NselJ2OVJtUzc0YnIrWlpXK29WNFFVUXEzUTQ4ZG0xRm9zSQqJzYGOwU7Y +Jt/x8jJohpCDiaBjukoqL0WH7ocjgjt084M+on5vp3pBbT9eIgErCJvGc7oDmke0 +Isnb6RvWg6fY66WY4Bsm67VqGiNyV1yQmAXB+zp6gfKjAfvdZk7wUbgll6mUYU8M +IVwvPHS6C3ByIMVU6OaNPXvAMIakDoQUM+HSQpy7Cu3ZuLwZJs7kM9CWGM/GzyNU +fhBiO8L17J5ZtiC5qOZ0DqIUCefdvKINXGLFCV1a/PoZwpbM7Q36R/urEEz77tLm +qzlM1qwq+G4SWjiihYwQ+3rcA2BPzDtYF/F0O9skw2FYFyRZhENqnba3OOewMb6C +CLVtJcCw7doOjHrpxCwYg7bcP1k9V7sR5F7ez80krQ72qHWlGBL7G4v8Mx9o/GQq +cNv8000KWIORBnPl7qyUc+Y5fZBqm8ebkGh9xg5wRflqXXZvOU81av2ayT4hjfgZ +dmSZPtYmX8jaTQwp/WqzpcJq47a9xaLfo4J8UNiG9y9paoN7J5fwn6IALrWnxK9U +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 +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/taskserver/credentials b/modules/system/secrets/taskserver/credentials new file mode 100644 index 00000000..f3aaf502 --- /dev/null +++ b/modules/system/secrets/taskserver/credentials @@ -0,0 +1,15 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdGQ3a0pWb3lvZXFWbTFQ +UG1JbGREZW9SS3ZuWXJhbTdvTTBqZUdhN0Q0CjF1cnJFM1d2ZFNyRW44Rzlvamlz +VWQycXhmWnB4L1hiSE5qbFozWFlGMU0KLT4gc3NoLWVkMjU1MTkgelpFb25nIEFk +bVQ3U3BsU1FkeWxBY0sySTV2UkxocXJpVXMyd1FrMXA3YUR0NWtTR1kKeUtHODVy +aXE3aXh4WkFmYTJtdlZyZ1A1QlhYZGZuTUYxYVVlblRUV1BqOAotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgdGR4cFMya3p6TEx5cnhYcWNXR2FlVEk3UTBEcHQ3Y3RmK0lY +YlpwRXJGcwpwZUVqODB3SUZUdTlQVW4yaWlZaTE0RE9OT1dLanZlSGV6cnlJRElQ +UjBBCi0+ICFALWdyZWFzZSB0MFU2IDZoIEJPWUZIP1sKN1l2dzdWN1JDbEhEeXBq +THV0cWJIV1RLalVsVVp3RCtwbk5NS2pnd3kxS1RhNTNaa3pqWXZFVm9FM2N2cFp5 +TQpYR2MKLS0tIEhLQWdwL0VoT1ZGNU5UUWs0SVVqK0ZQTndkTURPb0VtNEtJN3or +S0Q0K1UKRfhyrcVb0EbsKj9gL5kqaIpfrsWd2cizrVQ67y9ZOwWilWgk/gkoXadf +q7QeYjnWsHeIVtSZIaHSa8+9pvKAwiYW+B6DjRi7EXkCYz8zGeanMuoKA4by5Q9x +VMKJlWk7c0WIzSuviw== +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/taskserver/private.key b/modules/system/secrets/taskserver/private.key new file mode 100644 index 00000000..5afecdaf --- /dev/null +++ b/modules/system/secrets/taskserver/private.key @@ -0,0 +1,450 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNkZidXVhQ1ExVjdEQWY4 +bUtLR1VCNUl0c2tQUUxCZXFRNE43aDQybFdJCk5qN3FGY2JOV0VjS0R2a1JTR0Fz +NTl1WlV3QVZYdTBvUCt5T2tzV1dWbXcKLT4gc3NoLWVkMjU1MTkgelpFb25nIDBm +MUl6ZDNEL1BVVHNnSlpiRWhDMStBMjYrUEZZZEVnWGh3NjFBYWh0dzQKZjhXbFY4 +NllvbHdwKzFSR2FJUEdHWHdBeVRBRzh2NWU1UUlabnlHQmxkOAotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgd0MwWm1WY2R2NnhaS3dQYWZPcUtCY3BseEtkWUp1eURvKzRu +UXA2OStXMApXdjNEQ01JWlZSb1l3SmxYcDBMMUM4NEtPOVFvL2tHdlMzQ3hMN2t2 +N2w4Ci0+IFciK2Uicy1ncmVhc2UgKildWHNqZSA4QVIgNUE+T2EzdSYKODJIck9K +NzF0RW85RkJVNDBVaWNkTXlkbk03ZnBHNWFxSDN4K3A3THNVNEJLQXJ4MWxENWdq +d2oyL3lQUlVxcwp1VzJxTWpCMU9JRHc2NHZXM0ZvUm1MK1htaGFsTUVKaTZXbEtD +NTZzcy9hSFpGYmRzMzQKLS0tIFFjd25qSEdFT09LYlZCVzNNU04vVEY5RGdIdGs3 +ZkhodEM4SGZ4emlRUmMK3XxmNQwv5++wwwJ3CqpDfqKBLDcwyIfYM7VXqGlxaVR9 +TR9VjtFB6siP6Umo1oewRDt9Gc+MUI+rlc8aUN044ve5g+9im6uni2nQ6hubRZzD +Q3LQCLGGDiFL9+F7xHTLgFH8dIaLs4pnzeSzl+Od0Iybe05HOPGaZDhptqZvGWHr +uGHQz940sUU6k3kbnJ02qpj06AP3Uujl++s/4w5QKvVwx5m9Jio0ZOCaXv/6uUTn +Xq8l0uLMNBLtMhJsd4D5X5XRnvWSEWvUaQf2+nKFdCkxmDqxf8rv8qAE5ryx5SO0 +SnHVFZrSUhUDH4q2lVOPsGExwaExV/N/KB/24foJRoUafvpRb6GfNR8t2SmA82Qd +HVj2aqzuIcPBvefbq19T0WD2vJWHuF2p8NafL9x3KLdRIIm7urG+GLgZtB4am7BS +9B/bZrryjCVJybwy7POlIS1P+1OhuyNSdpv49tTL+v6o5PzGHeJFjykoEKyzTP5e +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 +7b+Hg4y4ZcH8mURkx3RCVDbH3g== +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/taskserver/public.cert b/modules/system/secrets/taskserver/public.cert new file mode 100644 index 00000000..1cf9b5f0 --- /dev/null +++ b/modules/system/secrets/taskserver/public.cert @@ -0,0 +1,83 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6RnRGSEZSNE0yWWhXODhk +N1FGNkFPSEVIaFJhWm52eEZ3Q3Bwb2I5c25nCkpCU1Zhd3ZhZ1YyOVFmTGxkVnZT +aDhxOHBrWGdhcE00THh2WnFSbUM1bHMKLT4gc3NoLWVkMjU1MTkgelpFb25nIFh2 +WmVLTTc0ZjUxaUFFNVFuNzVjNkhLRzR6VGdJOVRvZGtBT1BrTnJJQnMKOExOck0r +TW9mSVY0d0VTSk9IS0c3NHdscXVyMHhlUnkyNnFJWnFmekJJWQotPiBzc2gtZWQy +NTUxOSA3SGZGVXcgOXFTejhFNWd0TklHcytUMlJQdU1OaUlNVlBSbWZWdnhWbmVp +TlpNekwwcwoyQXpEd3JCVVcrdHR2cDN4LzdmSVhveGNiaThEOVE3TlJEUXdnejdY +R3NjCi0+IFdAQS1ncmVhc2UgWgpRei9tQTFCcjY1bGxEVlhxdWJFVnB1d3B5MWov +amVZbm1EaEovVmVnczA5RWpuSUx0eUFLc0J0aEZqVmpJMmIxCjUwWmJyYTNxT3g3 +Qjl5MGhuWEEKLS0tIHNaMnh1N1JhUkJIdFZ5TnRtR3hDM1kxRlNMU2pWL2VBdkkx +cUw1TWhWa28KwuibZXNGOy/Qqhs17FD2aTdWit9nvgRl/n+F/gKwJXoaEvRM7veM +uTEvmfIRJzLm5ox7ko48f8g+EWQDWvcXsa1KwCDI4DDoP3WxhMOUmNE6SYqDgGpP +ilQLOvX7kKrtY/oB6OQj6QFMEJe8dElNEq8rcapaqiWnRDQsqvDtFm7j0HcGNQ2U +Kg+/c6UQRf4lgZXLs2cGMCjUivEA6eojyLctIcXdswIxWI9TwxBOJ7NTKI7wF4hn +TKqZSlWhLg8xpW7s0ZRpAQaONMVo+Ve9TH3fPaPFsUZUu+x0jfk+NMUWBscYbYUN +JZT9xuMOmEcnXZ+/1DIgl0zw5kG2hQ30lX0QGRqrWaPoOv0KchORWuwsVgkFFMTk +eiYeqf5mkAfswR8iN6Ye1K6gH6WAI666yRbkMmdJTAO5iC2JhQVLgdJuKBWixTE7 +0Y6xdPIRUhDXn2fgeYFxnTwqR7oi7Aa9H6LVtxdFMVvhqJ2l0QKd8UqcwO3RrCRK +VLehYc3prKklzrkevKVr5k+62ateISjMF/NoEpZf4wTzh6wByyk32cNHT5OU1Qr7 +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 +m7vbEx2mecNNVw96F/k= +-----END AGE ENCRYPTED FILE----- diff --git a/modules/system/secrets/update.sh b/modules/system/secrets/update.sh new file mode 100755 index 00000000..edc4ae8a --- /dev/null +++ b/modules/system/secrets/update.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env nix +#! nix shell nixpkgs#age nixpkgs#jq nixpkgs#dash --command dash +# shellcheck shell=dash + +cleanup() { + [ "$key_file" ] && rm "$key_file" +} +trap cleanup EXIT + +update_lf_cd_paths() { + echo "Starting to update the lf/cd_paths file.." + + cd "$(git rev-parse --show-toplevel)/sys/secrets" || { + echo "A secrets dir does not exist! (This is most likely a bug)" + exit 1 + } + + key_file="$(mktemp)" + + nix eval -f ./secrets.nix --json | jq --raw-output '.["lf/cd_paths"].publicKeys | join("\n")' >"$key_file" + + # `lf-make-map` is provided by the dev shell + { + lf-make-map --quiet --depth 4 visualize ~/media ~/repos ~/school | sed 's|\(.*\)|# \1|' + lf-make-map --quiet --depth 4 generate ~/media ~/repos ~/school + } | age --recipients-file "$key_file" --encrypt --armor --output ./lf/cd_paths + + echo "Finished updating the lf/cd_paths file.." +} + +main() { + update_lf_cd_paths +} + +main + +# vim: ft=sh diff --git a/modules/system/services/adb/default.nix b/modules/system/services/adb/default.nix new file mode 100644 index 00000000..4055dbb1 --- /dev/null +++ b/modules/system/services/adb/default.nix @@ -0,0 +1,22 @@ +{ + lib, + config, + ... +}: let + cfg = config.soispha.adb; +in { + options.soispha.adb = { + enable = lib.mkEnableOption "Android adb bridge"; + user = lib.mkOption { + type = lib.types.str; + example = "soispha"; + default = "soispha"; + description = "Username to grant access to adb bridge"; + }; + }; + + config = lib.mkIf cfg.enable { + programs.adb.enable = true; + users.users."${cfg.user}".extraGroups = ["adbusers"]; + }; +} diff --git a/modules/system/services/backup/default.nix b/modules/system/services/backup/default.nix new file mode 100644 index 00000000..705dcf23 --- /dev/null +++ b/modules/system/services/backup/default.nix @@ -0,0 +1,49 @@ +{ + lib, + pkgs, + config, + ... +}: let + backup-script = pkgs.writeShellScriptBin "backsnap" '' + ${pkgs.util-linux}/bin/mount --mkdir "/dev/disk/by-uuid/${cfg.backupDiskUuid}" "/run/media/${cfg.backupDiskUuid}"; + ${pkgs.snap-sync-forked}/bin/snap-sync-forked --UUID "${cfg.backupDiskUuid}" --noconfirm; + ${pkgs.util-linux}/bin/umount "/run/media/${cfg.backupDiskUuid}"; + ''; + + cfg = config.soispha.backup; +in { + options.soispha.backup = { + enable = lib.mkEnableOption "backups with my forked snap-sync"; + backupDiskUuid = lib.mkOption { + type = lib.types.str; + example = lib.literalExpression "d1d20ae7-3d8a-44da-86da-677dbbb10c89"; + description = "The UUID of the backup disk"; + }; + }; + + config = lib.mkIf cfg.enable { + systemd = { + services.backup = { + wantedBy = lib.mkForce []; + unitConfig = { + Description = "Backup the last snapshots of the persitent-storage subvolume."; + }; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${backup-script}/bin/backsnap"; + }; + }; + + timers.backup = { + wantedBy = ["timers.target"]; + unitConfig = { + Description = "Backup 15min after boot and every 8 hours"; + }; + timerConfig = { + OnBootSec = "15min"; + OnUnitActiveSec = "8h"; + }; + }; + }; + }; +} diff --git a/modules/system/services/dconf/default.nix b/modules/system/services/dconf/default.nix new file mode 100644 index 00000000..f6598a9b --- /dev/null +++ b/modules/system/services/dconf/default.nix @@ -0,0 +1,7 @@ +{...}: { + # needed to make home-manager play nice with some apps. See: + # https://nix-community.github.io/home-manager/index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal + programs.dconf.enable = true; + # FIXME: This should also be parameterized. <2024-05-16> +} +# vim: nolinebreak nowrap textwidth=0 diff --git a/modules/system/services/default.nix b/modules/system/services/default.nix new file mode 100644 index 00000000..76ef26e2 --- /dev/null +++ b/modules/system/services/default.nix @@ -0,0 +1,19 @@ +{...}: { + imports = [ + #./serverphone + ./adb + ./backup + ./dconf + ./fwupd + ./issue_file + ./nix + ./openssh + ./postgresql + ./printing + ./scanning + ./snapper + ./steam + ./swaylock + ./xdg + ]; +} diff --git a/modules/system/services/fwupd/default.nix b/modules/system/services/fwupd/default.nix new file mode 100644 index 00000000..5ad4f467 --- /dev/null +++ b/modules/system/services/fwupd/default.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.services.fwupd; +in { + options.soispha.services.fwupd = { + enable = lib.mkEnableOption "fwupd"; + }; + config = lib.mkIf cfg.enable { + services.fwupd.enable = true; + }; +} diff --git a/modules/system/services/issue_file/default.nix b/modules/system/services/issue_file/default.nix new file mode 100644 index 00000000..930be1d9 --- /dev/null +++ b/modules/system/services/issue_file/default.nix @@ -0,0 +1,38 @@ +{config, ...}: { + environment.etc.issue = { + # Friendly greeting on the virtual consoles. + text = '' + [?25l[?7l  +  ▗▄▄▄ ▗▄▄▄▄ ▄▄▄▖  +  ▜███▙ ▜███▙ ▟███▛  +  ▜███▙ ▜███▙▟███▛  +  ▜███▙ ▜██████▛  +  ▟█████████████████▙ ▜████▛ ▟▙  +  ▟███████████████████▙ ▜███▙ ▟██▙  +  ▄▄▄▄▖ ▜███▙ ▟███▛  +  ▟███▛ ▜██▛ ▟███▛  +  ▟███▛ ▜▛ ▟███▛  + ▟███████████▛ ▟██████████▙ + ▜██████████▛ ▟███████████▛ +  ▟███▛ ▟▙ ▟███▛  +  ▟███▛ ▟██▙ ▟███▛  +  ▟███▛ ▜███▙ ▝▀▀▀▀  +  ▜██▛ ▜███▙ ▜██████████████████▛  +  ▜▛ ▟████▙ ▜████████████████▛  +  ▟██████▙ ▜███▙  +  ▟███▛▜███▙ ▜███▙  +  ▟███▛ ▜███▙ ▜███▙  +  ▝▀▀▀ ▀▀▀▀▘ ▀▀▀▘  +   +  NixOS ${config.system.nixos.label}  +  -------------- +  +   date: \d +   time: \t +   ipv4: \4 +   ipv6: \6 +   tty: \l +  + ''; + }; +} diff --git a/modules/system/services/nix/default.nix b/modules/system/services/nix/default.nix new file mode 100644 index 00000000..65fc7273 --- /dev/null +++ b/modules/system/services/nix/default.nix @@ -0,0 +1,53 @@ +{ + pkgs, + + # flakes + nixpkgs_as_input, + templates, + self, + ... +}: { + nix = { + package = pkgs.nixVersions.latest; + + # Disable nix channels (this is a remnant of old days) + channel.enable = false; + + registry = { + nixpkgs.flake = nixpkgs_as_input; + n.flake = self; # Otherwise the nixpkgs config is not available + + t.flake = templates; + + my_flake.flake = self; + m.flake = self; + }; + + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + + settings = { + auto-optimise-store = true; + experimental-features = [ + "nix-command" + "flakes" + #"ca-derivations" + ]; + + use-xdg-base-directories = true; + + #substituters = ["https://cache.ngi0.nixos.org/"]; + #trusted-public-keys = ["cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA="]; + + fallback = true; # Build from source, if binary can't be substituted + + keep-failed = true; # keep failed tmp build dirs + pure-eval = true; # restrict file system and network access to hash + + sandbox-fallback = false; # Don't disable the sandbox, if the kernel doesn't support it + }; + }; +} diff --git a/modules/system/services/openssh/default.nix b/modules/system/services/openssh/default.nix new file mode 100644 index 00000000..b733dbe7 --- /dev/null +++ b/modules/system/services/openssh/default.nix @@ -0,0 +1,15 @@ +{...}: { + services.openssh = { + enable = true; + hostKeys = [ + { + path = "/srv/sshd/ssh_host_ed25519_key"; + rounds = 1000; + type = "ed25519"; + } + ]; + settings = { + PasswordAuthentication = false; + }; + }; +} diff --git a/modules/system/services/postgresql/default.nix b/modules/system/services/postgresql/default.nix new file mode 100644 index 00000000..c47a235c --- /dev/null +++ b/modules/system/services/postgresql/default.nix @@ -0,0 +1,17 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.services.postgresql; +in { + options.soispha.services.postgresql = { + enable = lib.mkEnableOption "postgresql"; + }; + + config = lib.mkIf cfg.enable { + services.postgresql = { + enable = true; + }; + }; +} diff --git a/modules/system/services/printing/default.nix b/modules/system/services/printing/default.nix new file mode 100644 index 00000000..85d15b16 --- /dev/null +++ b/modules/system/services/printing/default.nix @@ -0,0 +1,45 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.services.printing; +in { + options.soispha.services.printing = { + enable = lib.mkEnableOption "default printing configuration"; + }; + + config = lib.mkIf cfg.enable { + services.avahi = { + enable = true; + nssmdns4 = true; + nssmdns6 = true; + openFirewall = true; + }; + + services.printing = { + enable = true; + startWhenNeeded = true; + webInterface = true; + + # deletes `/var/cache/cups`, `/var/lib/cups` and `/var/spool/cups` on cups startup + stateless = true; + + drivers = []; + }; + + hardware = { + printers = { + ensurePrinters = [ + { + name = "Brother"; + description = "Brother DCP-9022CDW"; + model = "everywhere"; + deviceUri = "dnssd://Brother%20DCP-9022CDW._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-30055c773bcf"; + } + ]; + ensureDefaultPrinter = "Brother"; + }; + }; + }; +} diff --git a/modules/system/services/scanning/default.nix b/modules/system/services/scanning/default.nix new file mode 100644 index 00000000..dda507fa --- /dev/null +++ b/modules/system/services/scanning/default.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.services.scanning; +in { + options.soispha.services.scanning = { + enable = lib.mkEnableOption "default scanning configuration"; + }; + + config = lib.mkIf cfg.enable { + hardware = { + sane = { + enable = true; + extraBackends = [pkgs.sane-airscan]; + }; + }; + + users.users.soispha.extraGroups = [ + "scanner" # for permission to access the scanner. + ]; + }; +} diff --git a/modules/system/services/serverphone/certificates/ca.crt b/modules/system/services/serverphone/certificates/ca.crt new file mode 100644 index 00000000..7a4ae6f9 --- /dev/null +++ b/modules/system/services/serverphone/certificates/ca.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBXDCCAQOgAwIBAgIIRQ2wXiaD5pMwCgYIKoZIzj0EAwIwGTEXMBUGA1UEAwwO +U2VydmVycGhvbmUgQ0EwHhcNMjMwNjA2MTIzNzM3WhcNMzMwNjAzMTIzNzM3WjAZ +MRcwFQYDVQQDDA5TZXJ2ZXJwaG9uZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABDZMtz3liWniBedisStXDO2sxFCKBH239ezH7uADu8g5peGssmNu1rXEDrg1 +sFwVUjQeJAocYYNoUeHiVpODf1ejNTAzMB0GA1UdDgQWBBST5oMmXrANRbCLIQpN +W7e5uSCL3DASBgNVHRMBAf8ECDAGAQH/AgEBMAoGCCqGSM49BAMCA0cAMEQCIFig +xA3MvRNP4uXaUEWwdP1pYL/R8N46G4NZrPEfiNV4AiA+NJSTFRCOUqEsvSb7PTFx +YuMuJF4XxWnmStz3ym7xXA== +-----END CERTIFICATE----- diff --git a/modules/system/services/serverphone/certificates/server.crt b/modules/system/services/serverphone/certificates/server.crt new file mode 100644 index 00000000..f994cdc8 --- /dev/null +++ b/modules/system/services/serverphone/certificates/server.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBTjCB9KADAgECAgkAhKrdjsoiOrkwCgYIKoZIzj0EAwIwGTEXMBUGA1UEAwwO +U2VydmVycGhvbmUgQ0EwHhcNMjMwNjA2MTIzOTIwWhcNMjQwNjA1MTIzOTIwWjAm +MSQwIgYDVQQDDBtDbGllbnQgcnVubmluZyBvbiBsb2NhbGhvc3QwWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAAS1ILQo8ae8ydqFlt5RncUT7joQiozk6Omunb0vxVz5 +toJRDmVqc1s6KhpCTipUV5coTcaK1TBz0+fft+9VH7cwoxgwFjAUBgNVHREEDTAL +gglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDSQAwRgIhAN7ohtsBLrjlgmSe9ngovxZM +z61n0+/7w2mtX/OrLMWIAiEAu+D2S2o0s7E9pp2Rkug8cT5T4GCWgFgEHk5x2L/E +RVI= +-----END CERTIFICATE----- diff --git a/modules/system/services/serverphone/default.nix b/modules/system/services/serverphone/default.nix new file mode 100644 index 00000000..20125a75 --- /dev/null +++ b/modules/system/services/serverphone/default.nix @@ -0,0 +1,49 @@ +{ + config, + serverphone, + system, + lib, + ... +}: { + config = lib.mkIf config.soispha.secrets.enable { + services.serverphone = { + package = "${serverphone.packages.${system}.default}"; + enable = true; + domain = "localhost"; + configureDoas = true; + acceptedSshKeys = [ + "AAAAC3NzaC1lZDI1NTE5AAAAIGBFuTNNn71Rhfnop2cdz3r/RhWWlCePnSBOhTBbu2ME" + ]; + authorized = { + acceptedGpgKeys = [ + { + source = ./keys/key_1; + trust = "ultimate"; + } + { + source = ./keys/key_2; + trust = "ultimate"; + } + ]; + }; + caCertificate = "${./certificates/ca.crt}"; + certificate = "${./certificates/server.crt}"; + privateKey = config.age.secrets.serverphoneServer.path; + certificateRequest = { + acceptedUsers = [ + "soispha $argon2id$v=19$m=19456,t=2,p=1$EvhPENIBqL5b1RO5waNMWA$pJ8vDrCNJKDlqwB5bVDLjHVPEXm9McQhtt9OXSD8Zkc" + ]; + caPrivateKey = config.age.secrets.serverphoneCa.path; + }; + }; + + users.users.serverphone = { + group = "serverphone"; + isSystemUser = true; + home = "/run/serverphone"; + }; + users.groups.serverphone = { + members = ["serverphone"]; + }; + }; +} diff --git a/modules/system/services/serverphone/keys/key_1 b/modules/system/services/serverphone/keys/key_1 new file mode 120000 index 00000000..67720882 --- /dev/null +++ b/modules/system/services/serverphone/keys/key_1 @@ -0,0 +1 @@ +../../../../home-manager/soispha/config/gpg/keys/key_1 \ No newline at end of file diff --git a/modules/system/services/serverphone/keys/key_2 b/modules/system/services/serverphone/keys/key_2 new file mode 120000 index 00000000..24df7207 --- /dev/null +++ b/modules/system/services/serverphone/keys/key_2 @@ -0,0 +1 @@ +../../../../home-manager/soispha/config/gpg/keys/key_2 \ No newline at end of file diff --git a/modules/system/services/snapper/default.nix b/modules/system/services/snapper/default.nix new file mode 100644 index 00000000..bf8201a4 --- /dev/null +++ b/modules/system/services/snapper/default.nix @@ -0,0 +1,53 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.services.snapper; +in { + options.soispha.services.snapper = { + enable = lib.mkEnableOption "snapper config"; + }; + + config = lib.mkIf cfg.enable { + services.snapper = { + configs = { + srv = { + SUBVOLUME = "/srv"; + FSTYPE = "btrfs"; + # users and groups allowed to work with config + ALLOW_GROUPS = ["wheel"]; + + # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots + # directory + SYNC_ACL = true; + + # run daily number cleanup + NUMBER_CLEANUP = false; + + # limit for number cleanup + NUMBER_MIN_AGE = 1800; + NUMBER_LIMIT = 50; + NUMBER_LIMIT_IMPORTANT = 10; + + # create hourly snapshots + TIMELINE_CREATE = true; + + # cleanup hourly snapshots after some time + TIMELINE_CLEANUP = true; + + # limits for timeline cleanup + TIMELINE_MIN_AGE = 1800; + TIMELINE_LIMIT_HOURLY = 7; + TIMELINE_LIMIT_DAILY = 3; + TIMELINE_LIMIT_WEEKLY = 2; + TIMELINE_LIMIT_MONTHLY = 0; + TIMELINE_LIMIT_YEARLY = 2; + + # cleanup empty pre-post-pairs + EMPTY_PRE_POST_CLEANUP = true; + }; + }; + }; + }; +} diff --git a/modules/system/services/steam/default.nix b/modules/system/services/steam/default.nix new file mode 100644 index 00000000..6e507fd9 --- /dev/null +++ b/modules/system/services/steam/default.nix @@ -0,0 +1,23 @@ +{ + lib, + config, + pkgs, + ... +}: let + cfg = config.soispha.services.steam; +in { + options.soispha.services.steam = { + enable = lib.mkEnableOption "Stream"; + }; + + config = lib.mkIf cfg.enable { + programs.steam = { + enable = true; + }; + + environment.systemPackages = [ + # TODO: Why is this package needed? <2024-05-16> + pkgs.wineWowPackages.waylandFull + ]; + }; +} diff --git a/modules/system/services/swaylock/default.nix b/modules/system/services/swaylock/default.nix new file mode 100644 index 00000000..6cbcef28 --- /dev/null +++ b/modules/system/services/swaylock/default.nix @@ -0,0 +1,4 @@ +{...}: { + # otherwise swaylock can't access the user password. + security.pam.services.swaylock = {}; +} diff --git a/modules/system/services/xdg/default.nix b/modules/system/services/xdg/default.nix new file mode 100644 index 00000000..5140a832 --- /dev/null +++ b/modules/system/services/xdg/default.nix @@ -0,0 +1,58 @@ +{ + pkgs, + nixpkgs_open_prs, + sysLib, + system, + ... +}: let + pkgs_tfc = nixpkgs_open_prs.nixpkgs-tfc.legacyPackages."${system}"; +in { + services.dbus.enable = true; + xdg = { + portal = { + enable = true; + termfilechooser = { + enable = true; + logLevel = "TRACE"; + package = pkgs_tfc.xdg-desktop-portal-termfilechooser; + settings = { + filechooser = { + default_dir = "/tmp"; + cmd = "${sysLib.writeShellScript { + src = ./scripts/lf_wrapper.sh; + name = "lf_wrapper"; + keepPath = true; + dependencies = with pkgs; [ + lf + alacritty + bash + ]; + }}/bin/lf_wrapper"; + }; + }; + }; + wlr = { + enable = true; + }; + config = { + common = { + # NOTE: The next entry is supposedly needed for gtk based apps <2023-08-31> + default = ["wlr" "gtk"]; + "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"]; + }; + + # TODO: Also activate, when on another wlr-based compositor <2023-11-25> + river = { + default = ["wlr" "gtk"]; + "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"]; + }; + }; + extraPortals = [ + pkgs.xdg-desktop-portal-gtk + pkgs.xdg-desktop-portal-wlr + pkgs_tfc.xdg-desktop-portal-termfilechooser + ]; + }; + }; + # TODO: mime = {}; +} diff --git a/modules/system/services/xdg/scripts/lf_wrapper.sh b/modules/system/services/xdg/scripts/lf_wrapper.sh new file mode 100755 index 00000000..16603fe4 --- /dev/null +++ b/modules/system/services/xdg/scripts/lf_wrapper.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# This wrapper script is invoked by xdg-desktop-portal-termfilechooser. +# +# Inputs: +# 1. "1" if multiple files can be chosen, "0" otherwise. +# 2. "1" if a directory should be chosen, "0" otherwise. +# 3. "0" if opening files was requested, "1" if writing to a file was +# requested. For example, when uploading files in Firefox, this will be "0". +# When saving a web page in Firefox, this will be "1". +# 4. If writing to a file, this is recommended path provided by the caller. For +# example, when saving a web page in Firefox, this will be the recommended +# path Firefox provided, such as "~/Downloads/webpage_title.html". +# Note that if the path already exists, we keep appending "_" to it until we +# get a path that does not exist. +# 5. The output path, to which results should be written. +# +# Output: +# The script should print the selected paths to the output path (argument #5), +# one path per line. +# If nothing is printed, then the operation is assumed to have been canceled. + +multiple="$1" +directory="$2" +save="$3" +recommended_path="$4" +out="$5" + +# echo > /tmp/stdout +# echo > /tmp/stderr +# +# exec 1>> /tmp/stdout +# exec 2>> /tmp/stderr + +cmd="$(command -v lf)" +termcmd="${TERMINAL:-$(command -v alacritty)}" + +if [ "$save" = "1" ]; then + set -- -selection-path="$out" -command='set promptfmt "Select the file to write to %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$recommended_path" + cat <"$recommended_path" +xdg-desktop-portal-termfilechooser saving files tutorial + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! === WARNING! === !!! +!!! The contents of *whatever* file you open last in !!! +!!! lf will be *overwritten*! !!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +Instructions: +1) Move this file wherever you want. +2) Rename the file if needed. +3) Confirm your selection by opening the file, for + example by pressing . + +Notes: +1) This file is provided for your convenience. You + could delete it and choose another file to overwrite + that, for example. +2) If you quit lf without opening a file, this file + will be removed and the save operation aborted. +EOF + +elif [ "$directory" = "1" ]; then + set -- -selection-path="$out" -command='set dironly' -command='set promptfmt "Select directory (quit in dir to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' +elif [ "$multiple" = "1" ]; then + set -- -selection-path="$out" -command='set promptfmt "Select file(s) (open file to select it; to select multiple) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' +else + set -- -selection-path="$out" -command='set promptfmt "Select file (open file to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' +fi + +"$termcmd" --title 'floating please' -e "$cmd" "$@" + +if [ "$save" = "1" ] && [ ! -s "$out" ]; then + rm "$recommended_path" +fi +# vim: ft=sh diff --git a/modules/system/services/xdg/scripts/ranger_wrapper.sh b/modules/system/services/xdg/scripts/ranger_wrapper.sh new file mode 100755 index 00000000..e148bf19 --- /dev/null +++ b/modules/system/services/xdg/scripts/ranger_wrapper.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH +# This wrapper script is invoked by xdg-desktop-portal-termfilechooser. +# +# Inputs: +# 1. "1" if multiple files can be chosen, "0" otherwise. +# 2. "1" if a directory should be chosen, "0" otherwise. +# 3. "0" if opening files was requested, "1" if writing to a file was +# requested. For example, when uploading files in Firefox, this will be "0". +# When saving a web page in Firefox, this will be "1". +# 4. If writing to a file, this is recommended path provided by the caller. For +# example, when saving a web page in Firefox, this will be the recommended +# path Firefox provided, such as "~/Downloads/webpage_title.html". +# Note that if the path already exists, we keep appending "_" to it until we +# get a path that does not exist. +# 5. The output path, to which results should be written. +# +# Output: +# The script should print the selected paths to the output path (argument #5), +# one path per line. +# If nothing is printed, then the operation is assumed to have been canceled. + +multiple="$1" +directory="$2" +save="$3" +path="$4" +out="$5" + +cmd="$(command -v ranger)" +termcmd="${TERMCMD:-$(command -v kitty)}" + +if [ "$save" = "1" ]; then + set -- --choosefile="$out" --cmd='echo Select save path (see tutorial in preview pane; try pressing zv or zp if no preview)' "$path" + printf '%s' 'xdg-desktop-portal-termfilechooser saving files tutorial + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! === WARNING! === !!! +!!! The contents of *whatever* file you open last in !!! +!!! ranger will be *overwritten*! !!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +Instructions: +1) Move this file wherever you want. +2) Rename the file if needed. +3) Confirm your selection by opening the file, for + example by pressing . + +Notes: +1) This file is provided for your convenience. You + could delete it and choose another file to overwrite + that, for example. +2) If you quit ranger without opening a file, this file + will be removed and the save operation aborted. +' >"$path" +elif [ "$directory" = "1" ]; then + set -- --choosedir="$out" --show-only-dirs --cmd="echo Select directory (quit in dir to select it)" +elif [ "$multiple" = "1" ]; then + set -- --choosefiles="$out" --cmd="echo Select file(s) (open file to select it; to select multiple)" +else + set -- --choosefile="$out" --cmd="echo Select file (open file to select it)" +fi + +"$termcmd" -- "$cmd" "$@" +if [ "$save" = "1" ] && [ ! -s "$out" ]; then + rm "$path" +fi diff --git a/modules/system/sound/default.nix b/modules/system/sound/default.nix new file mode 100644 index 00000000..f49cf95a --- /dev/null +++ b/modules/system/sound/default.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.sound; +in { + options.soispha.sound = { + enable = lib.mkEnableOption "sound based on pipewire"; + }; + + config = lib.mkIf cfg.enable { + sound.enable = true; + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; + + # TODO: Find a better way to set the default volume <2024-03-10> + # + # environment.etc.pipewire-pulse-config = { + # target = "pipewire/pipewire-pulse.conf.d/pipewire-pulse-config.conf"; + # text = '' + # # Extra scripts can be started here. Setup in default.pa can be moved in + # # a script or in pulse.cmd below + # context.exec = [ + # { path = "${pkgs.pulseaudio}/bin/pactl" args = "set-sink-volume 0 13%" } + # ] + # ''; + # }; + }; +} diff --git a/modules/system/tempfiles/default.nix b/modules/system/tempfiles/default.nix new file mode 100644 index 00000000..fa17f112 --- /dev/null +++ b/modules/system/tempfiles/default.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.temfiles; +in { + options.soispha.tempfiles = { + enable = lib.mkEnableOption "systemd tempfiles generation"; + }; + + config = lib.mkIf cfg.enable { + systemd.tmpfiles.rules = [ + # TODO: Find a way to move this file to the lf home manager config. + # + # This file is needed to trash stuff on the root ('/') temp file system. + "d /.Trash 1777 root root" + ]; + }; +} diff --git a/modules/system/users/default.nix b/modules/system/users/default.nix new file mode 100644 index 00000000..a44df7e8 --- /dev/null +++ b/modules/system/users/default.nix @@ -0,0 +1,50 @@ +{ + config, + pkgs, + lib, + ... +}: let + cfg = config.soispha.users; +in { + options.soispha.users = { + enable = lib.mkEnableOption "user set-up for soispha"; + hashedPassword = lib.mkOption { + type = lib.types.str; + example = lib.literalExpression "$y$jFT$ONrCqZIJKB7engmfA4orD/$0GO58/wV5wrYWj0cyONhyujZPjFmbT0XKtx2AvXLG0B"; + description = "The hashed password of the user"; + }; + groups = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = ["wheel"]; + description = "The groups the soispha user should be part of"; + }; + + # Although deprecated, this helps with old udev rules, that still use this group. + # TODO: Try to find a way to remove this option (i.e. set it always to false). + enableDeprecatedPlugdev = lib.mkEnableOption "the deprecated plugdev group for the user"; + }; + + config = lib.mkIf cfg.enable { + # Ensure that the default shell of the user is actually enabled. + programs.zsh.enable = true; + + users = { + mutableUsers = false; + + users.soispha = { + isNormalUser = true; + home = "/home/soispha"; + createHome = true; + shell = pkgs.zsh; + initialHashedPassword = cfg.hashedPassword; + extraGroups = cfg.groups ++ lib.optional cfg.enableDeprecatedPlugdev "plugdev"; + + uid = 1000; + openssh.authorizedKeys.keys = [ + # TODO: This should be parameterized. <2024-05-16> + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIME4ZVa+IoZf6T3U08JG93i6QIAJ4amm7mkBzO14JSkz" + ]; + }; + }; + }; +} diff --git a/modules/system/version/default.nix b/modules/system/version/default.nix new file mode 100644 index 00000000..77cada14 --- /dev/null +++ b/modules/system/version/default.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + self, + ... +}: let + cfg = config.soispha.version; +in { + options.soispha.version = { + enable = lib.mkEnableOption "storing the git revision in /etc/nixos_git_rev"; + }; + config = lib.mkIf cfg.enable { + environment.etc.nixos_git_rev = { + text = builtins.toString (self.longRev + or self.lastModified + or "unknown"); + }; + }; +} diff --git a/modules/system/waydroid/default.nix b/modules/system/waydroid/default.nix new file mode 100644 index 00000000..4680db63 --- /dev/null +++ b/modules/system/waydroid/default.nix @@ -0,0 +1,5 @@ +{...}: { + # FIXME: Running `waydroid session start` causes all fuse mounts instances to coredump <2023-09-02> + # Thus this setting must be false. + virtualisation.waydroid.enable = false; +} diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 00000000..38c58a95 --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,24 @@ +{ + lib, + system, + overlays ? [], + sysLib, + homeConfig, + nixosConfig, +}: let + additionalPackages = (import ./pkgs) {inherit homeConfig nixosConfig sysLib;}; + complete_overlays = overlays ++ additionalPackages; +in { + # TODO: inheriting system here is discouraged, localSystem or hostSystem should be inspected + inherit system; + overlays = complete_overlays; + config = { + # TODO: this fails because of the root tempsize, which should be increased + # contentAddressedByDefault = true; + + allowUnfreePredicate = pkg: + builtins.elem (lib.getName pkg) [ + "pypemicro" # required by pynitrokey + ]; + }; +} diff --git a/pkgs/sources/comments/.envrc b/pkgs/sources/comments/.envrc new file mode 100644 index 00000000..2b5fbb29 --- /dev/null +++ b/pkgs/sources/comments/.envrc @@ -0,0 +1,4 @@ +use flake + +PATH_add ./target/debug +PATH_add ./target/release diff --git a/pkgs/sources/comments/.gitignore b/pkgs/sources/comments/.gitignore new file mode 100644 index 00000000..c84fa049 --- /dev/null +++ b/pkgs/sources/comments/.gitignore @@ -0,0 +1,3 @@ +# build dirs +/target +/result diff --git a/pkgs/sources/comments/Cargo.lock b/pkgs/sources/comments/Cargo.lock new file mode 100644 index 00000000..54f19c46 --- /dev/null +++ b/pkgs/sources/comments/Cargo.lock @@ -0,0 +1,446 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "chrono-humanize" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799627e6b4d27827a814e837b9d8a504832086081806d45b1afa34dc982b023b" +dependencies = [ + "chrono", +] + +[[package]] +name = "cli-log" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d2ab00dc4c82ec28af25ac085aecc11ffeabf353755715a3113a7aa044ca5cc" +dependencies = [ + "chrono", + "file-size", + "log", + "proc-status", +] + +[[package]] +name = "comments" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "chrono-humanize", + "cli-log", + "log", + "regex", + "serde", + "serde_json", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "file-size" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9544f10105d33957765016b8a9baea7e689bf1f0f2f32c2fa2f568770c38d2b3" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-status" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e0c0ac915e7b76b47850ba4ffc377abde6c6ff9eeace61d0a89623db449712" +dependencies = [ + "thiserror", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/pkgs/sources/comments/Cargo.toml b/pkgs/sources/comments/Cargo.toml new file mode 100644 index 00000000..3ae3aa4c --- /dev/null +++ b/pkgs/sources/comments/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "comments" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.82" +chrono = "0.4.38" +chrono-humanize = "0.2.3" +cli-log = "2.0.0" +log = "0.4.21" +regex = "1.10.4" +serde = { version = "1.0.200", features = ["derive"] } +serde_json = "1.0.116" diff --git a/pkgs/sources/comments/comments.nix b/pkgs/sources/comments/comments.nix new file mode 100644 index 00000000..e8a33bff --- /dev/null +++ b/pkgs/sources/comments/comments.nix @@ -0,0 +1,25 @@ +{ + lib, + rustPlatform, + makeWrapper, + less, + coreutils, +}: +rustPlatform.buildRustPackage { + pname = "comments"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + + nativeBuildInputs = [ + makeWrapper + ]; + + postInstall = '' + wrapProgram $out/bin/comments \ + --set PATH ${lib.makeBinPath [less coreutils]} + ''; +} diff --git a/pkgs/sources/comments/default.nix b/pkgs/sources/comments/default.nix new file mode 100644 index 00000000..6205dcbe --- /dev/null +++ b/pkgs/sources/comments/default.nix @@ -0,0 +1,18 @@ +[ + ( + final: prev: { + comments = import ./comments.nix { + inherit + (prev) + lib + makeWrapper + rustPlatform + # dependencies + + less + coreutils + ; + }; + } + ) +] diff --git a/pkgs/sources/comments/flake.lock b/pkgs/sources/comments/flake.lock new file mode 100644 index 00000000..50494465 --- /dev/null +++ b/pkgs/sources/comments/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715087517, + "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/comments/flake.nix b/pkgs/sources/comments/flake.nix new file mode 100644 index 00000000..f5e44a65 --- /dev/null +++ b/pkgs/sources/comments/flake.nix @@ -0,0 +1,31 @@ +{ + description = "comments"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: (flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages."${system}"; + in { + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + # rust stuff + cargo + clippy + rustc + rustfmt + + cargo-edit + cargo-expand + cargo-audit + ]; + }; + })); +} diff --git a/pkgs/sources/comments/src/info_json.rs b/pkgs/sources/comments/src/info_json.rs new file mode 100644 index 00000000..eca4fae3 --- /dev/null +++ b/pkgs/sources/comments/src/info_json.rs @@ -0,0 +1,223 @@ +use std::collections::HashMap; + +use serde::{Deserialize, Deserializer}; + +#[derive(Debug, Deserialize)] +pub struct InfoJson { + pub id: String, + pub title: String, + pub formats: Vec, + pub thumbnails: Vec, + pub thumbnail: String, + pub description: String, + pub channel_id: String, + pub channel_url: String, + pub duration: u32, + pub view_count: u32, + pub age_limit: u32, + pub webpage_url: String, + pub categories: Vec, + pub tags: Vec, + pub playable_in_embed: bool, + pub live_status: String, + _format_sort_fields: Vec, + pub automatic_captions: HashMap>, + pub subtitles: Subtitles, + pub comment_count: u32, + pub like_count: u32, + pub channel: String, + pub channel_follower_count: u32, + pub channel_is_verified: Option, + pub uploader: String, + pub uploader_id: String, + pub uploader_url: String, + pub upload_date: String, + pub availability: String, + pub webpage_url_basename: String, + pub webpage_url_domain: String, + pub extractor: String, + pub extractor_key: String, + pub display_id: String, + pub fulltitle: String, + pub duration_string: String, + pub is_live: bool, + pub was_live: bool, + pub epoch: u32, + pub comments: Vec, + pub sponsorblock_chapters: Option>, + pub format: String, + pub format_id: String, + pub ext: String, + pub protocol: String, + pub language: Option, + pub format_note: String, + pub filesize_approx: u64, + pub tbr: f64, + pub width: u32, + pub height: u32, + pub resolution: String, + pub fps: f64, + pub dynamic_range: String, + pub vcodec: String, + pub vbr: f64, + pub aspect_ratio: f64, + pub acodec: String, + pub abr: f64, + pub asr: u32, + pub audio_channels: u32, + _type: String, + _version: Version, +} + +#[derive(Debug, Deserialize)] +pub struct Subtitles {} + +#[derive(Debug, Deserialize)] +pub struct Version { + pub version: String, + pub release_git_head: String, + pub repository: String, +} + +#[derive(Debug, Deserialize)] +pub struct SponsorblockChapter {} + +#[derive(Debug, Deserialize, Clone)] +#[serde(from = "String")] +pub enum Parent { + Root, + Id(String), +} + +impl Parent { + pub fn id(&self) -> Option<&str> { + if let Self::Id(id) = self { + Some(id) + } else { + None + } + } +} + +impl From for Parent { + fn from(value: String) -> Self { + if value == "root" { + Self::Root + } else { + Self::Id(value) + } + } +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(from = "String")] +pub struct Id { + pub id: String, +} +impl From for Id { + fn from(value: String) -> Self { + Self { + // Take the last element if the string is split with dots, otherwise take the full id + id: value.split('.').last().unwrap_or(&value).to_owned(), + } + } +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Comment { + pub id: Id, + pub text: String, + #[serde(default = "zero")] + pub like_count: u32, + pub author_id: String, + #[serde(default = "unknown")] + pub author: String, + pub author_thumbnail: String, + pub parent: Parent, + #[serde(deserialize_with = "edited_from_time_text", alias = "_time_text")] + pub edited: bool, + // Can't also be deserialized, as it's already used in 'edited' + // _time_text: String, + pub timestamp: i64, + pub author_url: String, + pub author_is_uploader: bool, + pub is_favorited: bool, +} +fn unknown() -> String { + "".to_string() +} +fn zero() -> u32 { + 0 +} +fn edited_from_time_text<'de, D>(d: D) -> Result +where + D: Deserializer<'de>, +{ + let s = String::deserialize(d)?; + if s.contains(" (edited)") { + Ok(true) + } else { + Ok(false) + } +} + +#[derive(Debug, Deserialize)] +pub struct Caption { + pub ext: String, + pub url: String, + pub name: Option, + pub protocol: Option, +} + +#[derive(Debug, Deserialize)] +pub struct ThumbNail { + pub url: String, + pub preference: i32, + pub id: String, + pub height: Option, + pub width: Option, + pub resolution: Option, +} + +#[derive(Debug, Deserialize)] +pub struct Format { + pub format_id: String, + pub format_note: Option, + pub ext: String, + pub protocol: String, + pub acodec: Option, + pub vcodec: String, + pub url: String, + pub width: Option, + pub height: Option, + pub fps: Option, + pub rows: Option, + pub columns: Option, + pub fragments: Option>, + pub resolution: String, + pub aspect_ratio: Option, + pub http_headers: HttpHeader, + pub audio_ext: String, + pub video_ext: String, + pub vbr: Option, + pub abr: Option, + pub format: String, +} + +#[derive(Debug, Deserialize)] +pub struct HttpHeader { + #[serde(alias = "User-Agent")] + pub user_agent: String, + #[serde(alias = "Accept")] + pub accept: String, + #[serde(alias = "Accept-Language")] + pub accept_language: String, + #[serde(alias = "Sec-Fetch-Mode")] + pub sec_fetch_mode: String, +} + +#[derive(Debug, Deserialize)] +pub struct Fragment { + pub url: String, + pub duration: f64, +} diff --git a/pkgs/sources/comments/src/main.rs b/pkgs/sources/comments/src/main.rs new file mode 100644 index 00000000..6e4f72e9 --- /dev/null +++ b/pkgs/sources/comments/src/main.rs @@ -0,0 +1,322 @@ +use std::{ + env, + fmt::Display, + fs::{self, File}, + io::{BufReader, Write}, + mem, + path::PathBuf, + process::{Command, Stdio}, +}; + +use anyhow::Context; +use chrono::{Local, TimeZone}; +use chrono_humanize::{Accuracy, HumanTime, Tense}; +use info_json::{Comment, InfoJson, Parent}; +use regex::Regex; + +mod info_json; + +fn get_runtime_path(component: &'static str) -> anyhow::Result { + let out: PathBuf = format!( + "{}/{}", + env::var("XDG_RUNTIME_DIR").expect("This should always exist"), + component + ) + .into(); + fs::create_dir_all(out.parent().expect("Parent should exist"))?; + Ok(out) +} + +const STATUS_PATH: &str = "ytcc/running"; +pub fn status_path() -> anyhow::Result { + get_runtime_path(STATUS_PATH) +} + +#[derive(Debug, Clone)] +pub struct CommentExt { + pub value: Comment, + pub replies: Vec, +} + +#[derive(Debug, Default)] +pub struct Comments { + vec: Vec, +} + +impl Comments { + pub fn new() -> Self { + Self::default() + } + pub fn push(&mut self, value: CommentExt) { + self.vec.push(value); + } + pub fn get_mut(&mut self, key: &str) -> Option<&mut CommentExt> { + self.vec.iter_mut().filter(|c| c.value.id.id == key).last() + } + pub fn insert(&mut self, key: &str, value: CommentExt) { + let parent = self + .vec + .iter_mut() + .filter(|c| c.value.id.id == key) + .last() + .expect("One of these should exist"); + parent.push_reply(value); + } +} +impl CommentExt { + pub fn push_reply(&mut self, value: CommentExt) { + self.replies.push(value) + } + pub fn get_mut_reply(&mut self, key: &str) -> Option<&mut CommentExt> { + self.replies + .iter_mut() + .filter(|c| c.value.id.id == key) + .last() + } +} + +impl From for CommentExt { + fn from(value: Comment) -> Self { + Self { + replies: vec![], + value, + } + } +} + +impl Display for Comments { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + macro_rules! c { + ($color:expr, $write:ident) => { + $write.write_str(concat!("\x1b[", $color, "m"))? + }; + } + + fn format( + comment: &CommentExt, + f: &mut std::fmt::Formatter<'_>, + ident_count: u32, + ) -> std::fmt::Result { + let ident = &(0..ident_count).map(|_| " ").collect::(); + let value = &comment.value; + + f.write_str(ident)?; + + if value.author_is_uploader { + c!("91;1", f); + } else { + c!("35", f); + } + + f.write_str(&value.author)?; + c!("0", f); + if value.edited || value.is_favorited { + f.write_str("[")?; + if value.edited { + f.write_str("")?; + } + if value.edited && value.is_favorited { + f.write_str(" ")?; + } + if value.is_favorited { + f.write_str("")?; + } + f.write_str("]")?; + } + + c!("36;1", f); + write!( + f, + " {}", + HumanTime::from( + Local + .timestamp_opt(value.timestamp, 0) + .single() + .expect("This should be valid") + ) + .to_text_en(Accuracy::Rough, Tense::Past) + )?; + c!("0", f); + + // c!("31;1", f); + // f.write_fmt(format_args!(" [{}]", comment.value.like_count))?; + // c!("0", f); + + f.write_str(":\n")?; + f.write_str(ident)?; + + f.write_str(&value.text.replace('\n', &format!("\n{}", ident)))?; + f.write_str("\n")?; + + if !comment.replies.is_empty() { + let mut children = comment.replies.clone(); + children.sort_by(|a, b| a.value.timestamp.cmp(&b.value.timestamp)); + + for child in children { + format(&child, f, ident_count + 4)?; + } + } else { + f.write_str("\n")?; + } + + Ok(()) + } + + if !&self.vec.is_empty() { + let mut children = self.vec.clone(); + children.sort_by(|a, b| b.value.like_count.cmp(&a.value.like_count)); + + for child in children { + format(&child, f, 0)? + } + } + Ok(()) + } +} + +fn main() -> anyhow::Result<()> { + cli_log::init_cli_log!(); + let args: Option = env::args().skip(1).last(); + let mut info_json: InfoJson = { + let status_path = if let Some(arg) = args { + PathBuf::from(arg) + } else { + status_path().context("Failed to get status path")? + }; + + let reader = + BufReader::new(File::open(&status_path).with_context(|| { + format!("Failed to open status file at {}", status_path.display()) + })?); + + serde_json::from_reader(reader)? + }; + + let base_comments = mem::take(&mut info_json.comments); + drop(info_json); + + let mut comments = Comments::new(); + base_comments.into_iter().for_each(|c| { + if let Parent::Id(id) = &c.parent { + comments.insert(&(id.clone()), CommentExt::from(c)); + } else { + comments.push(CommentExt::from(c)); + } + }); + + comments.vec.iter_mut().for_each(|comment| { + let replies = mem::take(&mut comment.replies); + let mut output_replies: Vec = vec![]; + + let re = Regex::new(r"\u{200b}?(@[^\t\s]+)\u{200b}?").unwrap(); + for reply in replies { + if let Some(replyee_match) = re.captures(&reply.value.text){ + let full_match = replyee_match.get(0).expect("This always exists"); + let text = reply. + value. + text[0..full_match.start()] + .to_owned() + + + &reply + .value + .text[full_match.end()..]; + let text: &str = text.trim().trim_matches('\u{200b}'); + + let replyee = replyee_match.get(1).expect("This should exist").as_str(); + + + if let Some(parent) = output_replies + .iter_mut() + // .rev() + .flat_map(|com| &mut com.replies) + .flat_map(|com| &mut com.replies) + .flat_map(|com| &mut com.replies) + .filter(|com| com.value.author == replyee) + .last() + { + parent.replies.push(CommentExt::from(Comment { + text: text.to_owned(), + ..reply.value + })) + } else if let Some(parent) = output_replies + .iter_mut() + // .rev() + .flat_map(|com| &mut com.replies) + .flat_map(|com| &mut com.replies) + .filter(|com| com.value.author == replyee) + .last() + { + parent.replies.push(CommentExt::from(Comment { + text: text.to_owned(), + ..reply.value + })) + } else if let Some(parent) = output_replies + .iter_mut() + // .rev() + .flat_map(|com| &mut com.replies) + .filter(|com| com.value.author == replyee) + .last() + { + parent.replies.push(CommentExt::from(Comment { + text: text.to_owned(), + ..reply.value + })) + } else if let Some(parent) = output_replies.iter_mut() + // .rev() + .filter(|com| com.value.author == replyee) + .last() + { + parent.replies.push(CommentExt::from(Comment { + text: text.to_owned(), + ..reply.value + })) + } else { + eprintln!( + "Failed to find a parent for ('{}') both directly and via replies! The reply text was:\n'{}'\n", + replyee, + reply.value.text + ); + output_replies.push(reply); + } + } else { + output_replies.push(reply); + } + } + comment.replies = output_replies; + }); + + let mut less = Command::new("less") + .args(["--raw-control-chars"]) + .stdin(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .context("Failed to run less")?; + + let mut child = Command::new("fmt") + .args(["--uniform-spacing", "--split-only", "--width=90"]) + .stdin(Stdio::piped()) + .stderr(Stdio::inherit()) + .stdout(less.stdin.take().expect("Should be open")) + .spawn() + .context("Failed to run fmt")?; + + let mut stdin = child.stdin.take().context("Failed to open stdin")?; + std::thread::spawn(move || { + stdin + .write_all(comments.to_string().as_bytes()) + .expect("Should be able to write to stdin of fmt"); + }); + + let _ = less.wait().context("Failed to await less")?; + + Ok(()) +} + +#[cfg(test)] +mod test { + #[test] + fn test_string_replacement() { + let s = "A \n\nB\n\nC".to_owned(); + assert_eq!("A \n \n B\n \n C", s.replace('\n', "\n ")) + } +} diff --git a/pkgs/sources/comments/update.sh b/pkgs/sources/comments/update.sh new file mode 100755 index 00000000..e500bb23 --- /dev/null +++ b/pkgs/sources/comments/update.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +nix flake update + +[ "$1" = "upgrade" ] && cargo upgrade +cargo update + +# vim: ft=sh diff --git a/pkgs/sources/default.nix b/pkgs/sources/default.nix new file mode 100644 index 00000000..4668d735 --- /dev/null +++ b/pkgs/sources/default.nix @@ -0,0 +1,27 @@ +{ + homeConfig, + nixosConfig, + sysLib, +}: let + comments = import ./comments; + generate_firefox_extensions = import ./generate_moz_extension; + lf_make_map = import ./lf-make-map; + nvim_plugs = import ./plgs-pkgs; + scripts = import ./scripts {inherit sysLib homeConfig nixosConfig;}; + snap-sync-forked = (import ./snap-sync-forked) {inherit sysLib;}; + update_vim_plugins = import ./update_vim_plugins; + yt = import ./yt; + yts-grammar = import ./tree-sitter-yts; + + overlays = + comments + ++ generate_firefox_extensions + ++ lf_make_map + ++ nvim_plugs + ++ scripts + ++ snap-sync-forked + ++ update_vim_plugins + ++ yt + ++ yts-grammar; +in + overlays diff --git a/pkgs/sources/generate_moz_extension/.envrc b/pkgs/sources/generate_moz_extension/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/pkgs/sources/generate_moz_extension/.envrc @@ -0,0 +1 @@ +use flake diff --git a/pkgs/sources/generate_moz_extension/.gitignore b/pkgs/sources/generate_moz_extension/.gitignore new file mode 100644 index 00000000..f717ddd7 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/.gitignore @@ -0,0 +1,3 @@ +/target +/result +.direnv diff --git a/pkgs/sources/generate_moz_extension/Cargo.lock b/pkgs/sources/generate_moz_extension/Cargo.lock new file mode 100644 index 00000000..c0a83aa8 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/Cargo.lock @@ -0,0 +1,1275 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generate_extensions" +version = "0.1.0" +dependencies = [ + "anyhow", + "futures", + "reqwest", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/pkgs/sources/generate_moz_extension/Cargo.toml b/pkgs/sources/generate_moz_extension/Cargo.toml new file mode 100644 index 00000000..e7d44db4 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "generate_extensions" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.83" +futures = "0.3.30" +reqwest = "0.12.4" +serde = { version = "1.0.201", features = ["derive"] } +serde_json = "1.0.117" +tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] } diff --git a/pkgs/sources/generate_moz_extension/default.nix b/pkgs/sources/generate_moz_extension/default.nix new file mode 100644 index 00000000..be734eee --- /dev/null +++ b/pkgs/sources/generate_moz_extension/default.nix @@ -0,0 +1,16 @@ +[ + ( + final: prev: { + generate_firefox_extensions = import ./generate_firefox_extensions.nix { + inherit + (prev) + rustPlatform + # Dependencies + + openssl + pkg-config + ; + }; + } + ) +] diff --git a/pkgs/sources/generate_moz_extension/examples/generate_extensions.sh b/pkgs/sources/generate_moz_extension/examples/generate_extensions.sh new file mode 100755 index 00000000..96802992 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/examples/generate_extensions.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +tmp=$(mktemp) +cat <"$tmp" + darkreader:navbar + keepassxc-browser:navbar + vhack-libredirect:navbar + # torproject-snowflake:navbar + tridactyl-vim:menupanel + ublock-origin:menupanel +EOF + +# The cat execution should be unquoted; +# shellcheck disable=SC2046 +cargo run -- $(cat "$tmp") + +rm "$tmp" diff --git a/pkgs/sources/generate_moz_extension/flake.lock b/pkgs/sources/generate_moz_extension/flake.lock new file mode 100644 index 00000000..741a8ad1 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/flake.lock @@ -0,0 +1,106 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1714864355, + "narHash": "sha256-uXNW6bapWFfkYIkK1EagydSrFMqycOYEDSq75GmUpjk=", + "owner": "ipetkov", + "repo": "crane", + "rev": "442a7a6152f49b907e73206dc8e1f46a61e8e873", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715037484, + "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1715221036, + "narHash": "sha256-81EKOdlmT/4hZpImRlvMVPgmCcJYZjwlWbJese/XqUw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "5c4bc8a0a70093a31a12509c5653c147f2310bd2", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/generate_moz_extension/flake.nix b/pkgs/sources/generate_moz_extension/flake.nix new file mode 100644 index 00000000..5575f90b --- /dev/null +++ b/pkgs/sources/generate_moz_extension/flake.nix @@ -0,0 +1,75 @@ +{ + description = "A simple way to query the mozialla api for extension data"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + crane = { + url = "github:ipetkov/crane"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + + flake-utils.url = "github:numtide/flake-utils"; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + }; + + outputs = { + self, + nixpkgs, + crane, + flake-utils, + rust-overlay, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [(import rust-overlay)]; + }; + + rust-stable = pkgs.rust-bin.stable.latest.default; + rust-minimal = pkgs.rust-bin.stable.latest.minimal; + + craneLib = (crane.mkLib pkgs).overrideToolchain rust-minimal; + + buildInputs = [ + pkgs.openssl # needed for openssl + ]; + nativeBuildInputs = [ + pkgs.pkg-config # needed for openssl + ]; + + craneBuild = craneLib.buildPackage { + src = craneLib.cleanCargoSource ./.; + inherit buildInputs nativeBuildInputs; + + doCheck = true; + }; + in { + packages.default = craneBuild; + app.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/generate_extensions"; + }; + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + cocogitto + + rust-stable + cargo-edit + ]; + inherit buildInputs nativeBuildInputs; + }; + }); +} +# vim: ts=2 + diff --git a/pkgs/sources/generate_moz_extension/generate_firefox_extensions.nix b/pkgs/sources/generate_moz_extension/generate_firefox_extensions.nix new file mode 100644 index 00000000..abd95c77 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/generate_firefox_extensions.nix @@ -0,0 +1,20 @@ +{ + rustPlatform, + openssl, + pkg-config, +}: +rustPlatform.buildRustPackage { + pname = "generate_firefox_extensions"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + buildInputs = [ + openssl # needed for openssl-sys crate + ]; + nativeBuildInputs = [ + pkg-config # needed for openssl dependency + ]; +} diff --git a/pkgs/sources/generate_moz_extension/res/generate_extensions.py b/pkgs/sources/generate_moz_extension/res/generate_extensions.py new file mode 100644 index 00000000..ee8cc966 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/res/generate_extensions.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# source: https://github.com/etu/nixconfig/blob/ba47d577c8bfb4a1c06927c34ece34118f4a0460/modules/graphical/firefox/generate.py + +from concurrent.futures import ThreadPoolExecutor +import json +import requests + +EXTENSIONS = sorted( + [ + "darkreader", + "firenvim", + "keepassxc-browser", + "simple-tab-groups", + ] +) + + +def index_ext(ext: str): + # print(f"Indexing {ext}...") + + resp = requests.get(f"https://addons.mozilla.org/api/v5/addons/addon/{ext}/").json() + rel = resp["current_version"] + + if not rel["file"]["hash"].startswith("sha256:"): + raise ValueError("Unhandled hash type") + + return { + "pname": ext, + "version": rel["version"], + "addonId": resp["guid"], + "url": rel["file"]["url"], + "sha256": rel["file"]["hash"], + } + + +if __name__ == "__main__": + # outfile = os.path.dirname(os.path.realpath(__file__)) + "/extensions.json" + + with ThreadPoolExecutor() as e: + extensions = {ext: e.submit(index_ext, ext) for ext in EXTENSIONS} + extensions = {k: v.result() for k, v in extensions.items()} + + # with open(outfile, "w") as f: + print(json.dumps(extensions, indent=2)) diff --git a/pkgs/sources/generate_moz_extension/res/reference.json b/pkgs/sources/generate_moz_extension/res/reference.json new file mode 100644 index 00000000..f46ea8ec --- /dev/null +++ b/pkgs/sources/generate_moz_extension/res/reference.json @@ -0,0 +1,30 @@ +{ + "darkreader": { + "pname": "darkreader", + "version": "4.9.62", + "addonId": "addon@darkreader.org", + "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", + "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc" + }, + "firenvim": { + "pname": "firenvim", + "version": "0.2.14", + "addonId": "firenvim@lacamb.re", + "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", + "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6" + }, + "keepassxc-browser": { + "pname": "keepassxc-browser", + "version": "1.8.4", + "addonId": "keepassxc-browser@keepassxc.org", + "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", + "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719" + }, + "simple-tab-groups": { + "pname": "simple-tab-groups", + "version": "4.7.2.1", + "addonId": "simple-tab-groups@drive4ik", + "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", + "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4" + } +} diff --git a/pkgs/sources/generate_moz_extension/res/test.json b/pkgs/sources/generate_moz_extension/res/test.json new file mode 100644 index 00000000..daa1d19a --- /dev/null +++ b/pkgs/sources/generate_moz_extension/res/test.json @@ -0,0 +1,30 @@ +{ + "darkreader": { + "addon_id": "addon@darkreader.org", + "pname": "darkreader", + "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc", + "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", + "version": "4.9.62" + }, + "firenvim": { + "addon_id": "firenvim@lacamb.re", + "pname": "firenvim", + "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6", + "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", + "version": "0.2.14" + }, + "keepassxc-browser": { + "addon_id": "keepassxc-browser@keepassxc.org", + "pname": "keepassxc-browser", + "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719", + "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", + "version": "1.8.4" + }, + "simple-tab-groups": { + "addon_id": "simple-tab-groups@drive4ik", + "pname": "simple-tab-groups", + "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4", + "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", + "version": "4.7.2.1" + } +} diff --git a/pkgs/sources/generate_moz_extension/src/main.rs b/pkgs/sources/generate_moz_extension/src/main.rs new file mode 100644 index 00000000..bde986a3 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/src/main.rs @@ -0,0 +1,138 @@ +use std::env::args; + +use anyhow::{bail, Context}; +use futures::StreamExt; +use reqwest::Client; +use serde_json::{json, Map, Value}; + +pub mod types; + +macro_rules! get_json_value { + ($key:expr, $json_value:ident, $type:ident, $get:ident) => { + match $json_value.get($key) { + Some(resp) => { + let resp = resp.to_owned(); + if resp.$type() { + resp.$get().expect( + "The should have been checked in the if guard, so unpacking here is fine", + ).to_owned() + } else { + bail!( + "Value {} => \n{}\n is not of type: {}", + $key, + resp, + stringify!($type) + ); + } + } + None => { + bail!( + "There seems to be no '{}' in your json data (json value: '{}')\n Has the api changend?", + $key, serde_json::to_string_pretty(&$json_value).expect("Will always work") + ); + } + } + }; +} + +use futures::stream::futures_unordered::FuturesUnordered; +use types::{Extension, InputExtension}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let mut extensions: Vec = vec![]; + for input_extension in args() + .skip(1) + .map(|str| InputExtension::try_from(str)) + .collect::>>() + { + extensions.push(input_extension?); + } + + let resulting_extensions = process_extensions(extensions).await?; + + let mut output = Map::new(); + for extension in resulting_extensions { + output.insert(extension.pname.clone(), json!(extension)); + } + + println!( + "{}", + serde_json::to_string_pretty(&serde_json::Value::Object(output)).expect( + "This is constructed from json, it should also be possible to serialize it again" + ) + ); + Ok(()) +} + +async fn process_extensions(extensions: Vec) -> anyhow::Result> { + let mut output = Vec::with_capacity(extensions.len()); + + let client = Client::new(); + for extension in extensions + .iter() + .map(|ext| { + let local_client = &client; + index_extension(ext, local_client) + }) + .collect::>() + .collect::>() + .await + { + output.push(extension?); + } + Ok(output) +} + +async fn index_extension(extension: &InputExtension, client: &Client) -> anyhow::Result { + let response = client + .get(format!( + "https://addons.mozilla.org/api/v5/addons/addon/{}", + extension, + )) + .send() + .await + .context("Accessing the mozzila extenios api failed with error: {e}")?; + + eprintln!("Indexing {} ({})...", extension, response.status()); + let response: Value = serde_json::from_str( + &response + .text() + .await + .context("Turning the response to text fail with error: {e}")?, + ) + .context("Deserializing the response failed! Error: {e}")?; + + if let Some(detail) = response.get("detail") { + if detail == "Not found." { + bail!("Your extension ('{}') was not found!", extension); + } + }; + + let release = { get_json_value!("current_version", response, is_object, as_object) }; + + #[allow(non_snake_case)] + let addonId = { get_json_value!("guid", response, is_string, as_str) }; + + let version = { get_json_value!("version", release, is_string, as_str) }; + let file = { get_json_value!("file", release, is_object, as_object) }; + + let url = { get_json_value!("url", file, is_string, as_str) }; + let sha256 = { + let hash = get_json_value!("hash", file, is_string, as_str); + if hash.starts_with("sha256:") { + hash + } else { + bail!("This hash type is unhandled: {}", hash); + } + }; + + Ok(Extension { + pname: extension.moz_name.clone(), + default_area: extension.default_area, + version, + addonId, + url, + sha256, + }) +} diff --git a/pkgs/sources/generate_moz_extension/src/types.rs b/pkgs/sources/generate_moz_extension/src/types.rs new file mode 100644 index 00000000..b830fe0d --- /dev/null +++ b/pkgs/sources/generate_moz_extension/src/types.rs @@ -0,0 +1,71 @@ +use std::fmt::Display; + +use anyhow::anyhow; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +#[allow(non_snake_case)] +pub struct Extension { + pub pname: String, + pub default_area: DefaultArea, + pub version: String, + pub addonId: String, + pub url: String, + pub sha256: String, +} + +#[derive(Debug, Clone)] +pub struct InputExtension { + pub moz_name: String, + pub default_area: DefaultArea, +} +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[allow(non_camel_case_types)] +pub enum DefaultArea { + navbar, + menupanel, +} + +impl Display for DefaultArea { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DefaultArea::navbar => f.write_str("navbar"), + DefaultArea::menupanel => f.write_str("menupanel"), + } + } +} + +impl TryFrom<&str> for DefaultArea { + type Error = anyhow::Error; + + fn try_from(value: &str) -> Result { + match value { + "navbar" => Ok(Self::navbar), + "menupanel" => Ok(Self::menupanel), + _ => Err(anyhow!( + "Your needs to be one of 'navbar' or 'menupanel', but is: '{}'", + value + )), + } + } +} + +impl Display for InputExtension { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.moz_name) + } +} +impl TryFrom for InputExtension { + type Error = anyhow::Error; + + fn try_from(value: String) -> Result { + if let Some((moz_name, default_area)) = value.split_once(':') { + Ok(Self { + moz_name: moz_name.to_owned(), + default_area: default_area.try_into()?, + }) + } else { + Err(anyhow!("Can't parse the input string as a InputExtension!\n Needs to be: ':'")) + } + } +} diff --git a/pkgs/sources/generate_moz_extension/update.sh b/pkgs/sources/generate_moz_extension/update.sh new file mode 100755 index 00000000..e500bb23 --- /dev/null +++ b/pkgs/sources/generate_moz_extension/update.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +nix flake update + +[ "$1" = "upgrade" ] && cargo upgrade +cargo update + +# vim: ft=sh diff --git a/pkgs/sources/lf-make-map/.envrc b/pkgs/sources/lf-make-map/.envrc new file mode 100644 index 00000000..c8c56659 --- /dev/null +++ b/pkgs/sources/lf-make-map/.envrc @@ -0,0 +1,11 @@ +use flake || use nix +watch_file flake.nix + +PATH_add ./target/debug +PATH_add ./target/release +PATH_add ./scripts + +if on_git_branch; then + echo && git status --short --branch && + echo && git fetch --verbose +fi diff --git a/pkgs/sources/lf-make-map/.gitignore b/pkgs/sources/lf-make-map/.gitignore new file mode 100644 index 00000000..cb87f36f --- /dev/null +++ b/pkgs/sources/lf-make-map/.gitignore @@ -0,0 +1,6 @@ +# build +/target +/result + +# dev env +.direnv diff --git a/pkgs/sources/lf-make-map/Cargo.lock b/pkgs/sources/lf-make-map/Cargo.lock new file mode 100644 index 00000000..16af6e03 --- /dev/null +++ b/pkgs/sources/lf-make-map/Cargo.lock @@ -0,0 +1,505 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lf-make-map" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "log", + "stderrlog", + "walkdir", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[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 = "stderrlog" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b" +dependencies = [ + "chrono", + "is-terminal", + "log", + "termcolor", + "thread_local", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[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 = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/pkgs/sources/lf-make-map/Cargo.toml b/pkgs/sources/lf-make-map/Cargo.toml new file mode 100644 index 00000000..da9881fd --- /dev/null +++ b/pkgs/sources/lf-make-map/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "lf-make-map" +description = "An automatic lf cd mapping generator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.83" +clap = { version = "4.5.4", features = ["derive", "env"] } +log = "0.4.21" +stderrlog = "0.6.0" +walkdir = "2.5.0" diff --git a/pkgs/sources/lf-make-map/README.md b/pkgs/sources/lf-make-map/README.md new file mode 100644 index 00000000..0c57cede --- /dev/null +++ b/pkgs/sources/lf-make-map/README.md @@ -0,0 +1,12 @@ +# Lf make map + +> An automatic lf cd mapping generator + +Some text about the project. + +## Licence + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. diff --git a/pkgs/sources/lf-make-map/default.nix b/pkgs/sources/lf-make-map/default.nix new file mode 100644 index 00000000..8ff4c624 --- /dev/null +++ b/pkgs/sources/lf-make-map/default.nix @@ -0,0 +1,12 @@ +[ + ( + final: prev: { + lf-make-map = import ./lf_make_map.nix { + inherit + (prev) + rustPlatform + ; + }; + } + ) +] diff --git a/pkgs/sources/lf-make-map/flake.lock b/pkgs/sources/lf-make-map/flake.lock new file mode 100644 index 00000000..611392df --- /dev/null +++ b/pkgs/sources/lf-make-map/flake.lock @@ -0,0 +1,147 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1714864355, + "narHash": "sha256-uXNW6bapWFfkYIkK1EagydSrFMqycOYEDSq75GmUpjk=", + "owner": "ipetkov", + "repo": "crane", + "rev": "442a7a6152f49b907e73206dc8e1f46a61e8e873", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715037484, + "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", + "systems": "systems", + "treefmt-nix": "treefmt-nix" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1715221036, + "narHash": "sha256-81EKOdlmT/4hZpImRlvMVPgmCcJYZjwlWbJese/XqUw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "5c4bc8a0a70093a31a12509c5653c147f2310bd2", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1680978846, + "narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=", + "owner": "nix-systems", + "repo": "x86_64-linux", + "rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "x86_64-linux", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1714058656, + "narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/lf-make-map/flake.nix b/pkgs/sources/lf-make-map/flake.nix new file mode 100644 index 00000000..dc8c24cc --- /dev/null +++ b/pkgs/sources/lf-make-map/flake.nix @@ -0,0 +1,125 @@ +{ + description = "An automatic lf cd mapping generator"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + + crane = { + url = "github:ipetkov/crane"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + # inputs for following + systems = { + url = "github:nix-systems/x86_64-linux"; # only evaluate for this system + }; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + flake-utils = { + url = "github:numtide/flake-utils"; + inputs = { + systems.follows = "systems"; + }; + }; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + treefmt-nix, + crane, + rust-overlay, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [(import rust-overlay)]; + }; + + nightly = false; + rust_minimal = + if nightly + then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.minimal) + else pkgs.rust-bin.stable.latest.minimal; + rust_default = + if nightly + then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default) + else pkgs.rust-bin.stable.latest.default; + + cargo_toml = craneLib.cleanCargoToml {cargoToml = ./Cargo.toml;}; + pname = cargo_toml.package.name; + + craneLib = (crane.mkLib pkgs).overrideToolchain rust_minimal; + craneBuild = craneLib.buildPackage { + src = craneLib.cleanCargoSource ./.; + + doCheck = true; + }; + + manual = pkgs.stdenv.mkDerivation { + name = "${pname}-manual"; + inherit (cargo_toml.package) version; + + src = ./docs; + nativeBuildInputs = with pkgs; [pandoc]; + + buildPhase = '' + mkdir --parents $out/docs; + + pandoc "./${pname}.1.md" -s -t man > $out/docs/${pname}.1 + ''; + + installPhase = '' + install -D $out/docs/${pname}.1 $out/share/man/man1/${pname}; + ''; + }; + + treefmtEval = import ./treefmt.nix {inherit treefmt-nix pkgs;}; + in { + packages.default = pkgs.symlinkJoin { + inherit (cargo_toml.package) name; + + paths = [manual craneBuild]; + }; + + checks = { + inherit craneBuild; + formatting = treefmtEval.config.build.check self; + }; + + formatter = treefmtEval.config.build.wrapper; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + cocogitto + + rust_default + cargo-edit + + licensure + ]; + }; + }); +} +# vim: ts=2 + diff --git a/pkgs/sources/lf-make-map/lf_make_map.nix b/pkgs/sources/lf-make-map/lf_make_map.nix new file mode 100644 index 00000000..afb067b8 --- /dev/null +++ b/pkgs/sources/lf-make-map/lf_make_map.nix @@ -0,0 +1,10 @@ +{rustPlatform}: +rustPlatform.buildRustPackage { + pname = "lf-make-map"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; +} diff --git a/pkgs/sources/lf-make-map/src/cli.rs b/pkgs/sources/lf-make-map/src/cli.rs new file mode 100644 index 00000000..a398e451 --- /dev/null +++ b/pkgs/sources/lf-make-map/src/cli.rs @@ -0,0 +1,49 @@ +use std::path::PathBuf; + +use clap::{ArgAction, Parser, Subcommand}; + +/// An automatic lf cd mapping generator +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +#[command(next_line_help = true)] +pub struct Args { + /// The directory to treat as home + #[arg(long, short = 'n', env = "HOME")] + pub home_name: PathBuf, + + /// The number of directories to generate mappings for, starting from each `relevant_directory` + #[arg(long, short, default_value = "2")] + pub depth: usize, + + /// Increase message verbosity + #[arg(long="verbose", short = 'v', action = ArgAction::Count)] + pub verbosity: u8, + + /// Silence all output + #[arg(long, short = 'q')] + pub quiet: bool, + + #[command(subcommand)] + pub command: Command, +} + +#[derive(Subcommand, Debug)] +pub enum Command { + /// Visualize the generated mappings in a tree + Visualize { + #[command(flatten)] + options: CommandOptions, + }, + + /// Output the generated mappings in a format suitable for the lf config file + Generate { + #[command(flatten)] + options: CommandOptions, + }, +} + +#[derive(Debug, Parser)] +pub struct CommandOptions { + /// The directories to generate mappings for + pub relevant_directories: Vec, +} diff --git a/pkgs/sources/lf-make-map/src/main.rs b/pkgs/sources/lf-make-map/src/main.rs new file mode 100644 index 00000000..aaf79b20 --- /dev/null +++ b/pkgs/sources/lf-make-map/src/main.rs @@ -0,0 +1,229 @@ +use std::path::{Path, PathBuf}; + +use anyhow::{Context, Result}; +use clap::Parser; +use cli::{Args, Command}; +use log::trace; +use mapping::map_tree::MappingTree; +use walkdir::{DirEntry, WalkDir}; + +use crate::mapping::MapKey; + +mod cli; +mod mapping; + +fn main() -> anyhow::Result<()> { + let args = Args::parse(); + + stderrlog::new() + .module(module_path!()) + .quiet(args.quiet) + .show_module_names(false) + .color(stderrlog::ColorChoice::Auto) + .verbosity(args.verbosity as usize) + .timestamp(stderrlog::Timestamp::Off) + .init()?; + + let mut mappings = MappingTree::new(); + + let relevant_directories = match &args.command { + Command::Visualize { options } => &options.relevant_directories, + Command::Generate { options } => &options.relevant_directories, + }; + + for dir in relevant_directories { + trace!("Processing '{}'..", dir.display()); + let path = strip_path(&dir, &args.home_name)?; + + mappings + .include(path_to_str(path)?) + .with_context(|| format!("Failed to include path: '{}'", path.display()))?; + } + + let home = path_to_str(&args.home_name)?.to_owned(); + + let mut current_depth = 1; + while current_depth != args.depth { + for (key, value) in mappings.iter(false) { + trace!( + "Adding to child ('{}' -> '{}')", + MapKey::display(&key), + value + ); + + let mut local_mappings = MappingTree::new(); + for dir in WalkDir::new(extend(&home, &value)?) + .min_depth(1) + .max_depth(1) + .into_iter() + .filter_entry(|e| is_dir(e) && !is_hidden(e)) + { + let directory = dir + .with_context(|| format!("Failed to read dir ('{}')", home.clone() + &value))?; + let path_to_strip = &PathBuf::from(extend(&home, &value)?); + let path = strip_path(&directory.path(), &path_to_strip)?; + trace!( + "Including: '{}' (after stripping '{}' from '{}' -> '{}' + '/' + '{}')", + path.display(), + directory.path().display(), + path_to_strip.display(), + home, + value + ); + + let gen_key = MapKey::new_ones_from_path(path_to_str(path)?, 1); + local_mappings + .insert( + &gen_key, + path_to_str(strip_path(&directory.path(), &PathBuf::from(&home))?)?, + ) + .with_context(|| format!("Failed to include path: '{}'", path.display()))?; + } + + trace!("{}", local_mappings); + + trace!( + "'{}' -> '{:#?}'", + MapKey::display(&key), + local_mappings.root_node() + ); + mappings.interleave(&key, local_mappings.root_node().to_owned())?; + } + current_depth += 1; + } + + match args.command { + Command::Visualize { .. } => println!("{}", mappings), + Command::Generate { .. } => println!("{}", mappings.to_lf_mappings(args.home_name)), + } + + Ok(()) +} + +fn extend(base: &str, value: &str) -> Result { + let base_path = PathBuf::from(base); + let value_path = PathBuf::from(value); + + Ok(path_to_str(&base_path.join(&value_path))?.to_owned()) +} + +fn is_hidden(entry: &DirEntry) -> bool { + entry + .file_name() + .to_str() + .map(|s| s.starts_with(".")) + .unwrap_or(false) +} + +fn is_dir(entry: &DirEntry) -> bool { + entry.file_type().is_dir() +} + +fn strip_path<'a>(path: &'a Path, to_strip: &Path) -> Result<&'a Path> { + path.strip_prefix(&to_strip).with_context(|| { + format!( + "'{}' is not under the specified home path ('{}')!", + path.display(), + to_strip.display() + ) + }) +} + +fn path_to_str(path: &Path) -> Result<&str> { + path.to_str().with_context(|| { + format!( + "\ +Can't derive a keymapping from path: '{}' \ +because it can't be turned to a string +", + path.display() + ) + }) +} + +// fn gen_lf_mappings(home_name: PathBuf, char_num: usize, rel_dirs: Vec) { +// let mut mappings_vec = vec![]; +// let mut index_counter = 0; +// rel_dirs.iter().for_each(|rel_dir| { +// mappings_vec.push(vec![Mapping::new( +// &gen_hot_key(rel_dir, rel_dir, char_num), +// rel_dir, +// rel_dir, +// None, +// )]); +// get_dir(rel_dir.to_owned()).iter().for_each(|path| { +// mappings_vec[index_counter].push(Mapping::new( +// &gen_hot_key( +// path, +// path.parent().expect("All paths here should have parents"), +// char_num, +// ), +// path, +// &path +// .parent() +// .expect("All paths here should have parents") +// .to_owned(), +// None, +// )); +// }); +// index_counter += 1; +// }); +// print_mappings(&mappings_vec, home_name); +// mappings_vec +// .into_iter() +// .for_each(|rel_dir_mapping: Vec| { +// let mut hash_map = sort_mapping_by_hot_key(rel_dir_mapping.clone()); +// //dbg!(hash_map); +// hash_map.insert("gsi".to_owned(), vec![rel_dir_mapping[0].clone()]); +// }); +// } +// +// fn sort_mapping_by_hot_key(mut mappings: Vec) -> HashMap> { +// mappings.sort_by_key(|mapping| mapping.hot_key.clone()); +// +// let mut filtered_mappings: HashMap> = HashMap::new(); +// mappings.iter().for_each(|mapping| { +// filtered_mappings.insert(mapping.hot_key.clone(), vec![]); +// }); +// //dbg!(&mappings); +// +// let mut index_counter = 1; +// mappings.iter().for_each(|mapping| { +// if mappings.len() > index_counter { +// let next_mapping = &mappings[index_counter]; +// let vec = filtered_mappings +// .get_mut(&mapping.hot_key) +// .expect("This existst as it has been initialized"); +// +// if &next_mapping.hot_key == &mapping.hot_key { +// vec.push(mapping.clone()); +// vec.push(next_mapping.clone()); +// } else { +// vec.push(mapping.clone()); +// } +// +// let new_vec = vec.to_owned(); +// filtered_mappings.insert(mapping.hot_key.to_owned(), new_vec); +// } +// +// index_counter += 1; +// }); +// filtered_mappings +// } +// +// fn print_mappings(mappings: &Vec>, home_name: PathBuf) { +// for mapping in mappings { +// mapping.iter().for_each(|map| { +// println!( +// "{} = \"cd {}\";", +// map.hot_key, +// map.path +// .display() +// .to_string() +// .replace(home_name.to_str().expect("This should be UTF-8"), "~") +// ); +// }); +// +// println!("# -------------"); +// } +// } diff --git a/pkgs/sources/lf-make-map/src/mapping/map_tree/display.rs b/pkgs/sources/lf-make-map/src/mapping/map_tree/display.rs new file mode 100644 index 00000000..65302e1e --- /dev/null +++ b/pkgs/sources/lf-make-map/src/mapping/map_tree/display.rs @@ -0,0 +1,91 @@ +use std::fmt::Display; + +use crate::mapping::{ + map_tree::{Node, NodeValue}, + MapKey, +}; + +use super::MappingTree; + +impl Display for MappingTree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn write_node( + f: &mut std::fmt::Formatter<'_>, + node: &Node, + indention: String, + location: Vec, + is_last: bool, + is_root: bool, + ) -> std::fmt::Result { + let node_value = match &node.value { + NodeValue::Parent { children: _ } => "".to_owned(), + NodeValue::Child { path, extandable } => { + path.to_owned() + if *extandable { " [exten.]" } else { " [stop]" } + } + }; + + let new_idention = indention.clone() + + if is_root { + "" + } else { + match is_last { + true => " ", + false => "│ ", + } + }; + + let bullet = match is_last { + true => String::from("└── "), + false => String::from("├── "), + }; + + if is_root { + write!(f, ": {}\n", node_value)?; + } else { + write!( + f, + "{}{}\x1b[1;33m{}\x1b[0m: {}\n", + indention, + bullet, + MapKey::display(&location), + node_value, + )?; + }; + + match &node.value { + NodeValue::Parent { children } => { + let mut children_vec: Vec<(&MapKey, &Node)> = children.iter().collect(); + children_vec.sort_by(|(a, _), (b, _)| a.key.cmp(&b.key)); + + let mut counter = 1; + for (key, child) in &children_vec { + let mut new_location = location.clone(); + new_location.push((*key).to_owned()); + + write_node( + f, + child, + new_idention.clone(), + new_location.clone(), + counter == children_vec.len(), + false, + )?; + counter += 1; + } + } + NodeValue::Child { + path: _, + extandable: _, + } => { + // Do nothing and stop the recursion + } + } + + Ok(()) + } + + write_node(f, &self.root, String::new(), vec![], false, true)?; + + Ok(()) + } +} diff --git a/pkgs/sources/lf-make-map/src/mapping/map_tree/iterator.rs b/pkgs/sources/lf-make-map/src/mapping/map_tree/iterator.rs new file mode 100644 index 00000000..4364bb2b --- /dev/null +++ b/pkgs/sources/lf-make-map/src/mapping/map_tree/iterator.rs @@ -0,0 +1,53 @@ +use crate::mapping::MapKey; + +use super::{MappingTree, Node, NodeValue}; + +pub struct MappingTreeIterator { + children: Vec<(Vec, String)>, +} + +impl MappingTreeIterator { + pub fn new(tree: &MappingTree, ignore_extendable: bool) -> Self { + let children = extract_child(vec![], &tree.root, ignore_extendable); + + Self { children } + } +} + +fn extract_child( + current_key: Vec, + node: &Node, + ignore_extendable: bool, +) -> Vec<(Vec, String)> { + match &node.value { + NodeValue::Parent { children } => children + .iter() + .map(|(key, value)| { + let mut new_key = current_key.clone(); + new_key.push(key.to_owned()); + + extract_child(new_key, value, ignore_extendable) + }) + .flatten() + .collect(), + NodeValue::Child { path, extandable } => { + if ignore_extendable { + vec![(current_key, path.to_string())] + } else { + if *extandable { + vec![(current_key, path.to_string())] + } else { + vec![] + } + } + } + } +} + +impl Iterator for MappingTreeIterator { + type Item = (Vec, String); + + fn next(&mut self) -> Option { + self.children.pop() + } +} diff --git a/pkgs/sources/lf-make-map/src/mapping/map_tree/lf_mapping.rs b/pkgs/sources/lf-make-map/src/mapping/map_tree/lf_mapping.rs new file mode 100644 index 00000000..6d9c7a0d --- /dev/null +++ b/pkgs/sources/lf-make-map/src/mapping/map_tree/lf_mapping.rs @@ -0,0 +1,19 @@ +use std::path::PathBuf; + +use crate::mapping::MapKey; + +use super::MappingTree; + +impl MappingTree { + pub fn to_lf_mappings(self, home_path: PathBuf) -> String { + self.iter(true) + .map(|(key, value)| { + format!( + "map g{} cd \"{}\"\n", + MapKey::display(&key), + home_path.join(&value).display() + ) + }) + .collect() + } +} diff --git a/pkgs/sources/lf-make-map/src/mapping/map_tree/mod.rs b/pkgs/sources/lf-make-map/src/mapping/map_tree/mod.rs new file mode 100644 index 00000000..35e6d91d --- /dev/null +++ b/pkgs/sources/lf-make-map/src/mapping/map_tree/mod.rs @@ -0,0 +1,402 @@ +use std::{collections::HashMap, mem}; + +use anyhow::{bail, Result}; +use log::debug; + +use self::iterator::MappingTreeIterator; + +use super::MapKey; + +pub mod display; +pub mod iterator; +pub mod lf_mapping; + +/// A prefix tree +#[derive(Debug)] +pub struct MappingTree { + root: Node, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum NodeValue { + Parent { children: HashMap }, + Child { path: String, extandable: bool }, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Node { + value: NodeValue, +} + +impl MappingTree { + pub fn new() -> Self { + Self { + root: Node::new_parent(), + } + } + + pub fn root_node(&self) -> &Node { + &self.root + } + + pub fn iter(&self, ignore_extendable: bool) -> MappingTreeIterator { + MappingTreeIterator::new(&self, ignore_extendable) + } + + /// Returns the node at the key, otherwise None. The node can be changed + pub fn get_mut(&mut self, key: &[MapKey]) -> Option<&mut Node> { + let mut current_node = &mut self.root; + for ch in key.iter() { + if let NodeValue::Parent { children } = &mut current_node.value { + current_node = children.get_mut(&ch)? + } else { + return None; + } + } + + Some(current_node) + } + + /// Returns the node at the key, otherwise the last node that matched. + pub fn try_get(&self, key: &[MapKey]) -> (&Node, Vec) { + let mut current_node = &self.root; + let mut current_key = vec![]; + + for ch in key.iter() { + if let NodeValue::Parent { children } = ¤t_node.value { + current_node = if let Some(node) = children.get(&ch) { + let (key, _value) = children + .get_key_value(&ch) + .expect("This exists, we checked"); + current_key.push(key.clone()); + + node + } else { + return (current_node, current_key); + }; + } else { + return (current_node, current_key); + } + } + + (current_node, current_key) + } + + pub fn include(&mut self, path: &str) -> Result<()> { + let associated_key = MapKey::new_ones_from_path(path, 1); + self.insert(&associated_key, path) + } + + pub fn insert(&mut self, key: &[MapKey], path: &str) -> Result<()> { + self.insert_node(key, Node::new_child(path.to_owned())) + } + + pub fn interleave(&mut self, key: &[MapKey], node: Node) -> Result<()> { + let want_to_be_parent = self.get_mut(&key).expect("This value exists"); + let (parent_value, _parent_children) = if let NodeValue::Parent { children } = node.value { + ( + NodeValue::Parent { + children: children.clone(), + }, + children, + ) + } else { + unreachable!("This value will be a parent") + }; + + let child_value = mem::replace(&mut want_to_be_parent.value, parent_value); + assert!(matches!( + child_value, + NodeValue::Child { + path: _, + extandable: _ + } + )); + + let child_value = if let NodeValue::Child { + path, + extandable: _, + } = child_value + { + NodeValue::Child { + path, + extandable: false, + } + } else { + unreachable!("This is only a child value") + }; + + let child = Node { value: child_value }; + + let mut new_key = key.to_vec(); + new_key.push(MapKey { + key: '.', + part_path: ".".to_owned(), + resolution: 1, + }); + self.insert_node(&new_key, child)?; + Ok(()) + } + + pub fn insert_node(&mut self, key: &[MapKey], node: Node) -> Result<()> { + let (_node, found_key) = self.try_get(key).clone(); + + if found_key != key { + let needed_nodes_key = key + .strip_prefix(&found_key[..]) + .expect("The node's location is a prefix"); + + let needed_nodes_length = needed_nodes_key.iter().count(); + + let mut current_node = self + .get_mut(&found_key[..]) + .expect("This should always exists"); + let mut current_location = found_key.clone(); + let mut counter = 1; + + for ch in needed_nodes_key.iter() { + current_location.push(ch.to_owned()); + + let next_node = if counter == needed_nodes_length { + node.clone() + } else { + Node::new_parent() + }; + + current_node = match ¤t_node.value { + NodeValue::Parent { children } => { + assert_eq!(children.get(&ch), None); + + let children = + if let NodeValue::Parent { children } = &mut current_node.value { + children + } else { + unreachable!("This is a parent, we cheched") + }; + + children.insert(ch.to_owned(), next_node); + children.get_mut(&ch).expect("Was just inserted") + } + NodeValue::Child { + path, + extandable: _, + } => { + // A node that should be a parent was classified + // as child before: + // + // 1. Remove the child node and replace it with a parent one. + // 2. Add the child node to the parent node as child, but with a '.' as MapKey. + // 3. Add the original node also as child to the parent node. + + let mut children = HashMap::new(); + let move_child_node = Node::new_child(path.to_owned()); + + children.insert( + MapKey { + key: '.', + part_path: ".".to_owned(), + resolution: 1, + }, + move_child_node, + ); + children.insert(ch.to_owned(), next_node); + + current_node.value = NodeValue::Parent { children }; + + let children = + if let NodeValue::Parent { children } = &mut current_node.value { + children + } else { + unreachable!("We just inserted the parent value.") + }; + + children.get_mut(&ch).expect("Was just inserted") + } + }; + + counter += 1; + } + } else { + fn reduce_string(a: &str) -> Option { + let first_char = a.chars().take(1).last().expect("Should contain one char"); + + if a.chars().all(|ch| ch == first_char) { + return Some(first_char); + } else { + return None; + } + } + fn check_subset(a: &str, b: &str) -> bool { + if a.len() > b.len() { + let a_prefix: String = a.chars().take(b.len()).collect(); + let a_suffix: String = a.chars().skip(b.len()).collect(); + + if a_prefix == b { + let clean_suffix = reduce_string(&a_suffix); + if let Some(ch) = clean_suffix { + ch == b.chars().last().expect("Will match") + } else { + false + } + } else { + false + } + } else if b.len() > a.len() { + let b_prefix: String = b.chars().take(a.len()).collect(); + let b_suffix: String = b.chars().skip(a.len()).collect(); + + if b_prefix == a { + let clean_suffix = reduce_string(&b_suffix); + if let Some(ch) = clean_suffix { + ch == a.chars().last().expect("Will match") + } else { + false + } + } else { + false + } + } else { + a == b + } + } + + // Another node was already inserted with the same key! + // So we simple increase the resolution of the other node and this node, until their + // keys are not the same anymore. + // This only includes the last segment of the `MapKey` + // + // 1. Change both keys, until they are not equal any more + // 2. Move the wrongly placed node to the new place. + // 3. Insert our node. + let mut foreign_key = vec![found_key.last().expect("This will exist").clone()]; + let mut our_key = vec![key.last().expect("This will exist").clone()]; + + debug!( + "'{}' ('{}') and '{}' ('{}') are the same, try to find a better combination!", + MapKey::display(&our_key), + our_key[0].part_path, + MapKey::display(&foreign_key), + foreign_key[0].part_path, + ); + + // The 'a' and 'b' stuff is here, to ensure that both returning None will not match + // this condition. + if reduce_string(&foreign_key[0].part_path).unwrap_or('a') + == reduce_string(&our_key[0].part_path).unwrap_or('b') + { + bail!( + "\ +The foreign_key ('{}', path_part: '{}' -> '{}') and our_key ('{}', path_part: '{}' -> '{}') \ +have an identical path_part (when duplicated chars are removed)! +I cannot extended them via incrementation. +Please rename the paths to fix this. + ", + MapKey::display(&foreign_key), + &foreign_key[0].part_path, + reduce_string(&foreign_key[0].part_path).expect("Is some here"), + MapKey::display(&our_key), + &our_key[0].part_path, + reduce_string(&our_key[0].part_path).expect("Is some here"), + ); + } + + if check_subset(&foreign_key[0].part_path, &our_key[0].part_path) { + bail!( + "\ +The foreign_key ('{}', path_part: '{}') and our_key ('{}', path_part: '{}') \ +are subsets of one another! +A discrimination through incrementation will not work! +Please rename the paths to fix this. + ", + MapKey::display(&foreign_key), + &foreign_key[0].part_path, + MapKey::display(&our_key), + &our_key[0].part_path, + ); + } + + while our_key == foreign_key { + our_key = our_key[0].increment(our_key[our_key.len() - 1].resolution + 1); + foreign_key = + foreign_key[0].increment(foreign_key[foreign_key.len() - 1].resolution + 1); + debug!( + "Now its: '{}' ('{}') and '{}' ('{}')", + MapKey::display(&our_key), + our_key[0].part_path, + MapKey::display(&foreign_key), + foreign_key[0].part_path, + ); + } + + debug!( + "Found a better one: '{}' ('{}') and '{}' ('{}')", + MapKey::display(&our_key), + our_key[0].part_path, + MapKey::display(&foreign_key), + foreign_key[0].part_path, + ); + + let parent = self + .get_mut(&found_key[..&found_key.len() - 1]) + .expect("This will exist"); + + if let NodeValue::Parent { children } = &mut parent.value { + if let NodeValue::Child { + path: _, + extandable: _, + } = children + .get(found_key.last().expect("Exists")) + .expect("This node also exists") + .value + { + let old = children + .remove(found_key.last().expect("This will exist")) + .expect("This will be there"); + + let full_foreign_key: Vec<_> = found_key + .clone() + .into_iter() + .rev() + .skip(1) + .rev() + .chain(foreign_key.clone().into_iter()) + .collect(); + self.insert_node(&full_foreign_key, old.clone())?; + } + + let full_our_key: Vec<_> = key + .to_vec() + .into_iter() + .rev() + .skip(1) + .rev() + .chain(our_key.clone().into_iter()) + .collect(); + + self.insert_node(&full_our_key, node.clone())?; + } else { + unreachable!("This node will be a parent"); + } + } + + Ok(()) + } +} + +impl Node { + pub fn new_child(path: String) -> Self { + Self { + value: NodeValue::Child { + path, + extandable: true, + }, + } + } + pub fn new_parent() -> Self { + Self { + value: NodeValue::Parent { + children: HashMap::new(), + }, + } + } +} diff --git a/pkgs/sources/lf-make-map/src/mapping/mod.rs b/pkgs/sources/lf-make-map/src/mapping/mod.rs new file mode 100644 index 00000000..114fdca0 --- /dev/null +++ b/pkgs/sources/lf-make-map/src/mapping/mod.rs @@ -0,0 +1,156 @@ +use std::{ + fmt::{Display, Write}, + hash::Hash, +}; + +use log::debug; + +pub mod map_tree; + +#[derive(Clone, Debug, Eq)] +pub struct MapKey { + pub key: char, + + resolution: usize, + + /// Part of the path, used to derive the key + part_path: String, +} + +impl Hash for MapKey { + fn hash(&self, state: &mut H) { + self.key.hash(state) + } +} + +impl PartialEq for MapKey { + fn eq(&self, other: &Self) -> bool { + self.key == other.key + } +} + +impl MapKey { + pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec { + let key = Self::part_path_to_key(&part_path, resolution); + + key.chars() + .map(|ch| Self { + key: ch, + resolution, + part_path: part_path.to_owned(), + }) + .collect() + } + + pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec { + let key: Vec = path + .split('/') + .map(|part| Self::new_from_part_path(part, number_of_chars)) + .flatten() + .collect(); + + debug!( + "Generated full MapKeys: '{}' -> '{}'", + path, + MapKey::display(&key) + ); + key + } + + pub fn increment(&self, target_resolution: usize) -> Vec { + let new_resolution = target_resolution; + + // debug!("Incrementing: '{}' ('{}')", &self, &self.part_path); + + let added_chars = if new_resolution < self.part_path.len() { + MapKey::part_path_to_key(&self.part_path, new_resolution) + } else { + let mut generated_chars = + MapKey::part_path_to_key(&self.part_path, self.part_path.len()); + + generated_chars.extend( + (0..(new_resolution - self.part_path.len())) + .into_iter() + .map(|_| self.part_path.chars().last().expect("This will exists")), + ); + + generated_chars + }; + + let part_path = self.part_path.clone(); + let output: Vec = added_chars + .chars() + .enumerate() + .map(|(res, ch)| MapKey { + key: ch, + resolution: res + 1, + part_path: part_path.clone(), + }) + .collect(); + + // debug!("Finished increment: '{}' ('{}')", MapKey::display(&output), output[0].part_path); + output + } + + pub fn display(values: &[Self]) -> String { + values.iter().map(|value| value.key.clone()).collect() + } + fn part_path_to_key(part: &str, number_of_chars: usize) -> String { + fn make(pat: char, part: &str, number_of_chars: usize) -> String { + let mut acc = String::new(); + + if !part.split(pat).all(|part| part.len() > 0) { + panic!( + "\ +Can't turn this path '{}' to a mapping. +This should not happen, please report the bug!", + part + ) + } + + let mut last_working = None; + for i in 0..number_of_chars { + for str in part.split(pat) { + if acc.len() != number_of_chars { + acc.push(match str.chars().nth(i) { + Some(ch) => ch, + None => { + if let Some(last) = last_working { + str.chars().nth(last).expect("This should always exist") + } else { + last_working = Some(i - 1); + str.chars().nth(i - 1).expect("This should always exist") + } + } + }) + } + } + } + + acc + } + + let value = if part.contains('_') && !part.starts_with('_') && !part.ends_with('_') { + make('_', part, number_of_chars) + } else if part.contains('-') && !part.starts_with('-') && !part.ends_with('-') { + make('-', part, number_of_chars) + } else { + part.chars().take(number_of_chars).collect::() + }; + + assert_eq!( + value.len(), + number_of_chars, + "'{}' does not have expected length of: {}", + value, + number_of_chars + ); + value + } +} + +impl Display for MapKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_char(self.key) + } +} diff --git a/pkgs/sources/lf-make-map/update.sh b/pkgs/sources/lf-make-map/update.sh new file mode 100755 index 00000000..a0a029f4 --- /dev/null +++ b/pkgs/sources/lf-make-map/update.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +nix flake update + +[ "$1" = "upgrade" ] && cargo upgrade +cargo update diff --git a/pkgs/sources/plgs-pkgs/README.md b/pkgs/sources/plgs-pkgs/README.md new file mode 100644 index 00000000..e8169951 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/README.md @@ -0,0 +1,92 @@ +# Fork + +All files in this repository where forked form [here](https://github.com/NixNeovim/NixNeovimPlugins) on commit `5010b91eb03696574c3c293f072a090618227e87`. +Below the original README. They were licensed under the MIT license. + +# All vim plugins, ready to go + +This repo auto generates nix packages for vim/neovim plugins. +Packages are automatically updated twice per week using a GitHub Actions. +Plugins are fetched from the `manifest.txt` and [awesome-neovim][0] repo. + +This is a fork of [this repo](https://github.com/m15a/nixpkgs-vim-extra-plugins); however, we fetch all additions from the original repo, so we will never have less plugins. +Further, the original deletes plugins that are available in the nixpkgs. We, instead, try to assemble a list of all available plugins. +Therefore, to access plugins you will never have to search in two places. + +This repo can be used as a stand-alone, by adding it to your inputs. +However, we recommend to use [NixNeovim](https://github.com/NixNeovim/NixNeovim) modules instead, and use this only when you need a plugins, which does not have a module, yet. + +## Available plugins + +The [plugins.md](plugins.md) contains an auto-generated list of all available plugins. + +## Usage + +- We recommend using [NixNeovim](https://github.com/NixNeovim/NixNeovim), and only access the plugins directly when they do not have a module in NixNeovim. + +However, you can also use this repo without NixNeovim: +To access the plugins, you need to add the overlay. +The overlay adds extra Vim plugins to `pkgs.vimExtraPlugins`. +First, add this repo to your inputs: + +``` +inputs.nixneovimplugins.url = github:jooooscha/nixpkgs-vim-extra-plugins +``` + +Next, apply the provided overlay: + +``` +nixpkgs.overlays = [ + inputs.nixneovimplugins.overlays.default +]; +``` + +Finally, you can add the packages to your vim/neovim config. For example you can use [NixNeovim](https://github.com/NixNeovim/Nixneovim) or you can add the plugins directly: + +``` + programs.neovim = { + plugins = [ + pkgs.vimExtraPlugins.nvim-colorizer-lua + ]; + } +``` + +More info on using neovim with nix can be found here: [NixOS Neovim](https://nixos.wiki/wiki/Neovim) + +## Contribution + +### How to add a new plugin + +#### 1. Add the plugin to manifest.txt: + +``` +# Examples + +haringsrob/nvim_context_vt +sourcehut:henriquehbr/ataraxis.lua +gitlab:yorickpeterse/nvim-pqf +williamboman/mason.nvim:45b9a4da776d9fb017960b3ac7241161fb7bc578 +foo/bar::baz --> renamed to baz +foo/bar:dev --> using dev branch +``` + +Supported are Github (default), SourceHut, and GitLab. + +#### 2. Create a Pull Request + +- Create a pull request with the changed manifest.txt (and blacklist.txt if neccessary). +- A GitHub action will check your contribution and generate all neccessary nix code for your new plugin. It will also take care of sorting and cleaning the manifest.txt +- After all checks have passed, I will merge your change. + +I am happy for any contribution. :) + +### How to remove a new plugin + +Copy the entry from manifest.txt to blacklist.txt and create a PR. +The GitHub Actions will do the rest, including removing the entry from manifest.txt + +## Credits + +This is originally based on work by [m15a](https://github.com/m15a/nixpkgs-vim-extra-plugins) + +[0]: https://github.com/rockerBOO/awesome-neovim diff --git a/pkgs/sources/plgs-pkgs/check.nix b/pkgs/sources/plgs-pkgs/check.nix new file mode 100644 index 00000000..ad23e2c7 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/check.nix @@ -0,0 +1,37 @@ +{ + pkgs, + lib, + ... +}: let + # checks if a plugin has a license + hasLicense = _: pkg: let + warn = x: lib.warn x x; + + msg = + if builtins.hasAttr "license" pkg.meta + then "${pkg.name} has license" + else warn "${pkg.name} has no license"; + + msg' = lib.replaceStrings [" "] ["-"] msg; + in + pkgs.runCommandNoCC msg' {} "echo : > $out "; + + # function to check License for all packages + check-missing-licenses = let + buildInputs = + lib.mapAttrsToList + hasLicense + pkgs.vimExtraPlugins; + in + pkgs.runCommandNoCC + "check-missing-licenses" + {inherit buildInputs;} + "echo : > $out"; +in { + checks = + pkgs.vimExtraPlugins + // { + inherit check-missing-licenses; + inherit (pkgs) update-vim-plugins; + }; +} diff --git a/pkgs/sources/plgs-pkgs/default.nix b/pkgs/sources/plgs-pkgs/default.nix new file mode 100644 index 00000000..0f7cd485 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/default.nix @@ -0,0 +1,15 @@ +[ + (final: prev: + prev.lib.composeManyExtensions [ + (self: super: let + origin = import ./plugins { + inherit (super.vimUtils) buildVimPlugin; + inherit (super) lib fetchurl fetchgit; + }; + in { + vimExtraPlugins = super.lib.makeExtensible (_: super.lib.recurseIntoAttrs origin); + }) + ] + final + prev) +] diff --git a/pkgs/sources/plgs-pkgs/overrides.nix b/pkgs/sources/plgs-pkgs/overrides.nix new file mode 100644 index 00000000..e03a78b1 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/overrides.nix @@ -0,0 +1,34 @@ +final: prev: let + inherit (final) lib; + + /* + * Mark broken packages here. + */ + markBrokenPackages = self: super: + lib.mapAttrs (attrName: broken: + super.${attrName}.overrideAttrs (old: { + meta = old.meta // {inherit broken;}; + })) + { + # = true; + }; + + /* + * Add licenses if missing or incorrect in generated ./pkgs/vim-plugins.nix. + */ + fixLicenses = self: super: + lib.mapAttrs (attrName: license: + super.${attrName}.overrideAttrs (old: { + meta = old.meta // {inherit license;}; + })) (with lib.licenses; { + /* + * Example: + * plugin-name = [] + */ + }); +in { + vimExtraPlugins = prev.vimExtraPlugins.extend (lib.composeManyExtensions [ + markBrokenPackages + fixLicenses + ]); +} diff --git a/pkgs/sources/plgs-pkgs/plugins/.plugins.json b/pkgs/sources/plgs-pkgs/plugins/.plugins.json new file mode 100644 index 00000000..9331bc8f --- /dev/null +++ b/pkgs/sources/plgs-pkgs/plugins/.plugins.json @@ -0,0 +1,7 @@ +{ + "ThePrimeagen/harpoon:master": "{\"description\": \"\", \"homepage\": \"https://github.com/ThePrimeagen/harpoon\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"harpoon\", \"owner\": \"ThePrimeagen\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1w4hi9hbdjwdhb4vwa0x08a25vbcxqg1d5cskm2qvjy5fdlqils0\", \"url\": \"https://github.com/ThePrimeagen/harpoon/archive/ccae1b9bec717ae284906b0bf83d720e59d12b91.tar.gz\"}, \"source_line\": \"ThePrimeagen/harpoon:master\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cMGg==\"]], \"py/object\": \"datetime.date\"}}", + "akinsho/toggleterm.nvim": "{\"description\": \"A neovim lua plugin to help easily manage multiple terminal windows\", \"homepage\": \"https://github.com/akinsho/toggleterm.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"gpl3Only\"]}]}, \"name\": \"toggleterm-nvim\", \"owner\": \"akinsho\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"0nx69q9597vy7lzvvh58fnjyin23ns6apmyp532sgf547bw7mld6\", \"url\": \"https://github.com/akinsho/toggleterm.nvim/archive/cbd041d91b90cd3c02df03fe6133208888f8e008.tar.gz\"}, \"source_line\": \"akinsho/toggleterm.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cMBg==\"]], \"py/object\": \"datetime.date\"}}", + "andrewferrier/debugprint.nvim": "{\"description\": \"Debugging in NeoVim the print() way!\", \"homepage\": \"https://github.com/andrewferrier/debugprint.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"debugprint-nvim\", \"owner\": \"andrewferrier\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"06r1jhx7jd15q8wvnw0xqwk3bkx39pm4pbv70hf9ggd6zsnmsrmn\", \"url\": \"https://github.com/andrewferrier/debugprint.nvim/archive/54297dd0a4f318b279a1cb954e7714f3942df123.tar.gz\"}, \"source_line\": \"andrewferrier/debugprint.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHQ==\"]], \"py/object\": \"datetime.date\"}}", + "lmburns/lf.nvim": "{\"description\": \"Lf file manager for Neovim (in Lua)\", \"homepage\": \"https://github.com/lmburns/lf.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"lf-nvim\", \"owner\": \"lmburns\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px\", \"url\": \"https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz\"}, \"source_line\": \"lmburns/lf.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cKAw==\"]], \"py/object\": \"datetime.date\"}}", + "nvim-telescope/telescope-bibtex.nvim": "{\"description\": \"A telescope.nvim extension to search and paste bibtex entries into your TeX files.\", \"homepage\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"telescope-bibtex-nvim\", \"owner\": \"nvim-telescope\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs\", \"url\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz\"}, \"source_line\": \"nvim-telescope/telescope-bibtex.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHA==\"]], \"py/object\": \"datetime.date\"}}" +} \ No newline at end of file diff --git a/pkgs/sources/plgs-pkgs/plugins/blacklist.txt b/pkgs/sources/plgs-pkgs/plugins/blacklist.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/plugins/blacklist.txt @@ -0,0 +1 @@ + diff --git a/pkgs/sources/plgs-pkgs/plugins/default.nix b/pkgs/sources/plgs-pkgs/plugins/default.nix new file mode 100644 index 00000000..df09e446 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/plugins/default.nix @@ -0,0 +1,55 @@ +{ + lib, + buildVimPlugin, + fetchurl, + fetchgit, +}: { + /* + Generated from: ThePrimeagen/harpoon:master + */ + harpoon = buildVimPlugin { + pname = "harpoon"; + version = "2023-12-26"; + src = fetchurl { + url = "https://github.com/ThePrimeagen/harpoon/archive/ccae1b9bec717ae284906b0bf83d720e59d12b91.tar.gz"; + sha256 = "1w4hi9hbdjwdhb4vwa0x08a25vbcxqg1d5cskm2qvjy5fdlqils0"; + }; + meta = with lib; { + description = ""; + homepage = "https://github.com/ThePrimeagen/harpoon"; + license = with licenses; [mit]; + }; + }; + /* + Generated from: lmburns/lf.nvim + */ + lf-nvim = buildVimPlugin { + pname = "lf-nvim"; + version = "2023-10-03"; + src = fetchurl { + url = "https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz"; + sha256 = "1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px"; + }; + meta = with lib; { + description = "Lf file manager for Neovim (in Lua)"; + homepage = "https://github.com/lmburns/lf.nvim"; + license = with licenses; [mit]; + }; + }; + /* + Generated from: nvim-telescope/telescope-bibtex.nvim + */ + telescope-bibtex-nvim = buildVimPlugin { + pname = "telescope-bibtex-nvim"; + version = "2024-03-28"; + src = fetchurl { + url = "https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz"; + sha256 = "1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs"; + }; + meta = with lib; { + description = "A telescope.nvim extension to search and paste bibtex entries into your TeX files."; + homepage = "https://github.com/nvim-telescope/telescope-bibtex.nvim"; + license = with licenses; [mit]; + }; + }; +} diff --git a/pkgs/sources/plgs-pkgs/plugins/manifest.txt b/pkgs/sources/plgs-pkgs/plugins/manifest.txt new file mode 100644 index 00000000..615083c8 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/plugins/manifest.txt @@ -0,0 +1,3 @@ +lmburns/lf.nvim +nvim-telescope/telescope-bibtex.nvim +ThePrimeagen/harpoon:master diff --git a/pkgs/sources/plgs-pkgs/plugins/plugins.md b/pkgs/sources/plgs-pkgs/plugins/plugins.md new file mode 100644 index 00000000..4f73f811 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/plugins/plugins.md @@ -0,0 +1,7 @@ +- Plugin count: 3 + +| Repo | Last Update | Nix package name | Last checked | +|:---|:---|:---|:---| +| [ThePrimeagen/harpoon:master](https://github.com/ThePrimeagen/harpoon) | 2023-12-26 | `harpoon` | 2024-05-09 | +| [lmburns/lf.nvim](https://github.com/lmburns/lf.nvim) | 2023-10-03 | `lf-nvim` | 2024-05-09 | +| [nvim-telescope/telescope-bibtex.nvim](https://github.com/nvim-telescope/telescope-bibtex.nvim) | 2024-03-28 | `telescope-bibtex-nvim` | 2024-05-09 | diff --git a/pkgs/sources/plgs-pkgs/plugins/whitelist.txt b/pkgs/sources/plgs-pkgs/plugins/whitelist.txt new file mode 100644 index 00000000..e69de29b diff --git a/pkgs/sources/plgs-pkgs/update.sh b/pkgs/sources/plgs-pkgs/update.sh new file mode 100755 index 00000000..6a0d3452 --- /dev/null +++ b/pkgs/sources/plgs-pkgs/update.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env sh + +BASE_DIR="$(readlink -f "$(dirname "$0")/plugins")" + +# Fetch plugins +cd "$BASE_DIR" || (echo "BUG: No '$BASE_DIR'" && exit 1) + +# Cleanup manifest +sort -o "$BASE_DIR/manifest.txt" "$BASE_DIR/manifest.txt" +sort -o "$BASE_DIR/blacklist.txt" "$BASE_DIR/blacklist.txt" +## Remove all plugins, which are on the blacklist +# The same file is read and written to +# shellcheck disable=SC2005 +echo "$(comm -23 "$BASE_DIR/manifest.txt" "$BASE_DIR/blacklist.txt")" >"$BASE_DIR/manifest.txt" + +# Backup vim-plugins.nix +mv "$BASE_DIR/default.nix" "$BASE_DIR/default.nix.bak" +echo "{...} : {}" >"$BASE_DIR/default.nix" + +# Generate derivations for new plugins (this binary is provided by the dev-environment) +update-vim-plugins cleanup "$BASE_DIR" + +# Restore vim-plugins.nix +mv "$BASE_DIR/default.nix.bak" "$BASE_DIR/default.nix" + +# Update new plugins +update-vim-plugins update "$BASE_DIR" --all diff --git a/pkgs/sources/scripts/default.nix b/pkgs/sources/scripts/default.nix new file mode 100644 index 00000000..09c8d411 --- /dev/null +++ b/pkgs/sources/scripts/default.nix @@ -0,0 +1,412 @@ +{ + sysLib, + homeConfig, + nixosConfig, +}: [ + ( + final: prev: let + inherit (prev) lib; + + write_shell = { + name, + path, + dependencies ? [], + keepPath ? false, + completions ? false, + }: + sysLib.writeShellScript { + inherit name keepPath; + src = ./source/${path}/${name}.sh; + dependencies = dependencies ++ [prev.dash]; + generateCompletions = completions; + }; + write_python = { + name, + path, + dependencies_system ? [], + dependencies_python ? _: [], + keepPath ? false, + }: let + src = ./source/${path}/${name}.py; + dependencies = + [(prev.python3.withPackages dependencies_python)] + ++ dependencies_system; + path_setting = + if keepPath + then "--prefix PATH :" + else "--set PATH"; + in + prev.runCommandLocal name { + nativeBuildInputs = [prev.makeWrapper] ++ dependencies; + } + '' + install -m755 ${src} -D "$out/bin/${name}" + patchShebangs "$out/bin/${name}" + wrapProgram "$out/bin/${name}" ${path_setting} ${prev.lib.makeBinPath dependencies}; + ''; + + ## Begin of shell scripts + aumo-scr = write_shell { + name = "aumo"; + path = "apps"; + dependencies = builtins.attrValues { + inherit + (prev) + udisks + findutils + rofi + ; + }; + }; + + battery-scr = write_shell { + name = "battery"; + path = "wrappers"; + dependencies = []; + }; + + brightness-scr = lib.mkIf nixosConfig.soispha.laptop.enable (write_shell { + name = "brightness"; + path = "small_functions"; + generateCompletions = true; + dependencies = []; + replacementStrings = {BACKLIGHT_NAME = nixosConfig.soispha.laptop.backlight;}; + }); + + con2pdf-scr = sysLib.writeShellScript { + name = "con2pdf"; + src = ./source/apps/con2pdf.sh; + dependencies = builtins.attrValues {inherit (prev) sane-backends imagemagick coreutils fd;}; + generateCompletions = true; + replacementStrings = { + DEVICE_FUNCTION = + # This is here, because escaping the whole function, to use it in the shell script + # directly just isn't possible + prev.writeText "DEVICE_FUNCTION" + /* + bash + */ + '' + scanimage -L | awk 'BEGIN { FS = "`" } { gsub(/'.*/, "", $2); print $2 }' + ''; + }; + }; + + description-scr = write_shell { + name = "description"; + path = "specific/ytcc"; + dependencies = builtins.attrValues { + inherit (prev) jq fmt less locale; + }; + }; + + fupdate-scr = write_shell { + name = "fupdate"; + path = "apps"; + keepPath = true; + completions = true; + dependencies = builtins.attrValues { + inherit + (prev) + dash + nix + gnugrep + fd + coreutils + bat # used by batgrep + gnused # required by batgrep + git # needed to fetch through git + ; + inherit (prev.bat-extras) batgrep; + }; + }; + + git-edit-index-scr = write_shell { + name = "git-edit-index"; + path = "apps"; + completions = true; + # This starts neovim, wich might want to shell out + keepPath = true; + dependencies = builtins.attrValues { + inherit + (prev) + git + gnused + # $EDITOR + + ; + }; + }; + + hibernate-scr = write_shell { + name = "hibernate"; + path = "wrappers"; + dependencies = builtins.attrValues { + inherit + (prev) + systemd + taskwarrior + ; + }; + }; + + ll-scr = sysLib.writeShellScript { + name = "ll"; + src = ./source/wrappers/ll.sh; + wrap = false; + }; + + # TODO: this need to be replaced with a wayland alternative + # llp-scr = write_shell { + # name = "llp"; + # path = "wrappers"; + # dependencies = builtins.attrValues {inherit (prev) lf ueberzug;}; + # }; + + lock-scr = write_shell { + name = "lock"; + path = "wrappers"; + dependencies = builtins.attrValues { + inherit + (prev) + taskwarrior + swaylock + ; + }; + }; + + lyrics-scr = write_shell { + name = "lyrics"; + path = "wrappers"; + dependencies = builtins.attrValues { + inherit + (prev) + exiftool + mpc-cli + jq + less + locale # dependency of less + ; + }; + }; + + mpc-fav-scr = write_shell { + name = "mpc-fav"; + path = "wrappers"; + dependencies = builtins.attrValues { + inherit + (prev) + mpc-cli + ; + }; + }; + + mpc-rm-scr = write_shell { + name = "mpc-rm"; + path = "wrappers"; + dependencies = builtins.attrValues { + inherit + (prev) + mpc-cli + trash-cli + ; + }; + }; + + mpc-scr = write_shell { + name = "mpc"; + path = "wrappers"; + dependencies = [ + mpc-fav-scr + mpc-rm-scr + prev.mpc-cli + ]; + }; + + nato-scr = write_python { + name = "nato"; + path = "small_functions"; + dependencies_python = ps: []; + }; + + neorg-scr = sysLib.writeShellScriptMultiPart { + name = "neorg"; + keepPath = true; + src = ./source/specific/neorg/sh; + baseName = "main.sh"; + cmdPrefix = "functions"; + cmdNames = [ + "add.sh" + "context.sh" + "dmenu.sh" + "f_start.sh" + "f_stop.sh" + "list.sh" + "project.sh" + "review.sh" + "utils.sh" + "workspace.sh" + ]; + dependencies = with prev; [ + cocogitto + rofi + libnotify + ]; + generateCompletions = true; + replacementStrings = { + DEFAULT_NEORG_PROJECT_DIR = + homeConfig.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces.projects; + HOME_TASKRC = "${homeConfig.xdg.configHome}/task/home-manager-taskrc"; + NEORG_REVIEW_PATH = "${homeConfig.xdg.dataHome}/neorg/review"; + ALL_PROJECTS_NEWLINE = "${homeConfig.soispha.taskwarrior.projects.projects_newline}"; + ALL_PROJECTS_COMMA = "${homeConfig.soispha.taskwarrior.projects.projects_comma}"; + ALL_PROJECTS_PIPE = "${homeConfig.soispha.taskwarrior.projects.projects_pipe}"; + ALL_WORKSPACES = "${lib.strings.concatStringsSep "|" (builtins.attrNames homeConfig.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces)}"; + ID_GENERATION_FUNCTION = "${sysLib.writeShellScript { + name = "neorg_id_function"; + src = ./source/specific/neorg/neorg_id_function.sh; + dependencies = with prev; [ + taskwarrior + gawk + findutils # xargs + ]; + }}/bin/neorg_id_function"; + + # TODO: Replace the hard-coded path here with some reference <2023-10-20> + TASK_PROJECT_FILE = "/home/soispha/repos/nix/nixos-config/hm/soispha/conf/taskwarrior/projects/default.nix"; + }; + }; + + screenshot_persistent-scr = write_shell { + name = "screenshot_persistent"; + path = "small_functions"; + keepPath = true; + dependencies = builtins.attrValues { + inherit + (prev) + grim + slurp + alacritty + rofi + libnotify + lf # TODO: add llp + ; + }; + }; + + screenshot_temporary-scr = write_shell { + name = "screenshot_temporary"; + path = "small_functions"; + dependencies = builtins.attrValues {inherit (prev) grim slurp wl-clipboard;}; + }; + + show-scr = write_shell { + name = "show"; + path = "wrappers"; + keepPath = true; # I might want to use nvim in less (and shell escapes) + dependencies = builtins.attrValues {inherit (prev) less locale;}; + }; + + sort_song-scr = write_shell { + name = "sort_song"; + path = "wrappers"; + dependencies = builtins.attrValues {inherit (prev) mediainfo jq gawk;}; + }; + + spodi-scr = sysLib.writeShellScriptMultiPart { + name = "spodi"; + keepPath = false; + src = ./source/specific/spodi; + baseName = "spodi.sh"; + cmdPrefix = "sh"; + cmdNames = [ + "download.sh" + "update.sh" + ]; + dependencies = with prev; [ + gawk + expect + spotdl + fd + coreutils + ]; + generateCompletions = true; + replacementStrings = { + XDG_CACHE_HOME = homeConfig.xdg.cacheHome; + XDG_MUSIC_DIR = homeConfig.xdg.userDirs.music; + }; + }; + + update-sys-scr = write_shell { + name = "update-sys"; + path = "small_functions"; + completions = true; + dependencies = builtins.attrValues { + inherit + (prev) + git + nixos-rebuild + sudo + openssh + coreutils + mktemp + gnugrep + gnused + systemd + ; + }; + }; + + virsh-del-scr = write_shell { + name = "virsh-del"; + path = "wrappers"; + dependencies = builtins.attrValues {inherit (prev) libvirt;}; + }; + + yti-scr = write_shell { + name = "yti"; + path = "wrappers"; + dependencies = builtins.attrValues {inherit (prev) gawk expect yt-dlp;}; + }; + in { + scripts = { + # llp = llp-scr; # TODO: see above + aumo = aumo-scr; + battery = battery-scr; + brightness = brightness-scr; + con2pdf = con2pdf-scr; + description = description-scr; + fupdate = fupdate-scr; + git-edit-index = git-edit-index-scr; + hibernate = hibernate-scr; + ll = ll-scr; + lock = lock-scr; + lyrics = lyrics-scr; + mpc = mpc-scr; + mpc-fav = mpc-fav-scr; + mpc-rm = mpc-rm-scr; + nato = nato-scr; + neorg = neorg-scr; + screenshot_persistent = screenshot_persistent-scr; + screenshot_temporary = screenshot_temporary-scr; + show = show-scr; + sort_song = sort_song-scr; + spodi = spodi-scr; + update-sys = update-sys-scr; + virsh-del = virsh-del-scr; + yti = yti-scr; + }; + } + ) +] + + + pkgs = import nixpkgs (import ./sys/nixpkgs { + inherit (nixpkgs) lib; + inherit system sysLib; + + # FIXME: Don't unconditionally use tiamat here <2024-02-24> + homeConfig = self.nixosConfigurations.tiamat.config.home-manager.users.soispha; + nixosConfig = self.nixosConfigurations.tiamat.config; + overlays = []; + }); diff --git a/pkgs/sources/scripts/source/apps/aumo.sh b/pkgs/sources/scripts/source/apps/aumo.sh new file mode 100755 index 00000000..84d39deb --- /dev/null +++ b/pkgs/sources/scripts/source/apps/aumo.sh @@ -0,0 +1,28 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +unmounting() { + disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" + + udisksctl unmount --block-device "/dev/disk/by-label/$disk_name" +} + +mounting() { + disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" + + udisksctl mount --block-device "/dev/disk/by-label/$disk_name" +} + +case "$1" in +"mount") + mounting + ;; +"unmount" | "umount") + unmounting + ;; +*) + die "Usage: $NAME mount|unmount" + ;; +esac diff --git a/pkgs/sources/scripts/source/apps/con2pdf.sh b/pkgs/sources/scripts/source/apps/con2pdf.sh new file mode 100755 index 00000000..08bf8998 --- /dev/null +++ b/pkgs/sources/scripts/source/apps/con2pdf.sh @@ -0,0 +1,234 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# needed for help() and version +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2023" +# shellcheck disable=2034 +VERSION="1.0.0" + +# NAME is from the wrapper +# shellcheck disable=SC2269 +NAME="$NAME" +help() { + cat <_1.pdf). + + --num-pages | -p NUM + Number of pages to merge into one pdf (default: 1). + + --device | -d DEVICE + Device used for scanning. + + --method | -m METHOD + Method to use for scanning (default: ADF). + + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. +ARGUMENTS: + FILE := [[fd . --max-depth 3]] + A name of a file to store, default is: ./pdf + + NAME | * := [[fd . --max-depth 3]] + The basename of the generated files + + NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4 + Possible numbers of pages, can be more than 4 + + DEVICE := [[$(cat %DEVICE_FUNCTION)]] + Possible scanner names + + METHOD := ADF | Flatbed + The scanning method to use, not all scanners support both of + these. The default is ADF +EOF +} + +scan_adf() { + device="$1" + sides_per_page="$2" + method="ADF" + for i in $(seq "$sides_per_page"); do + do_until_success \ + "scanimage --format=tiff --progress --source='$method' --device='$device' --batch=%d.tif --batch-increment='$sides_per_page' --batch-start='$i'" \ + "warn 'Retrying scan, as we assume a network error!'" + + if [ "$sides_per_page" -ne 1 ]; then + msg "Finished turn, please change side!" + readp "Press enter to continue" noop + fi + done +} +process_images_adf() { + tiff_temp_path="$1" + output_directory="$2" + name="$3" + + counter=0 + pdf_counter=0 + image_cache="$(mktmp)" + while read -r scanned_image; do + dbg "$scanned_image (scanned_image) at $counter (counter)" + echo "$scanned_image" >>"$image_cache" + : $((counter += 1)) + if [ "$counter" = "$number_of_pages" ]; then + dbg "$counter == $number_of_pages" + counter=0 + convert_images "$image_cache" "${name}_$pdf_counter" "$output_directory" + : $((pdf_counter += 1)) + printf "" >"$image_cache" + fi + done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" +} + +scan_flatbed() { + device="$1" + number_of_pages"$2" + method="Flatbed" + for i in $(seq "$number_of_pages"); do + do_until_success \ + "scanimage --format=tiff --progress --source='$method' --device='$device' --output-file=$i.tiff" \ + "warn 'Retrying scan, as we assume a network error!'" + if [ "$number_of_pages" -ne 1 ]; then + msg "Finished turn, please change side!" + readp "Press enter to continue" noop + fi + done +} +process_images_flatbed() { + tiff_temp_path="$1" + output_directory="$2" + name="$3" + + counter=0 + image_cache="$(mktmp)" + while read -r scanned_image; do + echo "$scanned_image" >>"$image_cache" + : $((counter += 1)) + if [ "$counter" = "$number_of_pages" ]; then + counter=0 + convert_images "$image_cache" "$name" "$output_directory" + printf "" >"$image_cache" + fi + done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" +} +convert_images() { + image_cache="$1" + pdf_name="$2" + output_dir="$3" + + set -- + while read -r image; do + dbg "setting image: $image" + set -- "$@" "$image" + done <"$image_cache" + + while [ -e "$output_dir/${pdf_name}.pdf" ]; do + pdf_name="${pdf_name}_$(tr -dc 'A-Za-z0-9' *|*--help*|*-h*\] + +# DESCRIPTION + +Argument can be stacked, this makes it possible to specify multiple targets to be updated in succession. See the Examples section for further details. + +No argument or *flake* +: **fupdate**, when executed without arguments or with *flake*, will update your *flake.lock*, check for duplicate flake inputs, i.e., an input has an input declared, which you have also declared as input, and will run a script called *update.sh*, if you allow it. +The allowance for the script is asked, when you run **fupdate** and the found script is not yet allowed. Furthermore, the allowance is based on the concrete sha256 hash of the script, so any changes will require another allowance. + +**\** as argument +: If the executable **update-\** is reachable thought the PATH variable, than this is run. Otherwise, the program will exit. + +# OPTIONS + +**--help**, **-h** +: Displays a help message and exit. + +**--version**, **-v** +: Displays the software version and exit. + +# EXAMPLES + +**fupdate** or **fupdate flake** +: Updates your *flake.lock*. See the Description section for further details. + +**fupdate sys** +: Run the executable **update-sys**, if it exists. See the Description section for further details. + +**fupdate flake sys docs** +: First updates your flake, then, if the command succeeded, runs **update-sys**, afterweich **update-docs** is run. + +# FILES + +*update.sh* +: This is supposed to be a shell script located in your flake base directory, i.e., the directory which contains both a *flake.nix* and a *flake.lock* file. + +*~/.local/share/flake-update/* +: **fupdate** will store the hashes to the allowed *update.sh* files here. + +# BUGS + +Report bugs to . + +# COPYRIGHT + +Copyright (C) 2023 Soispha + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/pkgs/sources/scripts/source/apps/fupdate.sh b/pkgs/sources/scripts/source/apps/fupdate.sh new file mode 100755 index 00000000..4322610a --- /dev/null +++ b/pkgs/sources/scripts/source/apps/fupdate.sh @@ -0,0 +1,197 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +UPDATE_SCRIPT_NAME="update.sh" +CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update" + +# Both are used in version() +# shellcheck disable=SC2034 +AUTHORS="Soispha" +# shellcheck disable=SC2034 +YEARS="2023" + +UPDATE_SCRIPT_NOT_WANTED=false + +# Searches upward for a `UPDATE_SCRIPT_NAME` script +# Returns a path to the script if it exists, otherwise nothing is returned +check_for_update_script() { + dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")" + if [ "$dirname" ]; then + printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME" + fi +} + +# Checks if a given path to the update script is allowed. +# Takes the path as input +# Return 0, if allowed, 1 if not. +check_for_allowed_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + if [ -f "$config_path" ]; then + if [ "$(cat "$config_path")" = "$update_script_hash" ]; then + dbg "Recorded hash matches" + return 0 + else + dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed" + return 1 + fi + else + dbg "Path \'$config_path\' does not exist, assuming not allowed" + return 1 + fi +} + +# Asks the user if they want to allow a given script. +# Takes the path as input +ask_to_allow_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + println "\033[2J" # clear the screen + cat "$update_script" + readp "Do you want to allow this script?[N/y]: " allow + # shellcheck disable=SC2154 + dbg "allow is: $allow" + case "$allow" in + [yY]) + dbg "allowed script" + dbg "storing contents in: $config_path" + mkdir --parents "$(dirname "$config_path")" + print "$update_script_hash" >"$config_path" + ;; + *) + UPDATE_SCRIPT_NOT_ALLOWED=true + ;; + esac +} + +# Runs the provided script and continues to update the nix flake +# Takes the path to the script and the directory to the flake as arguments +# If the path to the update script is empty, it will be ignored +update() { + update_script="$1" + flake_base_dir="$2" + shift 2 + dbg "Provided following args to update script: '$*'" + + cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed" + dbg "changed directory to: $flake_base_dir" + + nix flake update + + if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then + "$update_script" "$@" + fi + + if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then + batgrep '[^0-9]_[0-9]' flake.lock + die "Your flake.nix contains duplicate inputs!" + fi +} + +help() { + cat <] + +OPTIONS: + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. + + --no-script + Avoid running the 'update.sh' script +COMMANDS: + flake + update the flake project + + + runs a executable called "update-", if it exists +EOF +} + +main() { + if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then + update_script="$(check_for_update_script)" + flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir + dbg "update_script is: $update_script" + dbg "flake_base_dir is: $flake_base_dir" + + if [ "$update_script" = "" ]; then + update "" "$flake_base_dir" "$@" + elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then + update "$update_script" "$flake_base_dir" "$@" + else + ask_to_allow_update_script "$update_script" + main "$@" + fi + fi +} + +if [ "$#" -eq 0 ]; then + main + exit 0 +fi + +for input in "$@"; do + case "$input" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + "--no-script" | "-n") + UPDATE_SCRIPT_NOT_WANTED=true + ;; + "--") + end_of_cli_options=true + + # Stop processing args after that marker. + break + ;; + esac + [ "$end_of_cli_options" = "true" ] && break +done + +case "$1" in +"flake") + shift 1 + + # Filter out fupdate specific flags + while [ "$1" != "--" ]; do + # FIXME: This check allows to add a flag multiple times, but this should probably + # not be allowed <2024-03-29> + case "$1" in + "--no-script" | "-n") + shift 1 + ;; + *) + break + ;; + esac + done + + [ "$1" = "--" ] && shift 1 + main "$@" + ;; +*) + command="$1" + shift 1 + [ "$1" = "--" ] && shift 1 + if which update-"$command" >/dev/null 2>&1; then + update-"$command" "$@" + else + die "command \"update-$command\" is not executable, or does not exist" + fi + ;; +esac diff --git a/pkgs/sources/scripts/source/apps/git-edit-index.sh b/pkgs/sources/scripts/source/apps/git-edit-index.sh new file mode 100755 index 00000000..e73dc53c --- /dev/null +++ b/pkgs/sources/scripts/source/apps/git-edit-index.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# needed for help() and version +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2024" +# shellcheck disable=2034 +VERSION="1.0.0" + +# NAME is from the wrapper +# shellcheck disable=SC2269 +NAME="$NAME" + +help() { + cat <"$GIT_DIR/.git/EDIT_INDEX_PATCH" + + git add "$1" + git restore --staged "$1" + cat "$1" >"$GIT_DIR/.git/EDIT_INDEX_FILE" + git restore "$1" + + git apply "$GIT_DIR/.git/EDIT_INDEX_PATCH" + "$EDITOR" "$1" + + git add "$1" + mv "$GIT_DIR/.git/EDIT_INDEX_FILE" "$1" +} + +edit() { + files_to_add="$(mktmp)" + realpath --relative-to=. "$@" >"$files_to_add" + + index_files="$(mktmp)" + git diff --name-only --cached --diff-filter=AM >"$index_files" + + while read -r file; do + if grep -q "$file" "$files_to_add"; then + sed -i "s|$file||" "$files_to_add" + materialize_file "$file" + fi + done <"$index_files" + + files_to_check="$(mktmp)" + clean "$files_to_add" >"$files_to_check" + if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then + warn "Could not edit every file:" + cat "$files_to_add" + fi +} + +for arg in "$@"; do + case "$arg" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + "--") + end_of_cli_options=true + ;; + esac + [ "$end_of_cli_options" = "true" ] && break +done + +edit "$@" + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/small_functions/brightness.sh b/pkgs/sources/scripts/source/small_functions/brightness.sh new file mode 100755 index 00000000..a7272279 --- /dev/null +++ b/pkgs/sources/scripts/source/small_functions/brightness.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +help() { + cat < $BACKLIGHT/brightness" +} + +for arg in "$@"; do + case "$arg" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + esac +done + +case "$1" in +"up") + shift 1 + value="5" + [ -n "$1" ] && value="$1" + brightness "+$value" + ;; +"down") + shift 1 + value="-5" + [ -n "$1" ] && value="$1" + brightness "-$value" + ;; +*) + die "The command '$1' does not exist! See '--help' for a list" + ;; +esac + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/small_functions/nato.py b/pkgs/sources/scripts/source/small_functions/nato.py new file mode 100755 index 00000000..e9d15f56 --- /dev/null +++ b/pkgs/sources/scripts/source/small_functions/nato.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# originally from here: https://cgit.pacien.net/desktop-utilities/ + +import sys + +alphabet = { + "nato": { + "A": "Alfa", # No idea why this is not just 'Alpha' .. + "B": "Bravo", + "C": "Charlie", + "D": "Delta", + "E": "Echo", + "F": "Foxtrot", + "G": "Golf", + "H": "Hotel", + "I": "India", + "J": "Juliett", + "K": "Kilo", + "L": "Lima", + "M": "Mike", + "N": "November", + "O": "Oscar", + "P": "Papa", + "Q": "Quebec", + "R": "Romeo", + "S": "Sierra", + "T": "Tango", + "U": "Uniform", + "V": "Victor", + "W": "Whiskey", + "X": "X-ray", + "Y": "Yankee", + "Z": "Zulu", + "0": "Nadazero", + "1": "Unaone", + "2": "Bissotwo", + "3": "Terrathree", + "4": "Kartefour", + "5": "Pantafive", + "6": "Soxisix", + "7": "Setteseven", + "8": "Oktoeight", + "9": "Novenine", + ",": "Comma", + "/": "Forward slash", + ".": "Stop/Decimal", + }, + "german": { + "A": "Aachen", + "Ä": "Umlaut Aachen", + "B": "Berlin", + "C": "Chemnitz", + "D": "Düsseldorf", + "E": "Essen", + "F": "Frankfurt", + "G": "Goslar", + "H": "Hamburg", + "I": "Ingelheim", + "J": "Jena", + "K": "Köln", + "L": "Leipzig", + "M": "München", + "N": "Nürnberg", + "O": "Offenbach", + "Ö": "Umlaut Offenbach", + "P": "Potsdam", + "Q": "Quickborn", + "R": "Rostock", + "S": "Salzwedel", + "ẞ": "Eszett", + "T": "Tübingen", + "U": "Unna", + "Ü": "Umlaut Unna", + "V": "Völklingen", + "W": "Wuppertal", + "X": "Xanten", + "Y": "Ypsilon", + "Z": "Zwickau", + }, +} + + +def str_to_telephony(phrase, language): + language_alphabet = alphabet[language] + + return [ + language_alphabet[c] if c in language_alphabet else c for c in phrase.upper() + ] + + +language = sys.argv[1] +if language not in ["nato", "german"]: + print( + f"Langugae '{language}' is not a valid language, only 'nato' and 'german' are!", + file=sys.stderr, + ) + exit(1) + +print( + "\n".join( + str_to_telephony( + " ".join(sys.argv[2:]), + language, + ) + ) +) diff --git a/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh b/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh new file mode 100755 index 00000000..4308b8d2 --- /dev/null +++ b/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh @@ -0,0 +1,22 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# only generate a path (this could lead to a time-of-check/time-of-use bug) +tmp="$(mktmp --dry-run)" + +if grim -g "$(slurp)" "$tmp"; then + name="$(rofi -dmenu -p "Name of screenshot: " -l 0)" + screen_shot_path="$HOME/media/pictures/screenshots/$name.png" + while [ -f "$screen_shot_path" ]; do + notify-send "Warning" 'Screenshot name already in use!' + name="$(rofi -dmenu -p "New name of screenshot: " -l 0)" + screen_shot_path="$HOME/media/pictures/screenshots/$name.png" + done + + mv "$tmp" "$screen_shot_path" + alacritty -e lf -command ":{{ set sortby atime; set reverse!; }}" +fi + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh b/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh new file mode 100755 index 00000000..8968ca79 --- /dev/null +++ b/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh @@ -0,0 +1,8 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +grim -g "$(slurp)" | wl-copy + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/small_functions/update-sys.sh b/pkgs/sources/scripts/source/small_functions/update-sys.sh new file mode 100755 index 00000000..d28247f6 --- /dev/null +++ b/pkgs/sources/scripts/source/small_functions/update-sys.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +help() { + cat <] [--help] + +OPTIONS: + --branch | -b BRANCHNAME + select a branch to update from. + + --mode | -m MODE + select a mode to update with + + --help | -h + output this help. +ARGUMENTS: + BRANCHNAME := [[ git branch --list --format '%(refname:short)' ]] + The name of the branch to deploy the config from + + MODE := switch|boot|test|build|dry-build|dry-activate|edit|repl|build-vm|build-vm-with-bootloader + See the 'nixos-rebuild' manpage for more information about these modes. +EOF + exit "$1" +} +default_branch=$(mktmp) +BRANCH="" + +while [ "$#" -gt 0 ]; do + case "$1" in + "--help" | "-h") + help 0 + ;; + "--branch" | "-b") + if [ -n "$2" ]; then + BRANCH="$2" + else + error "$1 requires an argument" + help 1 + fi + shift 2 + ;; + "--mode" | "-m") + if [ -n "$2" ]; then + MODE="$2" + else + error "$1 requires an argument" + help 1 + fi + shift 2 + ;; + *) + error "the option $1 does not exist!" + help 1 + ;; + esac +done + +cd /etc/nixos || die "No /etc/nixos" +msg "Starting system update..." +git remote update origin --prune >/dev/null 2>&1 +if ! [ "$BRANCH" = "" ]; then + git switch "$BRANCH" >/dev/null 2>&1 && msg2 "Switched to branch '$BRANCH'" +fi +msg2 "Updating git repository..." +git pull --rebase + +git remote show origin | grep 'HEAD' | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/ *$//g' >"$default_branch" & + +msg2 "Updating system..." +if [ -n "$MODE" ]; then + nixos-rebuild "$MODE" +else + nixos-rebuild switch +fi + +git switch "$(cat "$default_branch")" >/dev/null 2>&1 && msg2 "Switched to branch '$(cat "$default_branch")'" +msg "Finished Update!" + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh b/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh new file mode 100755 index 00000000..865ecacf --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +context="$(task _get rc.context)" +if [ "$context" ]; then + filter="project:$context" +else + filter="0-10000" +fi +tasks="$(task "$filter" _ids)" + +if [ "$tasks" ]; then + echo "$tasks" | xargs task _zshids | awk -F: -v q="'" '{gsub(/'\''/, q "\\" q q ); print $1 ":" q $2 q}' +fi diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh new file mode 100755 index 00000000..5a830a10 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env dash + +add0open_taskwarrior_project_file() { + task_project_file="%TASK_PROJECT_FILE" + + cd "$(dirname $task_project_file)" || die "BUG: task_project_file ('$task_project_file') can't be accessed" + + git_dir="$(search_flake_base_dir)" + [ "$git_dir" ] || die "(BUG): No git directory?" + cd "$git_dir" || die "Unreachable, this MUST exists" + + nvim "$task_project_file" + git add "$task_project_file" + + base_task_project_file_path="$(awk "{ gsub(\"$git_dir/\", \"\", \$0); print }" "$(ptmp "$task_project_file")")" + git add $task_project_file + + # Check that only the project file has been added (and that our file is actually + # modified) + if git status --porcelain=v2 | awk -v path="$base_task_project_file_path" 'BEGIN { hit = 0 } { if ($2 ~ /A./ || $2 ~ /M./) { if ($NF ~ path) { hit = 1 } else { hit = 0; exit 1 } } } END { if (hit == 1) { exit 0 } else { exit 1 } }'; then + git commit --verbose --message="chore($(dirname "$base_task_project_file_path")): Update" + fi +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh new file mode 100755 index 00000000..7095847d --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env dash + +context0open_current_task_context() { + current_context="$(utils0get_current_context)" + + if [ "$current_context" ]; then + context_path="$(utils0get_current_context_path "$current_context")" + + extended_neorg_project_dir="$(utils0get_neorg_project_dir)" + cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir" + + nvim "$extended_neorg_project_dir/$context_path" + + git add . + git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign + else + warn "No context active" + fi +} + +context0open_current_task_context_at_task_id() { + task_id="$1" + current_context="$(utils0get_current_context)" + + if [ "$current_context" ]; then + context_path="$(utils0get_current_context_path "$current_context")" + extended_neorg_project_dir="$(utils0get_neorg_project_dir)" + task_uuid="$(task "$task_id" uuids)" + + cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir" + + if ! grep -q "% $task_uuid" "$extended_neorg_project_dir/$context_path"; then + echo "* TITLE (% $task_uuid)" >>"$extended_neorg_project_dir/$context_path" + fi + + nvim "$extended_neorg_project_dir/$context_path" -c "/% $task_uuid" + + git add . + git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign + else + warn "No context active" + fi +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh new file mode 100755 index 00000000..5a138982 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env dash + +dmenu0open_context_in_browser() { + project="$(echo "%ALL_PROJECTS_PIPE" | rofi -sep "|" -dmenu)" + + if [ "$project" ]; then + [ -d "%NEORG_REVIEW_PATH" ] || mkdir --parents "%NEORG_REVIEW_PATH" + [ -f "%NEORG_REVIEW_PATH/$project.lock" ] || touch "%NEORG_REVIEW_PATH/$project.lock" + project0open_project_in_browser "$project" + else + notify-send "(neorg/dmenu) No project selected" + exit 1 + fi +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh new file mode 100755 index 00000000..2423dd44 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env dash + +fstart0start_new_task() { + task_id="$1" + fstop0stop_current_task + task start "$task_id" +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh new file mode 100755 index 00000000..e4ff0b94 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env dash + +fstop0stop_current_task() { + # we ensured that only one task may be active + active="$(task +ACTIVE _ids)" + [ "$active" ] && task stop "$active" +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh new file mode 100755 index 00000000..10659457 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env dash + +list0list_all_contexts_newline() { + print "%ALL_PROJECTS_NEWLINE" +} +list0list_all_contexts_comma() { + print "%ALL_PROJECTS_COMMA" +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh new file mode 100755 index 00000000..64591850 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env dash + +project0open_current_context_in_browser() { + current_context="$(utils0get_current_context)" + [ "$current_context" ] || die "No current context to use" + project0open_context_in_browser "$(utils0context2project "$current_context")" +} + +project0open_project_in_browser() { + project="$1" + [ "$project" ] || die "BUG: No context supplied to project0open_context_in_browser" + + old_context="$(utils0get_current_context)" + # We have ensured that only one task may be active + old_started_task="$(task +ACTIVE _ids)" + + tracking="$(mktmp)" + task "project:$project" _ids | xargs --no-run-if-empty task _zshids >"$tracking" + task context "$(utils0project2context "$project")" + + while read -r description; do + desc="$(echo "$description" | awk -F: '{print $2}')" + if [ "$desc" = "tracking" ]; then + task_id="$(echo "$description" | awk -F: '{print $1}')" + notify-send "(Neorg)" "Starting task $project -> $desc" + task start "$task_id" + break + fi + done <"$tracking" + + firefox -P "$project" + + task stop "$task_id" + [ "$old_started_task" ] && task start "$old_started_task" + + if [ "$old_context" ]; then + task context "$old_context" + else + task context none + fi +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh new file mode 100755 index 00000000..a0a9ab8d --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env dash + +review0start() { + for project in $(list0list_all_contexts_newline); do + if [ -f "%NEORG_REVIEW_PATH/$project.lock" ]; then + msg "Reviewing '$project'" + notify-send "Neorg" "Reviewing '$project'" + firefox -P "$project" + rm "%NEORG_REVIEW_PATH/$project.lock" + fi + done +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh new file mode 100755 index 00000000..c3843e8e --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env dash + +# Runs it's first argument and then the second, regardless if the first failed or +# succeeded +utils0chain() { + eval "$1" + eval "$2" +} + +utils0get_current_context() { + current_context="$(task _get rc.context)" + printf "%s\n" "$current_context" +} + +utils0get_current_context_path() { + current_context="$1" + context_path="$(task _get rc.context."$current_context".rc.neorg_path 2>/dev/null)" + if ! [ "$context_path" ]; then + context_path="$(grep "context.$current_context.rc.neorg_path" "%HOME_TASKRC" | awk 'BEGIN {FS="="} {print $2}')" + [ "$context_path" ] || die "All contexts should have a 'neorg_path' set!" + fi + printf "%s\n" "$context_path" +} + +utils0get_neorg_project_dir() { + # Perform shell expansion of Tilde + neorg_project_dir="$(sed "s|^~|$HOME|" "$(ptmp "%DEFAULT_NEORG_PROJECT_DIR")")" + printf "%s\n" "$neorg_project_dir" +} + +utils0project2context() { + project="$1" + context="$(sed 's|\.|_|g' "$(ptmp "$project")")" + printf "%s\n" "$context" +} +utils0context2project() { + context="$1" + project="$(sed 's|_|\.|g' "$(ptmp "$context")")" + printf "%s\n" "$project" +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh new file mode 100755 index 00000000..d5eb2fca --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env dash + +workspace0open_neorg_workspace() { + workspace="$1" + nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace $workspace\n")" +} +workspace0open_neorg_workspace_prompt() { + nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace ")" +} diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/main.sh b/pkgs/sources/scripts/source/specific/neorg/sh/main.sh new file mode 100755 index 00000000..559351b9 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/neorg/sh/main.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# load dependencies +. ./functions/add.sh +. ./functions/context.sh +. ./functions/dmenu.sh +. ./functions/f_start.sh +. ./functions/f_stop.sh +. ./functions/list.sh +. ./functions/project.sh +. ./functions/utils.sh +. ./functions/workspace.sh +. ./functions/review.sh + +# these are used in version() +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2023" + +NAME="neorg" + +help() { + cat <' + + workspace [WS] + The neorg workspace (WS) to open at startup, an empty value drops + you at a prompt to enter the workspace yourself. + + project [P] + Opens the webbrowser with either the context (P) or + the current active context as argument if no context is supplied + + list + Lists all available contexts + + add + Allows you to quickly add projects + + fstart ID + Starts the task (ID) but only after it stooped + the previous active task, if it existed. + + fstop + Stops the current active task + + review + Review all firefox tabs +ARGUMENTS: + ID | *([0-9]) := [[%ID_GENERATION_FUNCTION]] + The function displays all possible IDs of the eligable tasks. + + WS := %ALL_WORKSPACES + All possible workspaces + + P := %ALL_PROJECTS_PIPE + The possible project + +EOF +} + +for arg in "$@"; do + case "$arg" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + esac +done + +while [ "$#" -ne 0 ]; do + case "$1" in + "t"*) # task + shift 1 + task_id="$1" + [ "$task_id" ] || utils0chain context0open_current_task_context "exit 0" + context0open_current_task_context_at_task_id "$task_id" + exit 0 + ;; + "w"*) # workspace + shift 1 + workspace_to_open="$1" + # TODO: Exit with 1 on error, instead of the 0 <2023-10-20> + [ "$workspace_to_open" ] || utils0chain workspace0open_neorg_workspace_prompt "exit 0" + workspace0open_neorg_workspace "$workspace_to_open" + exit 0 + ;; + "p"*) # project + shift 1 + project_to_open="$1" + # TODO: Exit with 1 on error, instead of the 0 <2023-10-20> + [ "$project_to_open" ] || utils0chain project0open_current_context_in_browser "exit 0" + if ! grep -q "$project_to_open" "$(ptmp "%ALL_PROJECTS_NEWLINE")"; then + die "Your project ('$project_to_open') is not in the list of available projects: +%ALL_PROJECTS_COMMA" + fi + project0open_project_in_browser "$project_to_open" + exit 0 + ;; + "l"*) # list + list0list_all_contexts_newline + exit 0 + ;; + "a"*) # add-project + add0open_taskwarrior_project_file + exit 0 + ;; + "d"*) # dmenu + dmenu0open_context_in_browser + exit 0 + ;; + "fsta"*) # fstart + shift 1 + task_id="$1" + [ "$task_id" ] || die "No task id provided to fstart" + fstart0start_new_task "$task_id" + exit 0 + ;; + "fsto"*) # fstop + fstop0stop_current_task + exit 0 + ;; + "r"*) # review + shift 1 + review0start + exit 0 + ;; + *) + die "Command '$1' does not exist! Please look at:\n $NAME --help" + exit 0 + ;; + esac +done + +context0open_current_task_context +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/specific/spodi/sh/download.sh b/pkgs/sources/scripts/source/specific/spodi/sh/download.sh new file mode 100755 index 00000000..fe9746c8 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/spodi/sh/download.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env dash + +download_to_down() { + DOWNLOAD_DIRECTORY="%XDG_MUSIC_DIR/down/spotify" + + already_downloaded_files="$(mktmp)" + fd . "$DOWNLOAD_DIRECTORY" --exclude spotdl.log --exclude spotdl-errors.log >"$already_downloaded_files" + if [ -z "$NO_CHECK" ] && [ "$(wc -l <"$already_downloaded_files")" -ne 0 ]; then + die "something is already downloaded" + fi + # [ -e "$DOWNLOAD_DIRECTORY/spotdl.log" ] && rm "$DOWNLOAD_DIRECTORY/spotdl.log" + + download "$1" "$DOWNLOAD_DIRECTORY" +} + +download() { + download_url="$1" + output_path="$2" + + config="$(mktmp)" + cat <"$config" +# Main options +--audio slider-kz bandcamp youtube-music piped youtube soundcloud +--lyrics genius musixmatch azlyrics synced + +# FFmpeg options +--ffmpeg ffmpeg +--threads 16 +--bitrate 256k + +# Spotify options +--cache-path %XDG_CACHE_HOME/spotdl/.spotipy + +# Output options +--preload +--format opus +--output {artists}_-_{title} +--print-errors +--save-errors $output_path/spotdl-errors.log +# TODO: Reactive whence spotdl support for these has improved <2023-12-19> +# --generate-lrc +--overwrite skip + +# Misc options +--log-level INFO +EOF + + cd "$output_path" || die "BUG: no $output_path" + touch "$output_path/spotdl-errors.log" + + # The sub shell needs to be unquoted, as the arguments may not be treated as one. + # shellcheck disable=2046 + unbuffer spotdl $(cat "$config") download "$download_url" | tee "$output_path/spotdl.log" + + [ -d ~/.spotdl ] && rm -r ~/.spotdl +} + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/specific/spodi/sh/update.sh b/pkgs/sources/scripts/source/specific/spodi/sh/update.sh new file mode 100755 index 00000000..a289cf58 --- /dev/null +++ b/pkgs/sources/scripts/source/specific/spodi/sh/update.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env dash + +update() { + UPDATE_DIRECTORY="%XDG_MUSIC_DIR/artists" + UPDATE_CONFIG_FILE="%XDG_MUSIC_DIR/artists/update.conf" + + if ! [ -f "$UPDATE_CONFIG_FILE" ]; then + error="$( + cat </| + +All comments and empty lines are ignored +EOF + )" + die "$error" + fi + + config_file="$(mktmp)" + clean "$UPDATE_CONFIG_FILE" >"$config_file" + + while IFS="|" read -r artist url; do + full_artist="$UPDATE_DIRECTORY/$artist" + [ -d "$full_artist" ] || mkdir --parents "$full_artist" + [ -d "$full_artist/update" ] || mkdir --parents "$full_artist/update" + [ -d "$full_artist/all" ] || mkdir --parents "$full_artist/all" + [ -d "$full_artist/filtered" ] || mkdir --parents "$full_artist/filtered" + + while read -r file; do + ln --symbolic --relative "$file" "$full_artist/update/$(basename "$file")" + done <"$(tmp fd --type file --extension opus . "$full_artist/all")" + + msg2 "Updating $artist with url: '$url'" + download "$url" "$full_artist/update" + + while read -r file; do + mv "$file" "$full_artist/all" + ln --symbolic --relative "$full_artist/all/$(basename "$file")" "$full_artist/filtered/$(basename "$file")" + done <"$(tmp fd --type file --extension opus . "$full_artist/update")" + + while read -r file; do + rm "$file" + done <"$(tmp fd --type symlink --extension opus . "$full_artist/update")" + + cp "$full_artist/update/spotdl.log" "$full_artist/all/spotdl.$(date +%Y_%m_%d).log" + cp "$full_artist/update/spotdl-errors.log" "$full_artist/all/spotdl-errors.$(date +%Y_%m_%d).log" + done <"$config_file" +} + +# vim: ft=sh diff --git a/pkgs/sources/scripts/source/specific/spodi/spodi.sh b/pkgs/sources/scripts/source/specific/spodi/spodi.sh new file mode 100755 index 00000000..475fd48a --- /dev/null +++ b/pkgs/sources/scripts/source/specific/spodi/spodi.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# these are used in version() +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2023" + +# load dependencies +. ./sh/update.sh +. ./sh/download.sh + +help() { + cat <>"$tmp"; done +[ "$(wc -l "$tmp" | awk '{print $1}')" -gt 2 ] && die "something is already downloaded" + +cat <"$config" +--paths home:"$DOWN_DIR" +#--output %(fulltitle) +--restrict-filenames +--no-overwrites +--no-write-info-json +--clean-info-json +--prefer-free-formats +#--format mp3 +--extract-audio +--audio-quality 0 +--audio-format best +EO + +rm "$DOWN_DIR/yt-dlp.log" +cd "$DOWN_DIR" || die "BUG: no $DOWN_DIR" + +unbuffer yt-dlp --config-location "$config" "$1" | tee "$DOWN_DIR/yt-dlp.log" + +# vim: ft=sh diff --git a/pkgs/sources/snap-sync-forked/default.nix b/pkgs/sources/snap-sync-forked/default.nix new file mode 100644 index 00000000..5b086a5a --- /dev/null +++ b/pkgs/sources/snap-sync-forked/default.nix @@ -0,0 +1,24 @@ +{sysLib}: [ + (final: prev: { + snap-sync-forked = sysLib.writeShellScript { + name = "snap-sync-forked"; + src = ./snap-sync-forked.sh; + dependencies = with prev; [ + bash + btrfs-progs + coreutils + gawk + gnugrep + snapper + util-linux + + # optional: + libnotify + openssh + pv + rsync + sudo + ]; + }; + }) +] diff --git a/pkgs/sources/snap-sync-forked/snap-sync-forked.sh b/pkgs/sources/snap-sync-forked/snap-sync-forked.sh new file mode 100755 index 00000000..3d9c1ac9 --- /dev/null +++ b/pkgs/sources/snap-sync-forked/snap-sync-forked.sh @@ -0,0 +1,534 @@ +#!/usr/bin/env bash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# +# snap-sync +# https://github.com/wesbarnett/snap-sync +# Copyright (C) 2016-2021 Wes Barnett + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., + +# ------------------------------------------------------------------------- + +# Takes snapshots of each snapper configuration. It then sends the snapshot to +# a location on an external drive. After the initial transfer, it does +# incremental snapshots on later calls. It's important not to delete the +# snapshot created on your system since that will be used to determine the +# difference for the next incremental snapshot. + +set -o errtrace + +version="0.7" +name="snap-sync" + +printf "\nsnap-sync version %s, Copyright (C) 2016-2021 Wes Barnett\n" "$version" +printf "snap-sync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the license for more information. \n\n" + +# The following line is modified by the Makefile or +# find_snapper_config script +SNAPPER_CONFIG=/etc/sysconfig/snapper + +donotify=0 +if ! command -v notify-send &>/dev/null; then + donotify=1 +fi + +doprogress=0 +if ! command -v pv &>/dev/null; then + doprogress=1 +fi + +error() { + printf "==> ERROR: %s\n" "$@" + notify_error 'Error' 'Check journal for more information.' +} >&2 + +die() { + error "$@" + exit 1 +} + +traperror() { + printf "Exited due to error on line %s.\n" "$1" + printf "exit status: %s\n" "$2" + printf "command: %s\n" "$3" + printf "bash line: %s\n" "$4" + printf "function name: %s\n" "$5" + exit 1 +} + +trapkill() { + die "Exited due to user intervention." +} + +trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCNAME[@]}"' ERR +trap trapkill SIGTERM SIGINT + +usage() { + cat < snapper configuration to backup + -d, --description snapper description + -h, --help print this message + -n, --noconfirm do not ask for confirmation + -k, --keepold keep old incremental snapshots instead of deleting them + after backup is performed + -p, --port remote port; used with '--remote'. + -q, --quiet do not send notifications; instead print them. + -r, --remote
ip address of a remote machine to backup to + --sudo use sudo on the remote machine + -s, --subvolid subvolume id of the mounted BTRFS subvolume to back up to + -u, --UUID UUID of the mounted BTRFS subvolume to back up to + +See 'man snap-sync' for more details. +EOF +} + +ssh="" +sudo=0 +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -d | --description) + description="$2" + shift 2 + ;; + -c | --config) + selected_configs="$2" + shift 2 + ;; + -u | --UUID) + uuid_cmdline="$2" + shift 2 + ;; + -s | --subvolid) + subvolid_cmdline="$2" + shift 2 + ;; + -k | --keepold) + keep="yes" + shift + ;; + -n | --noconfirm) + noconfirm="yes" + shift + ;; + -h | --help) + usage + exit 1 + ;; + -q | --quiet) + donotify=1 + shift + ;; + -r | --remote) + remote=$2 + shift 2 + ;; + -p | --port) + port=$2 + shift 2 + ;; + --sudo) + sudo=1 + shift + ;; + *) + die "Unknown option: '$key'. Run '$name -h' for valid options." + ;; + esac +done + +notify() { + for u in $(users | tr ' ' '\n' | sort -u); do + sudo -u "$u" DISPLAY=:0 \ + DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(sudo -u "$u" id -u)/bus" \ + notify-send -a $name "$1" "$2" --icon="dialog-$3" + done +} + +notify_info() { + if [[ $donotify -eq 0 ]]; then + notify "$1" "$2" "information" + else + printf '%s\n' "$1: $2" + fi +} + +notify_error() { + if [[ $donotify -eq 0 ]]; then + notify "$1" "$2" "error" + else + printf '%s\n' "$1: $2" + fi +} + +[[ $EUID -ne 0 ]] && die "Script must be run as root. See '$name -h' for a description of options" +! [[ -f $SNAPPER_CONFIG ]] && die "$SNAPPER_CONFIG does not exist." + +description=${description:-"latest incremental backup"} +uuid_cmdline=${uuid_cmdline:-"none"} +subvolid_cmdline=${subvolid_cmdline:-"5"} +noconfirm=${noconfirm:-"no"} + +if [[ -z $remote ]]; then + if ! command -v rsync &>/dev/null; then + die "--remote specified but rsync command not found" + fi +fi + +if [[ $uuid_cmdline != "none" ]]; then + if [[ -z $remote ]]; then + notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid=$subvolid_cmdline..." + else + notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid $subvolid_cmdline at $remote..." + fi +else + if [[ -z $remote ]]; then + notify_info "Backup started" "Starting backups. Use command line menu to select disk." + else + notify_info "Backup started" "Starting backups. Use command line menu to select disk on $remote." + fi +fi + +if [[ -n $remote ]]; then + ssh="ssh $remote" + if [[ -n $port ]]; then + ssh="$ssh -p $port" + fi + if [[ $sudo -eq 1 ]]; then + ssh="$ssh sudo" + fi +fi + +if [[ "$($ssh findmnt -n -v --target / -o FSTYPE)" == "btrfs" ]]; then + EXCLUDE_UUID=$($ssh findmnt -n -v -t btrfs --target / -o UUID) + TARGETS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $2}') + UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $1}') +else + TARGETS=$($ssh findmnt -n -v -t btrfs -o TARGET --list) + UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID --list) +fi + +declare -a TARGETS_ARRAY +declare -a UUIDS_ARRAY +declare -a SUBVOLIDS_ARRAY + +i=0 +for x in $TARGETS; do + SUBVOLIDS_ARRAY[i]=$($ssh btrfs subvolume show "$x" | awk '/Subvolume ID:/ { print $3 }') + TARGETS_ARRAY[i]=$x + i=$((i + 1)) +done + +i=0 +disk=-1 +disk_count=0 +for x in $UUIDS; do + UUIDS_ARRAY[i]=$x + if [[ $x == "$uuid_cmdline" && ${SUBVOLIDS_ARRAY[$((i))]} == "$subvolid_cmdline" ]]; then + disk=$i + disk_count=$((disk_count + 1)) + fi + i=$((i + 1)) +done + +if [[ ${#UUIDS_ARRAY[$@]} -eq 0 ]]; then + die "No external btrfs subvolumes found to backup to. Run '$name -h' for more options." +fi + +if [[ $disk_count -gt 1 ]]; then + printf "Multiple mount points were found with UUID %s and subvolid %s.\n" "$uuid_cmdline" "$subvolid_cmdline" + disk="-1" +fi + +if [[ $disk == -1 ]]; then + if [[ $disk_count == 0 && $uuid_cmdline != "none" ]]; then + error "A device with UUID $uuid_cmdline and subvolid $subvolid_cmdline was not found to be mounted, or it is not a BTRFS device." + fi + if [[ -z $ssh ]]; then + printf "Select a mounted BTRFS device on your local machine to backup to.\nFor more options, exit and run '%s -h'.\n" "$name" + else + printf "Select a mounted BTRFS device on %s to backup to.\nFor more options, exit and run '%s -h'.\n" "$remote" "$name" + fi + while [[ $disk -lt 0 || $disk -gt $i ]]; do + for x in "${!TARGETS_ARRAY[@]}"; do + printf "%4s) %s (uuid=%s, subvolid=%s)\n" "$((x + 1))" "${TARGETS_ARRAY[$x]}" "${UUIDS_ARRAY[$x]}" "${SUBVOLIDS_ARRAY[$x]}" + done + printf "%4s) Exit\n" "0" + read -e -r -p "Enter a number: " disk + if ! [[ $disk == ?(-)+([0-9]) ]] || [[ $disk -lt 0 || $disk -gt $i ]]; then + printf "\nNo disk selected. Select a disk to continue.\n" + disk=-1 + fi + done + if [[ $disk == 0 ]]; then + exit 0 + fi + disk=$((disk - 1)) +fi + +selected_subvolid="${SUBVOLIDS_ARRAY[$((disk))]}" +selected_uuid="${UUIDS_ARRAY[$((disk))]}" +selected_mnt="${TARGETS_ARRAY[$((disk))]}" +printf "\nYou selected the disk with uuid=%s, subvolid=%s.\n" "$selected_uuid" "$selected_subvolid" +if [[ -z $ssh ]]; then + printf "The disk is mounted at '%s'.\n" "$selected_mnt" +else + printf "The disk is mounted at '%s:%s'.\n" "$remote" "$selected_mnt" +fi + +# shellcheck source=/dev/null +source "$SNAPPER_CONFIG" + +if [[ -z $selected_configs ]]; then + printf "\nInteractively cycling through all snapper configurations...\n" +fi +selected_configs=${selected_configs:-$SNAPPER_CONFIGS} + +declare -a BACKUPDIRS_ARRAY +declare -a MYBACKUPDIR_ARRAY +declare -a OLD_NUM_ARRAY +declare -a OLD_SNAP_ARRAY +declare -a NEW_NUM_ARRAY +declare -a NEW_SNAP_ARRAY +declare -a NEW_INFO_ARRAY +declare -a BACKUPLOC_ARRAY +declare -a CONT_BACKUP_ARRAY + +# Initial configuration of where backup directories are +i=0 +for x in $selected_configs; do + + if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {cnt++} END {print cnt}')" -gt 1 ]]; then + error "More than one snapper entry found with UUID $selected_uuid subvolid $selected_subvolid for configuration $x. Skipping configuration $x." + continue + fi + + if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'$name' backup in progress/ {cnt++} END {print cnt}')" -gt 0 ]]; then + printf "\nNOTE: Previous failed %s backup snapshots found for '%s'.\n" "$name" "$x" + if [[ $noconfirm == "yes" ]]; then + printf "'noconfirm' option passed. Failed backups will not be deleted.\n" + else + read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N]? " delete_failed + while [[ -n $delete_failed && $delete_failed != [Yy]"es" && + $delete_failed != [Yy] && $delete_failed != [Nn]"o" && + $delete_failed != [Nn] ]]; do + read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N] " delete_failed + if [[ -n $delete_failed && $delete_failed != [Yy]"es" && + $delete_failed != [Yy] && $delete_failed != [Nn]"o" && + $delete_failed != [Nn] ]]; then + printf "Select 'y' or 'N'.\n" + fi + done + if [[ $delete_failed == [Yy]"es" || $delete_failed == [Yy] ]]; then + # explicit split list of snapshots (on whitespace) into multiple arguments + # shellcheck disable=SC2046 + snapper -c "$x" delete $(snapper -c "$x" list --disable-used-space | awk '/'$name' backup in progress/ {print $1}') + fi + fi + fi + + SNAP_SYNC_EXCLUDE=no + + if [[ -f "/etc/snapper/configs/$x" ]]; then + # shellcheck source=/dev/null + source "/etc/snapper/configs/$x" + else + die "Selected snapper configuration $x does not exist." + fi + + if [[ $SNAP_SYNC_EXCLUDE == "yes" ]]; then + continue + fi + + printf "\n" + + old_num=$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $1}') + old_snap=$SUBVOLUME/.snapshots/$old_num/snapshot + + OLD_NUM_ARRAY[i]=$old_num + OLD_SNAP_ARRAY[i]=$old_snap + + if [[ -z $old_num ]]; then + printf "No backups have been performed for '%s' on this disk.\n" "$x" + read -e -r -p "Enter name of subvolume to store backups, relative to $selected_mnt (to be created if not existing): " mybackupdir + printf "This will be the initial backup for snapper configuration '%s' to this disk. This could take awhile.\n" "$x" + BACKUPDIR="$selected_mnt/$mybackupdir" + $ssh test -d "$BACKUPDIR" || $ssh btrfs subvolume create "$BACKUPDIR" + else + mybackupdir=$(snapper -c "$x" list --disable-used-space -t single | awk -F"|" '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $5}' | awk -F "," '/backupdir/ {print $1}' | awk -F"=" '{print $2}') + BACKUPDIR="$selected_mnt/$mybackupdir" + $ssh test -d "$BACKUPDIR" || die "%s is not a directory on %s.\n" "$BACKUPDIR" "$selected_uuid" + fi + BACKUPDIRS_ARRAY[i]="$BACKUPDIR" + MYBACKUPDIR_ARRAY[i]="$mybackupdir" + + printf "Creating new local snapshot for '%s' configuration...\n" "$x" + new_num=$(snapper -c "$x" create --print-number -d "$name backup in progress") + new_snap=$SUBVOLUME/.snapshots/$new_num/snapshot + new_info=$SUBVOLUME/.snapshots/$new_num/info.xml + sync + backup_location=$BACKUPDIR/$x/$new_num/ + if [[ -z $ssh ]]; then + printf "Will backup %s to %s\n" "$new_snap" "$backup_location/snapshot" + else + printf "Will backup %s to %s\n" "$new_snap" "$remote":"$backup_location/snapshot" + fi + + if ($ssh test -d "$backup_location/snapshot"); then + printf "WARNING: Backup directory '%s' already exists. This configuration will be skipped!\n" "$backup_location/snapshot" + printf "Move or delete destination directory and try backup again.\n" + fi + + NEW_NUM_ARRAY[i]="$new_num" + NEW_SNAP_ARRAY[i]="$new_snap" + NEW_INFO_ARRAY[i]="$new_info" + BACKUPLOC_ARRAY[i]="$backup_location" + + cont_backup="K" + CONT_BACKUP_ARRAY[i]="yes" + if [[ $noconfirm == "yes" ]]; then + cont_backup="yes" + else + while [[ -n $cont_backup && $cont_backup != [Yy]"es" && + $cont_backup != [Yy] && $cont_backup != [Nn]"o" && + $cont_backup != [Nn] ]]; do + read -e -r -p "Proceed with backup of '$x' configuration [Y/n]? " cont_backup + if [[ -n $cont_backup && $cont_backup != [Yy]"es" && + $cont_backup != [Yy] && $cont_backup != [Nn]"o" && + $cont_backup != [Nn] ]]; then + printf "Select 'Y' or 'n'.\n" + fi + done + fi + + if [[ $cont_backup != [Yy]"es" && $cont_backup != [Yy] && -n $cont_backup ]]; then + CONT_BACKUP_ARRAY[i]="no" + printf "Not backing up '%s' configuration.\n" "$x" + snapper -c "$x" delete "$new_num" + fi + + i=$((i + 1)) + +done + +# Actual backing up +printf "\nPerforming backups...\n" +i=-1 +for x in $selected_configs; do + + i=$((i + 1)) + + SNAP_SYNC_EXCLUDE=no + + if [[ -f "/etc/snapper/configs/$x" ]]; then + # shellcheck source=/dev/null + source "/etc/snapper/configs/$x" + else + die "Selected snapper configuration $x does not exist." + fi + + cont_backup=${CONT_BACKUP_ARRAY[$i]} + if [[ $cont_backup == "no" || $SNAP_SYNC_EXCLUDE == "yes" ]]; then + notify_info "Backup in progress" "NOTE: Skipping $x configuration." + continue + fi + + notify_info "Backup in progress" "Backing up $x configuration." + + printf "\n" + + old_num="${OLD_NUM_ARRAY[$i]}" + old_snap="${OLD_SNAP_ARRAY[$i]}" + BACKUPDIR="${BACKUPDIRS_ARRAY[$i]}" + mybackupdir="${MYBACKUPDIR_ARRAY[$i]}" + new_num="${NEW_NUM_ARRAY[$i]}" + new_snap="${NEW_SNAP_ARRAY[$i]}" + new_info="${NEW_INFO_ARRAY[$i]}" + backup_location="${BACKUPLOC_ARRAY[$i]}" + + if ($ssh test -d "$backup_location/snapshot"); then + printf "ERROR: Backup directory '%s' already exists. Skipping backup of this configuration!\n" "$backup_location/snapshot" + continue + fi + + $ssh mkdir -p "$backup_location" + + if [[ -z $old_num ]]; then + printf "Sending first snapshot for '%s' configuration...\n" "$x" + if [[ $doprogress -eq 0 ]]; then + btrfs send "$new_snap" | pv | $ssh btrfs receive "$backup_location" &>/dev/null + else + btrfs send "$new_snap" | $ssh btrfs receive "$backup_location" &>/dev/null + fi + else + + printf "Sending incremental snapshot for '%s' configuration...\n" "$x" + # Sends the difference between the new snapshot and old snapshot to the + # backup location. Using the -c flag instead of -p tells it that there + # is an identical subvolume to the old snapshot at the receiving + # location where it can get its data. This helps speed up the transfer. + + if [[ $doprogress -eq 0 ]]; then + btrfs send -c "$old_snap" "$new_snap" | pv | $ssh btrfs receive "$backup_location" + else + btrfs send -c "$old_snap" "$new_snap" | $ssh btrfs receive "$backup_location" + fi + + if [[ $keep == "yes" ]]; then + printf "Modifying data for old local snapshot for '%s' configuration...\n" "$x" + snapper -v -c "$x" modify -d "old snap-sync snapshot (you may remove)" -u "backupdir=,subvolid=,uuid=" -c "number" "$old_num" + else + printf "Deleting old snapshot for %s...\n" "$x" + snapper -c "$x" delete "$old_num" + fi + + fi + + if [[ -z $remote ]]; then + cp "$new_info" "$backup_location" + else + if [[ -z $port ]]; then + rsync -avzq "$new_info" "$remote":"$backup_location" + else + rsync -avzqe "ssh -p $port" "$new_info" "$remote":"$backup_location" + fi + fi + + # It's important not to change this userdata in the snapshots, since that's how + # we find the previous one. + + userdata="backupdir=$mybackupdir, subvolid=$selected_subvolid, uuid=$selected_uuid" + + # Tag new snapshot as the latest + printf "Tagging local snapshot as latest backup for '%s' configuration...\n" "$x" + snapper -v -c "$x" modify -d "$description" -u "$userdata" "$new_num" + + printf "Backup complete for '%s' configuration.\n" "$x" + +done + +printf "\nDone!\n" + +if [[ $uuid_cmdline != "none" ]]; then + notify_info "Finished" "Backups to $uuid_cmdline complete!" +else + notify_info "Finished" "Backups complete!" +fi diff --git a/pkgs/sources/tree-sitter-yts/.editorconfig b/pkgs/sources/tree-sitter-yts/.editorconfig new file mode 100644 index 00000000..919c78fa --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/.editorconfig @@ -0,0 +1,21 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = false + +# for testing purposes, the corpus may have trailing whitespace +# and may have mixed EOL. +# Still want a final newline though, as that makes no semantic difference. +[corpus/*] +trim_trailing_whitespace = false +end_of_line = unset + +[**.{js,json,cc,css}] +indent_style = space +indent_size = 2 + +# tree-sitter generate emits json with no trailing newline +[src/node-types.json] +insert_final_newline = false diff --git a/pkgs/sources/tree-sitter-yts/.envrc b/pkgs/sources/tree-sitter-yts/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/.envrc @@ -0,0 +1 @@ +use flake diff --git a/pkgs/sources/tree-sitter-yts/.gitignore b/pkgs/sources/tree-sitter-yts/.gitignore new file mode 100644 index 00000000..c4e2e389 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/.gitignore @@ -0,0 +1,3 @@ +/.direnv +/result +/node_modules diff --git a/pkgs/sources/tree-sitter-yts/Cargo.toml b/pkgs/sources/tree-sitter-yts/Cargo.toml new file mode 100644 index 00000000..5287c420 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "tree-sitter-yts" +description = "yts grammar for the tree-sitter parsing library" +version = "0.0.1" +keywords = ["incremental", "parsing", "yts"] +categories = ["parsing", "text-editors"] +repository = "https://github.com/tree-sitter/tree-sitter-yts" +edition = "2018" +license = "MIT" + +build = "bindings/rust/build.rs" +include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"] + +[lib] +path = "bindings/rust/lib.rs" + +[dependencies] +tree-sitter = "~0.20.10" + +[build-dependencies] +cc = "1.0" diff --git a/pkgs/sources/tree-sitter-yts/binding.gyp b/pkgs/sources/tree-sitter-yts/binding.gyp new file mode 100644 index 00000000..b05038b4 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/binding.gyp @@ -0,0 +1,19 @@ +{ + "targets": [ + { + "target_name": "tree_sitter_yts_binding", + "include_dirs": [ + " + +using namespace v8; + +extern "C" TSLanguage *tree_sitter_yts (); + +namespace +{ + +NAN_METHOD (New) {} + +void +Init (Local exports, Local module) +{ + Local tpl = Nan::New (New); + tpl->SetClassName (Nan::New ("Language").ToLocalChecked ()); + tpl->InstanceTemplate ()->SetInternalFieldCount (1); + + Local constructor = Nan::GetFunction (tpl).ToLocalChecked (); + Local instance + = constructor->NewInstance (Nan::GetCurrentContext ()).ToLocalChecked (); + Nan::SetInternalFieldPointer (instance, 0, tree_sitter_yts ()); + + Nan::Set (instance, Nan::New ("name").ToLocalChecked (), + Nan::New ("yts").ToLocalChecked ()); + Nan::Set (module, Nan::New ("exports").ToLocalChecked (), instance); +} + +NODE_MODULE (tree_sitter_yts_binding, Init) + +} // namespace diff --git a/pkgs/sources/tree-sitter-yts/bindings/node/index.js b/pkgs/sources/tree-sitter-yts/bindings/node/index.js new file mode 100644 index 00000000..32179742 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/bindings/node/index.js @@ -0,0 +1,19 @@ +try { + module.exports = require("../../build/Release/tree_sitter_yts_binding"); +} catch (error1) { + if (error1.code !== "MODULE_NOT_FOUND") { + throw error1; + } + try { + module.exports = require("../../build/Debug/tree_sitter_yts_binding"); + } catch (error2) { + if (error2.code !== "MODULE_NOT_FOUND") { + throw error2; + } + throw error1; + } +} + +try { + module.exports.nodeTypeInfo = require("../../src/node-types.json"); +} catch (_) {} diff --git a/pkgs/sources/tree-sitter-yts/bindings/rust/build.rs b/pkgs/sources/tree-sitter-yts/bindings/rust/build.rs new file mode 100644 index 00000000..c6061f09 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/bindings/rust/build.rs @@ -0,0 +1,40 @@ +fn main() { + let src_dir = std::path::Path::new("src"); + + let mut c_config = cc::Build::new(); + c_config.include(&src_dir); + c_config + .flag_if_supported("-Wno-unused-parameter") + .flag_if_supported("-Wno-unused-but-set-variable") + .flag_if_supported("-Wno-trigraphs"); + let parser_path = src_dir.join("parser.c"); + c_config.file(&parser_path); + + // If your language uses an external scanner written in C, + // then include this block of code: + + /* + let scanner_path = src_dir.join("scanner.c"); + c_config.file(&scanner_path); + println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + */ + + c_config.compile("parser"); + println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); + + // If your language uses an external scanner written in C++, + // then include this block of code: + + /* + let mut cpp_config = cc::Build::new(); + cpp_config.cpp(true); + cpp_config.include(&src_dir); + cpp_config + .flag_if_supported("-Wno-unused-parameter") + .flag_if_supported("-Wno-unused-but-set-variable"); + let scanner_path = src_dir.join("scanner.cc"); + cpp_config.file(&scanner_path); + cpp_config.compile("scanner"); + println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + */ +} diff --git a/pkgs/sources/tree-sitter-yts/bindings/rust/lib.rs b/pkgs/sources/tree-sitter-yts/bindings/rust/lib.rs new file mode 100644 index 00000000..f1868b2d --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/bindings/rust/lib.rs @@ -0,0 +1,52 @@ +//! This crate provides yts language support for the [tree-sitter][] parsing library. +//! +//! Typically, you will use the [language][language func] function to add this language to a +//! tree-sitter [Parser][], and then use the parser to parse some code: +//! +//! ``` +//! let code = ""; +//! let mut parser = tree_sitter::Parser::new(); +//! parser.set_language(tree_sitter_yts::language()).expect("Error loading yts grammar"); +//! let tree = parser.parse(code, None).unwrap(); +//! ``` +//! +//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html +//! [language func]: fn.language.html +//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html +//! [tree-sitter]: https://tree-sitter.github.io/ + +use tree_sitter::Language; + +extern "C" { + fn tree_sitter_yts() -> Language; +} + +/// Get the tree-sitter [Language][] for this grammar. +/// +/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html +pub fn language() -> Language { + unsafe { tree_sitter_yts() } +} + +/// The content of the [`node-types.json`][] file for this grammar. +/// +/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types +pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json"); + +// Uncomment these to include any queries that this grammar contains + +// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm"); +// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm"); +// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm"); +// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm"); + +#[cfg(test)] +mod tests { + #[test] + fn test_can_load_grammar() { + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(super::language()) + .expect("Error loading yts language"); + } +} diff --git a/pkgs/sources/tree-sitter-yts/corpus/comments.txt b/pkgs/sources/tree-sitter-yts/corpus/comments.txt new file mode 100644 index 00000000..0070baf8 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/corpus/comments.txt @@ -0,0 +1,51 @@ +================================================================================ +Parse multiple lines +================================================================================ + +pick 6221 "Name" "2024-01-17" "A" "[0m 0s]" "url" +pick 6181 "Name2" "2024-01-16" "A2" "[0m 0s]" "url" + +# This is a comment +# it contains information + +-------------------------------------------------------------------------------- + +(source_file + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (comment) + (comment)) diff --git a/pkgs/sources/tree-sitter-yts/corpus/comments_correct.txt b/pkgs/sources/tree-sitter-yts/corpus/comments_correct.txt new file mode 100644 index 00000000..40cdab7d --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/corpus/comments_correct.txt @@ -0,0 +1,27 @@ +================================================================================ +Disregard comments in title +================================================================================ + +pick 6094 "#100 Name" "2024-01-12" "A" "[133m 29s]" "url" + +-------------------------------------------------------------------------------- + +(source_file + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote)))) diff --git a/pkgs/sources/tree-sitter-yts/corpus/duration.txt b/pkgs/sources/tree-sitter-yts/corpus/duration.txt new file mode 100644 index 00000000..59476b98 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/corpus/duration.txt @@ -0,0 +1,84 @@ +================================================================================ +Parse multiple lines with different durations +================================================================================ + +pick 6221 "Name" "2024-01-17" "A" "[1h 0m]" "url" +pick 6181 "Name2" "2024-01-16" "A2" "[20m 02s]" "url2" +pick 6184 "Name3" "2024-01-16" "A3" "[20h 0m]" "url3" +pick 6206 "Name4" "2024-01-16" "A4" "[No Duration]" "url4" + +-------------------------------------------------------------------------------- + +(source_file + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote)))) diff --git a/pkgs/sources/tree-sitter-yts/corpus/url.txt b/pkgs/sources/tree-sitter-yts/corpus/url.txt new file mode 100644 index 00000000..1ae3d106 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/corpus/url.txt @@ -0,0 +1,84 @@ +================================================================================ +Parse multiple lines with url +================================================================================ + +pick 6221 "Name" "2024-01-17" "A" "[0h 0m]" "url" +pick 6181 "Name2" "2024-01-16" "A2" "[0h 0m]" "url2" +pick 6184 "Name3" "2024-01-16" "A3" "[0h 0m]" "url3" +pick 6206 "Name4" "2024-01-16" "A4" "[0h 0m]" "url4" + +-------------------------------------------------------------------------------- + +(source_file + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote))) + (line + (command) + (id) + (title + (quote) + (quote)) + (date + (quote) + (quote)) + (author + (quote) + (quote)) + (duration + (quote) + (quote)) + (url + (quote) + (quote)))) diff --git a/pkgs/sources/tree-sitter-yts/default.nix b/pkgs/sources/tree-sitter-yts/default.nix new file mode 100644 index 00000000..7e15481c --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/default.nix @@ -0,0 +1,11 @@ +[ + ( + final: prev: { + yts-grammar = (prev.callPackage ./package.nix {}) { + language = "yts"; + version = "1.0"; + src = ./.; + }; + } + ) +] diff --git a/pkgs/sources/tree-sitter-yts/flake.lock b/pkgs/sources/tree-sitter-yts/flake.lock new file mode 100644 index 00000000..bff9f1fa --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/flake.lock @@ -0,0 +1,97 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": ["nixpkgs"] + }, + "locked": { + "lastModified": 1704819371, + "narHash": "sha256-oFUfPWrWGQTZaCM3byxwYwrMLwshDxVGOrMH5cVP/X8=", + "owner": "ipetkov", + "repo": "crane", + "rev": "5c234301a1277e4cc759c23a2a7a00a06ddd7111", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1705133751, + "narHash": "sha256-rCIsyE80jgiOU78gCWN3A0wE0tR2GI5nH6MlS+HaaSQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9b19f5e77dd906cb52dade0b7bd280339d2a1f3d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "npmlock2nix": { + "flake": false, + "locked": { + "lastModified": 1673447413, + "narHash": "sha256-sJM82Sj8yfQYs9axEmGZ9Evzdv/kDcI9sddqJ45frrU=", + "owner": "nix-community", + "repo": "npmlock2nix", + "rev": "9197bbf397d76059a76310523d45df10d2e4ca81", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "npmlock2nix", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "npmlock2nix": "npmlock2nix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/tree-sitter-yts/flake.nix b/pkgs/sources/tree-sitter-yts/flake.nix new file mode 100644 index 00000000..1b6f8ab0 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/flake.nix @@ -0,0 +1,82 @@ +{ + description = "tree-sitter-yts"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-utils.url = "github:numtide/flake-utils"; + + npmlock2nix = { + url = "github:nix-community/npmlock2nix"; + flake = false; + }; + + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + npmlock2nix, + crane, + }: (flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs) lib; + + npmlock2nix' = pkgs.callPackage npmlock2nix {}; + craneLib = crane.lib.${system}; + in { + build = self.packages.${system}.tree-sitter-nix; + + rust-bindings = craneLib.buildPackage { + src = self; + }; + + # Requires xcode + node-bindings = npmlock2nix'.v2.build { + src = self; + inherit (self.devShells.${system}.default) nativeBuildInputs; + inherit (pkgs) nodejs; + + buildCommands = [ + "${pkgs.nodePackages.node-gyp}/bin/node-gyp configure" + "npm run build" + ]; + + installPhase = '' + touch $out + ''; + }; + + packages.tree-sitter-yts = (pkgs.callPackage ./grammar.nix {}) { + language = "yts"; + version = "1.0"; + src = self; + }; + + packages.default = self.packages.${system}.tree-sitter-yts; + devShells.default = pkgs.mkShell { + packages = [ + pkgs.nodejs + pkgs.python3 + + pkgs.tree-sitter + pkgs.editorconfig-checker + + pkgs.rustc + pkgs.cargo + + # Formatters + pkgs.treefmt + pkgs.nixpkgs-fmt + pkgs.nodePackages.prettier + pkgs.rustfmt + pkgs.clang-tools + ]; + }; + })); +} diff --git a/pkgs/sources/tree-sitter-yts/grammar.js b/pkgs/sources/tree-sitter-yts/grammar.js new file mode 100644 index 00000000..655f6dea --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/grammar.js @@ -0,0 +1,26 @@ +module.exports = grammar({ + name: "yts", + + rules: { + source_file: ($) => repeat(choice($.line, $.comment)), + line: ($) => + seq($.command, $.id, $.title, $.date, $.author, $.duration, $.url, "\n"), + + command: ($) => choice("pick", "p", "watch", "w", "drop", "d", "url", "u"), + id: ($) => /[0-9]+/, + title: ($) => seq($._q, /[^"]+/, $._q), + date: ($) => seq($._q, /\d{4}-\d{2}-\d{2}/, $._q), + author: ($) => seq($._q, /[^"]+/, $._q), + duration: ($) => + seq( + $._q, + seq("[", choice("No Duration", /\d+m \d+s/, /\d+h \d+m/), "]"), + $._q, + ), + url: ($) => seq($._q, /[^"]+/, $._q), + comment: ($) => /#.*/, + _q: ($) => $.quote, + quote: ($) => /"/, + }, + extras: ($) => [/\s/, /\\\r?\n/], +}); diff --git a/pkgs/sources/tree-sitter-yts/highlight.yts b/pkgs/sources/tree-sitter-yts/highlight.yts new file mode 100644 index 00000000..319ee95c --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/highlight.yts @@ -0,0 +1,4 @@ +pick 6221 "Name" "2024-01-17" "A" "0:00" "url" +pick 6181 "Name2" "2024-01-16" "A2" "0:00" "url2" +pick 6184 "Name3" "2024-01-16" "A3" "0:00" "url3" +pick 6206 "Name4" "2024-01-16" "A4" "299:36" "url4" diff --git a/pkgs/sources/tree-sitter-yts/package.json b/pkgs/sources/tree-sitter-yts/package.json new file mode 100644 index 00000000..2511ccb7 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/package.json @@ -0,0 +1,31 @@ +{ + "name": "tree-sitter-yts", + "version": "0.0.1", + "description": "yts grammar for tree-sitter", + "main": "bindings/node", + "keywords": [ + "parsing", + "incremental" + ], + "dependencies": { + "nan": "^2.12.1" + }, + "devDependencies": { + "tree-sitter-cli": "^0.20.8" + }, + "scripts": { + "test": "tree-sitter test" + }, + "tree-sitter": [ + { + "scope": "source.yts", + "file-types": [ + "yts" + ], + "highlights": [ + "queries/highlights.scm" + ], + "injection-regex": "^(yts)$" + } + ] +} diff --git a/pkgs/sources/tree-sitter-yts/package.nix b/pkgs/sources/tree-sitter-yts/package.nix new file mode 100644 index 00000000..fe9a7326 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/package.nix @@ -0,0 +1,63 @@ +# taken from nixpgks: pkgs/development/tools/parsing/tree-sitter/grammar.nix +{ + stdenv, + nodejs, + tree-sitter, + lib, +}: +# Build a parser grammar and put the resulting shared object in `$out/parser` +{ + # language name + language, + version, + src, + location ? null, + generate ? false, + ... +} @ args: +stdenv.mkDerivation ({ + pname = "${language}-grammar"; + + inherit src version; + + nativeBuildInputs = lib.optionals generate [nodejs tree-sitter]; + + CFLAGS = ["-Isrc" "-O2"]; + CXXFLAGS = ["-Isrc" "-O2"]; + + stripDebugList = ["parser"]; + + configurePhase = + lib.optionalString (location != null) '' + cd ${location} + '' + + lib.optionalString generate '' + tree-sitter generate + ''; + + # When both scanner.{c,cc} exist, we should not link both since they may be the same but in + # different languages. Just randomly prefer C++ if that happens. + buildPhase = '' + runHook preBuild + if [[ -e src/scanner.cc ]]; then + $CXX -fPIC -c src/scanner.cc -o scanner.o $CXXFLAGS + elif [[ -e src/scanner.c ]]; then + $CC -fPIC -c src/scanner.c -o scanner.o $CFLAGS + fi + $CC -fPIC -c src/parser.c -o parser.o $CFLAGS + rm -rf parser + $CXX -shared -o parser *.o + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir $out + mv parser $out/ + if [[ -d queries ]]; then + cp -r queries $out + fi + runHook postInstall + ''; + } + // removeAttrs args ["language" "location" "generate"]) diff --git a/pkgs/sources/tree-sitter-yts/queries/highlights.scm b/pkgs/sources/tree-sitter-yts/queries/highlights.scm new file mode 100644 index 00000000..674cbf18 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/queries/highlights.scm @@ -0,0 +1,11 @@ +(command) @keyword +(id) @constant +(title) @text.title +(date) @number +(author) @operator +(duration) @property +((url) @conceal (#set! conceal "")) + + +((quote) @conceal (#set! conceal "")) +(comment) @comment @spell diff --git a/pkgs/sources/tree-sitter-yts/src/grammar.json b/pkgs/sources/tree-sitter-yts/src/grammar.json new file mode 100644 index 00000000..a35a5464 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/src/grammar.json @@ -0,0 +1,238 @@ +{ + "name": "yts", + "rules": { + "source_file": { + "type": "REPEAT", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "line" + }, + { + "type": "SYMBOL", + "name": "comment" + } + ] + } + }, + "line": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "command" + }, + { + "type": "SYMBOL", + "name": "id" + }, + { + "type": "SYMBOL", + "name": "title" + }, + { + "type": "SYMBOL", + "name": "date" + }, + { + "type": "SYMBOL", + "name": "author" + }, + { + "type": "SYMBOL", + "name": "duration" + }, + { + "type": "SYMBOL", + "name": "url" + }, + { + "type": "STRING", + "value": "\n" + } + ] + }, + "command": { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "pick" + }, + { + "type": "STRING", + "value": "p" + }, + { + "type": "STRING", + "value": "watch" + }, + { + "type": "STRING", + "value": "w" + }, + { + "type": "STRING", + "value": "drop" + }, + { + "type": "STRING", + "value": "d" + }, + { + "type": "STRING", + "value": "url" + }, + { + "type": "STRING", + "value": "u" + } + ] + }, + "id": { + "type": "PATTERN", + "value": "[0-9]+" + }, + "title": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_q" + }, + { + "type": "PATTERN", + "value": "[^\"]+" + }, + { + "type": "SYMBOL", + "name": "_q" + } + ] + }, + "date": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_q" + }, + { + "type": "PATTERN", + "value": "\\d{4}-\\d{2}-\\d{2}" + }, + { + "type": "SYMBOL", + "name": "_q" + } + ] + }, + "author": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_q" + }, + { + "type": "PATTERN", + "value": "[^\"]+" + }, + { + "type": "SYMBOL", + "name": "_q" + } + ] + }, + "duration": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_q" + }, + { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "[" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "No Duration" + }, + { + "type": "PATTERN", + "value": "\\d+m \\d+s" + }, + { + "type": "PATTERN", + "value": "\\d+h \\d+m" + } + ] + }, + { + "type": "STRING", + "value": "]" + } + ] + }, + { + "type": "SYMBOL", + "name": "_q" + } + ] + }, + "url": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_q" + }, + { + "type": "PATTERN", + "value": "[^\"]+" + }, + { + "type": "SYMBOL", + "name": "_q" + } + ] + }, + "comment": { + "type": "PATTERN", + "value": "#.*" + }, + "_q": { + "type": "SYMBOL", + "name": "quote" + }, + "quote": { + "type": "PATTERN", + "value": "\"" + } + }, + "extras": [ + { + "type": "PATTERN", + "value": "\\s" + }, + { + "type": "PATTERN", + "value": "\\\\\\r?\\n" + } + ], + "conflicts": [], + "precedences": [], + "externals": [], + "inline": [], + "supertypes": [] +} + diff --git a/pkgs/sources/tree-sitter-yts/src/node-types.json b/pkgs/sources/tree-sitter-yts/src/node-types.json new file mode 100644 index 00000000..1a63a552 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/src/node-types.json @@ -0,0 +1,200 @@ +[ + { + "type": "author", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "quote", + "named": true + } + ] + } + }, + { + "type": "command", + "named": true, + "fields": {} + }, + { + "type": "date", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "quote", + "named": true + } + ] + } + }, + { + "type": "duration", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "quote", + "named": true + } + ] + } + }, + { + "type": "line", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "author", + "named": true + }, + { + "type": "command", + "named": true + }, + { + "type": "date", + "named": true + }, + { + "type": "duration", + "named": true + }, + { + "type": "id", + "named": true + }, + { + "type": "title", + "named": true + }, + { + "type": "url", + "named": true + } + ] + } + }, + { + "type": "source_file", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": false, + "types": [ + { + "type": "comment", + "named": true + }, + { + "type": "line", + "named": true + } + ] + } + }, + { + "type": "title", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "quote", + "named": true + } + ] + } + }, + { + "type": "url", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "quote", + "named": true + } + ] + } + }, + { + "type": "\n", + "named": false + }, + { + "type": "No Duration", + "named": false + }, + { + "type": "[", + "named": false + }, + { + "type": "]", + "named": false + }, + { + "type": "comment", + "named": true + }, + { + "type": "d", + "named": false + }, + { + "type": "drop", + "named": false + }, + { + "type": "id", + "named": true + }, + { + "type": "p", + "named": false + }, + { + "type": "pick", + "named": false + }, + { + "type": "quote", + "named": true + }, + { + "type": "u", + "named": false + }, + { + "type": "url", + "named": false + }, + { + "type": "w", + "named": false + }, + { + "type": "watch", + "named": false + } +] \ No newline at end of file diff --git a/pkgs/sources/tree-sitter-yts/src/parser.c b/pkgs/sources/tree-sitter-yts/src/parser.c new file mode 100644 index 00000000..ded5c342 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/src/parser.c @@ -0,0 +1,1108 @@ +#include + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#define LANGUAGE_VERSION 14 +#define STATE_COUNT 31 +#define LARGE_STATE_COUNT 2 +#define SYMBOL_COUNT 30 +#define ALIAS_COUNT 0 +#define TOKEN_COUNT 20 +#define EXTERNAL_TOKEN_COUNT 0 +#define FIELD_COUNT 0 +#define MAX_ALIAS_SEQUENCE_LENGTH 8 +#define PRODUCTION_ID_COUNT 1 + +enum +{ + anon_sym_LF = 1, + anon_sym_pick = 2, + anon_sym_p = 3, + anon_sym_watch = 4, + anon_sym_w = 5, + anon_sym_drop = 6, + anon_sym_d = 7, + anon_sym_url = 8, + anon_sym_u = 9, + sym_id = 10, + aux_sym_title_token1 = 11, + aux_sym_date_token1 = 12, + anon_sym_LBRACK = 13, + anon_sym_NoDuration = 14, + aux_sym_duration_token1 = 15, + aux_sym_duration_token2 = 16, + anon_sym_RBRACK = 17, + sym_comment = 18, + sym_quote = 19, + sym_source_file = 20, + sym_line = 21, + sym_command = 22, + sym_title = 23, + sym_date = 24, + sym_author = 25, + sym_duration = 26, + sym_url = 27, + sym__q = 28, + aux_sym_source_file_repeat1 = 29, +}; + +static const char *const ts_symbol_names[] = { + [ts_builtin_sym_end] = "end", + [anon_sym_LF] = "\n", + [anon_sym_pick] = "pick", + [anon_sym_p] = "p", + [anon_sym_watch] = "watch", + [anon_sym_w] = "w", + [anon_sym_drop] = "drop", + [anon_sym_d] = "d", + [anon_sym_url] = "url", + [anon_sym_u] = "u", + [sym_id] = "id", + [aux_sym_title_token1] = "title_token1", + [aux_sym_date_token1] = "date_token1", + [anon_sym_LBRACK] = "[", + [anon_sym_NoDuration] = "No Duration", + [aux_sym_duration_token1] = "duration_token1", + [aux_sym_duration_token2] = "duration_token2", + [anon_sym_RBRACK] = "]", + [sym_comment] = "comment", + [sym_quote] = "quote", + [sym_source_file] = "source_file", + [sym_line] = "line", + [sym_command] = "command", + [sym_title] = "title", + [sym_date] = "date", + [sym_author] = "author", + [sym_duration] = "duration", + [sym_url] = "url", + [sym__q] = "_q", + [aux_sym_source_file_repeat1] = "source_file_repeat1", +}; + +static const TSSymbol ts_symbol_map[] = { + [ts_builtin_sym_end] = ts_builtin_sym_end, + [anon_sym_LF] = anon_sym_LF, + [anon_sym_pick] = anon_sym_pick, + [anon_sym_p] = anon_sym_p, + [anon_sym_watch] = anon_sym_watch, + [anon_sym_w] = anon_sym_w, + [anon_sym_drop] = anon_sym_drop, + [anon_sym_d] = anon_sym_d, + [anon_sym_url] = anon_sym_url, + [anon_sym_u] = anon_sym_u, + [sym_id] = sym_id, + [aux_sym_title_token1] = aux_sym_title_token1, + [aux_sym_date_token1] = aux_sym_date_token1, + [anon_sym_LBRACK] = anon_sym_LBRACK, + [anon_sym_NoDuration] = anon_sym_NoDuration, + [aux_sym_duration_token1] = aux_sym_duration_token1, + [aux_sym_duration_token2] = aux_sym_duration_token2, + [anon_sym_RBRACK] = anon_sym_RBRACK, + [sym_comment] = sym_comment, + [sym_quote] = sym_quote, + [sym_source_file] = sym_source_file, + [sym_line] = sym_line, + [sym_command] = sym_command, + [sym_title] = sym_title, + [sym_date] = sym_date, + [sym_author] = sym_author, + [sym_duration] = sym_duration, + [sym_url] = sym_url, + [sym__q] = sym__q, + [aux_sym_source_file_repeat1] = aux_sym_source_file_repeat1, +}; + +static const TSSymbolMetadata ts_symbol_metadata[] = { + [ts_builtin_sym_end] = { + .visible = false, + .named = true, + }, + [anon_sym_LF] = { + .visible = true, + .named = false, + }, + [anon_sym_pick] = { + .visible = true, + .named = false, + }, + [anon_sym_p] = { + .visible = true, + .named = false, + }, + [anon_sym_watch] = { + .visible = true, + .named = false, + }, + [anon_sym_w] = { + .visible = true, + .named = false, + }, + [anon_sym_drop] = { + .visible = true, + .named = false, + }, + [anon_sym_d] = { + .visible = true, + .named = false, + }, + [anon_sym_url] = { + .visible = true, + .named = false, + }, + [anon_sym_u] = { + .visible = true, + .named = false, + }, + [sym_id] = { + .visible = true, + .named = true, + }, + [aux_sym_title_token1] = { + .visible = false, + .named = false, + }, + [aux_sym_date_token1] = { + .visible = false, + .named = false, + }, + [anon_sym_LBRACK] = { + .visible = true, + .named = false, + }, + [anon_sym_NoDuration] = { + .visible = true, + .named = false, + }, + [aux_sym_duration_token1] = { + .visible = false, + .named = false, + }, + [aux_sym_duration_token2] = { + .visible = false, + .named = false, + }, + [anon_sym_RBRACK] = { + .visible = true, + .named = false, + }, + [sym_comment] = { + .visible = true, + .named = true, + }, + [sym_quote] = { + .visible = true, + .named = true, + }, + [sym_source_file] = { + .visible = true, + .named = true, + }, + [sym_line] = { + .visible = true, + .named = true, + }, + [sym_command] = { + .visible = true, + .named = true, + }, + [sym_title] = { + .visible = true, + .named = true, + }, + [sym_date] = { + .visible = true, + .named = true, + }, + [sym_author] = { + .visible = true, + .named = true, + }, + [sym_duration] = { + .visible = true, + .named = true, + }, + [sym_url] = { + .visible = true, + .named = true, + }, + [sym__q] = { + .visible = false, + .named = true, + }, + [aux_sym_source_file_repeat1] = { + .visible = false, + .named = false, + }, +}; + +static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT] + [MAX_ALIAS_SEQUENCE_LENGTH] + = { + [0] = { 0 }, + }; + +static const uint16_t ts_non_terminal_alias_map[] = { + 0, +}; + +static const TSStateId ts_primary_state_ids[STATE_COUNT] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, + [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, + [14] = 14, [15] = 15, [16] = 16, [17] = 17, [18] = 18, [19] = 19, [20] = 20, + [21] = 21, [22] = 22, [23] = 23, [24] = 24, [25] = 25, [26] = 26, [27] = 27, + [28] = 28, [29] = 29, [30] = 30, +}; + +static bool +ts_lex (TSLexer *lexer, TSStateId state) +{ + START_LEXER (); + eof = lexer->eof (lexer); + switch (state) + { + case 0: + if (eof) + ADVANCE (47); + if (lookahead == '"') + ADVANCE (74); + if (lookahead == '#') + ADVANCE (73); + if (lookahead == 'N') + ADVANCE (30); + if (lookahead == '[') + ADVANCE (68); + if (lookahead == '\\') + SKIP (46) + if (lookahead == ']') + ADVANCE (72); + if (lookahead == 'd') + ADVANCE (54); + if (lookahead == 'p') + ADVANCE (50); + if (lookahead == 'u') + ADVANCE (56); + if (lookahead == 'w') + ADVANCE (52); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' + || lookahead == ' ') + SKIP (0) + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (60); + END_STATE (); + case 1: + if (lookahead == '\n') + SKIP (14) + END_STATE (); + case 2: + if (lookahead == '\n') + SKIP (14) + if (lookahead == '\r') + SKIP (1) + END_STATE (); + case 3: + if (lookahead == '\n') + SKIP (16) + END_STATE (); + case 4: + if (lookahead == '\n') + SKIP (16) + if (lookahead == '\r') + SKIP (3) + END_STATE (); + case 5: + if (lookahead == '\n') + SKIP (7) + END_STATE (); + case 6: + if (lookahead == '\n') + SKIP (7) + if (lookahead == '\r') + SKIP (5) + END_STATE (); + case 7: + if (lookahead == '\n') + ADVANCE (48); + if (lookahead == '\\') + SKIP (6) + if (lookahead == '\t' || lookahead == '\r' || lookahead == ' ') + SKIP (7) + END_STATE (); + case 8: + if (lookahead == ' ') + ADVANCE (13); + END_STATE (); + case 9: + if (lookahead == ' ') + ADVANCE (39); + END_STATE (); + case 10: + if (lookahead == ' ') + ADVANCE (40); + END_STATE (); + case 11: + if (lookahead == '-') + ADVANCE (43); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (24); + END_STATE (); + case 12: + if (lookahead == '-') + ADVANCE (44); + END_STATE (); + case 13: + if (lookahead == 'D') + ADVANCE (38); + END_STATE (); + case 14: + if (lookahead == 'N') + ADVANCE (30); + if (lookahead == '\\') + SKIP (2) + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' + || lookahead == ' ') + SKIP (14) + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (23); + END_STATE (); + case 15: + if (lookahead == '\\') + ADVANCE (63); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' + || lookahead == ' ') + ADVANCE (65); + if (lookahead != 0 && lookahead != '"') + ADVANCE (66); + END_STATE (); + case 16: + if (lookahead == '\\') + SKIP (4) + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' + || lookahead == ' ') + SKIP (16) + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (62); + END_STATE (); + case 17: + if (lookahead == 'a') + ADVANCE (36); + END_STATE (); + case 18: + if (lookahead == 'c') + ADVANCE (26); + END_STATE (); + case 19: + if (lookahead == 'c') + ADVANCE (20); + END_STATE (); + case 20: + if (lookahead == 'h') + ADVANCE (51); + END_STATE (); + case 21: + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (11); + END_STATE (); + case 22: + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (21); + END_STATE (); + case 23: + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (22); + END_STATE (); + case 24: + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (24); + END_STATE (); + case 25: + if (lookahead == 'i') + ADVANCE (32); + END_STATE (); + case 26: + if (lookahead == 'k') + ADVANCE (49); + END_STATE (); + case 27: + if (lookahead == 'l') + ADVANCE (55); + END_STATE (); + case 28: + if (lookahead == 'm') + ADVANCE (71); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (28); + END_STATE (); + case 29: + if (lookahead == 'n') + ADVANCE (69); + END_STATE (); + case 30: + if (lookahead == 'o') + ADVANCE (8); + END_STATE (); + case 31: + if (lookahead == 'o') + ADVANCE (33); + END_STATE (); + case 32: + if (lookahead == 'o') + ADVANCE (29); + END_STATE (); + case 33: + if (lookahead == 'p') + ADVANCE (53); + END_STATE (); + case 34: + if (lookahead == 'r') + ADVANCE (17); + END_STATE (); + case 35: + if (lookahead == 's') + ADVANCE (70); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (35); + END_STATE (); + case 36: + if (lookahead == 't') + ADVANCE (25); + END_STATE (); + case 37: + if (lookahead == 't') + ADVANCE (19); + END_STATE (); + case 38: + if (lookahead == 'u') + ADVANCE (34); + END_STATE (); + case 39: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (28); + END_STATE (); + case 40: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (35); + END_STATE (); + case 41: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (12); + END_STATE (); + case 42: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (67); + END_STATE (); + case 43: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (41); + END_STATE (); + case 44: + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (42); + END_STATE (); + case 45: + if (eof) + ADVANCE (47); + if (lookahead == '\n') + SKIP (0) + END_STATE (); + case 46: + if (eof) + ADVANCE (47); + if (lookahead == '\n') + SKIP (0) + if (lookahead == '\r') + SKIP (45) + END_STATE (); + case 47: + ACCEPT_TOKEN (ts_builtin_sym_end); + END_STATE (); + case 48: + ACCEPT_TOKEN (anon_sym_LF); + if (lookahead == '\n') + ADVANCE (48); + END_STATE (); + case 49: + ACCEPT_TOKEN (anon_sym_pick); + END_STATE (); + case 50: + ACCEPT_TOKEN (anon_sym_p); + if (lookahead == 'i') + ADVANCE (18); + END_STATE (); + case 51: + ACCEPT_TOKEN (anon_sym_watch); + END_STATE (); + case 52: + ACCEPT_TOKEN (anon_sym_w); + if (lookahead == 'a') + ADVANCE (37); + END_STATE (); + case 53: + ACCEPT_TOKEN (anon_sym_drop); + END_STATE (); + case 54: + ACCEPT_TOKEN (anon_sym_d); + if (lookahead == 'r') + ADVANCE (31); + END_STATE (); + case 55: + ACCEPT_TOKEN (anon_sym_url); + END_STATE (); + case 56: + ACCEPT_TOKEN (anon_sym_u); + if (lookahead == 'r') + ADVANCE (27); + END_STATE (); + case 57: + ACCEPT_TOKEN (sym_id); + if (lookahead == '-') + ADVANCE (43); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (61); + END_STATE (); + case 58: + ACCEPT_TOKEN (sym_id); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (57); + END_STATE (); + case 59: + ACCEPT_TOKEN (sym_id); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (58); + END_STATE (); + case 60: + ACCEPT_TOKEN (sym_id); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (59); + END_STATE (); + case 61: + ACCEPT_TOKEN (sym_id); + if (lookahead == 'h') + ADVANCE (9); + if (lookahead == 'm') + ADVANCE (10); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (61); + END_STATE (); + case 62: + ACCEPT_TOKEN (sym_id); + if (('0' <= lookahead && lookahead <= '9')) + ADVANCE (62); + END_STATE (); + case 63: + ACCEPT_TOKEN (aux_sym_title_token1); + if (lookahead == '\n') + ADVANCE (65); + if (lookahead == '\r') + ADVANCE (64); + if (lookahead != 0 && lookahead != '"') + ADVANCE (66); + END_STATE (); + case 64: + ACCEPT_TOKEN (aux_sym_title_token1); + if (lookahead == '\n') + ADVANCE (65); + if (lookahead != 0 && lookahead != '"') + ADVANCE (66); + END_STATE (); + case 65: + ACCEPT_TOKEN (aux_sym_title_token1); + if (lookahead == '\\') + ADVANCE (63); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' + || lookahead == ' ') + ADVANCE (65); + if (lookahead != 0 && lookahead != '"') + ADVANCE (66); + END_STATE (); + case 66: + ACCEPT_TOKEN (aux_sym_title_token1); + if (lookahead != 0 && lookahead != '"') + ADVANCE (66); + END_STATE (); + case 67: + ACCEPT_TOKEN (aux_sym_date_token1); + END_STATE (); + case 68: + ACCEPT_TOKEN (anon_sym_LBRACK); + END_STATE (); + case 69: + ACCEPT_TOKEN (anon_sym_NoDuration); + END_STATE (); + case 70: + ACCEPT_TOKEN (aux_sym_duration_token1); + END_STATE (); + case 71: + ACCEPT_TOKEN (aux_sym_duration_token2); + END_STATE (); + case 72: + ACCEPT_TOKEN (anon_sym_RBRACK); + END_STATE (); + case 73: + ACCEPT_TOKEN (sym_comment); + if (lookahead != 0 && lookahead != '\n') + ADVANCE (73); + END_STATE (); + case 74: + ACCEPT_TOKEN (sym_quote); + END_STATE (); + default: + return false; + } +} + +static const TSLexMode ts_lex_modes[STATE_COUNT] = { + [0] = { .lex_state = 0 }, [1] = { .lex_state = 0 }, + [2] = { .lex_state = 0 }, [3] = { .lex_state = 0 }, + [4] = { .lex_state = 0 }, [5] = { .lex_state = 0 }, + [6] = { .lex_state = 0 }, [7] = { .lex_state = 0 }, + [8] = { .lex_state = 14 }, [9] = { .lex_state = 0 }, + [10] = { .lex_state = 0 }, [11] = { .lex_state = 0 }, + [12] = { .lex_state = 0 }, [13] = { .lex_state = 0 }, + [14] = { .lex_state = 0 }, [15] = { .lex_state = 0 }, + [16] = { .lex_state = 15 }, [17] = { .lex_state = 0 }, + [18] = { .lex_state = 0 }, [19] = { .lex_state = 16 }, + [20] = { .lex_state = 0 }, [21] = { .lex_state = 7 }, + [22] = { .lex_state = 15 }, [23] = { .lex_state = 14 }, + [24] = { .lex_state = 0 }, [25] = { .lex_state = 15 }, + [26] = { .lex_state = 16 }, [27] = { .lex_state = 0 }, + [28] = { .lex_state = 7 }, [29] = { .lex_state = 0 }, + [30] = { .lex_state = 0 }, +}; + +static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { + [0] = { + [ts_builtin_sym_end] = ACTIONS(1), + [anon_sym_pick] = ACTIONS(1), + [anon_sym_p] = ACTIONS(1), + [anon_sym_watch] = ACTIONS(1), + [anon_sym_w] = ACTIONS(1), + [anon_sym_drop] = ACTIONS(1), + [anon_sym_d] = ACTIONS(1), + [anon_sym_url] = ACTIONS(1), + [anon_sym_u] = ACTIONS(1), + [sym_id] = ACTIONS(1), + [aux_sym_date_token1] = ACTIONS(1), + [anon_sym_LBRACK] = ACTIONS(1), + [anon_sym_NoDuration] = ACTIONS(1), + [aux_sym_duration_token1] = ACTIONS(1), + [aux_sym_duration_token2] = ACTIONS(1), + [anon_sym_RBRACK] = ACTIONS(1), + [sym_comment] = ACTIONS(1), + [sym_quote] = ACTIONS(1), + }, + [1] = { + [sym_source_file] = STATE(29), + [sym_line] = STATE(2), + [sym_command] = STATE(26), + [aux_sym_source_file_repeat1] = STATE(2), + [ts_builtin_sym_end] = ACTIONS(3), + [anon_sym_pick] = ACTIONS(5), + [anon_sym_p] = ACTIONS(7), + [anon_sym_watch] = ACTIONS(5), + [anon_sym_w] = ACTIONS(7), + [anon_sym_drop] = ACTIONS(5), + [anon_sym_d] = ACTIONS(7), + [anon_sym_url] = ACTIONS(5), + [anon_sym_u] = ACTIONS(7), + [sym_comment] = ACTIONS(9), + }, +}; + +static const uint16_t ts_small_parse_table[] = { + [0] = 6, + ACTIONS (11), + 1, + ts_builtin_sym_end, + ACTIONS (13), + 1, + sym_comment, + STATE (26), + 1, + sym_command, + STATE (3), + 2, + sym_line, + aux_sym_source_file_repeat1, + ACTIONS (5), + 4, + anon_sym_pick, + anon_sym_watch, + anon_sym_drop, + anon_sym_url, + ACTIONS (7), + 4, + anon_sym_p, + anon_sym_w, + anon_sym_d, + anon_sym_u, + [26] = 6, + ACTIONS (15), + 1, + ts_builtin_sym_end, + ACTIONS (23), + 1, + sym_comment, + STATE (26), + 1, + sym_command, + STATE (3), + 2, + sym_line, + aux_sym_source_file_repeat1, + ACTIONS (17), + 4, + anon_sym_pick, + anon_sym_watch, + anon_sym_drop, + anon_sym_url, + ACTIONS (20), + 4, + anon_sym_p, + anon_sym_w, + anon_sym_d, + anon_sym_u, + [52] = 2, + ACTIONS (28), + 4, + anon_sym_p, + anon_sym_w, + anon_sym_d, + anon_sym_u, + ACTIONS (26), + 6, + ts_builtin_sym_end, + anon_sym_pick, + anon_sym_watch, + anon_sym_drop, + anon_sym_url, + sym_comment, + [67] = 3, + ACTIONS (30), + 1, + sym_quote, + STATE (21), + 1, + sym_url, + STATE (22), + 1, + sym__q, + [77] = 3, + ACTIONS (32), + 1, + sym_quote, + STATE (7), + 1, + sym_title, + STATE (25), + 1, + sym__q, + [87] = 3, + ACTIONS (34), + 1, + sym_quote, + STATE (9), + 1, + sym_date, + STATE (23), + 1, + sym__q, + [97] = 1, + ACTIONS (36), + 3, + anon_sym_NoDuration, + aux_sym_duration_token1, + aux_sym_duration_token2, + [103] = 3, + ACTIONS (38), + 1, + sym_quote, + STATE (10), + 1, + sym_author, + STATE (16), + 1, + sym__q, + [113] = 3, + ACTIONS (40), + 1, + sym_quote, + STATE (5), + 1, + sym_duration, + STATE (18), + 1, + sym__q, + [123] = 2, + ACTIONS (42), + 1, + sym_quote, + STATE (30), + 1, + sym__q, + [130] = 2, + ACTIONS (44), + 1, + sym_quote, + STATE (28), + 1, + sym__q, + [137] = 2, + ACTIONS (46), + 1, + sym_quote, + STATE (24), + 1, + sym__q, + [144] = 2, + ACTIONS (48), + 1, + sym_quote, + STATE (17), + 1, + sym__q, + [151] = 2, + ACTIONS (50), + 1, + sym_quote, + STATE (20), + 1, + sym__q, + [158] = 1, + ACTIONS (52), + 1, + aux_sym_title_token1, + [162] = 1, + ACTIONS (54), + 1, + sym_quote, + [166] = 1, + ACTIONS (56), + 1, + anon_sym_LBRACK, + [170] = 1, + ACTIONS (58), + 1, + sym_id, + [174] = 1, + ACTIONS (60), + 1, + sym_quote, + [178] = 1, + ACTIONS (62), + 1, + anon_sym_LF, + [182] = 1, + ACTIONS (64), + 1, + aux_sym_title_token1, + [186] = 1, + ACTIONS (66), + 1, + aux_sym_date_token1, + [190] = 1, + ACTIONS (68), + 1, + sym_quote, + [194] = 1, + ACTIONS (70), + 1, + aux_sym_title_token1, + [198] = 1, + ACTIONS (72), + 1, + sym_id, + [202] = 1, + ACTIONS (74), + 1, + anon_sym_RBRACK, + [206] = 1, + ACTIONS (76), + 1, + anon_sym_LF, + [210] = 1, + ACTIONS (78), + 1, + ts_builtin_sym_end, + [214] = 1, + ACTIONS (80), + 1, + sym_quote, +}; + +static const uint32_t ts_small_parse_table_map[] = { + [SMALL_STATE (2)] = 0, [SMALL_STATE (3)] = 26, [SMALL_STATE (4)] = 52, + [SMALL_STATE (5)] = 67, [SMALL_STATE (6)] = 77, [SMALL_STATE (7)] = 87, + [SMALL_STATE (8)] = 97, [SMALL_STATE (9)] = 103, [SMALL_STATE (10)] = 113, + [SMALL_STATE (11)] = 123, [SMALL_STATE (12)] = 130, [SMALL_STATE (13)] = 137, + [SMALL_STATE (14)] = 144, [SMALL_STATE (15)] = 151, [SMALL_STATE (16)] = 158, + [SMALL_STATE (17)] = 162, [SMALL_STATE (18)] = 166, [SMALL_STATE (19)] = 170, + [SMALL_STATE (20)] = 174, [SMALL_STATE (21)] = 178, [SMALL_STATE (22)] = 182, + [SMALL_STATE (23)] = 186, [SMALL_STATE (24)] = 190, [SMALL_STATE (25)] = 194, + [SMALL_STATE (26)] = 198, [SMALL_STATE (27)] = 202, [SMALL_STATE (28)] = 206, + [SMALL_STATE (29)] = 210, [SMALL_STATE (30)] = 214, +}; + +static const TSParseActionEntry ts_parse_actions[] = { + [0] = { .entry = { .count = 0, .reusable = false } }, + [1] = { .entry = { .count = 1, .reusable = false } }, + RECOVER (), + [3] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_source_file, 0), + [5] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (19), + [7] = { .entry = { .count = 1, .reusable = false } }, + SHIFT (19), + [9] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (2), + [11] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_source_file, 1), + [13] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (3), + [15] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (aux_sym_source_file_repeat1, 2), + [17] = { .entry = { .count = 2, .reusable = true } }, + REDUCE (aux_sym_source_file_repeat1, 2), + SHIFT_REPEAT (19), + [20] = { .entry = { .count = 2, .reusable = false } }, + REDUCE (aux_sym_source_file_repeat1, 2), + SHIFT_REPEAT (19), + [23] = { .entry = { .count = 2, .reusable = true } }, + REDUCE (aux_sym_source_file_repeat1, 2), + SHIFT_REPEAT (3), + [26] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_line, 8), + [28] = { .entry = { .count = 1, .reusable = false } }, + REDUCE (sym_line, 8), + [30] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (22), + [32] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (25), + [34] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (23), + [36] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (27), + [38] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (16), + [40] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (18), + [42] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (30), + [44] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (28), + [46] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (24), + [48] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (17), + [50] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (20), + [52] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (13), + [54] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_title, 3), + [56] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (8), + [58] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_command, 1), + [60] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_date, 3), + [62] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (4), + [64] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (12), + [66] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (15), + [68] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_author, 3), + [70] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (14), + [72] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (6), + [74] = { .entry = { .count = 1, .reusable = true } }, + SHIFT (11), + [76] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_url, 3), + [78] = { .entry = { .count = 1, .reusable = true } }, + ACCEPT_INPUT (), + [80] = { .entry = { .count = 1, .reusable = true } }, + REDUCE (sym_duration, 5), +}; + +#ifdef __cplusplus +extern "C" +{ +#endif +#ifdef _WIN32 +#define extern __declspec (dllexport) +#endif + + extern const TSLanguage * + tree_sitter_yts (void) + { + static const TSLanguage language = { + .version = LANGUAGE_VERSION, + .symbol_count = SYMBOL_COUNT, + .alias_count = ALIAS_COUNT, + .token_count = TOKEN_COUNT, + .external_token_count = EXTERNAL_TOKEN_COUNT, + .state_count = STATE_COUNT, + .large_state_count = LARGE_STATE_COUNT, + .production_id_count = PRODUCTION_ID_COUNT, + .field_count = FIELD_COUNT, + .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, + .parse_table = &ts_parse_table[0][0], + .small_parse_table = ts_small_parse_table, + .small_parse_table_map = ts_small_parse_table_map, + .parse_actions = ts_parse_actions, + .symbol_names = ts_symbol_names, + .symbol_metadata = ts_symbol_metadata, + .public_symbol_map = ts_symbol_map, + .alias_map = ts_non_terminal_alias_map, + .alias_sequences = &ts_alias_sequences[0][0], + .lex_modes = ts_lex_modes, + .lex_fn = ts_lex, + .primary_state_ids = ts_primary_state_ids, + }; + return &language; + } +#ifdef __cplusplus +} +#endif diff --git a/pkgs/sources/tree-sitter-yts/src/tree_sitter/parser.h b/pkgs/sources/tree-sitter-yts/src/tree_sitter/parser.h new file mode 100644 index 00000000..972913cf --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/src/tree_sitter/parser.h @@ -0,0 +1,241 @@ +#ifndef TREE_SITTER_PARSER_H_ +#define TREE_SITTER_PARSER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +#define ts_builtin_sym_error ((TSSymbol)-1) +#define ts_builtin_sym_end 0 +#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 + + typedef uint16_t TSStateId; + +#ifndef TREE_SITTER_API_H_ + typedef uint16_t TSSymbol; + typedef uint16_t TSFieldId; + typedef struct TSLanguage TSLanguage; +#endif + + typedef struct + { + TSFieldId field_id; + uint8_t child_index; + bool inherited; + } TSFieldMapEntry; + + typedef struct + { + uint16_t index; + uint16_t length; + } TSFieldMapSlice; + + typedef struct + { + bool visible; + bool named; + bool supertype; + } TSSymbolMetadata; + + typedef struct TSLexer TSLexer; + + struct TSLexer + { + int32_t lookahead; + TSSymbol result_symbol; + void (*advance) (TSLexer *, bool); + void (*mark_end) (TSLexer *); + uint32_t (*get_column) (TSLexer *); + bool (*is_at_included_range_start) (const TSLexer *); + bool (*eof) (const TSLexer *); + }; + + typedef enum + { + TSParseActionTypeShift, + TSParseActionTypeReduce, + TSParseActionTypeAccept, + TSParseActionTypeRecover, + } TSParseActionType; + + typedef union + { + struct + { + uint8_t type; + TSStateId state; + bool extra; + bool repetition; + } shift; + struct + { + uint8_t type; + uint8_t child_count; + TSSymbol symbol; + int16_t dynamic_precedence; + uint16_t production_id; + } reduce; + uint8_t type; + } TSParseAction; + + typedef struct + { + uint16_t lex_state; + uint16_t external_lex_state; + } TSLexMode; + + typedef union + { + TSParseAction action; + struct + { + uint8_t count; + bool reusable; + } entry; + } TSParseActionEntry; + + struct TSLanguage + { + uint32_t version; + uint32_t symbol_count; + uint32_t alias_count; + uint32_t token_count; + uint32_t external_token_count; + uint32_t state_count; + uint32_t large_state_count; + uint32_t production_id_count; + uint32_t field_count; + uint16_t max_alias_sequence_length; + const uint16_t *parse_table; + const uint16_t *small_parse_table; + const uint32_t *small_parse_table_map; + const TSParseActionEntry *parse_actions; + const char *const *symbol_names; + const char *const *field_names; + const TSFieldMapSlice *field_map_slices; + const TSFieldMapEntry *field_map_entries; + const TSSymbolMetadata *symbol_metadata; + const TSSymbol *public_symbol_map; + const uint16_t *alias_map; + const TSSymbol *alias_sequences; + const TSLexMode *lex_modes; + bool (*lex_fn) (TSLexer *, TSStateId); + bool (*keyword_lex_fn) (TSLexer *, TSStateId); + TSSymbol keyword_capture_token; + struct + { + const bool *states; + const TSSymbol *symbol_map; + void *(*create) (void); + void (*destroy) (void *); + bool (*scan) (void *, TSLexer *, const bool *symbol_whitelist); + unsigned (*serialize) (void *, char *); + void (*deserialize) (void *, const char *, unsigned); + } external_scanner; + const TSStateId *primary_state_ids; + }; + + /* + * Lexer Macros + */ + +#define START_LEXER() \ + bool result = false; \ + bool skip = false; \ + bool eof = false; \ + int32_t lookahead; \ + goto start; \ + next_state: \ + lexer->advance (lexer, skip); \ + start: \ + skip = false; \ + lookahead = lexer->lookahead; + +#define ADVANCE(state_value) \ + { \ + state = state_value; \ + goto next_state; \ + } + +#define SKIP(state_value) \ + { \ + skip = true; \ + state = state_value; \ + goto next_state; \ + } + +#define ACCEPT_TOKEN(symbol_value) \ + result = true; \ + lexer->result_symbol = symbol_value; \ + lexer->mark_end (lexer); + +#define END_STATE() return result; + + /* + * Parse Table Macros + */ + +#define SMALL_STATE(id) id - LARGE_STATE_COUNT + +#define STATE(id) id + +#define ACTIONS(id) id + +#define SHIFT(state_value) \ + { \ + { \ + .shift = {.type = TSParseActionTypeShift, .state = state_value } \ + } \ + } + +#define SHIFT_REPEAT(state_value) \ + { \ + { \ + .shift \ + = {.type = TSParseActionTypeShift, \ + .state = state_value, \ + .repetition = true } \ + } \ + } + +#define SHIFT_EXTRA() \ + { \ + { \ + .shift = {.type = TSParseActionTypeShift, .extra = true } \ + } \ + } + +#define REDUCE(symbol_val, child_count_val, ...) \ + { \ + { \ + .reduce = { .type = TSParseActionTypeReduce, \ + .symbol = symbol_val, \ + .child_count = child_count_val, \ + __VA_ARGS__ }, \ + } \ + } + +#define RECOVER() \ + { \ + { \ + .type = TSParseActionTypeRecover \ + } \ + } + +#define ACCEPT_INPUT() \ + { \ + { \ + .type = TSParseActionTypeAccept \ + } \ + } + +#ifdef __cplusplus +} +#endif + +#endif // TREE_SITTER_PARSER_H_ diff --git a/pkgs/sources/tree-sitter-yts/treefmt.toml b/pkgs/sources/tree-sitter-yts/treefmt.toml new file mode 100644 index 00000000..3d604b40 --- /dev/null +++ b/pkgs/sources/tree-sitter-yts/treefmt.toml @@ -0,0 +1,35 @@ +[formatter.nix] +command = "nixpkgs-fmt" +includes = ["*.nix"] +excludes = ["test/**.nix"] + +[formatter.prettier] +command = "prettier" +options = ["--write"] +includes = [ + "*.css", + "*.html", + "*.js", + "*.json", + "*.jsx", + "*.md", + "*.mdx", + "*.scss", + "*.ts", +] +excludes = ["src/**.json"] + +[formatter.rust] +command = "rustfmt" +options = ["--edition", "2018"] +includes = ["*.rs"] + +[formatter.c] +command = "clang-format" +options = ["-i"] +includes = ["*.c", "*.cpp", "*.cc", "*.h", "*.hpp"] +excludes = [ + "bindings/node/binding.cc", + "src/parser.c", + "src/tree_sitter/parser.h", +] diff --git a/pkgs/sources/update_pkgs.sh b/pkgs/sources/update_pkgs.sh new file mode 100755 index 00000000..be1573c6 --- /dev/null +++ b/pkgs/sources/update_pkgs.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +die() { + printf "\033[31;1mError: \033[0m%s" "$1" + exit 1 +} + +cd "$(dirname "$0")" || die "Bug: run with false dirname ('$0')!" + +fd . --type directory --max-depth 1 | while read -r dir; do + cd "$dir" || die "Dir '$dir' does not exist" + + if [ -f update.sh ]; then + printf "\033[34;1m> \033[0m\033[34;1m%s\033[0m\n" "Running '${dir}update.sh'" + + [ -f flake.nix ] && nix flake update + + direnv allow + eval "$(direnv export bash 2>/dev/null)" + ./update.sh "$@" + fi + cd - >/dev/null || die "Bug: Last dir does not exist" +done + +# vim: ft=sh diff --git a/pkgs/sources/update_vim_plugins/.envrc b/pkgs/sources/update_vim_plugins/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/pkgs/sources/update_vim_plugins/.envrc @@ -0,0 +1 @@ +use flake diff --git a/pkgs/sources/update_vim_plugins/check-duplicates.sh b/pkgs/sources/update_vim_plugins/check-duplicates.sh new file mode 100755 index 00000000..781b8aeb --- /dev/null +++ b/pkgs/sources/update_vim_plugins/check-duplicates.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +plugins="$(grep -E "^ [a-zA-Z-]+ =" ./pkgs/vim-plugins.nix | sed -E 's/^ ([a-zA-Z-]+) =.*$/\1/' | sort)" +count=$(echo "$plugins" | uniq -d | wc -l) + +echo "duplicates count: $count" + +if [ "$count" -gt 0 ]; then + filtered_plugins=$(echo "$plugins" | uniq -d) + + if [ "$1" == "check-only" ]; then + echo "$filtered_plugins" + exit 1 + else + known_issues=$(gh issue list --state "open" --label "bot" --json "body" | jq -r ".[].body") + + echo "known_issues: $known_issues" + + # iterate over plugins we found missing and + # compare them to all open issues. + # We no matching issue was found, we create a new one + for f in $filtered_plugins; do # do not add " " here. It would break the plugin + found=false + + for k in $known_issues; do + if [[ $f == "$k" ]]; then + found=true + break + fi + done + + # test if matching issue was found + if ! $found; then + echo "Did not find an issue for $f. Creating a new one ..." + gh issue create --title "Detected broken plugin: $f" --label "bot" --body "$f" + else + echo "Issue for $f already exists" + fi + done + fi +else + echo "No duplicates found" +fi diff --git a/pkgs/sources/update_vim_plugins/default.nix b/pkgs/sources/update_vim_plugins/default.nix new file mode 100644 index 00000000..7f0b3f0d --- /dev/null +++ b/pkgs/sources/update_vim_plugins/default.nix @@ -0,0 +1,17 @@ +[ + ( + final: prev: { + update-vim-plugins = import ./package.nix { + inherit + (prev) + python3 + # dependencies + + nix + alejandra + nix-prefetch-git + ; + }; + } + ) +] diff --git a/pkgs/sources/update_vim_plugins/flake.lock b/pkgs/sources/update_vim_plugins/flake.lock new file mode 100644 index 00000000..50494465 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715087517, + "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/update_vim_plugins/flake.nix b/pkgs/sources/update_vim_plugins/flake.nix new file mode 100644 index 00000000..ef440af0 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/flake.nix @@ -0,0 +1,24 @@ +{ + description = "update_vim_plugins"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: (flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShells.default = pkgs.mkShell { + packages = [ + pkgs.python3 + pkgs.poetry + ]; + }; + })); +} diff --git a/pkgs/sources/update_vim_plugins/package.nix b/pkgs/sources/update_vim_plugins/package.nix new file mode 100644 index 00000000..e74a29b1 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/package.nix @@ -0,0 +1,47 @@ +{ + python3, + # dependencies + nix, + alejandra, + nix-prefetch-git, +}: +python3.pkgs.buildPythonApplication { + pname = "update-vim-plugins"; + version = "0.1.0"; + format = "pyproject"; + + src = ./.; + + # NOTE: The test are not really meant to work <2023-12-09> + doCheck = false; + + nativeBuildInputs = [ + python3.pkgs.poetry-core + ]; + buildInputs = [ + alejandra + nix-prefetch-git + nix + ]; + propagatedBuildInputs = with python3.pkgs; [ + requests + cleo + jsonpickle + dateparser + ]; + nativeCheckInputs = with python3.pkgs; [ + pytestCheckHook + + pytest-cov + pytest-mock + ]; + pytestFlagsArray = [ + "--cov" + "update_vim_plugins" + "--cov-report" + "term-missing:skip-covered" + "--cov-fail-under" + "50" + "update_vim_plugins/tests" + ]; +} diff --git a/pkgs/sources/update_vim_plugins/poetry.lock b/pkgs/sources/update_vim_plugins/poetry.lock new file mode 100644 index 00000000..f4764b42 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/poetry.lock @@ -0,0 +1,680 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "cleo" +version = "2.1.0" +description = "Cleo allows you to create beautiful and testable command-line interfaces." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "cleo-2.1.0-py3-none-any.whl", hash = "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e"}, + {file = "cleo-2.1.0.tar.gz", hash = "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523"}, +] + +[package.dependencies] +crashtest = ">=0.4.1,<0.5.0" +rapidfuzz = ">=3.0.0,<4.0.0" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.5.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, + {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, + {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, + {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, + {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, + {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, + {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, + {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, + {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, + {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, + {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, + {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, + {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, + {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "crashtest" +version = "0.4.1" +description = "Manage Python errors with ease" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, + {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, +] + +[[package]] +name = "dateparser" +version = "1.2.0" +description = "Date parsing library designed to parse dates from HTML pages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"}, + {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"}, +] + +[package.dependencies] +python-dateutil = "*" +pytz = "*" +regex = "<2019.02.19 || >2019.02.19,<2021.8.27 || >2021.8.27" +tzlocal = "*" + +[package.extras] +calendars = ["convertdate", "hijri-converter"] +fasttext = ["fasttext"] +langdetect = ["langdetect"] + +[[package]] +name = "exceptiongroup" +version = "1.2.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "jsonpickle" +version = "3.0.4" +description = "Serialize any Python object to JSON" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpickle-3.0.4-py3-none-any.whl", hash = "sha256:04ae7567a14269579e3af66b76bda284587458d7e8a204951ca8f71a3309952e"}, + {file = "jsonpickle-3.0.4.tar.gz", hash = "sha256:a1b14c8d6221cd8f394f2a97e735ea1d7edc927fbd135b26f2f8700657c8c62b"}, +] + +[package.extras] +docs = ["furo", "rst.linker (>=1.9)", "sphinx"] +packaging = ["build", "twine"] +testing = ["bson", "ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-benchmark", "pytest-benchmark[histogram]", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-ruff (>=0.2.1)", "scikit-learn", "scipy", "scipy (>=1.9.3)", "simplejson", "sqlalchemy", "ujson"] + +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "rapidfuzz" +version = "3.9.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bd375c4830fee11d502dd93ecadef63c137ae88e1aaa29cc15031fa66d1e0abb"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:55e2c5076f38fc1dbaacb95fa026a3e409eee6ea5ac4016d44fb30e4cad42b20"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:488f74126904db6b1bea545c2f3567ea882099f4c13f46012fe8f4b990c683df"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3f2d1ea7cd57dfcd34821e38b4924c80a31bcf8067201b1ab07386996a9faee"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b11e602987bcb4ea22b44178851f27406fca59b0836298d0beb009b504dba266"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3083512e9bf6ed2bb3d25883922974f55e21ae7f8e9f4e298634691ae1aee583"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b33c6d4b3a1190bc0b6c158c3981535f9434e8ed9ffa40cf5586d66c1819fb4b"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcb95fde22f98e6d0480db8d6038c45fe2d18a338690e6f9bba9b82323f3469"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:08d8b49b3a4fb8572e480e73fcddc750da9cbb8696752ee12cca4bf8c8220d52"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e721842e6b601ebbeb8cc5e12c75bbdd1d9e9561ea932f2f844c418c31256e82"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7988363b3a415c5194ce1a68d380629247f8713e669ad81db7548eb156c4f365"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2d267d4c982ab7d177e994ab1f31b98ff3814f6791b90d35dda38307b9e7c989"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bb28ab5300cf974c7eb68ea21125c493e74b35b1129e629533468b2064ae0a2"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-win32.whl", hash = "sha256:1b1f74997b6d94d66375479fa55f70b1c18e4d865d7afcd13f0785bfd40a9d3c"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:c56d2efdfaa1c642029f3a7a5bb76085c5531f7a530777be98232d2ce142553c"}, + {file = "rapidfuzz-3.9.0-cp310-cp310-win_arm64.whl", hash = "sha256:6a83128d505cac76ea560bb9afcb3f6986e14e50a6f467db9a31faef4bd9b347"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e2218d62ab63f3c5ad48eced898854d0c2c327a48f0fb02e2288d7e5332a22c8"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36bf35df2d6c7d5820da20a6720aee34f67c15cd2daf8cf92e8141995c640c25"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:905b01a9b633394ff6bb5ebb1c5fd660e0e180c03fcf9d90199cc6ed74b87cf7"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33cfabcb7fd994938a6a08e641613ce5fe46757832edc789c6a5602e7933d6fa"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1179dcd3d150a67b8a678cd9c84f3baff7413ff13c9e8fe85e52a16c97e24c9b"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47d97e28c42f1efb7781993b67c749223f198f6653ef177a0c8f2b1c516efcaf"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28da953eb2ef9ad527e536022da7afff6ace7126cdd6f3e21ac20f8762e76d2c"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:182b4e11de928fb4834e8f8b5ecd971b5b10a86fabe8636ab65d3a9b7e0e9ca7"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c74f2da334ce597f31670db574766ddeaee5d9430c2c00e28d0fbb7f76172036"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:014ac55b03f4074f903248ded181f3000f4cdbd134e6155cbf643f0eceb4f70f"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c4ef34b2ddbf448f1d644b4ec6475df8bbe5b9d0fee173ff2e87322a151663bd"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fc02157f521af15143fae88f92ef3ddcc4e0cff05c40153a9549dc0fbdb9adb3"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ff08081c49b18ba253a99e6a47f492e6ee8019e19bbb6ddc3ed360cd3ecb2f62"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-win32.whl", hash = "sha256:b9bf90b3d96925cbf8ef44e5ee3cf39ef0c422f12d40f7a497e91febec546650"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5d5684f54d82d9b0cf0b2701e55a630527a9c3dd5ddcf7a2e726a475ac238f2"}, + {file = "rapidfuzz-3.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:a2de844e0e971d7bd8aa41284627dbeacc90e750b90acfb016836553c7a63192"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f81fe99a69ac8ee3fd905e70c62f3af033901aeb60b69317d1d43d547b46e510"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:633b9d03fc04abc585c197104b1d0af04b1f1db1abc99f674d871224cd15557a"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab872cb57ae97c54ba7c71a9e3c9552beb57cb907c789b726895576d1ea9af6f"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdd8c15c3a14e409507fdf0c0434ec481d85c6cbeec8bdcd342a8cd1eda03825"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2444d8155d9846f206e2079bb355b85f365d9457480b0d71677a112d0a7f7128"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83bd3d01f04061c3660742dc85143a89d49fd23eb31eccbf60ad56c4b955617"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ca799f882364e69d0872619afb19efa3652b7133c18352e4a3d86a324fb2bb1"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6993d361f28b9ef5f0fa4e79b8541c2f3507be7471b9f9cb403a255e123b31e1"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:170822a1b1719f02b58e3dce194c8ad7d4c5b39be38c0fdec603bd19c6f9cf81"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e86e39c1c1a0816ceda836e6f7bd3743b930cbc51a43a81bb433b552f203f25"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:731269812ea837e0b93d913648e404736407408e33a00b75741e8f27c590caa2"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8e5ff882d3a3d081157ceba7e0ebc7fac775f95b08cbb143accd4cece6043819"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2003071aa633477a01509890c895f9ef56cf3f2eaa72c7ec0b567f743c1abcba"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-win32.whl", hash = "sha256:13857f9070600ea1f940749f123b02d0b027afbaa45e72186df0f278915761d0"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:134b7098ac109834eeea81424b6822f33c4c52bf80b81508295611e7a21be12a"}, + {file = "rapidfuzz-3.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:2a96209f046fe328be30fc43f06e3d4b91f0d5b74e9dcd627dbfd65890fa4a5e"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:544b0bf9d17170720809918e9ccd0d482d4a3a6eca35630d8e1459f737f71755"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d536f8beb8dd82d6efb20fe9f82c2cfab9ffa0384b5d184327e393a4edde91d"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:30f7609da871510583f87484a10820b26555a473a90ab356cdda2f3b4456256c"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f4a2468432a1db491af6f547fad8f6d55fa03e57265c2f20e5eaceb68c7907e"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a7ec4676242c8a430509cff42ce98bca2fbe30188a63d0f60fdcbfd7e84970"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dcb523243e988c849cf81220164ec3bbed378a699e595a8914fffe80596dc49f"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4eea3bf72c4fe68e957526ffd6bcbb403a21baa6b3344aaae2d3252313df6199"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4514980a5d204c076dd5b756960f6b1b7598f030009456e6109d76c4c331d03c"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9a06a99f1335fe43464d7121bc6540de7cd9c9475ac2025babb373fe7f27846b"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6c1ed63345d1581c39d4446b1a8c8f550709656ce2a3c88c47850b258167f3c2"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cd2e6e97daf17ebb3254285cf8dd86c60d56d6cf35c67f0f9a557ef26bd66290"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:9bc0f7e6256a9c668482c41c8a3de5d0aa12e8ca346dcc427b97c7edb82cba48"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c09f4e87e82a164c9db769474bc61f8c8b677f2aeb0234b8abac73d2ecf9799"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-win32.whl", hash = "sha256:e65b8f7921bf60cbb207c132842a6b45eefef48c4c3b510eb16087d6c08c70af"}, + {file = "rapidfuzz-3.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9d6478957fb35c7844ad08f2442b62ba76c1857a56370781a707eefa4f4981e1"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:65d9250a4b0bf86320097306084bc3ca479c8f5491927c170d018787793ebe95"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47b7c0840afa724db3b1a070bc6ed5beab73b4e659b1d395023617fc51bf68a2"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a16c48c6df8fb633efbbdea744361025d01d79bca988f884a620e63e782fe5b"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48105991ff6e4a51c7f754df500baa070270ed3d41784ee0d097549bc9fcb16d"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a7f273906b3c7cc6d63a76e088200805947aa0bc1ada42c6a0e582e19c390d7"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c396562d304e974b4b0d5cd3afc4f92c113ea46a36e6bc62e45333d6aa8837e"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68da1b70458fea5290ec9a169fcffe0c17ff7e5bb3c3257e63d7021a50601a8e"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c5b8f9a7b177af6ce7c6ad5b95588b4b73e37917711aafa33b2e79ee80fe709"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3c42a238bf9dd48f4ccec4c6934ac718225b00bb3a438a008c219e7ccb3894c7"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a365886c42177b2beab475a50ba311b59b04f233ceaebc4c341f6f91a86a78e2"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ce897b5dafb7fb7587a95fe4d449c1ea0b6d9ac4462fbafefdbbeef6eee4cf6a"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:413ac49bae291d7e226a5c9be65c71b2630b3346bce39268d02cb3290232e4b7"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8982fc3bd49d55a91569fc8a3feba0de4cef0b391ff9091be546e9df075b81"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-win32.whl", hash = "sha256:3904d0084ab51f82e9f353031554965524f535522a48ec75c30b223eb5a0a488"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:3733aede16ea112728ffeafeb29ccc62e095ed8ec816822fa2a82e92e2c08696"}, + {file = "rapidfuzz-3.9.0-cp39-cp39-win_arm64.whl", hash = "sha256:fc4e26f592b51f97acf0a3f8dfed95e4d830c6a8fbf359361035df836381ab81"}, + {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e33362e98c7899b5f60dcb06ada00acd8673ce0d59aefe9a542701251fd00423"}, + {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb67cf43ad83cb886cbbbff4df7dcaad7aedf94d64fca31aea0da7d26684283c"}, + {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2e106cc66453bb80d2ad9c0044f8287415676df5c8036d737d05d4b9cdbf8e"}, + {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1256915f7e7a5cf2c151c9ac44834b37f9bd1c97e8dec6f936884f01b9dfc7d"}, + {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ae643220584518cbff8bf2974a0494d3e250763af816b73326a512c86ae782ce"}, + {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:491274080742110427f38a6085bb12dffcaff1eef12dccf9e8758398c7e3957e"}, + {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bc5559b9b94326922c096b30ae2d8e5b40b2e9c2c100c2cc396ad91bcb84d30"}, + {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:849160dc0f128acb343af514ca827278005c1d00148d025e4035e034fc2d8c7f"}, + {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:623883fb78e692d54ed7c43b09beec52c6685f10a45a7518128e25746667403b"}, + {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d20ab9abc7e19767f1951772a6ab14cb4eddd886493c2da5ee12014596ad253f"}, + {file = "rapidfuzz-3.9.0.tar.gz", hash = "sha256:b182f0fb61f6ac435e416eb7ab330d62efdbf9b63cf0c7fa12d1f57c2eaaf6f3"}, +] + +[package.extras] +full = ["numpy"] + +[[package]] +name = "regex" +version = "2024.4.28" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61"}, + {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f"}, + {file = "regex-2024.4.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea"}, + {file = "regex-2024.4.28-cp310-cp310-win32.whl", hash = "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d"}, + {file = "regex-2024.4.28-cp310-cp310-win_amd64.whl", hash = "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f"}, + {file = "regex-2024.4.28-cp311-cp311-win32.whl", hash = "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630"}, + {file = "regex-2024.4.28-cp311-cp311-win_amd64.whl", hash = "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6"}, + {file = "regex-2024.4.28-cp312-cp312-win32.whl", hash = "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17"}, + {file = "regex-2024.4.28-cp312-cp312-win_amd64.whl", hash = "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150"}, + {file = "regex-2024.4.28-cp38-cp38-win32.whl", hash = "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58"}, + {file = "regex-2024.4.28-cp38-cp38-win_amd64.whl", hash = "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1"}, + {file = "regex-2024.4.28-cp39-cp39-win32.whl", hash = "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc"}, + {file = "regex-2024.4.28-cp39-cp39-win_amd64.whl", hash = "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962"}, + {file = "regex-2024.4.28.tar.gz", hash = "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "tzlocal" +version = "5.2" +description = "tzinfo object for the local timezone" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, + {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, +] + +[package.dependencies] +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "f65cd66387236673e2a5afb3b2a75362c97815cdde592a86712737fb9ca71695" diff --git a/pkgs/sources/update_vim_plugins/pyproject.toml b/pkgs/sources/update_vim_plugins/pyproject.toml new file mode 100644 index 00000000..38caf76d --- /dev/null +++ b/pkgs/sources/update_vim_plugins/pyproject.toml @@ -0,0 +1,45 @@ +[tool.poetry] +name = "update_vim_plugins" +version = "0.1.0" +description = "" +authors = ["Your Name "] +packages = [{ include = "update_vim_plugins" }] + +[tool.poetry.scripts] +update-vim-plugins = "update_vim_plugins.__main__:main" + +[tool.poetry.dependencies] +python = "^3.10" +requests = "^2.28.2" +cleo = "^2.0.1" +jsonpickle = "*" +dateparser = "^1.1.8" + +[tool.poetry.group.test.dependencies] +pytest-cov = "^4.0.0" +pytest = "^7.3.1" +pytest-mock = "^3.10.0" + +[tool.poetry.group.dev] +optional = true + +[tool.poetry.group.dev.dependencies] +# black = "^23.3.0" +# ruff-lsp = "^0.0.24" +# mypy = "^1.2.0" +# types-requests = "^2.28.11.17" +# isort = "^5.12.0" +# ruff = "^0.0.262" + +[tool.isort] +profile = "black" + +[tool.black] +line-length = 120 + +[tool.ruff] +line-length = 120 + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/pkgs/sources/update_vim_plugins/update.sh b/pkgs/sources/update_vim_plugins/update.sh new file mode 100755 index 00000000..1bad12a9 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +poetry update --lock + +# vim: ft=sh diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/__init__.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/__main__.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/__main__.py new file mode 100644 index 00000000..a8d9e06f --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/__main__.py @@ -0,0 +1,15 @@ +from cleo.application import Application + +from .update import UpdateCommand +from .cleanup import CleanUpCommand + + +def main(): + application = Application() + application.add(UpdateCommand()) + application.add(CleanUpCommand()) + application.run() + + +if __name__ == "__main__": + main() diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/cleanup.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/cleanup.py new file mode 100644 index 00000000..fd313ed0 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/cleanup.py @@ -0,0 +1,100 @@ +from cleo.commands.command import Command +from cleo.helpers import argument + +from .helpers import read_manifest_to_spec, read_blacklist_to_spec, write_manifest_from_spec + + +class CleanUpCommand(Command): + name = "cleanup" + description = "Clean up manifest" + arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)] + + def handle(self): + """Main command function""" + + plug_dir = self.argument("plug_dir") + self.line("Checking manifest file") + # all cleaning up will be done during reading and writing automatically + manifest = read_manifest_to_spec(plug_dir) + blacklist = read_blacklist_to_spec(plug_dir) + + new_manifest = [spec for spec in manifest if spec not in blacklist] + + new_manifest_filterd = self.filter_renamed(new_manifest) + + write_manifest_from_spec(new_manifest_filterd, plug_dir) + + self.line("Done") + + def filter_renamed(self, specs): + """Filter specs that define the same plugin (same owner and same repo) but with different properties. + This could be a different name, source, or branch + """ + + error = False + for i, p in enumerate(specs): + for p2 in specs: + same_owner = p.owner.lower() == p2.owner.lower() + same_repo = p.repo.lower() == p2.repo.lower() + different_specs = p != p2 + marked_duplicate = p.marked_duplicate or p2.marked_duplicate + + if same_owner and same_repo and different_specs and not marked_duplicate: + self.line("The following lines appear to define the same plugin") + + p_props_defined = p.branch is not None or p.custom_name is not None + p2_props_defined = p2.branch is not None or p2.custom_name is not None + p_is_lower_case = p.owner == p.owner.lower() and p.name == p.name.lower() + p2_is_lower_case = p2.owner == p2.owner.lower() and p2.name == p2.name.lower() + + # list of conditions for selecting p + select_p = p_props_defined and not p2_props_defined or p2_is_lower_case and not p_is_lower_case + # list of conditions for selecting p2 + select_p2 = p2_props_defined and not p_props_defined or p_is_lower_case and not p2_is_lower_case + + # one is more defined and is all lower, but the other is not all lower + # (we assume the not all lower case is the correct naming) + error_props_lower = ( + p_props_defined and p_is_lower_case and not p2_props_defined and not p2_is_lower_case + ) + error_props_lower2 = ( + p2_props_defined and p2_is_lower_case and not p_props_defined and not p_is_lower_case + ) + + # both props are defined + error_props = p_props_defined and p2_props_defined + + # the sources are different + error_source = p.repository_host != p2.repository_host + + if error_props_lower or error_props_lower2 or error_props or error_source: + self.line(" • Cannot determine which is the correct plugin") + self.line(f" - {p.line}") + self.line(f" - {p2.line}") + error = True + # remove second spec to not encounter the error twice + # this will not be written to the manifest.txt because we set + # the error flag and will exit after the loop + specs.remove(p2) + elif select_p: + self.line(f" - {p.line}") + self.line(f" - {p2.line}") + specs.remove(p2) + elif select_p2: + self.line(f" - {p.line}") + self.line(f" - {p2.line}") + specs.remove(p) + else: + self.line(" • Logic error in correct spec determination") + self.line(f" - {p.line}") + self.line(f" - {p2.line}") + error = True + # remove second spec to not encounter the error twice + # this will not be written to the manifest.txt because we set + # the error flag and will exit after the loop + specs.remove(p) + if error: + # exit after all errors have been found + exit(1) + + return specs diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/helpers.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/helpers.py new file mode 100644 index 00000000..8a28b0e8 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/helpers.py @@ -0,0 +1,61 @@ +from .spec import PluginSpec + +MANIFEST_FILE = "manifest.txt" +BLACKLIST_FILE = "blacklist.txt" +PKGS_FILE = "default.nix" +JSON_FILE = ".plugins.json" +PLUGINS_LIST_FILE = "plugins.md" + + +def get_const(const: str, plug_dir: str) -> str: + out = plug_dir + "/" + const + return out + + +def read_manifest(plug_dir: str) -> list[str]: + with open(get_const(MANIFEST_FILE, plug_dir), "r") as file: + specs = set([spec.strip() for spec in file.readlines()]) + + return sorted(specs) + + +def read_manifest_to_spec(plug_dir: str) -> list[PluginSpec]: + manifest = read_manifest(plug_dir) + specs = [PluginSpec.from_spec(spec.strip()) for spec in manifest] + + return sorted(specs) + + +def read_blacklist(plug_dir: str) -> list[str]: + with open(get_const(BLACKLIST_FILE, plug_dir), "r") as file: + if len(file.readlines()) == 0: + return [""] + else: + blacklisted_specs = set([spec.strip() for spec in file.readlines()]) + + return sorted(blacklisted_specs) + + +def read_blacklist_to_spec(plug_dir: str) -> list[PluginSpec]: + blacklist = read_blacklist(plug_dir) + specs = [PluginSpec.from_spec(spec.strip()) for spec in blacklist] + + return sorted(specs) + + +def write_manifest(specs: list[str] | set[str], plug_dir: str): + """write specs to manifest file. Does some cleaning up""" + + with open(get_const(MANIFEST_FILE, plug_dir), "w") as file: + specs = sorted(set(specs), key=lambda x: x.lower()) + specs = [p for p in specs] + + for s in specs: + file.write(f"{s}\n") + + +def write_manifest_from_spec(specs: list[PluginSpec], plug_dir: str): + """write specs to manifest file. Does some cleaning up""" + + strings = [f"{spec}" for spec in specs] + write_manifest(strings, plug_dir) diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/nix.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/nix.py new file mode 100644 index 00000000..66a8df4c --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/nix.py @@ -0,0 +1,121 @@ +import abc +import enum +import json +import subprocess + + +def nix_prefetch_url(url): + """Return the sha256 hash of the given url.""" + subprocess_output = subprocess.check_output( + ["nix-prefetch-url", "--type", "sha256", url], + stderr=subprocess.DEVNULL, + ) + sha256 = subprocess_output.decode("utf-8").strip() + return sha256 + + +def nix_prefetch_git(url): + """Return the sha256 hash of the given git url.""" + subprocess_output = subprocess.check_output(["nix-prefetch-git", url], stderr=subprocess.DEVNULL) + sha256 = json.loads(subprocess_output)["sha256"] + return sha256 + + +class Source(abc.ABC): + """Abstract base class for sources.""" + + url: str + sha256: str + + @abc.abstractmethod + def __init__(self, url: str) -> None: + """Initialize a Source.""" + + @abc.abstractmethod + def get_nix_expression(self): + """Return the nix expression for this source.""" + + def __repr__(self): + """Return the representation of this source.""" + return self.get_nix_expression() + + +class UrlSource(Source): + """A source that is a url.""" + + def __init__(self, url: str) -> None: + """Initialize a UrlSource.""" + self.url = url + self.sha256 = nix_prefetch_url(url) + + def get_nix_expression(self): + """Return the nix expression for this source.""" + return f'fetchurl {{ url = "{self.url}"; sha256 = "{self.sha256}"; }}' + + +class GitSource(Source): + """A source that is a git repository.""" + + def __init__(self, url: str, rev: str) -> None: + """Initialize a GitSource.""" + self.url = url + self.rev = rev + self.sha256 = nix_prefetch_git(url) + + def get_nix_expression(self): + """Return the nix expression for this source.""" + return f'fetchgit {{ url = "{self.url}"; rev = "{self.rev}"; sha256 = "{self.sha256}"; }}' + + +class License(enum.Enum): + """An enumeration of licenses.""" + + AGPL_3_0 = "agpl3Only" + APACHE_2_0 = "asf20" + BSD_2_CLAUSE = "bsd2" + BSD_3_CLAUSE = "bsd3" + BSL_1_0 = "bsl1_0" + CC0_1_0 = "cc0" + EPL_2_0 = "epl20" + GPL_2_0 = "gpl2Only" + GPL_3_0 = "gpl3Only" + ISCLGPL_2_1 = "lgpl21Only" + MIT = "mit" + MPL_2_0 = "mpl20" + UNLUNLICENSE = "unlicense" + WTFPL = "wtfpl" + UNFREE = "unfree" + UNKNOWN = "" + + @classmethod + def from_spdx_id(cls, spdx_id: str | None) -> "License": + """Return the License from the given spdx_id.""" + mapping = { + "AGPL-3.0": cls.AGPL_3_0, + "AGPL-3.0-only": cls.AGPL_3_0, + "Apache-2.0": cls.APACHE_2_0, + "BSD-2-Clause": cls.BSD_2_CLAUSE, + "BSD-3-Clause": cls.BSD_3_CLAUSE, + "BSL-1.0": cls.BSL_1_0, + "CC0-1.0": cls.CC0_1_0, + "EPL-2.0": cls.EPL_2_0, + "GPL-2.0": cls.GPL_2_0, + "GPL-2.0-only": cls.GPL_2_0, + "GPL-3.0": cls.GPL_3_0, + "GPL-3.0-only": cls.GPL_3_0, + "LGPL-2.1-only": cls.ISCLGPL_2_1, + "MIT": cls.MIT, + "MPL-2.0": cls.MPL_2_0, + "Unlicense": cls.UNLUNLICENSE, + "WTFPL": cls.WTFPL, + } + + if spdx_id is None: + return cls.UNKNOWN + + spdx_id = spdx_id.upper() + return mapping.get(spdx_id, cls.UNKNOWN) + + def __str__(self): + """Return the string representation of this license.""" + return self.value diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/plugin.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/plugin.py new file mode 100644 index 00000000..8334ad53 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/plugin.py @@ -0,0 +1,182 @@ +import logging +import os +import urllib + +import requests +import jsonpickle +from datetime import datetime, date +from dateparser import parse + +from .nix import GitSource, License, Source, UrlSource +from .spec import PluginSpec, RepositoryHost + + +logger = logging.getLogger(__name__) + + +class VimPlugin: + """Abstract base class for vim plugins.""" + + name: str + owner: str + repo: str + version: date + source: Source + description: str = "No description" + homepage: str + license: License + source_line: str + checked: date = datetime.now().date() + + def to_nix(self): + """Return the nix expression for this plugin.""" + meta = f'with lib; {{ description = "{self.description}"; homepage = "{self.homepage}"; license = with licenses; [ {self.license.value} ]; }}' + return f'/* Generated from: {self.source_line} */ {self.name} = buildVimPlugin {{ pname = "{self.name}"; version = "{self.version}"; src = {self.source.get_nix_expression()}; meta = {meta}; }};' + + def to_json(self): + """Serizalize the plugin to json""" + return jsonpickle.encode(self) + + def to_markdown(self): + link = f"[{self.source_line}]({self.homepage})" + version = f"{self.version}" + package_name = f"{self.name}" + checked = f"{self.checked}" + + return f"| {link} | {version} | `{package_name}` | {checked} |" + + def __lt__(self, o: object) -> bool: + if not isinstance(o, VimPlugin): + return False + + return self.name.lower() < o.name.lower() + + def __repr__(self): + """Return the representation of this plugin.""" + return f"VimPlugin({self.name!r}, {self.version.strftime('%Y-%m-%d')})" + + +def _get_github_token(): + token = os.environ.get("GITHUB_TOKEN") + if token is None: + # NOTE: This should never use more than the free api requests <2023-12-09> + pass + # logger.warning("GITHUB_TOKEN environment variable not set") + return token + + +class GitHubPlugin(VimPlugin): + def __init__(self, plugin_spec: PluginSpec) -> None: + """Initialize a GitHubPlugin.""" + + full_name = f"{plugin_spec.owner}/{plugin_spec.repo}" + repo_info = self._api_call(f"repos/{full_name}") + default_branch = plugin_spec.branch or repo_info["default_branch"] + api_callback = self._api_call(f"repos/{full_name}/commits/{default_branch}") + latest_commit = api_callback["commit"] + sha = api_callback["sha"] + + self.name = plugin_spec.name + self.owner = plugin_spec.owner + self.version = parse(latest_commit["committer"]["date"]).date() + self.source = UrlSource(f"https://github.com/{full_name}/archive/{sha}.tar.gz") + self.description = (repo_info.get("description") or "").replace('"', '\\"') + self.homepage = repo_info["html_url"] + self.license = plugin_spec.license or License.from_spdx_id((repo_info.get("license") or {}).get("spdx_id")) + self.source_line = plugin_spec.line + + def _api_call(self, path: str, token: str | None = _get_github_token()): + """Call the GitHub API.""" + url = f"https://api.github.com/{path}" + headers = {"Content-Type": "application/json"} + if token is not None: + headers["Authorization"] = f"token {token}" + response = requests.get(url, headers=headers) + if response.status_code != 200: + raise RuntimeError(f"GitHub API call failed: {response.text}") + return response.json() + + +class GitlabPlugin(VimPlugin): + def __init__(self, plugin_spec: PluginSpec) -> None: + """Initialize a GitlabPlugin.""" + + full_name = urllib.parse.quote(f"{plugin_spec.owner}/{plugin_spec.repo}", safe="") + repo_info = self._api_call(f"projects/{full_name}") + default_branch = plugin_spec.branch or repo_info["default_branch"] + api_callback = self._api_call(f"projects/{full_name}/repository/branches/{default_branch}") + latest_commit = api_callback["commit"] + sha = latest_commit["id"] + + self.name = plugin_spec.name + self.owner = plugin_spec.owner + self.version = parse(latest_commit["created_at"]).date() + self.source = UrlSource(f"https://gitlab.com/api/v4/projects/{full_name}/repository/archive.tar.gz?sha={sha}") + self.description = (repo_info.get("description") or "").replace('"', '\\"') + self.homepage = repo_info["web_url"] + self.license = plugin_spec.license or License.from_spdx_id(repo_info.get("license", {}).get("key")) + self.source_line = plugin_spec.line + + def _api_call(self, path: str) -> dict: + """Call the Gitlab API.""" + url = f"https://gitlab.com/api/v4/{path}" + response = requests.get(url) + if response.status_code != 200: + raise RuntimeError(f"Gitlab API call failed: {response.text}") + return response.json() + + +def _get_sourcehut_token(): + token = os.environ.get("SOURCEHUT_TOKEN") + if token is None: + # NOTE: This should never use more than the free requests <2023-12-09> + pass + # logger.warning("SOURCEHUT_TOKEN environment variable not set") + return token + + +class SourceHutPlugin(VimPlugin): + def __init__(self, plugin_spec: PluginSpec) -> None: + """Initialize a SourceHutPlugin.""" + + repo_info = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}") + if plugin_spec.branch is None: + commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log") + else: + commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log/{plugin_spec.branch}") + latest_commit = commits["results"][0] + sha = latest_commit["id"] + + self.name = plugin_spec.name + self.owner = plugin_spec.owner + self.version = parse(latest_commit["timestamp"]).date() + self.description = (repo_info.get("description") or "").replace('"', '\\"') + self.homepage = f"https://git.sr.ht/~{plugin_spec.owner}/{plugin_spec.repo}" + self.source = GitSource(self.homepage, sha) + self.license = plugin_spec.license or License.UNKNOWN # cannot be determined via API + self.source_line = plugin_spec.line + + def _api_call(self, path: str, token: str | None = _get_sourcehut_token()): + """Call the SourceHut API.""" + + url = f"https://git.sr.ht/api/{path}" + headers = {"Content-Type": "application/json"} + if token is not None: + headers["Authorization"] = f"token {token}" + response = requests.get(url, headers=headers) + if response.status_code != 200: + raise RuntimeError(f"SourceHut API call failed: {response.json()}") + return response.json() + + +def plugin_from_spec(plugin_spec: PluginSpec) -> VimPlugin: + """Initialize a VimPlugin.""" + + if plugin_spec.repository_host == RepositoryHost.GITHUB: + return GitHubPlugin(plugin_spec) + elif plugin_spec.repository_host == RepositoryHost.GITLAB: + return GitlabPlugin(plugin_spec) + elif plugin_spec.repository_host == RepositoryHost.SOURCEHUT: + return SourceHutPlugin(plugin_spec) + else: + raise NotImplementedError(f"Unsupported source: {plugin_spec.repository_host}") diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/spec.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/spec.py new file mode 100644 index 00000000..0f2fb29c --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/spec.py @@ -0,0 +1,143 @@ +import enum +import re + +from .nix import License + + +class RepositoryHost(enum.Enum): + """A repository host.""" + + GITHUB = "github" + GITLAB = "gitlab" + SOURCEHUT = "sourcehut" + + +class PluginSpec: + """A Vim plugin Spec.""" + + @classmethod + def from_spec(cls, spec): + """The spec line must be in the format: + [:]/[:][:name]. + + repository_host is one of github (default), gitlab, or sourcehut. + owner is the repository owner. + repo is the repository name. + branch is the git branch. + name is the name to use for the plugin (default is value of repo). + """ + repository_host = RepositoryHost.GITHUB + # gitref = "master" + + repository_host_regex = r"((?P[^:]+):)" + owner_regex = r"(?P[^/:]+)" + repo_regex = r"(?P[^:]+)" + branch_regex = r"(:(?P[^:]+)?)" + name_regex = r"(:(?P[^:]+)?)" + license_regex = r"(:(?P[^:]+)?)" + marked_duplicate_regex = r"(:(?Pduplicate))" + + spec_regex = re.compile( + f"^{repository_host_regex}?{owner_regex}/{repo_regex}{branch_regex}?{name_regex}?{license_regex}?{marked_duplicate_regex}?$", + ) + + match = spec_regex.match(spec) + if match is None: + raise ValueError(f"Invalid spec: {spec}") + + group_dict = match.groupdict() + + repository_host = RepositoryHost(group_dict.get("repository_host") or "github") + + owner = group_dict.get("owner") + if owner is None: + raise RuntimeError("Could not get owner") + + repo = group_dict.get("repo") + if repo is None: + raise RuntimeError("Could not get repo") + + branch = group_dict.get("branch") + name = group_dict.get("name") + license = group_dict.get("license") + marked_duplicate = bool(group_dict.get("duplicate")) # True if 'duplicate', False if None + + line = spec + + return cls(repository_host, owner, repo, line, branch, name, license, marked_duplicate) + + def __init__( + self, + repository_host: RepositoryHost, + owner: str, + repo: str, + line: str, + branch: str | None = None, + name: str | None = None, + license: str | None = None, + marked_duplicate: bool = False, + ) -> None: + """Initialize a VimPluginSpec.""" + self.repository_host = repository_host + self.owner = owner + self.repo = repo + self.branch = branch + self.custom_name = name + self.name = name or repo.replace(".", "-").replace("_", "-") + self.license = License(license) if license else None + self.line = line + self.marked_duplicate = marked_duplicate + + def __str__(self) -> str: + """Return a string representation of a VimPluginSpec.""" + spec = "" + + if self.repository_host != RepositoryHost.GITHUB: + spec += f"{self.repository_host.value}:" + + spec += f"{self.owner}/{self.repo}" + + spec += ":" + if self.branch is not None: + spec += self.branch + + spec += ":" + if self.custom_name is not None: + spec += self.custom_name + + spec += ":" + if self.license is not None: + spec += str(self.license) + + spec += ":" + if self.marked_duplicate: + spec += "duplicate" + + return spec.rstrip(":") + + def __repr__(self): + """Return the representation of the specs""" + return f"PluginSpec({self.owner}/{self.repo}, {self.name})" + + def to_spec(self): + """Return a spec line for a VimPluginSpec.""" + return str(self) + + def __lt__(self, o: object) -> bool: + if not isinstance(o, PluginSpec): + return False + + return self.name.lower() < o.name.lower() + + def __eq__(self, o: object) -> bool: + """Return True if the two specs are equal.""" + if not isinstance(o, PluginSpec): + return False + + return ( + self.repository_host == o.repository_host + and self.owner == o.owner + and self.repo == o.repo + and self.branch == o.branch + and self.name == o.name + ) diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/__init__.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/fixtures.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/fixtures.py new file mode 100644 index 00000000..75dd251a --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/fixtures.py @@ -0,0 +1,44 @@ +import json + +import pytest +from pytest_mock import MockerFixture + +from update_vim_plugins.nix import GitSource, UrlSource + + +@pytest.fixture() +def url(): + return "https://example.com" + + +@pytest.fixture() +def rev(): + return "1234567890abcdef" + + +@pytest.fixture() +def sha256(): + return "sha256-1234567890abcdef" + + +@pytest.fixture() +def url_source(mocker: MockerFixture, url: str, sha256: str): + mocker.patch("subprocess.check_output", return_value=bytes(sha256, "utf-8")) + return UrlSource(url) + + +@pytest.fixture() +def git_source(mocker: MockerFixture, url: str, rev: str, sha256: str): + return_value = { + "url": url, + "rev": rev, + "date": "1970-01-01T00:00:00+00:00", + "path": "", + "sha256": sha256, + "fetchLFS": False, + "fetchSubmodules": False, + "deepClone": False, + "leaveDotGit": False, + } + mocker.patch("subprocess.check_output", return_value=json.dumps(return_value).encode("utf-8")) + return GitSource(url, rev) diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_nix.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_nix.py new file mode 100644 index 00000000..46e59f76 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_nix.py @@ -0,0 +1,32 @@ +from update_vim_plugins.nix import GitSource, License, UrlSource + + +def test_url_source(url_source: UrlSource, url: str, sha256: str): + assert url_source.url == url + assert url_source.sha256 == sha256 + + +def test_url_source_nix_expression(url_source: UrlSource, url: str, sha256: str): + assert url_source.get_nix_expression() == f'fetchurl {{ url = "{url}"; sha256 = "{sha256}"; }}' + + +def test_git_source(git_source: GitSource, url: str, rev: str, sha256: str): + assert git_source.url == url + assert git_source.sha256 == sha256 + assert git_source.rev == rev + + +def test_git_source_nix_expression(git_source: GitSource, url: str, rev: str, sha256: str): + assert git_source.get_nix_expression() == f'fetchgit {{ url = "{url}"; rev = "{rev}"; sha256 = "{sha256}"; }}' + + +def test_license_github(): + github_license = "MIT" + license = License.from_spdx_id(github_license) + assert license == License.MIT + + +def test_license_gitlab(): + gitlab_license = "mit" + license = License.from_spdx_id(gitlab_license) + assert license == License.MIT diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_plugin.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_plugin.py new file mode 100644 index 00000000..32377e24 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_plugin.py @@ -0,0 +1,144 @@ +import json +from typing import Callable + +import pytest +from pytest_mock import MockFixture + +from update_vim_plugins.nix import License, UrlSource +from update_vim_plugins.plugin import GitHubPlugin, VimPlugin +from update_vim_plugins.spec import PluginSpec + + +@pytest.fixture() +def mock_source(sha256: str): + class MockSource: + def __init__(self, *args, **kwargs): + pass + + def get_nix_expression(self): + return "src" + + return MockSource() + + +@pytest.fixture() +def mock_plugin(mock_source): + class MockVimPlugin(VimPlugin): + def __init__(self): + self.name = "test" + self.version = "1.0.0" + self.source = mock_source + self.description = "No description" + self.homepage = "https://example.com" + self.license = License.UNKNOWN + + return MockVimPlugin() + + +def test_vim_plugin_nix_expression(mock_plugin): + assert ( + mock_plugin.get_nix_expression() + == 'test = buildVimPluginFrom2Nix { pname = "test"; version = "1.0.0"; src = src; meta = with lib; { description = "No description"; homepage = "https://example.com"; license = with licenses; [ ]; }; };' + ) + + +class MockResponse: + def __init__(self, status_code: int, content: bytes): + self.status_code = status_code + self.content = content + + def json(self): + return json.loads(self.content) + + +def mock_request_get(repsonses: dict[str, MockResponse]): + respones_not_found = MockResponse(404, b'{"message": "Not Found"}') + + def mock_get(url: str, *args, **kwargs): + return repsonses.get(url, respones_not_found) + + return mock_get + + +@pytest.fixture() +def github_commits_response(): + return MockResponse( + 200, + json.dumps( + { + "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", + "commit": { + "committer": { + "date": "2011-04-14T16:00:49Z", + }, + }, + } + ), + ) + + +@pytest.fixture() +def github_get(github_commits_response: MockResponse): + repos_response = MockResponse( + 200, + json.dumps( + { + "html_url": "https://github.com/octocat/Hello-World", + "description": "This your first repo!", + "fork": False, + "default_branch": "master", + "license": { + "spdx_id": "MIT", + }, + } + ), + ) + responses = { + "https://api.github.com/repos/octocat/Hello-World": repos_response, + "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response, + } + return mock_request_get(responses) + + +@pytest.fixture() +def github_get_no_license(github_commits_response: MockResponse): + repos_response = MockResponse( + 200, + json.dumps( + { + "html_url": "https://github.com/octocat/Hello-World", + "description": "This your first repo!", + "fork": False, + "default_branch": "master", + } + ), + ) + responses = { + "https://api.github.com/repos/octocat/Hello-World": repos_response, + "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response, + } + return mock_request_get(responses) + + +def test_github_plugin(mocker: MockFixture, github_get: Callable, url_source: UrlSource): + mocker.patch("requests.get", github_get) + url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source) + + spec = PluginSpec.from_spec("octocat/Hello-World") + plugin = GitHubPlugin(spec) + + assert plugin.name == "Hello-World" + assert plugin.version == "2011-04-14" + assert plugin.description == "This your first repo!" + assert plugin.homepage == "https://github.com/octocat/Hello-World" + assert plugin.license == License.MIT + + +def test_github_plugin_no_license(mocker: MockFixture, github_get_no_license: Callable, url_source: UrlSource): + mocker.patch("requests.get", github_get_no_license) + url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source) + + spec = PluginSpec.from_spec("octocat/Hello-World") + plugin = GitHubPlugin(spec) + + assert plugin.license == License.UNKNOWN diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_spec.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_spec.py new file mode 100644 index 00000000..2b9a1d24 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/tests/test_spec.py @@ -0,0 +1,136 @@ +import pytest + +from update_vim_plugins.spec import PluginSpec, RepositoryHost + + +@pytest.fixture() +def owner(): + return "owner" + + +@pytest.fixture() +def repo(): + return "repo.nvim" + + +@pytest.fixture() +def branch(): + return "main" + + +@pytest.fixture() +def name(): + return "repo-nvim" + + +@pytest.fixture() +def license(): + return "mit" + + +def test_from_spec_simple(owner: str, repo: str): + vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}") + + assert vim_plugin.owner == owner + assert vim_plugin.repo == repo + + +def test_from_spec_with_gitref(owner: str, repo: str, branch: str): + vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}:{branch}") + + assert vim_plugin.branch == branch + + +def test_from_spec_with_name(owner: str, repo: str, name: str): + vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}::{name}") + + assert vim_plugin.name == name + + +@pytest.mark.parametrize("host", RepositoryHost) +def test_from_spec_with_repository_host(owner: str, repo: str, host: RepositoryHost): + vim_plugin = PluginSpec.from_spec(f"{host.value}:{owner}/{repo}") + + assert vim_plugin.repository_host == host + + +def test_from_spec_without_repository_host(owner: str, repo: str): + vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}") + + assert vim_plugin.repository_host == RepositoryHost.GITHUB + + +def test_from_spec_complex(owner: str, repo: str, branch: str, name: str): + vim_plugin = PluginSpec.from_spec(f"gitlab:{owner}/{repo}:{branch}:{name}") + + assert vim_plugin.repository_host == RepositoryHost.GITLAB + assert vim_plugin.owner == owner + assert vim_plugin.repo == repo + assert vim_plugin.branch == branch + assert vim_plugin.name == name + + +def test_from_spec_invalid_spec(): + with pytest.raises(ValueError): + PluginSpec.from_spec("invalid_spec") + + +def test_to_spec_simple(owner: str, repo: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) + + assert vim_plugin.to_spec() == f"{owner}/{repo}" + + +def test_to_spec_with_branch(owner: str, repo: str, branch: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch=branch) + assert vim_plugin.to_spec() == f"{owner}/{repo}:{branch}" + + +def test_to_spec_with_name(owner: str, repo: str, name: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name) + + assert vim_plugin.to_spec() == f"{owner}/{repo}::{name}" + + +@pytest.mark.parametrize("host", [RepositoryHost.GITLAB, RepositoryHost.SOURCEHUT]) +def test_to_spec_with_repository_host(host: RepositoryHost, owner: str, repo: str): + vim_plugin = PluginSpec(host, owner, repo) + + assert vim_plugin.to_spec() == f"{host.value}:{owner}/{repo}" + + +def test_to_spec_complex(owner: str, repo: str, branch: str, name: str, license: str): + vim_plugin = PluginSpec(RepositoryHost.GITLAB, owner, repo, branch=branch, name=name, license=license) + + assert vim_plugin.to_spec() == f"gitlab:{owner}/{repo}:{branch}:{name}:{license}" + + +def test_spec_equal(owner: str, repo: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) + vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo) + + assert vim_plugin == vim_plugin2 + + +def test_spec_not_equal_different_branch(owner: str, repo: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) + vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch="main") + + assert vim_plugin != vim_plugin2 + + +def test_spec_not_equal_different_name(owner: str, repo: str): + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) + vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name="renamed") + + assert vim_plugin != vim_plugin2 + + +def test_spec_equal_same_normalized_name(owner: str): + repo = "repo.nvim" + name = "repo-nvim" + + vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) + vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name) + + assert vim_plugin == vim_plugin2 diff --git a/pkgs/sources/update_vim_plugins/update_vim_plugins/update.py b/pkgs/sources/update_vim_plugins/update_vim_plugins/update.py new file mode 100644 index 00000000..7eb3eeb4 --- /dev/null +++ b/pkgs/sources/update_vim_plugins/update_vim_plugins/update.py @@ -0,0 +1,212 @@ +import subprocess +from random import shuffle +from cleo.helpers import argument, option +from cleo.commands.command import Command +from concurrent.futures import ThreadPoolExecutor, as_completed + +from pprint import pprint + +from .plugin import plugin_from_spec + +from .helpers import read_manifest_to_spec, get_const +from .helpers import JSON_FILE, PLUGINS_LIST_FILE, PKGS_FILE + +import json +import jsonpickle + +jsonpickle.set_encoder_options("json", sort_keys=True) + + +class UpdateCommand(Command): + name = "update" + description = "Generate nix module from input file" + arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)] + options = [ + option("all", "a", description="Update all plugins. Else only update new plugins", flag=True), + option("dry-run", "d", description="Show which plugins would be updated", flag=True), + ] + + def handle(self): + """Main command function""" + + plug_dir = self.argument("plug_dir") + self.specs = read_manifest_to_spec(plug_dir) + + if self.option("all"): + # update all plugins + spec_list = self.specs + known_plugins = [] + else: + # filter plugins we already know + spec_list = self.specs + + with open(get_const(JSON_FILE, plug_dir), "r") as json_file: + data = json.load(json_file) + + known_specs = list(filter(lambda x: x.line in data, spec_list)) + known_plugins = [jsonpickle.decode(data[x.line]) for x in known_specs] + + spec_list = list(filter(lambda x: x.line not in data, spec_list)) + + if self.option("dry-run"): + self.line("These plugins would be updated") + pprint(spec_list) + self.line(f"Total: {len(spec_list)}") + exit(0) + + processed_plugins, failed_plugins, failed_but_known = self.process_manifest(spec_list, plug_dir) + + processed_plugins += known_plugins # add plugins from .plugins.json + processed_plugins: list = sorted(set(processed_plugins)) # remove duplicates based only on source line + + self.check_duplicates(processed_plugins) + + if failed_plugins != []: + self.line("Not processed: The following plugins could not be updated") + for s, e in failed_plugins: + self.line(f" - {s!r} - {e}") + + if failed_but_known != []: + self.line( + "Not updated: The following plugins could not be updated but an older version is known" + ) + for s, e in failed_but_known: + self.line(f" - {s!r} - {e}") + + # update plugin "database" + self.write_plugins_json(processed_plugins, plug_dir) + + # generate output + self.write_plugins_nix(processed_plugins, plug_dir) + + self.write_plugins_markdown(processed_plugins, plug_dir) + + self.line("Done") + + def write_plugins_markdown(self, plugins, plug_dir): + """Write the list of all plugins to PLUGINS_LIST_FILE in markdown""" + + plugins.sort() + + self.line("Updating plugins.md") + + header = f" - Plugin count: {len(plugins)}\n\n| Repo | Last Update | Nix package name | Last checked |\n|:---|:---|:---|:---|\n" + + with open(get_const(PLUGINS_LIST_FILE, plug_dir), "w") as file: + file.write(header) + for plugin in plugins: + file.write(f"{plugin.to_markdown()}\n") + + def write_plugins_nix(self, plugins, plug_dir): + self.line("Generating nix output") + + plugins.sort() + + header = "{ lib, buildVimPlugin, fetchurl, fetchgit }: {" + footer = "}" + + with open(get_const(PKGS_FILE, plug_dir), "w") as file: + file.write(header) + for plugin in plugins: + file.write(f"{plugin.to_nix()}\n") + file.write(footer) + + self.line("Formatting nix output") + + subprocess.run( + ["alejandra", get_const(PKGS_FILE, plug_dir)], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + + def write_plugins_json(self, plugins, plug_dir): + self.line("Storing results in .plugins.json") + + plugins.sort() + + with open(get_const(JSON_FILE, plug_dir), "r+") as json_file: + data = json.load(json_file) + + for plugin in plugins: + data.update({f"{plugin.source_line}": plugin.to_json()}) + + json_file.seek(0) + json_file.write(json.dumps(data, indent=2, sort_keys=True)) + json_file.truncate() + + def check_duplicates(self, plugins): + """check for duplicates in proccesed_plugins""" + error = False + for i, plugin in enumerate(plugins): + for p in plugins[i + 1 :]: + if plugin.name == p.name: + self.line( + f"Error: The following two lines produce the same plugin name:\n - {plugin.source_line}\n - {p.source_line}\n -> {p.name}" + ) + error = True + + # We want to exit if the resulting nix file would be broken + # But we want to go through all plugins before we do so + if error: + exit(1) + + def generate_plugin(self, spec, i, size, plug_dir): + debug_string = "" + + processed_plugin = None + failed_but_known = None + failed_plugin = None + try: + debug_string += f" - ({i+1}/{size}) Processing {spec!r}\n" + vim_plugin = plugin_from_spec(spec) + debug_string += f" • Success {vim_plugin!r}\n" + processed_plugin = vim_plugin + except Exception as e: + debug_string += f" • Error: Could not update {spec.name}. Keeping old values. Reason: {e}\n" + with open(get_const(JSON_FILE, plug_dir), "r") as json_file: + data = json.load(json_file) + + plugin_json = data.get(spec.line) + if plugin_json: + vim_plugin = jsonpickle.decode(plugin_json) + processed_plugin = vim_plugin + failed_but_known = (vim_plugin, e) + else: + debug_string += f" • Error: No entries for {spec.name} in '.plugins.json'. Skipping...\n" + failed_plugin = (spec, e) + + self.line(debug_string.strip()) + + return processed_plugin, failed_plugin, failed_but_known + + def process_manifest(self, spec_list, plug_dir): + """Read specs in 'spec_list' and generate plugins""" + + size = len(spec_list) + + # We have to assume that we will reach an api limit. Therefore + # we randomize the spec list to give every entry the same change to be updated and + # not favor those at the start of the list + shuffle(spec_list) + + with ThreadPoolExecutor() as executor: + futures = [ + executor.submit(self.generate_plugin, spec, i, size, plug_dir) for i, spec in enumerate(spec_list) + ] + results = [future.result() for future in as_completed(futures)] + + processed_plugins = [r[0] for r in results] + failed_plugins = [r[1] for r in results] + failed_but_known = [r[2] for r in results] + + processed_plugins = list(filter(lambda x: x is not None, processed_plugins)) + failed_plugins = list(filter(lambda x: x is not None, failed_plugins)) + failed_but_known = list(filter(lambda x: x is not None, failed_but_known)) + + processed_plugins.sort() + failed_plugins.sort() + failed_but_known.sort() + + assert len(processed_plugins) == len(spec_list) - len(failed_plugins) + + return processed_plugins, failed_plugins, failed_but_known diff --git a/pkgs/sources/yt/.env b/pkgs/sources/yt/.env new file mode 100755 index 00000000..8018a738 --- /dev/null +++ b/pkgs/sources/yt/.env @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +PATH="$(pwd)/target/release/:$(pwd)/target/debug/:$PATH" diff --git a/pkgs/sources/yt/.envrc b/pkgs/sources/yt/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/pkgs/sources/yt/.envrc @@ -0,0 +1 @@ +use flake diff --git a/pkgs/sources/yt/.gitignore b/pkgs/sources/yt/.gitignore new file mode 100644 index 00000000..c84fa049 --- /dev/null +++ b/pkgs/sources/yt/.gitignore @@ -0,0 +1,3 @@ +# build dirs +/target +/result diff --git a/pkgs/sources/yt/Cargo.lock b/pkgs/sources/yt/Cargo.lock new file mode 100644 index 00000000..ef2a53fd --- /dev/null +++ b/pkgs/sources/yt/Cargo.lock @@ -0,0 +1,640 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "cli-log" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d2ab00dc4c82ec28af25ac085aecc11ffeabf353755715a3113a7aa044ca5cc" +dependencies = [ + "chrono", + "file-size", + "log", + "proc-status", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "file-size" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9544f10105d33957765016b8a9baea7e689bf1f0f2f32c2fa2f568770c38d2b3" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-status" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e0c0ac915e7b76b47850ba4ffc377abde6c6ff9eeace61d0a89623db449712" +dependencies = [ + "thiserror", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "yt" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "cli-log", + "log", + "serde", + "serde_json", + "tempfile", + "url", +] diff --git a/pkgs/sources/yt/Cargo.toml b/pkgs/sources/yt/Cargo.toml new file mode 100644 index 00000000..7c17d20b --- /dev/null +++ b/pkgs/sources/yt/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "yt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.83" +clap = { version = "4.5.4", features = ["derive"] } +cli-log = "2.0.0" +log = "0.4.21" +serde = { version = "1.0.201", features = ["derive"] } +serde_json = "1.0.117" +tempfile = "3.10.1" +url = "2.5.0" + +# This is here to be able to tell nix which binary to build +[features] +yts = [] +ytc = [] +yt = [] +default = ["yt", "yts", "ytc"] + +[[bin]] +name = "yts" +required-features = ["yts"] + +[[bin]] +name = "ytc" +required-features = ["ytc"] + +[[bin]] +name = "yt" +required-features = ["yt"] diff --git a/pkgs/sources/yt/default.nix b/pkgs/sources/yt/default.nix new file mode 100644 index 00000000..32396051 --- /dev/null +++ b/pkgs/sources/yt/default.nix @@ -0,0 +1,51 @@ +[ + ( + final: prev: { + yt = import ./yt.nix { + inherit + (prev) + lib + makeWrapper + rustPlatform + # dependencies + + ytcc + yt-dlp + mpv + ; + }; + } + ) + ( + final: prev: { + yts = import ./yts.nix { + inherit + (prev) + lib + makeWrapper + rustPlatform + # dependencies + + ytcc + ; + }; + } + ) + ( + final: prev: { + ytc = import ./ytc.nix { + inherit + (prev) + lib + makeWrapper + rustPlatform + # dependencies + + ytcc + yt-dlp + mpv + ; + }; + } + ) +] diff --git a/pkgs/sources/yt/flake.lock b/pkgs/sources/yt/flake.lock new file mode 100644 index 00000000..50494465 --- /dev/null +++ b/pkgs/sources/yt/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715087517, + "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/pkgs/sources/yt/flake.nix b/pkgs/sources/yt/flake.nix new file mode 100644 index 00000000..561b1c0d --- /dev/null +++ b/pkgs/sources/yt/flake.nix @@ -0,0 +1,30 @@ +{ + description = "yt"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: (flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages."${system}"; + in { + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + # rust stuff + cargo + clippy + rustc + rustfmt + + cargo-edit + cargo-expand + ]; + }; + })); +} diff --git a/pkgs/sources/yt/src/bin/yt/main.rs b/pkgs/sources/yt/src/bin/yt/main.rs new file mode 100644 index 00000000..37348834 --- /dev/null +++ b/pkgs/sources/yt/src/bin/yt/main.rs @@ -0,0 +1,91 @@ +use anyhow::{bail, Context, Result}; +use std::{ + env, fs, + io::{BufRead, BufReader, BufWriter, Write}, + process::Command as StdCmd, +}; +use tempfile::Builder; +use yt::{ + constants::{last_select, HELP_STR}, + downloader::Downloader, + filter_line, YtccListData, +}; + +fn main() -> Result<()> { + cli_log::init_cli_log!(); + + let json_map = { + let mut ytcc = StdCmd::new("ytcc"); + ytcc.args([ + "--output", + "json", + "list", + "--order-by", + "publish_date", + "desc", + ]); + + serde_json::from_slice::>( + &ytcc.output().context("Failed to json from ytcc")?.stdout, + ) + .context("Failed to deserialize json output")? + }; + + let temp_file = Builder::new() + .prefix("yt_video_select-") + .suffix(".yts") + .rand_bytes(6) + .tempfile() + .context("Failed to get tempfile")?; + + { + let mut edit_file = BufWriter::new(&temp_file); + + json_map.iter().for_each(|line| { + let line = line.to_string(); + edit_file + .write_all(line.as_bytes()) + .expect("This write should not fail"); + }); + + edit_file.write_all(HELP_STR.as_bytes())?; + edit_file.flush().context("Failed to flush edit file")?; + + let mut nvim = StdCmd::new("nvim"); + nvim.arg(temp_file.path()); + let status = nvim.status().context("Falied to run nvim")?; + if !status.success() { + bail!("nvim exited with error status: {}", status) + } + } + + let read_file = temp_file.reopen()?; + fs::copy( + temp_file.path(), + last_select().context("Failed to get the persistent selection file path")?, + ) + .context("Failed to persist selection file")?; + + let mut watching = Vec::new(); + let reader = BufReader::new(&read_file); + for line in reader.lines() { + let line = line.context("Failed to read line")?; + + if let Some(downloadable) = + filter_line(&line).with_context(|| format!("Failed to process line: '{}'", line))? + { + watching.push(downloadable); + } + } + + if watching.is_empty() { + return Ok(()); + } + + let downloader = Downloader::new(watching).context("Failed to construct downloader")?; + downloader + .consume() + .context("Failed to consume downloader")?; + + Ok(()) +} diff --git a/pkgs/sources/yt/src/bin/ytc/args.rs b/pkgs/sources/yt/src/bin/ytc/args.rs new file mode 100644 index 00000000..8b2d6a61 --- /dev/null +++ b/pkgs/sources/yt/src/bin/ytc/args.rs @@ -0,0 +1,26 @@ +use clap::{Parser, Subcommand}; +/// A helper for downloading and playing youtube videos +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +pub struct Args { + #[command(subcommand)] + /// The subcommand to execute + pub subcommand: Command, +} +#[derive(Subcommand, Debug)] +pub enum Command { + #[clap(value_parser)] + /// Work based of ytcc ids + Id { + #[clap(value_parser)] + /// A list of ids to play + ids: Vec, + }, + #[clap(value_parser)] + /// Work based of raw youtube urls + Url { + #[clap(value_parser)] + /// A list of urls to play + urls: Vec, + }, +} diff --git a/pkgs/sources/yt/src/bin/ytc/main.rs b/pkgs/sources/yt/src/bin/ytc/main.rs new file mode 100644 index 00000000..b38157df --- /dev/null +++ b/pkgs/sources/yt/src/bin/ytc/main.rs @@ -0,0 +1,77 @@ +use std::{env, process::Command as StdCmd}; + +use anyhow::{bail, Context, Result}; +use clap::Parser; +use log::debug; +use url::Url; +use yt::{ + downloader::{Downloadable, Downloader}, + YtccListData, +}; + +use crate::args::{Args, Command}; + +mod args; + +fn main() -> Result<()> { + let args = Args::parse(); + cli_log::init_cli_log!(); + + let playspec: Vec = match args.subcommand { + Command::Id { ids } => { + let mut output = Vec::with_capacity(ids.len()); + for id in ids { + debug!("Adding {}", id); + let mut ytcc = StdCmd::new("ytcc"); + ytcc.args([ + "--output", + "json", + "list", + "--watched", + "--unwatched", + "--attributes", + "url", + "--ids", + id.to_string().as_str(), + ]); + let json = serde_json::from_slice::>( + &ytcc.output().context("Failed to get url from id")?.stdout, + ) + .context("Failed to deserialize json output")?; + + if json.is_empty() { + bail!("Could not find a video with id: {}", id); + } + assert_eq!(json.len(), 1); + let json = json.first().expect("Has only one element"); + + debug!("Id resolved to: '{}'", &json.url); + + output.push(Downloadable { + url: Url::parse(&json.url)?, + id: Some(json.id), + }) + } + output + } + Command::Url { urls } => { + let mut output = Vec::with_capacity(urls.len()); + for url in urls { + output.push(Downloadable { + url: Url::parse(&url).context("Failed to parse url")?, + id: None, + }) + } + output + } + }; + + debug!("Initializing downloader"); + let downloader = Downloader::new(playspec)?; + + downloader + .consume() + .context("Failed to consume downloader")?; + + Ok(()) +} diff --git a/pkgs/sources/yt/src/bin/yts/args.rs b/pkgs/sources/yt/src/bin/yts/args.rs new file mode 100644 index 00000000..56989421 --- /dev/null +++ b/pkgs/sources/yt/src/bin/yts/args.rs @@ -0,0 +1,41 @@ +use clap::{Parser, Subcommand}; +/// A helper for selecting which videos to download from ytcc to ytc +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +pub struct Args { + #[command(subcommand)] + /// subcommand to execute + pub subcommand: Option, +} + +#[derive(Subcommand, Debug)] +pub enum Command { + #[clap(value_parser)] + /// Which ordering to use + Order { + #[command(subcommand)] + command: OrderCommand, + }, +} + +#[derive(Subcommand, Debug)] +pub enum OrderCommand { + #[clap(value_parser)] + /// Order by date + #[group(required = true)] + Date { + #[arg(value_parser)] + /// Order descending + desc: bool, + #[clap(value_parser)] + /// Order ascending + asc: bool, + }, + #[clap(value_parser)] + /// Pass a raw SQL 'ORDER BY' value + Raw { + #[clap(value_parser)] + /// The raw value(s) to pass + value: Vec, + }, +} diff --git a/pkgs/sources/yt/src/bin/yts/main.rs b/pkgs/sources/yt/src/bin/yts/main.rs new file mode 100644 index 00000000..7398db61 --- /dev/null +++ b/pkgs/sources/yt/src/bin/yts/main.rs @@ -0,0 +1,91 @@ +use anyhow::{bail, Context, Result}; +use clap::Parser; +use std::{ + env, + io::{BufRead, BufReader, Write}, + process::Command as StdCmd, +}; +use tempfile::NamedTempFile; +use yt::{constants::HELP_STR, filter_line, YtccListData}; + +use crate::args::{Args, Command, OrderCommand}; + +mod args; + +fn main() -> Result<()> { + let args = Args::parse(); + cli_log::init_cli_log!(); + + let ordering = match args.subcommand.unwrap_or(Command::Order { + command: OrderCommand::Date { + desc: true, + asc: false, + }, + }) { + Command::Order { command } => match command { + OrderCommand::Date { desc, asc } => { + if desc { + vec!["--order-by".into(), "publish_date".into(), "desc".into()] + } else if asc { + vec!["--order-by".into(), "publish_date".into(), "asc".into()] + } else { + vec!["--order-by".into(), "publish_date".into(), "desc".into()] + } + } + OrderCommand::Raw { value } => [vec!["--order-by".into()], value].concat(), + }, + }; + + let json_map = { + let mut ytcc = StdCmd::new("ytcc"); + ytcc.args(["--output", "json", "list"]); + ytcc.args(ordering); + + serde_json::from_slice::>( + &ytcc.output().context("Failed to json from ytcc")?.stdout, + ) + .context("Failed to deserialize json output")? + }; + + let mut edit_file = NamedTempFile::new().context("Failed to get tempfile")?; + + json_map.iter().for_each(|line| { + let line = line.to_string(); + edit_file + .write_all(line.as_bytes()) + .expect("This write should not fail"); + }); + + write!(&edit_file, "{}", HELP_STR)?; + edit_file.flush().context("Failed to flush edit file")?; + + let read_file = edit_file.reopen()?; + + let mut nvim = StdCmd::new("nvim"); + nvim.arg(edit_file.path()); + + let status = nvim.status().context("Falied to run nvim")?; + if !status.success() { + bail!("Nvim exited with error status: {}", status) + } + + let mut watching = Vec::new(); + let reader = BufReader::new(&read_file); + for line in reader.lines() { + let line = line.context("Failed to read line")?; + + if let Some(downloadable) = + filter_line(&line).with_context(|| format!("Failed to process line: '{}'", line))? + { + watching.push(downloadable); + } + } + + let watching: String = watching + .iter() + .map(|d| d.to_string()) + .collect::>() + .join("\n"); + println!("{}", &watching); + Ok(()) +} diff --git a/pkgs/sources/yt/src/constants.rs b/pkgs/sources/yt/src/constants.rs new file mode 100644 index 00000000..5e233656 --- /dev/null +++ b/pkgs/sources/yt/src/constants.rs @@ -0,0 +1,51 @@ +use std::{env, fs, path::PathBuf}; + +pub const HELP_STR: &str = include_str!("./help.str"); + +pub const YT_DLP_FLAGS: [&str; 13] = [ + // Ignore errors arising of unavailable sponsor block API + "--ignore-errors", + "--format", + "bestvideo[height<=?1080]+bestaudio/best", + "--embed-chapters", + "--progress", + "--write-comments", + "--extractor-args", + "youtube:max_comments=150,all,100;comment_sort=top", + "--write-info-json", + "--sponsorblock-mark", + "default", + "--sponsorblock-remove", + "sponsor", +]; +pub const MPV_FLAGS: [&str; 4] = [ + "--speed=2.7", + "--volume=75", + "--keep-open=yes", + "--msg-level=osd/libass=fatal", +]; + +pub const CONCURRENT: u32 = 5; + +pub const DOWNLOAD_DIR: &str = "/tmp/ytcc"; + +fn get_runtime_path(component: &'static str) -> anyhow::Result { + let out: PathBuf = format!( + "{}/{}", + env::var("XDG_RUNTIME_DIR").expect("This should always exist"), + component + ) + .into(); + fs::create_dir_all(out.parent().expect("Parent should exist"))?; + Ok(out) +} + +const STATUS_PATH: &str = "ytcc/running"; +pub fn status_path() -> anyhow::Result { + get_runtime_path(STATUS_PATH) +} + +const LAST_SELECT: &str = "ytcc/selected.yts"; +pub fn last_select() -> anyhow::Result { + get_runtime_path(LAST_SELECT) +} diff --git a/pkgs/sources/yt/src/downloader.rs b/pkgs/sources/yt/src/downloader.rs new file mode 100644 index 00000000..e915700d --- /dev/null +++ b/pkgs/sources/yt/src/downloader.rs @@ -0,0 +1,212 @@ +use std::{ + fs::{self, canonicalize}, + io::{stderr, stdout, Read}, + mem, + os::unix::fs::symlink, + path::PathBuf, + process::Command, + sync::mpsc::{self, Receiver, Sender}, + thread::{self, JoinHandle}, +}; + +use anyhow::{bail, Context, Result}; +use log::{debug, error, warn}; +use url::Url; + +use crate::constants::{status_path, CONCURRENT, DOWNLOAD_DIR, MPV_FLAGS, YT_DLP_FLAGS}; + +#[derive(Debug)] +pub struct Downloadable { + pub url: Url, + pub id: Option, +} + +impl std::fmt::Display for Downloadable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!( + f, + "{}|{}", + self.url.as_str().replace('|', ";"), + self.id.unwrap_or(0), + ) + } +} + +pub struct Downloader { + sent: usize, + download_thread: JoinHandle>, + orx: Receiver<(PathBuf, Option)>, + itx: Option>, + playspec: Vec, +} + +impl Downloader { + pub fn new(mut playspec: Vec) -> anyhow::Result { + let (itx, irx): (Sender, Receiver) = mpsc::channel(); + let (otx, orx) = mpsc::channel(); + let jh = thread::spawn(move || -> Result<()> { + while let Ok(pt) = irx.recv() { + debug!("Got '{}' to be downloaded", pt); + let path = download_url(&pt.url) + .with_context(|| format!("Failed to download url: '{}'", &pt.url))?; + otx.send((path, pt.id)).expect("Should not be dropped"); + } + debug!("Finished Downloading everything"); + Ok(()) + }); + + playspec.reverse(); + let mut output = Downloader { + sent: 0, + download_thread: jh, + orx, + itx: Some(itx), + playspec, + }; + if output.playspec.len() <= CONCURRENT as usize { + output.add(output.playspec.len() as u32)?; + } else { + output.add(CONCURRENT)?; + } + Ok(output) + } + + pub fn add(&mut self, number_to_add: u32) -> Result<()> { + debug!("Adding {} to be downloaded concurrently", number_to_add); + for _ in 0..number_to_add { + let pt = self.playspec.pop().expect("This call should be guarded"); + self.itx.as_ref().expect("Should still be valid").send(pt)?; + self.sent += 1; + } + Ok(()) + } + + /// Return the next video already downloaded, will block until the download is complete + pub fn next(&mut self) -> Option<(PathBuf, Option)> { + debug!("Requesting next output"); + match self.orx.recv() { + Ok(ok) => { + debug!("Output downloaded to: {}", ok.0.display()); + if !self.playspec.is_empty() { + self.add(1).ok()?; + } else { + debug!( + "Done sending videos to be downloaded, downoladed: {} videos", + self.sent + ); + let itx = mem::take(&mut self.itx); + drop(itx) + } + debug!("Returning: {}|{}", ok.0.display(), ok.1.unwrap_or(0)); + Some(ok) + } + Err(err) => { + debug!("Received error while listening: {}", err); + None + } + } + } + + pub fn drop(self) -> anyhow::Result<()> { + // Check that we really downloaded everything + assert_eq!(self.playspec.len(), 0); + match self.download_thread.join() { + Ok(ok) => ok, + Err(err) => panic!("Failed to join downloader thread: '{:#?}'", err), + } + } + + pub fn consume(mut self) -> anyhow::Result<()> { + while let Some((path, id)) = self.next() { + debug!("Next path to play is: '{}'", path.display()); + let mut info_json = canonicalize(&path).context("Failed to canoncialize path")?; + info_json.set_extension("info.json"); + + if status_path()?.is_symlink() { + fs::remove_file(status_path()?).context("Failed to delete old status file")?; + } else if !status_path()?.exists() { + debug!( + "The status path at '{}' does not exists", + status_path()?.display() + ); + } else { + bail!( + "The status path ('{}') is not a symlink but exists!", + status_path()?.display() + ); + } + + symlink(info_json, status_path()?).context("Failed to symlink")?; + + let mut mpv = Command::new("mpv"); + mpv.stdout(stdout()); + mpv.stderr(stderr()); + mpv.args(MPV_FLAGS); + // TODO: Set the title to the name of the video, not the path <2024-02-09> + // mpv.arg(format!("--title=")) + mpv.arg(&path); + + let status = mpv.status().context("Failed to run mpv")?; + if status.success() { + fs::remove_file(&path)?; + if let Some(id) = id { + println!("\x1b[32;1mMarking {} as watched!\x1b[0m", id); + let mut ytcc = std::process::Command::new("ytcc"); + ytcc.stdout(stdout()); + ytcc.stderr(stderr()); + ytcc.args(["mark"]); + ytcc.arg(id.to_string()); + let status = ytcc.status().context("Failed to run ytcc")?; + if let Some(code) = status.code() { + if code != 0 { + bail!("Ytcc failed with status: {}", code); + } + } + } + debug!("mpv exited with: '{}'", status); + } else { + warn!("mpv exited with: '{}'", status); + } + } + self.drop()?; + Ok(()) + } +} + +fn download_url(url: &Url) -> Result { + let output_file = tempfile::NamedTempFile::new().context("Failed to create tempfile")?; + output_file + .as_file() + .set_len(0) + .context("Failed to truncate temp-file")?; + if !Into::::into(DOWNLOAD_DIR).exists() { + fs::create_dir_all(DOWNLOAD_DIR) + .with_context(|| format!("Failed to create download dir at: {}", DOWNLOAD_DIR))? + } + let mut yt_dlp = Command::new("yt-dlp"); + yt_dlp.current_dir(DOWNLOAD_DIR); + yt_dlp.stdout(stdout()); + yt_dlp.stderr(stderr()); + yt_dlp.args(YT_DLP_FLAGS); + yt_dlp.args([ + "--output", + "%(channel)s/%(title)s.%(ext)s", + url.as_str(), + "--print-to-file", + "after_move:filepath", + ]); + yt_dlp.arg(output_file.path().as_os_str()); + + let status = yt_dlp.status().context("Failed to run yt-dlp")?; + if !status.success() { + error!("yt-dlp execution failed with error: '{}'", status); + } + + let mut path = String::new(); + output_file + .as_file() + .read_to_string(&mut path) + .context("Failed to read output file temp file")?; + let path = path.trim(); + Ok(path.into()) +} diff --git a/pkgs/sources/yt/src/help.str b/pkgs/sources/yt/src/help.str new file mode 100644 index 00000000..130fe42a --- /dev/null +++ b/pkgs/sources/yt/src/help.str @@ -0,0 +1,8 @@ +# Commands: +# w, watch = watch id +# d, drop = mark id as watched +# u, url = open the associated URL in the `timesinks.youtube` Firefox profile +# p, pick = leave id as is; This is a noop +# +# These lines can be re-ordered; they are executed from top to bottom. +# vim: filetype=yts conceallevel=2 concealcursor=nc colorcolumn= diff --git a/pkgs/sources/yt/src/lib.rs b/pkgs/sources/yt/src/lib.rs new file mode 100644 index 00000000..b089c1a2 --- /dev/null +++ b/pkgs/sources/yt/src/lib.rs @@ -0,0 +1,185 @@ +use anyhow::{bail, Context}; +use downloader::Downloadable; +use serde::Deserialize; +use url::Url; + +pub mod constants; +pub mod downloader; + +#[derive(Deserialize)] +pub struct YtccListData { + pub url: String, + pub title: String, + pub description: String, + pub publish_date: String, + pub watch_date: Option, + pub duration: String, + pub thumbnail_url: Option, + pub extractor_hash: String, + pub id: u32, + pub playlists: Vec, +} + +impl std::fmt::Display for YtccListData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!( + f, + r#"pick {} "{}" "{}" "{}" "{}" "{}"{}"#, + self.id, + self.title.replace(['"', '„', '”'], "'"), + self.publish_date, + self.playlists + .iter() + .map(|p| p.name.replace('"', "'")) + .collect::>() + .join(", "), + Duration::from(self.duration.trim()), + self.url.replace('"', "'"), + "\n" + ) + } +} + +#[derive(Deserialize)] +pub struct YtccPlaylistData { + pub name: String, + pub url: String, + pub reverse: bool, +} + +pub enum LineCommand { + Pick, + Drop, + Watch, + Url, +} + +impl std::str::FromStr for LineCommand { + type Err = anyhow::Error; + fn from_str(v: &str) -> Result::Err> { + match v { + "pick" | "p" => Ok(Self::Pick), + "drop" | "d" => Ok(Self::Drop), + "watch" | "w" => Ok(Self::Watch), + "url" | "u" => Ok(Self::Url), + other => bail!("'{}' is not a recognized command!", other), + } + } +} + +pub struct Line { + pub cmd: LineCommand, + pub id: u32, + pub url: Url, +} + +/// We expect that each line is correctly formatted, and simply use default ones if they are not +impl From<&str> for Line { + fn from(v: &str) -> Self { + let buf: Vec<_> = v.split_whitespace().collect(); + let url: Url = Url::parse( + buf.last() + .expect("This should always exists") + .trim_matches('"'), + ) + .expect("This parsing should work,as the url is generated"); + + Line { + cmd: buf + .get(0) + .unwrap_or(&"pick") + .parse() + .unwrap_or(LineCommand::Pick), + id: buf.get(1).unwrap_or(&"0").parse().unwrap_or(0), + url, + } + } +} + +pub struct Duration { + time: u32, +} + +impl From<&str> for Duration { + fn from(v: &str) -> Self { + let buf: Vec<_> = v.split(':').take(2).collect(); + Self { + time: (buf[0].parse::().expect("Should be a number") * 60) + + buf[1].parse::().expect("Should be a number"), + } + } +} + +impl std::fmt::Display for Duration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + const SECOND: u32 = 1; + const MINUTE: u32 = 60 * SECOND; + const HOUR: u32 = 60 * MINUTE; + + let base_hour = self.time - (self.time % HOUR); + let base_min = (self.time % HOUR) - ((self.time % HOUR) % MINUTE); + let base_sec = (self.time % HOUR) % MINUTE; + + let h = base_hour / HOUR; + let m = base_min / MINUTE; + let s = base_sec / SECOND; + + if self.time == 0 { + write!(f, "[No Duration]") + } else if h > 0 { + write!(f, "[{h}h {m}m]") + } else { + write!(f, "[{m}m {s}s]") + } + } +} +#[cfg(test)] +mod test { + use crate::Duration; + + #[test] + fn test_display_duration_1h() { + let dur = Duration { time: 60 * 60 }; + assert_eq!("[1h 0m]".to_owned(), dur.to_string()); + } + #[test] + fn test_display_duration_30min() { + let dur = Duration { time: 60 * 30 }; + assert_eq!("[30m 0s]".to_owned(), dur.to_string()); + } +} + +pub fn ytcc_drop(id: u32) -> anyhow::Result<()> { + let mut ytcc = std::process::Command::new("ytcc"); + ytcc.args(["mark", &format!("{}", id)]); + if !ytcc.status().context("Failed to run ytcc")?.success() { + bail!("`ytcc mark {}` failed to execute", id) + } + Ok(()) +} + +pub fn filter_line(line: &str) -> anyhow::Result> { + // Filter out comments and empty lines + if line.starts_with('#') || line.trim().is_empty() { + return Ok(None); + } + + let line = Line::from(line); + match line.cmd { + LineCommand::Pick => Ok(None), + LineCommand::Drop => ytcc_drop(line.id) + .with_context(|| format!("Failed to drop: {}", line.id)) + .map(|_| None), + LineCommand::Watch => Ok(Some(Downloadable { + id: Some(line.id), + url: line.url, + })), + LineCommand::Url => { + let mut firefox = std::process::Command::new("firefox"); + firefox.args(["-P", "timesinks.youtube"]); + firefox.arg(line.url.as_str()); + let _handle = firefox.spawn().context("Failed to run firefox")?; + Ok(None) + } + } +} diff --git a/pkgs/sources/yt/todo b/pkgs/sources/yt/todo new file mode 100644 index 00000000..3f22042c --- /dev/null +++ b/pkgs/sources/yt/todo @@ -0,0 +1 @@ +subtitles diff --git a/pkgs/sources/yt/update.sh b/pkgs/sources/yt/update.sh new file mode 100755 index 00000000..e500bb23 --- /dev/null +++ b/pkgs/sources/yt/update.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +nix flake update + +[ "$1" = "upgrade" ] && cargo upgrade +cargo update + +# vim: ft=sh diff --git a/pkgs/sources/yt/yt.nix b/pkgs/sources/yt/yt.nix new file mode 100644 index 00000000..aaa971c3 --- /dev/null +++ b/pkgs/sources/yt/yt.nix @@ -0,0 +1,29 @@ +{ + lib, + rustPlatform, + ytcc, + yt-dlp, + mpv, + makeWrapper, +}: +rustPlatform.buildRustPackage { + pname = "yt"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + + buildNoDefaultFeatures = true; + buildFeatures = ["yt"]; + + nativeBuildInputs = [ + makeWrapper + ]; + + postInstall = '' + wrapProgram $out/bin/yt \ + --prefix PATH : ${lib.makeBinPath [mpv yt-dlp ytcc]} + ''; +} diff --git a/pkgs/sources/yt/ytc.nix b/pkgs/sources/yt/ytc.nix new file mode 100644 index 00000000..dff5bcf8 --- /dev/null +++ b/pkgs/sources/yt/ytc.nix @@ -0,0 +1,29 @@ +{ + lib, + rustPlatform, + ytcc, + yt-dlp, + mpv, + makeWrapper, +}: +rustPlatform.buildRustPackage { + pname = "ytc"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + + buildNoDefaultFeatures = true; + buildFeatures = ["ytc"]; + + nativeBuildInputs = [ + makeWrapper + ]; + + postInstall = '' + wrapProgram $out/bin/ytc \ + --set PATH ${lib.makeBinPath [mpv yt-dlp ytcc]} + ''; +} diff --git a/pkgs/sources/yt/yts.nix b/pkgs/sources/yt/yts.nix new file mode 100644 index 00000000..9a8b172e --- /dev/null +++ b/pkgs/sources/yt/yts.nix @@ -0,0 +1,27 @@ +{ + lib, + rustPlatform, + ytcc, + makeWrapper, +}: +rustPlatform.buildRustPackage { + pname = "yts"; + version = "0.1.0"; + + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + + buildNoDefaultFeatures = true; + buildFeatures = ["yts"]; + + nativeBuildInputs = [ + makeWrapper + ]; + + postInstall = '' + wrapProgram $out/bin/yts \ + --prefix PATH : ${lib.makeBinPath [ytcc]} + ''; +} diff --git a/sys/boot/archlive_iso.nix b/sys/boot/archlive_iso.nix deleted file mode 100644 index d19a4a87..00000000 --- a/sys/boot/archlive_iso.nix +++ /dev/null @@ -1,77 +0,0 @@ -{pkgs ? (builtins.getFlake "nixpkgs").legacyPackages."x86_64-linux"}: let - signing_key = import ./signing_key.nix {inherit pkgs;}; - - checked_iso = pkgs.stdenv.mkDerivation { - pname = "archlinux-iso"; - version = "2024.05.01"; - - srcs = [ - (pkgs.fetchurl { - url = "https://archlinux.org/iso/2024.05.01/archlinux-2024.05.01-x86_64.iso.sig"; - hash = "sha256-QOGYng6a7zA5EJKGotDccJ7fD2MmPPXQEdVr1kjJvi4="; - }) - (pkgs.fetchurl { - url = "https://mirror.informatik.tu-freiberg.de/arch/iso/latest/archlinux-2024.05.01-x86_64.iso"; - hash = "sha256-G0oE74pzUIUqEwcO5JhEKwh6YHoYhAtN19mYZ+tfakw="; - }) - (pkgs.fetchurl { - url = "https://archlinux.org/iso/2024.05.01/b2sums.txt"; - hash = "sha256-HSMS13hHXFKKQsCA8spa7XtirHCBTmePwhOsStVPbHw="; - }) - ]; - - dontUnpack = true; - - nativeBuildInputs = with pkgs; [ - sequoia-sq - ]; - - buildPhase = - /* - bash - */ - '' - cp -r "${signing_key}" ./release-key.pgp - for src in $srcs; do - cp -r "$src" "$(stripHash "$src")" - done - - sed '2d;3d;4d' b2sums.txt > b2sums_clean.txt - - # As per the directions from: https://archlinux.org/download/ - - # blake hash check - b2sum -c ./b2sums_clean.txt - - # pgp signature check - sq verify --signer-file release-key.pgp --detached archlinux-2024.05.01-x86_64.iso.sig archlinux-2024.05.01-x86_64.iso - ''; - - installPhase = '' - cp archlinux-2024.05.01-x86_64.iso "$out"; - ''; - }; -in - pkgs.stdenv.mkDerivation { - name = "live_iso_boot_entry"; - - src = checked_iso; - - dontUnpack = true; - - nativeBuildInputs = with pkgs; [ - libarchive # for bsdtar - ]; - - buildPhase = '' - mkdir iso - bsdtar -xf "$src" -C iso - ''; - - installPhase = '' - install -D ./iso/arch/boot/x86_64/initramfs-linux.img "$out/live/initramfs-linux.img" - install -D ./iso/arch/boot/x86_64/vmlinuz-linux "$out/live/vmlinuz-linux" - - install -D "$src" "$out/archlinux.iso" - ''; - } diff --git a/sys/boot/boot_pictures/gnu.png b/sys/boot/boot_pictures/gnu.png deleted file mode 100755 index d07dee3e..00000000 Binary files a/sys/boot/boot_pictures/gnu.png and /dev/null differ diff --git a/sys/boot/boot_pictures/gnulin_emb_1.png b/sys/boot/boot_pictures/gnulin_emb_1.png deleted file mode 100755 index 483f2681..00000000 Binary files a/sys/boot/boot_pictures/gnulin_emb_1.png and /dev/null differ diff --git a/sys/boot/boot_pictures/gnulin_emb_2.png b/sys/boot/boot_pictures/gnulin_emb_2.png deleted file mode 100755 index 48cd6ad7..00000000 Binary files a/sys/boot/boot_pictures/gnulin_emb_2.png and /dev/null differ diff --git a/sys/boot/default.nix b/sys/boot/default.nix deleted file mode 100644 index e5d05f31..00000000 --- a/sys/boot/default.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: let - cfg = config.boot.loader.systemd-boot; - inherit (config.boot.loader) efi; - - esa = n: lib.strings.escapeShellArg n; - - bootMountPoint = - if cfg.xbootldrMountPoint != null - then cfg.xbootldrMountPoint - else efi.efiSysMountPoint; - - nixosDir = "/EFI/nixos"; - - # FIXME: This system has two big problems: - # 1. It does not updated files, which still have the same name - # 2. It forgets about files, which were 'deleted' in this configuration (these just - # stay on disk forever) <2024-05-11> - copyExtraFiles = '' - echo "[systemd-boot] copying files to ${bootMountPoint}" - empty_file=$(mktemp) - - ${lib.concatStrings (lib.mapAttrsToList (n: v: - /* - bash - */ - '' - if ! [ -e ${esa "${bootMountPoint}/${n}"} ]; then - install -Dp "${v}" ${esa "${bootMountPoint}/${n}"} - install -D "$empty_file" ${esa "${bootMountPoint}/${nixosDir}/.extra-files/${n}"} - fi - '') - cfg.extraFiles)} - - ${lib.concatStrings (lib.mapAttrsToList (n: v: - /* - bash - */ - '' - # if ! [ -e ${esa "${bootMountPoint}/loader/entries/${n}"} ]; then - install -Dp "${pkgs.writeText n v}" ${esa "${bootMountPoint}/loader/entries/${n}"} - install -D "$empty_file" ${esa "${bootMountPoint}/${nixosDir}/.extra-files/loader/entries/${n}"} - # fi - '') - cfg.extraEntries)} - ''; -in { - # FIXME: Reactviate this whole iso thing when a disko redeploy is done. - # (and switch to tails instead of arch)<2024-05-12> - # system.activationScripts = { - # copyExtraFilesForBoot = copyExtraFiles; - # }; - - boot = { - initrd = { - #compressor = "lz4"; - #compressorArgs = ["-9"]; - kernelModules = ["nvme" "btrfs"]; - }; - - kernelPackages = pkgs.linuxPackages_latest; - - lanzaboote = { - enable = true; - pkiBundle = "/etc/secureboot"; - - settings = { - # Disable editing the kernel command line (which could allow someone to become root) - editor = false; - }; - }; - - loader = { - systemd-boot = { - # Lanzaboote currently replaces the systemd-boot module. - # This setting is usually set to true in configuration.nix - # generated at installation time. So we force it to false - # for now. - enable = false; - - extraEntries = { - "live.conf" = '' - title Archlinux Live ISO - linux /live/vmlinuz-linux - initrd /live/initramfs-linux.img - options img_dev=${config.soispha.disks.disk} img_loop=/archlinux.iso copytoram - ''; - }; - - extraFiles = let - iso = import ./archlive_iso.nix {inherit pkgs;}; - in { - "archlinux.iso" = "${iso}/archlinux.iso"; - "live/initramfs-linux.img" = "${iso}/live/initramfs-linux.img"; - "live/vmlinuz-linux" = "${iso}/live/vmlinuz-linux"; - }; - }; - - grub = { - enable = false; - # theme = pkgs.nixos-grub2-theme; - splashImage = ./boot_pictures/gnu.png; - efiSupport = true; - device = "nodev"; # only for efi - }; - - efi = { - canTouchEfiVariables = true; - efiSysMountPoint = "/boot"; - }; - }; - }; -} diff --git a/sys/boot/signing_key.nix b/sys/boot/signing_key.nix deleted file mode 100644 index 788447be..00000000 --- a/sys/boot/signing_key.nix +++ /dev/null @@ -1,18 +0,0 @@ -{pkgs ? (builtins.getFlake "nixpkgs").legacyPackages."x86_64-linux"}: -pkgs.stdenv.mkDerivation { - name = "archlinux_signing_keys"; - - outputHash = "sha256-evGWzkxMaZw3rlixKsyWCS/ZvNuZ+OfXQb6sgiHz9XY="; - outputHashAlgo = "sha256"; - NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - - nativeBuildInputs = with pkgs; [ - sequoia-sq - ]; - - dontUnpack = true; - - buildPhase = '' - sq --verbose --no-cert-store --no-key-store network wkd fetch pierre@archlinux.org --output "$out" - ''; -} diff --git a/sys/default.nix b/sys/default.nix deleted file mode 100644 index 68a24892..00000000 --- a/sys/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{lib, ...}: { - imports = [ - #./nixpkgs already at flake level imported - ./boot - ./disks - ./documentation - ./font - ./git_revision - ./hardware - ./impermanence - ./libvirtd - ./locale - ./network - ./options - ./polkit - ./power - ./secrets - ./sound - ./svcs - ./tempfiles - ./users - ./waydroid - ]; - # remove all the bloat, which NixOS installs by default - environment = { - defaultPackages = lib.mkForce []; - }; -} diff --git a/sys/disks/default.nix b/sys/disks/default.nix deleted file mode 100644 index 2283db96..00000000 --- a/sys/disks/default.nix +++ /dev/null @@ -1,137 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - # FIXME: The iso redeploy requires a bigger efi partition <2024-05-12> - cfg = config.soispha.disks; - defaultMountOptions = [ - "compress-force=zstd:15" # This saves disk space, at a performance cost - "noatime" # should have some performance upsides, and I don't use it anyways - "lazytime" # make time changes in memory - ]; -in { - options.soispha.disks = { - enable = lib.mkEnableOption "disk setup with disko"; - disk = lib.mkOption { - type = lib.types.path; - example = lib.literalExpression "/dev/disk/by-uuid/0442cb6d-f13a-4635-b487-fa76189774c5"; - description = '' - The disk used for installing the OS. - ''; - }; - ssd = lib.mkOption { - type = lib.types.bool; - example = lib.literalExpression "true"; - default = false; - description = lib.mdDoc "Enable ssd specific improvements, like trim"; - }; - swap = { - uuid = lib.mkOption { - type = lib.types.str; - example = lib.literalExpression "d1d20ae7-3d8a-44da-86da-677dbbb10c89"; - description = lib.mdDoc "The uuid of the swapfile"; - }; - resumeOffset = lib.mkOption { - type = lib.types.str; - example = lib.literalExpression "134324224"; - description = lib.mdDoc "The resume offset of the swapfile"; - }; - }; - }; - - config = lib.mkIf cfg.enable { - systemd = lib.recursiveUpdate (import ./hibernate.nix {inherit pkgs;}) (import ./fstrim.nix {inherit pkgs lib cfg;}); - - disko.devices = { - disk = { - main = { - device = cfg.disk; - content = { - type = "gpt"; - partitions = { - root = { - size = "100%"; - name = "root"; - content = { - type = "luks"; - name = "nixos"; - extraOpenArgs = ["--allow-discards"]; - content = { - type = "btrfs"; - extraArgs = ["-f" "--label nixos"]; # Override existing partitions - subvolumes = { - "nix" = { - mountpoint = "/nix"; - mountOptions = defaultMountOptions; - }; - "persistent-storage" = { - mountpoint = "/srv"; - mountOptions = defaultMountOptions; - }; - "persistent-storage@snapshots" = { - mountpoint = "/srv/.snapshots"; - mountOptions = defaultMountOptions; - }; - "swap" = { - mountpoint = "/swap"; - mountOptions = defaultMountOptions; - }; - }; - }; - }; - }; - boot = { - type = "EF00"; - size = "512M"; - name = "boot"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - }; - }; - }; - }; - nodev = { - "/" = { - fsType = "tmpfs"; - mountOptions = ["defaults" "size=4G" "mode=755"]; - }; - "/tmp" = { - fsType = "tmpfs"; - mountOptions = ["defaults" "size=16G" "mode=755"]; - }; - }; - }; - fileSystems = { - "/srv" = { - neededForBoot = true; - }; - "/swap" = { - neededForBoot = true; - }; - }; - swapDevices = [ - #{ - # device = "/swap/swapfile"; - # priority = 1; # lower than zramSwap, just in case - # # size = 2048; # TODO: can nixos create a btrfs swapfile correctly? - #} - ]; - zramSwap = { - enable = true; - priority = 10; # needs to be higher than hardware-swap - }; - boot = { - kernelParams = [ - "resume_offset=${cfg.swap.resumeOffset}" - "zswap.enabled=0" # zswap and zram are not really compatible - ]; - resumeDevice = "/dev/disk/by-uuid/${cfg.swap.uuid}"; - }; - }; -} diff --git a/sys/disks/fstrim.nix b/sys/disks/fstrim.nix deleted file mode 100644 index 6daeb65e..00000000 --- a/sys/disks/fstrim.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - pkgs, - lib, - cfg, -}: { - timers.fstrim = lib.mkIf cfg.ssd { - wantedBy = ["timers.target"]; - wants = ["fstrim.service"]; - unitConfig = { - Description = "Discard unused blocks once a week"; - Documentation = "man:fstrim"; - ConditionVirtualization = "!container"; - ConditionPathExists = "!/etc/initrd-release"; - }; - timerConfig = { - OnCalendar = "weekly"; - AccuracySec = "1h"; - Persistent = "true"; - RandomizedDelaySec = "6000"; - }; - }; - services.fstrim = lib.mkIf cfg.ssd { - wantedBy = lib.mkForce []; - unitConfig = { - Description = "Discard unused blocks on filesystems from /etc/fstab"; - Documentation = "man:fstrim(8)"; - ConditionVirtualization = "!container"; - }; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.util-linux}/bin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported"; - PrivateDevices = "no"; - PrivateNetwork = "yes"; - PrivateUsers = "no"; - ProtectKernelTunables = "yes"; - ProtectKernelModules = "yes"; - ProtectControlGroups = "yes"; - MemoryDenyWriteExecute = "yes"; - SystemCallFilter = "@default @file-system @basic-io @system-service"; - }; - }; -} diff --git a/sys/disks/hibernate.nix b/sys/disks/hibernate.nix deleted file mode 100644 index ad7ca12c..00000000 --- a/sys/disks/hibernate.nix +++ /dev/null @@ -1,44 +0,0 @@ -{pkgs}: { - services = { - hibernate-preparation = { - wantedBy = ["systemd-hibernate.service"]; - unitConfig = { - Description = "Enable swap file and disable zram before hibernate"; - Before = "systemd-hibernate.service"; - }; - serviceConfig = { - Type = "oneshot"; - User = "root"; - ExecStart = "${pkgs.bash}/bin/bash -c \"${pkgs.util-linux}/bin/swapon /swap/swapfile && ${pkgs.util-linux}/bin/swapoff /dev/zram0\""; - }; - }; - hibernate-resume = { - wantedBy = ["systemd-hibernate.service"]; - unitConfig = { - Description = "Disable swap after resuming from hibernation"; - After = "hibernate.target"; - }; - serviceConfig = { - Type = "oneshot"; - User = "root"; - ExecStart = "${pkgs.util-linux}/bin/swapoff /swap/swapfile"; - }; - }; - # swapoff-start = { - # wantedBy = ["multi-user.target"]; - # unitConfig = { - # Description = "Disable hardware swap after booting"; - # }; - # serviceConfig = { - # Type = "oneshot"; - # User = "root"; - # ExecStart = "${pkgs.util-linux}/bin/swapoff /swap/swapfile"; - # }; - # }; - systemd-hibernate.serviceConfig.Environment = "SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"; - systemd-logind.serviceConfig.Environment = "SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"; - }; - sleep.extraConfig = '' - HibernateDelaySec=5m - ''; -} diff --git a/sys/documentation/default.nix b/sys/documentation/default.nix deleted file mode 100644 index 6e7f4912..00000000 --- a/sys/documentation/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{...}: { - documentation = { - nixos = { - # TODO: Enable this, when the build is no longer local (i.e. I've access to a remote build server) <2023-08-28> - includeAllModules = true; - - # I don't use this, and it has a considerable build time. - enable = false; - }; - dev = { - # Add man pages aimed at developers (I guess c library stuff, and the like) - enable = true; - }; - }; -} diff --git a/sys/font/default.nix b/sys/font/default.nix deleted file mode 100644 index cdbf03cf..00000000 --- a/sys/font/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - pkgs, - lib, - ... -}: let - nerdFont = pkgs.nerdfonts.override { - fonts = [ - "SourceCodePro" - "Overpass" - "FiraCode" - ]; - }; -in { - fonts = { - packages = [ - nerdFont - pkgs.noto-fonts-emoji - ]; - fontconfig = { - # NOTE: This is responsible for color emoji support <2023-08-28> --> - /* - WARNING: This [link](https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/111#note_630720) - contains some discussion about, the below code. But it's down right now. - <2023-08-28> - */ - localConf = builtins.readFile ./font.xml; - defaultFonts = { - # FIXME: Add a serif font <2023-08-28> - serif = []; - sansSerif = lib.mkForce ["Overpass Nerd Font Propo"]; - monospace = lib.mkForce ["SauceCodePro Nerd Font Mono" "Noto Color Emoji"]; - emoji = lib.mkForce ["Noto Color Emoji"]; - }; - allowType1 = false; - allowBitmaps = false; - }; - }; -} diff --git a/sys/font/font.xml b/sys/font/font.xml deleted file mode 100644 index f3f6bb3e..00000000 --- a/sys/font/font.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - monospace - - emoji - - - - sans-serif - - emoji - - - - serif - - emoji - - - diff --git a/sys/git_revision/default.nix b/sys/git_revision/default.nix deleted file mode 100644 index c0a8bf72..00000000 --- a/sys/git_revision/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -{self, ...}: { - environment.etc.nixos_git_rev = { - text = builtins.toString (self.longRev - or self.dirtyShortRev - or self.lastModified - or "unknown"); - }; -} diff --git a/sys/hardware/default.nix b/sys/hardware/default.nix deleted file mode 100644 index 28d70d99..00000000 --- a/sys/hardware/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{pkgs, ...}: { - hardware = { - keyboard.zsa.enable = false; - onlykey.enable = true; - nitrokey.enable = true; - - opengl = { - enable = true; - extraPackages = builtins.attrValues { - inherit - (pkgs) - vaapiVdpau - libvdpau-va-gl - ; - }; - }; - }; - services.udev.extraRules = '' - # Rules for Oryx web flashing and live training - KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev" - KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev" - - # Legacy rules for live training over webusb (Not needed for firmware v21+) - # Rule for all ZSA keyboards - SUBSYSTEM=="usb", ATTR{idVendor}=="3297", GROUP="plugdev" - # Rule for the Moonlander - SUBSYSTEM=="usb", ATTR{idVendor}=="3297", ATTR{idProduct}=="1969", GROUP="plugdev" - # Rule for the Ergodox EZ - SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="1307", GROUP="plugdev" - # Rule for the Planck EZ - SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="6060", GROUP="plugdev" - - # Wally Flashing rules for the Ergodox EZ - ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1" - ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" - SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" - KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" - - # Wally Flashing rules for the Moonlander and Planck EZ - SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", \ - MODE:="0666", \ - SYMLINK+="stm32_dfu" - ''; -} diff --git a/sys/impermanence/default.nix b/sys/impermanence/default.nix deleted file mode 100644 index d116f45f..00000000 --- a/sys/impermanence/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - config, - lib, - ... -}: let - cfg = config.soispha.impermanence; - directories = - [ - "/etc/nixos" - "/var/log" - "/var/lib/systemd" - ] - ++ lib.optional config.networking.networkmanager.enable "/etc/NetworkManager" - ++ lib.optional config.boot.lanzaboote.enable "/etc/secureboot" - ++ lib.optional config.hardware.bluetooth.enable "/var/lib/bluetooth" - ++ lib.optional config.virtualisation.waydroid.enable "/var/lib/waydroid" - ++ lib.optional config.services.postgresql.enable "/var/lib/postgresql"; -in { - options.soispha.impermanence = { - enable = lib.mkOption { - type = lib.types.bool; - default = true; - description = lib.mdDoc "Disk setup with disko"; - }; - }; - - config = lib.mkIf cfg.enable { - # needed for the hm impermanence config - programs.fuse.userAllowOther = true; - - environment.persistence = { - "/srv" = { - hideMounts = true; - inherit directories; - files = [ - "/etc/machine-id" - ]; - }; - }; - }; -} diff --git a/sys/libvirtd/default.nix b/sys/libvirtd/default.nix deleted file mode 100644 index 5c519550..00000000 --- a/sys/libvirtd/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{pkgs, ...}: { - # virtualisation = { - # spiceUSBRedirection.enable = true; # TODO: this allows usb access to any user, which shouldn't be that bad - # cores = 8; - # diskSize = 25000; - # useEFIBoot = true; - # resolution = { - # x = 1920; - # y = 1080; - # }; - # memorySize = 8024; - # sharedDirectories = {}; # TODO: add some - # libvirtd = { - # enable = true; - # qemu = { - # package = pkgs.qemu_full; - # ovmf = { - # enable = true; - # packages = [pkgs.OVMFFull.fd]; - # }; - # }; - # }; - # }; - # users.users.soispha.extraGroups = [ - # "libvirtd" # to run libvirt stuff as this user - # ]; -} diff --git a/sys/locale/default.nix b/sys/locale/default.nix deleted file mode 100644 index 7912b45b..00000000 --- a/sys/locale/default.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - lib, - ... -}: let - cfg = config.soispha.locale; -in { - options.soispha.locale = { - enable = lib.mkEnableOption (lib.mdDoc "locale"); - keyMap = lib.mkOption { - type = lib.types.str; - example = "us"; - default = "dvorak"; - }; - }; - - config = lib.mkIf cfg.enable { - # Set your time zone. - time.timeZone = "Europe/Berlin"; - - # Select internationalisation properties. - i18n = { - defaultLocale = "en_CA.UTF-8"; - extraLocaleSettings = { - LANGUAGE = "en_CA:en_US:en"; - LC_TIME = "en_DK.UTF-8"; - LC_COLLATE = "C.UTF-8"; - }; - }; - - # Layout - console = { - inherit (cfg) keyMap; - }; - - services.xserver.xkb.extraLayouts = { - "us-modified" = { - description = "standard us with german and swedish extra chars."; - languages = ["eng" "swe" "deu"]; - symbolsFile = ./keymaps/us_modified.xkb; - }; - "dvorak-modified" = { - description = "standard dvorak english with german and swedish extra chars."; - languages = ["eng" "swe" "deu"]; - symbolsFile = ./keymaps/dvorak_modified.xkb; - }; - }; - }; -} diff --git a/sys/locale/keymaps/dvorak_modified.xkb b/sys/locale/keymaps/dvorak_modified.xkb deleted file mode 100644 index 63f5d4fb..00000000 --- a/sys/locale/keymaps/dvorak_modified.xkb +++ /dev/null @@ -1,15 +0,0 @@ -partial alphanumeric_keys -xkb_symbols "dvorak-modified" { - name[Group1]= "Dvorak English with additional keys"; - - key {[ o, O, odiaeresis, Odiaeresis]}; - key {[ u, U, udiaeresis, Udiaeresis]}; - key {type[Group1]="EIGHT_LEVEL", - [ a, A, adiaeresis, Adiaeresis, aring, Aring]}; - - - include "us(dvorak)" - include "level3(caps_switch)" - include "level5(ralt_switch)" -}; -// vim: ft=xkb diff --git a/sys/locale/keymaps/us_modified.xkb b/sys/locale/keymaps/us_modified.xkb deleted file mode 100644 index 6299a5e9..00000000 --- a/sys/locale/keymaps/us_modified.xkb +++ /dev/null @@ -1,9 +0,0 @@ -partial alphanumeric_keys -xkb_symbols "us-modified" { - name[Group1]= "US English with caps lock key as compose key"; - - - include "us(basic)" - include "compose(caps)" -}; -// vim: ft=xkb diff --git a/sys/network/default.nix b/sys/network/default.nix deleted file mode 100644 index 9c570f3b..00000000 --- a/sys/network/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - config, - lib, - ... -}: -{ - systemd.network = { - networks = { - "tap0" = { - name = "tap0"; - bridge = [ - "virbr0" - ]; - }; - "enp4s0" = { - name = "enp4s0"; - networkConfig = { - DHCP = "yes"; - DNSOverTLS = "yes"; - DNSSEC = "yes"; - }; - bridge = [ - "virbr0" - ]; - }; - }; - netdevs = { - "tap0" = { - netdevConfig = { - Name = "tap0"; - Kind = "tap"; - }; - tapConfig = { - User = "${config.users.users.soispha.uid}"; - Group = "libvirtd"; - }; - }; - "virbr0" = { - netdevConfig = { - Name = "br0"; - Kind = "bridge"; - }; - }; - }; - }; -} -// lib.mkIf config.networking.networkmanager.enable { - users.users.soispha.extraGroups = [ - "networkmanager" # allows to configure networkmanager as this user - ]; -} diff --git a/sys/nixpkgs/default.nix b/sys/nixpkgs/default.nix deleted file mode 100644 index 7fd640d1..00000000 --- a/sys/nixpkgs/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - lib, - system, - overlays ? [], - sysLib, - config, -}: let - additionalPackages = (import ./pkgs) {inherit config sysLib;}; - complete_overlays = overlays ++ additionalPackages; -in { - # TODO: inheriting system here is discouraged, localSystem or hostSystem should be inspected - inherit system; - overlays = complete_overlays; - config = { - # TODO: this fails because of the root tempsize, which should be increased - # contentAddressedByDefault = true; - - allowUnfreePredicate = pkg: - builtins.elem (lib.getName pkg) [ - "pypemicro" # required by pynitrokey - ]; - }; -} diff --git a/sys/nixpkgs/pkgs/comments/.envrc b/sys/nixpkgs/pkgs/comments/.envrc deleted file mode 100644 index 2b5fbb29..00000000 --- a/sys/nixpkgs/pkgs/comments/.envrc +++ /dev/null @@ -1,4 +0,0 @@ -use flake - -PATH_add ./target/debug -PATH_add ./target/release diff --git a/sys/nixpkgs/pkgs/comments/.gitignore b/sys/nixpkgs/pkgs/comments/.gitignore deleted file mode 100644 index c84fa049..00000000 --- a/sys/nixpkgs/pkgs/comments/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# build dirs -/target -/result diff --git a/sys/nixpkgs/pkgs/comments/Cargo.lock b/sys/nixpkgs/pkgs/comments/Cargo.lock deleted file mode 100644 index 54f19c46..00000000 --- a/sys/nixpkgs/pkgs/comments/Cargo.lock +++ /dev/null @@ -1,446 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets", -] - -[[package]] -name = "chrono-humanize" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799627e6b4d27827a814e837b9d8a504832086081806d45b1afa34dc982b023b" -dependencies = [ - "chrono", -] - -[[package]] -name = "cli-log" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d2ab00dc4c82ec28af25ac085aecc11ffeabf353755715a3113a7aa044ca5cc" -dependencies = [ - "chrono", - "file-size", - "log", - "proc-status", -] - -[[package]] -name = "comments" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "chrono-humanize", - "cli-log", - "log", - "regex", - "serde", - "serde_json", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "file-size" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9544f10105d33957765016b8a9baea7e689bf1f0f2f32c2fa2f568770c38d2b3" - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.154" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "proc-macro2" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-status" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e0c0ac915e7b76b47850ba4ffc377abde6c6ff9eeace61d0a89623db449712" -dependencies = [ - "thiserror", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "2.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -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.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/sys/nixpkgs/pkgs/comments/Cargo.toml b/sys/nixpkgs/pkgs/comments/Cargo.toml deleted file mode 100644 index 3ae3aa4c..00000000 --- a/sys/nixpkgs/pkgs/comments/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "comments" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.82" -chrono = "0.4.38" -chrono-humanize = "0.2.3" -cli-log = "2.0.0" -log = "0.4.21" -regex = "1.10.4" -serde = { version = "1.0.200", features = ["derive"] } -serde_json = "1.0.116" diff --git a/sys/nixpkgs/pkgs/comments/comments.nix b/sys/nixpkgs/pkgs/comments/comments.nix deleted file mode 100644 index e8a33bff..00000000 --- a/sys/nixpkgs/pkgs/comments/comments.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - lib, - rustPlatform, - makeWrapper, - less, - coreutils, -}: -rustPlatform.buildRustPackage { - pname = "comments"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - - nativeBuildInputs = [ - makeWrapper - ]; - - postInstall = '' - wrapProgram $out/bin/comments \ - --set PATH ${lib.makeBinPath [less coreutils]} - ''; -} diff --git a/sys/nixpkgs/pkgs/comments/default.nix b/sys/nixpkgs/pkgs/comments/default.nix deleted file mode 100644 index 6205dcbe..00000000 --- a/sys/nixpkgs/pkgs/comments/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -[ - ( - final: prev: { - comments = import ./comments.nix { - inherit - (prev) - lib - makeWrapper - rustPlatform - # dependencies - - less - coreutils - ; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/comments/flake.lock b/sys/nixpkgs/pkgs/comments/flake.lock deleted file mode 100644 index 50494465..00000000 --- a/sys/nixpkgs/pkgs/comments/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1715087517, - "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/comments/flake.nix b/sys/nixpkgs/pkgs/comments/flake.nix deleted file mode 100644 index f5e44a65..00000000 --- a/sys/nixpkgs/pkgs/comments/flake.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - description = "comments"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - }: (flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages."${system}"; - in { - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - # rust stuff - cargo - clippy - rustc - rustfmt - - cargo-edit - cargo-expand - cargo-audit - ]; - }; - })); -} diff --git a/sys/nixpkgs/pkgs/comments/src/info_json.rs b/sys/nixpkgs/pkgs/comments/src/info_json.rs deleted file mode 100644 index eca4fae3..00000000 --- a/sys/nixpkgs/pkgs/comments/src/info_json.rs +++ /dev/null @@ -1,223 +0,0 @@ -use std::collections::HashMap; - -use serde::{Deserialize, Deserializer}; - -#[derive(Debug, Deserialize)] -pub struct InfoJson { - pub id: String, - pub title: String, - pub formats: Vec, - pub thumbnails: Vec, - pub thumbnail: String, - pub description: String, - pub channel_id: String, - pub channel_url: String, - pub duration: u32, - pub view_count: u32, - pub age_limit: u32, - pub webpage_url: String, - pub categories: Vec, - pub tags: Vec, - pub playable_in_embed: bool, - pub live_status: String, - _format_sort_fields: Vec, - pub automatic_captions: HashMap>, - pub subtitles: Subtitles, - pub comment_count: u32, - pub like_count: u32, - pub channel: String, - pub channel_follower_count: u32, - pub channel_is_verified: Option, - pub uploader: String, - pub uploader_id: String, - pub uploader_url: String, - pub upload_date: String, - pub availability: String, - pub webpage_url_basename: String, - pub webpage_url_domain: String, - pub extractor: String, - pub extractor_key: String, - pub display_id: String, - pub fulltitle: String, - pub duration_string: String, - pub is_live: bool, - pub was_live: bool, - pub epoch: u32, - pub comments: Vec, - pub sponsorblock_chapters: Option>, - pub format: String, - pub format_id: String, - pub ext: String, - pub protocol: String, - pub language: Option, - pub format_note: String, - pub filesize_approx: u64, - pub tbr: f64, - pub width: u32, - pub height: u32, - pub resolution: String, - pub fps: f64, - pub dynamic_range: String, - pub vcodec: String, - pub vbr: f64, - pub aspect_ratio: f64, - pub acodec: String, - pub abr: f64, - pub asr: u32, - pub audio_channels: u32, - _type: String, - _version: Version, -} - -#[derive(Debug, Deserialize)] -pub struct Subtitles {} - -#[derive(Debug, Deserialize)] -pub struct Version { - pub version: String, - pub release_git_head: String, - pub repository: String, -} - -#[derive(Debug, Deserialize)] -pub struct SponsorblockChapter {} - -#[derive(Debug, Deserialize, Clone)] -#[serde(from = "String")] -pub enum Parent { - Root, - Id(String), -} - -impl Parent { - pub fn id(&self) -> Option<&str> { - if let Self::Id(id) = self { - Some(id) - } else { - None - } - } -} - -impl From for Parent { - fn from(value: String) -> Self { - if value == "root" { - Self::Root - } else { - Self::Id(value) - } - } -} - -#[derive(Debug, Deserialize, Clone)] -#[serde(from = "String")] -pub struct Id { - pub id: String, -} -impl From for Id { - fn from(value: String) -> Self { - Self { - // Take the last element if the string is split with dots, otherwise take the full id - id: value.split('.').last().unwrap_or(&value).to_owned(), - } - } -} - -#[derive(Debug, Deserialize, Clone)] -pub struct Comment { - pub id: Id, - pub text: String, - #[serde(default = "zero")] - pub like_count: u32, - pub author_id: String, - #[serde(default = "unknown")] - pub author: String, - pub author_thumbnail: String, - pub parent: Parent, - #[serde(deserialize_with = "edited_from_time_text", alias = "_time_text")] - pub edited: bool, - // Can't also be deserialized, as it's already used in 'edited' - // _time_text: String, - pub timestamp: i64, - pub author_url: String, - pub author_is_uploader: bool, - pub is_favorited: bool, -} -fn unknown() -> String { - "".to_string() -} -fn zero() -> u32 { - 0 -} -fn edited_from_time_text<'de, D>(d: D) -> Result -where - D: Deserializer<'de>, -{ - let s = String::deserialize(d)?; - if s.contains(" (edited)") { - Ok(true) - } else { - Ok(false) - } -} - -#[derive(Debug, Deserialize)] -pub struct Caption { - pub ext: String, - pub url: String, - pub name: Option, - pub protocol: Option, -} - -#[derive(Debug, Deserialize)] -pub struct ThumbNail { - pub url: String, - pub preference: i32, - pub id: String, - pub height: Option, - pub width: Option, - pub resolution: Option, -} - -#[derive(Debug, Deserialize)] -pub struct Format { - pub format_id: String, - pub format_note: Option, - pub ext: String, - pub protocol: String, - pub acodec: Option, - pub vcodec: String, - pub url: String, - pub width: Option, - pub height: Option, - pub fps: Option, - pub rows: Option, - pub columns: Option, - pub fragments: Option>, - pub resolution: String, - pub aspect_ratio: Option, - pub http_headers: HttpHeader, - pub audio_ext: String, - pub video_ext: String, - pub vbr: Option, - pub abr: Option, - pub format: String, -} - -#[derive(Debug, Deserialize)] -pub struct HttpHeader { - #[serde(alias = "User-Agent")] - pub user_agent: String, - #[serde(alias = "Accept")] - pub accept: String, - #[serde(alias = "Accept-Language")] - pub accept_language: String, - #[serde(alias = "Sec-Fetch-Mode")] - pub sec_fetch_mode: String, -} - -#[derive(Debug, Deserialize)] -pub struct Fragment { - pub url: String, - pub duration: f64, -} diff --git a/sys/nixpkgs/pkgs/comments/src/main.rs b/sys/nixpkgs/pkgs/comments/src/main.rs deleted file mode 100644 index 6e4f72e9..00000000 --- a/sys/nixpkgs/pkgs/comments/src/main.rs +++ /dev/null @@ -1,322 +0,0 @@ -use std::{ - env, - fmt::Display, - fs::{self, File}, - io::{BufReader, Write}, - mem, - path::PathBuf, - process::{Command, Stdio}, -}; - -use anyhow::Context; -use chrono::{Local, TimeZone}; -use chrono_humanize::{Accuracy, HumanTime, Tense}; -use info_json::{Comment, InfoJson, Parent}; -use regex::Regex; - -mod info_json; - -fn get_runtime_path(component: &'static str) -> anyhow::Result { - let out: PathBuf = format!( - "{}/{}", - env::var("XDG_RUNTIME_DIR").expect("This should always exist"), - component - ) - .into(); - fs::create_dir_all(out.parent().expect("Parent should exist"))?; - Ok(out) -} - -const STATUS_PATH: &str = "ytcc/running"; -pub fn status_path() -> anyhow::Result { - get_runtime_path(STATUS_PATH) -} - -#[derive(Debug, Clone)] -pub struct CommentExt { - pub value: Comment, - pub replies: Vec, -} - -#[derive(Debug, Default)] -pub struct Comments { - vec: Vec, -} - -impl Comments { - pub fn new() -> Self { - Self::default() - } - pub fn push(&mut self, value: CommentExt) { - self.vec.push(value); - } - pub fn get_mut(&mut self, key: &str) -> Option<&mut CommentExt> { - self.vec.iter_mut().filter(|c| c.value.id.id == key).last() - } - pub fn insert(&mut self, key: &str, value: CommentExt) { - let parent = self - .vec - .iter_mut() - .filter(|c| c.value.id.id == key) - .last() - .expect("One of these should exist"); - parent.push_reply(value); - } -} -impl CommentExt { - pub fn push_reply(&mut self, value: CommentExt) { - self.replies.push(value) - } - pub fn get_mut_reply(&mut self, key: &str) -> Option<&mut CommentExt> { - self.replies - .iter_mut() - .filter(|c| c.value.id.id == key) - .last() - } -} - -impl From for CommentExt { - fn from(value: Comment) -> Self { - Self { - replies: vec![], - value, - } - } -} - -impl Display for Comments { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - macro_rules! c { - ($color:expr, $write:ident) => { - $write.write_str(concat!("\x1b[", $color, "m"))? - }; - } - - fn format( - comment: &CommentExt, - f: &mut std::fmt::Formatter<'_>, - ident_count: u32, - ) -> std::fmt::Result { - let ident = &(0..ident_count).map(|_| " ").collect::(); - let value = &comment.value; - - f.write_str(ident)?; - - if value.author_is_uploader { - c!("91;1", f); - } else { - c!("35", f); - } - - f.write_str(&value.author)?; - c!("0", f); - if value.edited || value.is_favorited { - f.write_str("[")?; - if value.edited { - f.write_str("")?; - } - if value.edited && value.is_favorited { - f.write_str(" ")?; - } - if value.is_favorited { - f.write_str("")?; - } - f.write_str("]")?; - } - - c!("36;1", f); - write!( - f, - " {}", - HumanTime::from( - Local - .timestamp_opt(value.timestamp, 0) - .single() - .expect("This should be valid") - ) - .to_text_en(Accuracy::Rough, Tense::Past) - )?; - c!("0", f); - - // c!("31;1", f); - // f.write_fmt(format_args!(" [{}]", comment.value.like_count))?; - // c!("0", f); - - f.write_str(":\n")?; - f.write_str(ident)?; - - f.write_str(&value.text.replace('\n', &format!("\n{}", ident)))?; - f.write_str("\n")?; - - if !comment.replies.is_empty() { - let mut children = comment.replies.clone(); - children.sort_by(|a, b| a.value.timestamp.cmp(&b.value.timestamp)); - - for child in children { - format(&child, f, ident_count + 4)?; - } - } else { - f.write_str("\n")?; - } - - Ok(()) - } - - if !&self.vec.is_empty() { - let mut children = self.vec.clone(); - children.sort_by(|a, b| b.value.like_count.cmp(&a.value.like_count)); - - for child in children { - format(&child, f, 0)? - } - } - Ok(()) - } -} - -fn main() -> anyhow::Result<()> { - cli_log::init_cli_log!(); - let args: Option = env::args().skip(1).last(); - let mut info_json: InfoJson = { - let status_path = if let Some(arg) = args { - PathBuf::from(arg) - } else { - status_path().context("Failed to get status path")? - }; - - let reader = - BufReader::new(File::open(&status_path).with_context(|| { - format!("Failed to open status file at {}", status_path.display()) - })?); - - serde_json::from_reader(reader)? - }; - - let base_comments = mem::take(&mut info_json.comments); - drop(info_json); - - let mut comments = Comments::new(); - base_comments.into_iter().for_each(|c| { - if let Parent::Id(id) = &c.parent { - comments.insert(&(id.clone()), CommentExt::from(c)); - } else { - comments.push(CommentExt::from(c)); - } - }); - - comments.vec.iter_mut().for_each(|comment| { - let replies = mem::take(&mut comment.replies); - let mut output_replies: Vec = vec![]; - - let re = Regex::new(r"\u{200b}?(@[^\t\s]+)\u{200b}?").unwrap(); - for reply in replies { - if let Some(replyee_match) = re.captures(&reply.value.text){ - let full_match = replyee_match.get(0).expect("This always exists"); - let text = reply. - value. - text[0..full_match.start()] - .to_owned() - + - &reply - .value - .text[full_match.end()..]; - let text: &str = text.trim().trim_matches('\u{200b}'); - - let replyee = replyee_match.get(1).expect("This should exist").as_str(); - - - if let Some(parent) = output_replies - .iter_mut() - // .rev() - .flat_map(|com| &mut com.replies) - .flat_map(|com| &mut com.replies) - .flat_map(|com| &mut com.replies) - .filter(|com| com.value.author == replyee) - .last() - { - parent.replies.push(CommentExt::from(Comment { - text: text.to_owned(), - ..reply.value - })) - } else if let Some(parent) = output_replies - .iter_mut() - // .rev() - .flat_map(|com| &mut com.replies) - .flat_map(|com| &mut com.replies) - .filter(|com| com.value.author == replyee) - .last() - { - parent.replies.push(CommentExt::from(Comment { - text: text.to_owned(), - ..reply.value - })) - } else if let Some(parent) = output_replies - .iter_mut() - // .rev() - .flat_map(|com| &mut com.replies) - .filter(|com| com.value.author == replyee) - .last() - { - parent.replies.push(CommentExt::from(Comment { - text: text.to_owned(), - ..reply.value - })) - } else if let Some(parent) = output_replies.iter_mut() - // .rev() - .filter(|com| com.value.author == replyee) - .last() - { - parent.replies.push(CommentExt::from(Comment { - text: text.to_owned(), - ..reply.value - })) - } else { - eprintln!( - "Failed to find a parent for ('{}') both directly and via replies! The reply text was:\n'{}'\n", - replyee, - reply.value.text - ); - output_replies.push(reply); - } - } else { - output_replies.push(reply); - } - } - comment.replies = output_replies; - }); - - let mut less = Command::new("less") - .args(["--raw-control-chars"]) - .stdin(Stdio::piped()) - .stderr(Stdio::inherit()) - .spawn() - .context("Failed to run less")?; - - let mut child = Command::new("fmt") - .args(["--uniform-spacing", "--split-only", "--width=90"]) - .stdin(Stdio::piped()) - .stderr(Stdio::inherit()) - .stdout(less.stdin.take().expect("Should be open")) - .spawn() - .context("Failed to run fmt")?; - - let mut stdin = child.stdin.take().context("Failed to open stdin")?; - std::thread::spawn(move || { - stdin - .write_all(comments.to_string().as_bytes()) - .expect("Should be able to write to stdin of fmt"); - }); - - let _ = less.wait().context("Failed to await less")?; - - Ok(()) -} - -#[cfg(test)] -mod test { - #[test] - fn test_string_replacement() { - let s = "A \n\nB\n\nC".to_owned(); - assert_eq!("A \n \n B\n \n C", s.replace('\n', "\n ")) - } -} diff --git a/sys/nixpkgs/pkgs/comments/update.sh b/sys/nixpkgs/pkgs/comments/update.sh deleted file mode 100755 index e500bb23..00000000 --- a/sys/nixpkgs/pkgs/comments/update.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh - -nix flake update - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/default.nix b/sys/nixpkgs/pkgs/default.nix deleted file mode 100644 index 633d2f7e..00000000 --- a/sys/nixpkgs/pkgs/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - config, - sysLib, -}: let - comments = import ./comments; - generate_firefox_extensions = import ./generate_moz_extension; - lf_make_map = import ./lf-make-map; - nvim_plugs = import ./plgs-pkgs; - scripts = import ./scripts {inherit sysLib config;}; - snap-sync-forked = (import ./snap-sync-forked) {inherit sysLib;}; - update_vim_plugins = import ./update_vim_plugins; - yt = import ./yt; - yts-grammar = import ./tree-sitter-yts; - - overlays = - comments - ++ generate_firefox_extensions - ++ lf_make_map - ++ nvim_plugs - ++ scripts - ++ snap-sync-forked - ++ update_vim_plugins - ++ yt - ++ yts-grammar; -in - overlays diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/.envrc b/sys/nixpkgs/pkgs/generate_moz_extension/.envrc deleted file mode 100644 index 3550a30f..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/.gitignore b/sys/nixpkgs/pkgs/generate_moz_extension/.gitignore deleted file mode 100644 index f717ddd7..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target -/result -.direnv diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.lock b/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.lock deleted file mode 100644 index c0a83aa8..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.lock +++ /dev/null @@ -1,1275 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "anyhow" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "backtrace" -version = "0.3.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "bytes" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" - -[[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generate_extensions" -version = "0.1.0" -dependencies = [ - "anyhow", - "futures", - "reqwest", - "serde", - "serde_json", - "tokio", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "h2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "hyper" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2", - "tokio", - "tower", - "tower-service", - "tracing", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.154" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "proc-macro2" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "reqwest" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" -dependencies = [ - "base64", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "security-framework" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" -dependencies = [ - "bitflags 2.5.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "syn" -version = "2.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.toml b/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.toml deleted file mode 100644 index e7d44db4..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "generate_extensions" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.83" -futures = "0.3.30" -reqwest = "0.12.4" -serde = { version = "1.0.201", features = ["derive"] } -serde_json = "1.0.117" -tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] } diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/default.nix b/sys/nixpkgs/pkgs/generate_moz_extension/default.nix deleted file mode 100644 index be734eee..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -[ - ( - final: prev: { - generate_firefox_extensions = import ./generate_firefox_extensions.nix { - inherit - (prev) - rustPlatform - # Dependencies - - openssl - pkg-config - ; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/examples/generate_extensions.sh b/sys/nixpkgs/pkgs/generate_moz_extension/examples/generate_extensions.sh deleted file mode 100755 index 96802992..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/examples/generate_extensions.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -tmp=$(mktemp) -cat <"$tmp" - darkreader:navbar - keepassxc-browser:navbar - vhack-libredirect:navbar - # torproject-snowflake:navbar - tridactyl-vim:menupanel - ublock-origin:menupanel -EOF - -# The cat execution should be unquoted; -# shellcheck disable=SC2046 -cargo run -- $(cat "$tmp") - -rm "$tmp" diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/flake.lock b/sys/nixpkgs/pkgs/generate_moz_extension/flake.lock deleted file mode 100644 index 741a8ad1..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/flake.lock +++ /dev/null @@ -1,106 +0,0 @@ -{ - "nodes": { - "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1714864355, - "narHash": "sha256-uXNW6bapWFfkYIkK1EagydSrFMqycOYEDSq75GmUpjk=", - "owner": "ipetkov", - "repo": "crane", - "rev": "442a7a6152f49b907e73206dc8e1f46a61e8e873", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1715037484, - "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1715221036, - "narHash": "sha256-81EKOdlmT/4hZpImRlvMVPgmCcJYZjwlWbJese/XqUw=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "5c4bc8a0a70093a31a12509c5653c147f2310bd2", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/flake.nix b/sys/nixpkgs/pkgs/generate_moz_extension/flake.nix deleted file mode 100644 index 5575f90b..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/flake.nix +++ /dev/null @@ -1,75 +0,0 @@ -{ - description = "A simple way to query the mozialla api for extension data"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - - crane = { - url = "github:ipetkov/crane"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - - flake-utils.url = "github:numtide/flake-utils"; - - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs = { - nixpkgs.follows = "nixpkgs"; - flake-utils.follows = "flake-utils"; - }; - }; - }; - - outputs = { - self, - nixpkgs, - crane, - flake-utils, - rust-overlay, - ... - }: - flake-utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { - inherit system; - overlays = [(import rust-overlay)]; - }; - - rust-stable = pkgs.rust-bin.stable.latest.default; - rust-minimal = pkgs.rust-bin.stable.latest.minimal; - - craneLib = (crane.mkLib pkgs).overrideToolchain rust-minimal; - - buildInputs = [ - pkgs.openssl # needed for openssl - ]; - nativeBuildInputs = [ - pkgs.pkg-config # needed for openssl - ]; - - craneBuild = craneLib.buildPackage { - src = craneLib.cleanCargoSource ./.; - inherit buildInputs nativeBuildInputs; - - doCheck = true; - }; - in { - packages.default = craneBuild; - app.default = { - type = "app"; - program = "${self.packages.${system}.default}/bin/generate_extensions"; - }; - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - cocogitto - - rust-stable - cargo-edit - ]; - inherit buildInputs nativeBuildInputs; - }; - }); -} -# vim: ts=2 - diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/generate_firefox_extensions.nix b/sys/nixpkgs/pkgs/generate_moz_extension/generate_firefox_extensions.nix deleted file mode 100644 index abd95c77..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/generate_firefox_extensions.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - rustPlatform, - openssl, - pkg-config, -}: -rustPlatform.buildRustPackage { - pname = "generate_firefox_extensions"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - buildInputs = [ - openssl # needed for openssl-sys crate - ]; - nativeBuildInputs = [ - pkg-config # needed for openssl dependency - ]; -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/res/generate_extensions.py b/sys/nixpkgs/pkgs/generate_moz_extension/res/generate_extensions.py deleted file mode 100644 index ee8cc966..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/res/generate_extensions.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -# source: https://github.com/etu/nixconfig/blob/ba47d577c8bfb4a1c06927c34ece34118f4a0460/modules/graphical/firefox/generate.py - -from concurrent.futures import ThreadPoolExecutor -import json -import requests - -EXTENSIONS = sorted( - [ - "darkreader", - "firenvim", - "keepassxc-browser", - "simple-tab-groups", - ] -) - - -def index_ext(ext: str): - # print(f"Indexing {ext}...") - - resp = requests.get(f"https://addons.mozilla.org/api/v5/addons/addon/{ext}/").json() - rel = resp["current_version"] - - if not rel["file"]["hash"].startswith("sha256:"): - raise ValueError("Unhandled hash type") - - return { - "pname": ext, - "version": rel["version"], - "addonId": resp["guid"], - "url": rel["file"]["url"], - "sha256": rel["file"]["hash"], - } - - -if __name__ == "__main__": - # outfile = os.path.dirname(os.path.realpath(__file__)) + "/extensions.json" - - with ThreadPoolExecutor() as e: - extensions = {ext: e.submit(index_ext, ext) for ext in EXTENSIONS} - extensions = {k: v.result() for k, v in extensions.items()} - - # with open(outfile, "w") as f: - print(json.dumps(extensions, indent=2)) diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/res/reference.json b/sys/nixpkgs/pkgs/generate_moz_extension/res/reference.json deleted file mode 100644 index f46ea8ec..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/res/reference.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "darkreader": { - "pname": "darkreader", - "version": "4.9.62", - "addonId": "addon@darkreader.org", - "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", - "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc" - }, - "firenvim": { - "pname": "firenvim", - "version": "0.2.14", - "addonId": "firenvim@lacamb.re", - "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", - "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6" - }, - "keepassxc-browser": { - "pname": "keepassxc-browser", - "version": "1.8.4", - "addonId": "keepassxc-browser@keepassxc.org", - "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", - "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719" - }, - "simple-tab-groups": { - "pname": "simple-tab-groups", - "version": "4.7.2.1", - "addonId": "simple-tab-groups@drive4ik", - "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", - "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4" - } -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/res/test.json b/sys/nixpkgs/pkgs/generate_moz_extension/res/test.json deleted file mode 100644 index daa1d19a..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/res/test.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "darkreader": { - "addon_id": "addon@darkreader.org", - "pname": "darkreader", - "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc", - "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", - "version": "4.9.62" - }, - "firenvim": { - "addon_id": "firenvim@lacamb.re", - "pname": "firenvim", - "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6", - "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", - "version": "0.2.14" - }, - "keepassxc-browser": { - "addon_id": "keepassxc-browser@keepassxc.org", - "pname": "keepassxc-browser", - "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719", - "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", - "version": "1.8.4" - }, - "simple-tab-groups": { - "addon_id": "simple-tab-groups@drive4ik", - "pname": "simple-tab-groups", - "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4", - "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", - "version": "4.7.2.1" - } -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/src/main.rs b/sys/nixpkgs/pkgs/generate_moz_extension/src/main.rs deleted file mode 100644 index bde986a3..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/src/main.rs +++ /dev/null @@ -1,138 +0,0 @@ -use std::env::args; - -use anyhow::{bail, Context}; -use futures::StreamExt; -use reqwest::Client; -use serde_json::{json, Map, Value}; - -pub mod types; - -macro_rules! get_json_value { - ($key:expr, $json_value:ident, $type:ident, $get:ident) => { - match $json_value.get($key) { - Some(resp) => { - let resp = resp.to_owned(); - if resp.$type() { - resp.$get().expect( - "The should have been checked in the if guard, so unpacking here is fine", - ).to_owned() - } else { - bail!( - "Value {} => \n{}\n is not of type: {}", - $key, - resp, - stringify!($type) - ); - } - } - None => { - bail!( - "There seems to be no '{}' in your json data (json value: '{}')\n Has the api changend?", - $key, serde_json::to_string_pretty(&$json_value).expect("Will always work") - ); - } - } - }; -} - -use futures::stream::futures_unordered::FuturesUnordered; -use types::{Extension, InputExtension}; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - let mut extensions: Vec = vec![]; - for input_extension in args() - .skip(1) - .map(|str| InputExtension::try_from(str)) - .collect::>>() - { - extensions.push(input_extension?); - } - - let resulting_extensions = process_extensions(extensions).await?; - - let mut output = Map::new(); - for extension in resulting_extensions { - output.insert(extension.pname.clone(), json!(extension)); - } - - println!( - "{}", - serde_json::to_string_pretty(&serde_json::Value::Object(output)).expect( - "This is constructed from json, it should also be possible to serialize it again" - ) - ); - Ok(()) -} - -async fn process_extensions(extensions: Vec) -> anyhow::Result> { - let mut output = Vec::with_capacity(extensions.len()); - - let client = Client::new(); - for extension in extensions - .iter() - .map(|ext| { - let local_client = &client; - index_extension(ext, local_client) - }) - .collect::>() - .collect::>() - .await - { - output.push(extension?); - } - Ok(output) -} - -async fn index_extension(extension: &InputExtension, client: &Client) -> anyhow::Result { - let response = client - .get(format!( - "https://addons.mozilla.org/api/v5/addons/addon/{}", - extension, - )) - .send() - .await - .context("Accessing the mozzila extenios api failed with error: {e}")?; - - eprintln!("Indexing {} ({})...", extension, response.status()); - let response: Value = serde_json::from_str( - &response - .text() - .await - .context("Turning the response to text fail with error: {e}")?, - ) - .context("Deserializing the response failed! Error: {e}")?; - - if let Some(detail) = response.get("detail") { - if detail == "Not found." { - bail!("Your extension ('{}') was not found!", extension); - } - }; - - let release = { get_json_value!("current_version", response, is_object, as_object) }; - - #[allow(non_snake_case)] - let addonId = { get_json_value!("guid", response, is_string, as_str) }; - - let version = { get_json_value!("version", release, is_string, as_str) }; - let file = { get_json_value!("file", release, is_object, as_object) }; - - let url = { get_json_value!("url", file, is_string, as_str) }; - let sha256 = { - let hash = get_json_value!("hash", file, is_string, as_str); - if hash.starts_with("sha256:") { - hash - } else { - bail!("This hash type is unhandled: {}", hash); - } - }; - - Ok(Extension { - pname: extension.moz_name.clone(), - default_area: extension.default_area, - version, - addonId, - url, - sha256, - }) -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/src/types.rs b/sys/nixpkgs/pkgs/generate_moz_extension/src/types.rs deleted file mode 100644 index b830fe0d..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/src/types.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::fmt::Display; - -use anyhow::anyhow; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -#[allow(non_snake_case)] -pub struct Extension { - pub pname: String, - pub default_area: DefaultArea, - pub version: String, - pub addonId: String, - pub url: String, - pub sha256: String, -} - -#[derive(Debug, Clone)] -pub struct InputExtension { - pub moz_name: String, - pub default_area: DefaultArea, -} -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] -#[allow(non_camel_case_types)] -pub enum DefaultArea { - navbar, - menupanel, -} - -impl Display for DefaultArea { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - DefaultArea::navbar => f.write_str("navbar"), - DefaultArea::menupanel => f.write_str("menupanel"), - } - } -} - -impl TryFrom<&str> for DefaultArea { - type Error = anyhow::Error; - - fn try_from(value: &str) -> Result { - match value { - "navbar" => Ok(Self::navbar), - "menupanel" => Ok(Self::menupanel), - _ => Err(anyhow!( - "Your needs to be one of 'navbar' or 'menupanel', but is: '{}'", - value - )), - } - } -} - -impl Display for InputExtension { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.moz_name) - } -} -impl TryFrom for InputExtension { - type Error = anyhow::Error; - - fn try_from(value: String) -> Result { - if let Some((moz_name, default_area)) = value.split_once(':') { - Ok(Self { - moz_name: moz_name.to_owned(), - default_area: default_area.try_into()?, - }) - } else { - Err(anyhow!("Can't parse the input string as a InputExtension!\n Needs to be: ':'")) - } - } -} diff --git a/sys/nixpkgs/pkgs/generate_moz_extension/update.sh b/sys/nixpkgs/pkgs/generate_moz_extension/update.sh deleted file mode 100755 index e500bb23..00000000 --- a/sys/nixpkgs/pkgs/generate_moz_extension/update.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh - -nix flake update - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/lf-make-map/.envrc b/sys/nixpkgs/pkgs/lf-make-map/.envrc deleted file mode 100644 index c8c56659..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/.envrc +++ /dev/null @@ -1,11 +0,0 @@ -use flake || use nix -watch_file flake.nix - -PATH_add ./target/debug -PATH_add ./target/release -PATH_add ./scripts - -if on_git_branch; then - echo && git status --short --branch && - echo && git fetch --verbose -fi diff --git a/sys/nixpkgs/pkgs/lf-make-map/.gitignore b/sys/nixpkgs/pkgs/lf-make-map/.gitignore deleted file mode 100644 index cb87f36f..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# build -/target -/result - -# dev env -.direnv diff --git a/sys/nixpkgs/pkgs/lf-make-map/Cargo.lock b/sys/nixpkgs/pkgs/lf-make-map/Cargo.lock deleted file mode 100644 index 16af6e03..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/Cargo.lock +++ /dev/null @@ -1,505 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "anyhow" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets", -] - -[[package]] -name = "clap" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "is-terminal" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lf-make-map" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "log", - "stderrlog", - "walkdir", -] - -[[package]] -name = "libc" -version = "0.2.154" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "proc-macro2" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[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 = "stderrlog" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b" -dependencies = [ - "chrono", - "is-terminal", - "log", - "termcolor", - "thread_local", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[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 = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "winapi-util" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -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.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/sys/nixpkgs/pkgs/lf-make-map/Cargo.toml b/sys/nixpkgs/pkgs/lf-make-map/Cargo.toml deleted file mode 100644 index da9881fd..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "lf-make-map" -description = "An automatic lf cd mapping generator" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.83" -clap = { version = "4.5.4", features = ["derive", "env"] } -log = "0.4.21" -stderrlog = "0.6.0" -walkdir = "2.5.0" diff --git a/sys/nixpkgs/pkgs/lf-make-map/README.md b/sys/nixpkgs/pkgs/lf-make-map/README.md deleted file mode 100644 index 0c57cede..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Lf make map - -> An automatic lf cd mapping generator - -Some text about the project. - -## Licence - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. diff --git a/sys/nixpkgs/pkgs/lf-make-map/default.nix b/sys/nixpkgs/pkgs/lf-make-map/default.nix deleted file mode 100644 index 8ff4c624..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -[ - ( - final: prev: { - lf-make-map = import ./lf_make_map.nix { - inherit - (prev) - rustPlatform - ; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/lf-make-map/flake.lock b/sys/nixpkgs/pkgs/lf-make-map/flake.lock deleted file mode 100644 index 611392df..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/flake.lock +++ /dev/null @@ -1,147 +0,0 @@ -{ - "nodes": { - "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1714864355, - "narHash": "sha256-uXNW6bapWFfkYIkK1EagydSrFMqycOYEDSq75GmUpjk=", - "owner": "ipetkov", - "repo": "crane", - "rev": "442a7a6152f49b907e73206dc8e1f46a61e8e873", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1715037484, - "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay", - "systems": "systems", - "treefmt-nix": "treefmt-nix" - } - }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1715221036, - "narHash": "sha256-81EKOdlmT/4hZpImRlvMVPgmCcJYZjwlWbJese/XqUw=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "5c4bc8a0a70093a31a12509c5653c147f2310bd2", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1680978846, - "narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=", - "owner": "nix-systems", - "repo": "x86_64-linux", - "rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "x86_64-linux", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1714058656, - "narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/flake.nix b/sys/nixpkgs/pkgs/lf-make-map/flake.nix deleted file mode 100644 index dc8c24cc..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/flake.nix +++ /dev/null @@ -1,125 +0,0 @@ -{ - description = "An automatic lf cd mapping generator"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - - treefmt-nix = { - url = "github:numtide/treefmt-nix"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - - crane = { - url = "github:ipetkov/crane"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs = { - nixpkgs.follows = "nixpkgs"; - flake-utils.follows = "flake-utils"; - }; - }; - - # inputs for following - systems = { - url = "github:nix-systems/x86_64-linux"; # only evaluate for this system - }; - flake-compat = { - url = "github:edolstra/flake-compat"; - flake = false; - }; - flake-utils = { - url = "github:numtide/flake-utils"; - inputs = { - systems.follows = "systems"; - }; - }; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - treefmt-nix, - crane, - rust-overlay, - ... - }: - flake-utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { - inherit system; - overlays = [(import rust-overlay)]; - }; - - nightly = false; - rust_minimal = - if nightly - then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.minimal) - else pkgs.rust-bin.stable.latest.minimal; - rust_default = - if nightly - then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default) - else pkgs.rust-bin.stable.latest.default; - - cargo_toml = craneLib.cleanCargoToml {cargoToml = ./Cargo.toml;}; - pname = cargo_toml.package.name; - - craneLib = (crane.mkLib pkgs).overrideToolchain rust_minimal; - craneBuild = craneLib.buildPackage { - src = craneLib.cleanCargoSource ./.; - - doCheck = true; - }; - - manual = pkgs.stdenv.mkDerivation { - name = "${pname}-manual"; - inherit (cargo_toml.package) version; - - src = ./docs; - nativeBuildInputs = with pkgs; [pandoc]; - - buildPhase = '' - mkdir --parents $out/docs; - - pandoc "./${pname}.1.md" -s -t man > $out/docs/${pname}.1 - ''; - - installPhase = '' - install -D $out/docs/${pname}.1 $out/share/man/man1/${pname}; - ''; - }; - - treefmtEval = import ./treefmt.nix {inherit treefmt-nix pkgs;}; - in { - packages.default = pkgs.symlinkJoin { - inherit (cargo_toml.package) name; - - paths = [manual craneBuild]; - }; - - checks = { - inherit craneBuild; - formatting = treefmtEval.config.build.check self; - }; - - formatter = treefmtEval.config.build.wrapper; - - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - cocogitto - - rust_default - cargo-edit - - licensure - ]; - }; - }); -} -# vim: ts=2 - diff --git a/sys/nixpkgs/pkgs/lf-make-map/lf_make_map.nix b/sys/nixpkgs/pkgs/lf-make-map/lf_make_map.nix deleted file mode 100644 index afb067b8..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/lf_make_map.nix +++ /dev/null @@ -1,10 +0,0 @@ -{rustPlatform}: -rustPlatform.buildRustPackage { - pname = "lf-make-map"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/cli.rs b/sys/nixpkgs/pkgs/lf-make-map/src/cli.rs deleted file mode 100644 index a398e451..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/cli.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::path::PathBuf; - -use clap::{ArgAction, Parser, Subcommand}; - -/// An automatic lf cd mapping generator -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -#[command(next_line_help = true)] -pub struct Args { - /// The directory to treat as home - #[arg(long, short = 'n', env = "HOME")] - pub home_name: PathBuf, - - /// The number of directories to generate mappings for, starting from each `relevant_directory` - #[arg(long, short, default_value = "2")] - pub depth: usize, - - /// Increase message verbosity - #[arg(long="verbose", short = 'v', action = ArgAction::Count)] - pub verbosity: u8, - - /// Silence all output - #[arg(long, short = 'q')] - pub quiet: bool, - - #[command(subcommand)] - pub command: Command, -} - -#[derive(Subcommand, Debug)] -pub enum Command { - /// Visualize the generated mappings in a tree - Visualize { - #[command(flatten)] - options: CommandOptions, - }, - - /// Output the generated mappings in a format suitable for the lf config file - Generate { - #[command(flatten)] - options: CommandOptions, - }, -} - -#[derive(Debug, Parser)] -pub struct CommandOptions { - /// The directories to generate mappings for - pub relevant_directories: Vec, -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/main.rs b/sys/nixpkgs/pkgs/lf-make-map/src/main.rs deleted file mode 100644 index aaf79b20..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/main.rs +++ /dev/null @@ -1,229 +0,0 @@ -use std::path::{Path, PathBuf}; - -use anyhow::{Context, Result}; -use clap::Parser; -use cli::{Args, Command}; -use log::trace; -use mapping::map_tree::MappingTree; -use walkdir::{DirEntry, WalkDir}; - -use crate::mapping::MapKey; - -mod cli; -mod mapping; - -fn main() -> anyhow::Result<()> { - let args = Args::parse(); - - stderrlog::new() - .module(module_path!()) - .quiet(args.quiet) - .show_module_names(false) - .color(stderrlog::ColorChoice::Auto) - .verbosity(args.verbosity as usize) - .timestamp(stderrlog::Timestamp::Off) - .init()?; - - let mut mappings = MappingTree::new(); - - let relevant_directories = match &args.command { - Command::Visualize { options } => &options.relevant_directories, - Command::Generate { options } => &options.relevant_directories, - }; - - for dir in relevant_directories { - trace!("Processing '{}'..", dir.display()); - let path = strip_path(&dir, &args.home_name)?; - - mappings - .include(path_to_str(path)?) - .with_context(|| format!("Failed to include path: '{}'", path.display()))?; - } - - let home = path_to_str(&args.home_name)?.to_owned(); - - let mut current_depth = 1; - while current_depth != args.depth { - for (key, value) in mappings.iter(false) { - trace!( - "Adding to child ('{}' -> '{}')", - MapKey::display(&key), - value - ); - - let mut local_mappings = MappingTree::new(); - for dir in WalkDir::new(extend(&home, &value)?) - .min_depth(1) - .max_depth(1) - .into_iter() - .filter_entry(|e| is_dir(e) && !is_hidden(e)) - { - let directory = dir - .with_context(|| format!("Failed to read dir ('{}')", home.clone() + &value))?; - let path_to_strip = &PathBuf::from(extend(&home, &value)?); - let path = strip_path(&directory.path(), &path_to_strip)?; - trace!( - "Including: '{}' (after stripping '{}' from '{}' -> '{}' + '/' + '{}')", - path.display(), - directory.path().display(), - path_to_strip.display(), - home, - value - ); - - let gen_key = MapKey::new_ones_from_path(path_to_str(path)?, 1); - local_mappings - .insert( - &gen_key, - path_to_str(strip_path(&directory.path(), &PathBuf::from(&home))?)?, - ) - .with_context(|| format!("Failed to include path: '{}'", path.display()))?; - } - - trace!("{}", local_mappings); - - trace!( - "'{}' -> '{:#?}'", - MapKey::display(&key), - local_mappings.root_node() - ); - mappings.interleave(&key, local_mappings.root_node().to_owned())?; - } - current_depth += 1; - } - - match args.command { - Command::Visualize { .. } => println!("{}", mappings), - Command::Generate { .. } => println!("{}", mappings.to_lf_mappings(args.home_name)), - } - - Ok(()) -} - -fn extend(base: &str, value: &str) -> Result { - let base_path = PathBuf::from(base); - let value_path = PathBuf::from(value); - - Ok(path_to_str(&base_path.join(&value_path))?.to_owned()) -} - -fn is_hidden(entry: &DirEntry) -> bool { - entry - .file_name() - .to_str() - .map(|s| s.starts_with(".")) - .unwrap_or(false) -} - -fn is_dir(entry: &DirEntry) -> bool { - entry.file_type().is_dir() -} - -fn strip_path<'a>(path: &'a Path, to_strip: &Path) -> Result<&'a Path> { - path.strip_prefix(&to_strip).with_context(|| { - format!( - "'{}' is not under the specified home path ('{}')!", - path.display(), - to_strip.display() - ) - }) -} - -fn path_to_str(path: &Path) -> Result<&str> { - path.to_str().with_context(|| { - format!( - "\ -Can't derive a keymapping from path: '{}' \ -because it can't be turned to a string -", - path.display() - ) - }) -} - -// fn gen_lf_mappings(home_name: PathBuf, char_num: usize, rel_dirs: Vec) { -// let mut mappings_vec = vec![]; -// let mut index_counter = 0; -// rel_dirs.iter().for_each(|rel_dir| { -// mappings_vec.push(vec![Mapping::new( -// &gen_hot_key(rel_dir, rel_dir, char_num), -// rel_dir, -// rel_dir, -// None, -// )]); -// get_dir(rel_dir.to_owned()).iter().for_each(|path| { -// mappings_vec[index_counter].push(Mapping::new( -// &gen_hot_key( -// path, -// path.parent().expect("All paths here should have parents"), -// char_num, -// ), -// path, -// &path -// .parent() -// .expect("All paths here should have parents") -// .to_owned(), -// None, -// )); -// }); -// index_counter += 1; -// }); -// print_mappings(&mappings_vec, home_name); -// mappings_vec -// .into_iter() -// .for_each(|rel_dir_mapping: Vec| { -// let mut hash_map = sort_mapping_by_hot_key(rel_dir_mapping.clone()); -// //dbg!(hash_map); -// hash_map.insert("gsi".to_owned(), vec![rel_dir_mapping[0].clone()]); -// }); -// } -// -// fn sort_mapping_by_hot_key(mut mappings: Vec) -> HashMap> { -// mappings.sort_by_key(|mapping| mapping.hot_key.clone()); -// -// let mut filtered_mappings: HashMap> = HashMap::new(); -// mappings.iter().for_each(|mapping| { -// filtered_mappings.insert(mapping.hot_key.clone(), vec![]); -// }); -// //dbg!(&mappings); -// -// let mut index_counter = 1; -// mappings.iter().for_each(|mapping| { -// if mappings.len() > index_counter { -// let next_mapping = &mappings[index_counter]; -// let vec = filtered_mappings -// .get_mut(&mapping.hot_key) -// .expect("This existst as it has been initialized"); -// -// if &next_mapping.hot_key == &mapping.hot_key { -// vec.push(mapping.clone()); -// vec.push(next_mapping.clone()); -// } else { -// vec.push(mapping.clone()); -// } -// -// let new_vec = vec.to_owned(); -// filtered_mappings.insert(mapping.hot_key.to_owned(), new_vec); -// } -// -// index_counter += 1; -// }); -// filtered_mappings -// } -// -// fn print_mappings(mappings: &Vec>, home_name: PathBuf) { -// for mapping in mappings { -// mapping.iter().for_each(|map| { -// println!( -// "{} = \"cd {}\";", -// map.hot_key, -// map.path -// .display() -// .to_string() -// .replace(home_name.to_str().expect("This should be UTF-8"), "~") -// ); -// }); -// -// println!("# -------------"); -// } -// } diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/display.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/display.rs deleted file mode 100644 index 65302e1e..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/display.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::fmt::Display; - -use crate::mapping::{ - map_tree::{Node, NodeValue}, - MapKey, -}; - -use super::MappingTree; - -impl Display for MappingTree { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fn write_node( - f: &mut std::fmt::Formatter<'_>, - node: &Node, - indention: String, - location: Vec, - is_last: bool, - is_root: bool, - ) -> std::fmt::Result { - let node_value = match &node.value { - NodeValue::Parent { children: _ } => "".to_owned(), - NodeValue::Child { path, extandable } => { - path.to_owned() + if *extandable { " [exten.]" } else { " [stop]" } - } - }; - - let new_idention = indention.clone() - + if is_root { - "" - } else { - match is_last { - true => " ", - false => "│ ", - } - }; - - let bullet = match is_last { - true => String::from("└── "), - false => String::from("├── "), - }; - - if is_root { - write!(f, ": {}\n", node_value)?; - } else { - write!( - f, - "{}{}\x1b[1;33m{}\x1b[0m: {}\n", - indention, - bullet, - MapKey::display(&location), - node_value, - )?; - }; - - match &node.value { - NodeValue::Parent { children } => { - let mut children_vec: Vec<(&MapKey, &Node)> = children.iter().collect(); - children_vec.sort_by(|(a, _), (b, _)| a.key.cmp(&b.key)); - - let mut counter = 1; - for (key, child) in &children_vec { - let mut new_location = location.clone(); - new_location.push((*key).to_owned()); - - write_node( - f, - child, - new_idention.clone(), - new_location.clone(), - counter == children_vec.len(), - false, - )?; - counter += 1; - } - } - NodeValue::Child { - path: _, - extandable: _, - } => { - // Do nothing and stop the recursion - } - } - - Ok(()) - } - - write_node(f, &self.root, String::new(), vec![], false, true)?; - - Ok(()) - } -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/iterator.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/iterator.rs deleted file mode 100644 index 4364bb2b..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/iterator.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::mapping::MapKey; - -use super::{MappingTree, Node, NodeValue}; - -pub struct MappingTreeIterator { - children: Vec<(Vec, String)>, -} - -impl MappingTreeIterator { - pub fn new(tree: &MappingTree, ignore_extendable: bool) -> Self { - let children = extract_child(vec![], &tree.root, ignore_extendable); - - Self { children } - } -} - -fn extract_child( - current_key: Vec, - node: &Node, - ignore_extendable: bool, -) -> Vec<(Vec, String)> { - match &node.value { - NodeValue::Parent { children } => children - .iter() - .map(|(key, value)| { - let mut new_key = current_key.clone(); - new_key.push(key.to_owned()); - - extract_child(new_key, value, ignore_extendable) - }) - .flatten() - .collect(), - NodeValue::Child { path, extandable } => { - if ignore_extendable { - vec![(current_key, path.to_string())] - } else { - if *extandable { - vec![(current_key, path.to_string())] - } else { - vec![] - } - } - } - } -} - -impl Iterator for MappingTreeIterator { - type Item = (Vec, String); - - fn next(&mut self) -> Option { - self.children.pop() - } -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/lf_mapping.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/lf_mapping.rs deleted file mode 100644 index 6d9c7a0d..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/lf_mapping.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::path::PathBuf; - -use crate::mapping::MapKey; - -use super::MappingTree; - -impl MappingTree { - pub fn to_lf_mappings(self, home_path: PathBuf) -> String { - self.iter(true) - .map(|(key, value)| { - format!( - "map g{} cd \"{}\"\n", - MapKey::display(&key), - home_path.join(&value).display() - ) - }) - .collect() - } -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/mod.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/mod.rs deleted file mode 100644 index 35e6d91d..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree/mod.rs +++ /dev/null @@ -1,402 +0,0 @@ -use std::{collections::HashMap, mem}; - -use anyhow::{bail, Result}; -use log::debug; - -use self::iterator::MappingTreeIterator; - -use super::MapKey; - -pub mod display; -pub mod iterator; -pub mod lf_mapping; - -/// A prefix tree -#[derive(Debug)] -pub struct MappingTree { - root: Node, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum NodeValue { - Parent { children: HashMap }, - Child { path: String, extandable: bool }, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Node { - value: NodeValue, -} - -impl MappingTree { - pub fn new() -> Self { - Self { - root: Node::new_parent(), - } - } - - pub fn root_node(&self) -> &Node { - &self.root - } - - pub fn iter(&self, ignore_extendable: bool) -> MappingTreeIterator { - MappingTreeIterator::new(&self, ignore_extendable) - } - - /// Returns the node at the key, otherwise None. The node can be changed - pub fn get_mut(&mut self, key: &[MapKey]) -> Option<&mut Node> { - let mut current_node = &mut self.root; - for ch in key.iter() { - if let NodeValue::Parent { children } = &mut current_node.value { - current_node = children.get_mut(&ch)? - } else { - return None; - } - } - - Some(current_node) - } - - /// Returns the node at the key, otherwise the last node that matched. - pub fn try_get(&self, key: &[MapKey]) -> (&Node, Vec) { - let mut current_node = &self.root; - let mut current_key = vec![]; - - for ch in key.iter() { - if let NodeValue::Parent { children } = ¤t_node.value { - current_node = if let Some(node) = children.get(&ch) { - let (key, _value) = children - .get_key_value(&ch) - .expect("This exists, we checked"); - current_key.push(key.clone()); - - node - } else { - return (current_node, current_key); - }; - } else { - return (current_node, current_key); - } - } - - (current_node, current_key) - } - - pub fn include(&mut self, path: &str) -> Result<()> { - let associated_key = MapKey::new_ones_from_path(path, 1); - self.insert(&associated_key, path) - } - - pub fn insert(&mut self, key: &[MapKey], path: &str) -> Result<()> { - self.insert_node(key, Node::new_child(path.to_owned())) - } - - pub fn interleave(&mut self, key: &[MapKey], node: Node) -> Result<()> { - let want_to_be_parent = self.get_mut(&key).expect("This value exists"); - let (parent_value, _parent_children) = if let NodeValue::Parent { children } = node.value { - ( - NodeValue::Parent { - children: children.clone(), - }, - children, - ) - } else { - unreachable!("This value will be a parent") - }; - - let child_value = mem::replace(&mut want_to_be_parent.value, parent_value); - assert!(matches!( - child_value, - NodeValue::Child { - path: _, - extandable: _ - } - )); - - let child_value = if let NodeValue::Child { - path, - extandable: _, - } = child_value - { - NodeValue::Child { - path, - extandable: false, - } - } else { - unreachable!("This is only a child value") - }; - - let child = Node { value: child_value }; - - let mut new_key = key.to_vec(); - new_key.push(MapKey { - key: '.', - part_path: ".".to_owned(), - resolution: 1, - }); - self.insert_node(&new_key, child)?; - Ok(()) - } - - pub fn insert_node(&mut self, key: &[MapKey], node: Node) -> Result<()> { - let (_node, found_key) = self.try_get(key).clone(); - - if found_key != key { - let needed_nodes_key = key - .strip_prefix(&found_key[..]) - .expect("The node's location is a prefix"); - - let needed_nodes_length = needed_nodes_key.iter().count(); - - let mut current_node = self - .get_mut(&found_key[..]) - .expect("This should always exists"); - let mut current_location = found_key.clone(); - let mut counter = 1; - - for ch in needed_nodes_key.iter() { - current_location.push(ch.to_owned()); - - let next_node = if counter == needed_nodes_length { - node.clone() - } else { - Node::new_parent() - }; - - current_node = match ¤t_node.value { - NodeValue::Parent { children } => { - assert_eq!(children.get(&ch), None); - - let children = - if let NodeValue::Parent { children } = &mut current_node.value { - children - } else { - unreachable!("This is a parent, we cheched") - }; - - children.insert(ch.to_owned(), next_node); - children.get_mut(&ch).expect("Was just inserted") - } - NodeValue::Child { - path, - extandable: _, - } => { - // A node that should be a parent was classified - // as child before: - // - // 1. Remove the child node and replace it with a parent one. - // 2. Add the child node to the parent node as child, but with a '.' as MapKey. - // 3. Add the original node also as child to the parent node. - - let mut children = HashMap::new(); - let move_child_node = Node::new_child(path.to_owned()); - - children.insert( - MapKey { - key: '.', - part_path: ".".to_owned(), - resolution: 1, - }, - move_child_node, - ); - children.insert(ch.to_owned(), next_node); - - current_node.value = NodeValue::Parent { children }; - - let children = - if let NodeValue::Parent { children } = &mut current_node.value { - children - } else { - unreachable!("We just inserted the parent value.") - }; - - children.get_mut(&ch).expect("Was just inserted") - } - }; - - counter += 1; - } - } else { - fn reduce_string(a: &str) -> Option { - let first_char = a.chars().take(1).last().expect("Should contain one char"); - - if a.chars().all(|ch| ch == first_char) { - return Some(first_char); - } else { - return None; - } - } - fn check_subset(a: &str, b: &str) -> bool { - if a.len() > b.len() { - let a_prefix: String = a.chars().take(b.len()).collect(); - let a_suffix: String = a.chars().skip(b.len()).collect(); - - if a_prefix == b { - let clean_suffix = reduce_string(&a_suffix); - if let Some(ch) = clean_suffix { - ch == b.chars().last().expect("Will match") - } else { - false - } - } else { - false - } - } else if b.len() > a.len() { - let b_prefix: String = b.chars().take(a.len()).collect(); - let b_suffix: String = b.chars().skip(a.len()).collect(); - - if b_prefix == a { - let clean_suffix = reduce_string(&b_suffix); - if let Some(ch) = clean_suffix { - ch == a.chars().last().expect("Will match") - } else { - false - } - } else { - false - } - } else { - a == b - } - } - - // Another node was already inserted with the same key! - // So we simple increase the resolution of the other node and this node, until their - // keys are not the same anymore. - // This only includes the last segment of the `MapKey` - // - // 1. Change both keys, until they are not equal any more - // 2. Move the wrongly placed node to the new place. - // 3. Insert our node. - let mut foreign_key = vec![found_key.last().expect("This will exist").clone()]; - let mut our_key = vec![key.last().expect("This will exist").clone()]; - - debug!( - "'{}' ('{}') and '{}' ('{}') are the same, try to find a better combination!", - MapKey::display(&our_key), - our_key[0].part_path, - MapKey::display(&foreign_key), - foreign_key[0].part_path, - ); - - // The 'a' and 'b' stuff is here, to ensure that both returning None will not match - // this condition. - if reduce_string(&foreign_key[0].part_path).unwrap_or('a') - == reduce_string(&our_key[0].part_path).unwrap_or('b') - { - bail!( - "\ -The foreign_key ('{}', path_part: '{}' -> '{}') and our_key ('{}', path_part: '{}' -> '{}') \ -have an identical path_part (when duplicated chars are removed)! -I cannot extended them via incrementation. -Please rename the paths to fix this. - ", - MapKey::display(&foreign_key), - &foreign_key[0].part_path, - reduce_string(&foreign_key[0].part_path).expect("Is some here"), - MapKey::display(&our_key), - &our_key[0].part_path, - reduce_string(&our_key[0].part_path).expect("Is some here"), - ); - } - - if check_subset(&foreign_key[0].part_path, &our_key[0].part_path) { - bail!( - "\ -The foreign_key ('{}', path_part: '{}') and our_key ('{}', path_part: '{}') \ -are subsets of one another! -A discrimination through incrementation will not work! -Please rename the paths to fix this. - ", - MapKey::display(&foreign_key), - &foreign_key[0].part_path, - MapKey::display(&our_key), - &our_key[0].part_path, - ); - } - - while our_key == foreign_key { - our_key = our_key[0].increment(our_key[our_key.len() - 1].resolution + 1); - foreign_key = - foreign_key[0].increment(foreign_key[foreign_key.len() - 1].resolution + 1); - debug!( - "Now its: '{}' ('{}') and '{}' ('{}')", - MapKey::display(&our_key), - our_key[0].part_path, - MapKey::display(&foreign_key), - foreign_key[0].part_path, - ); - } - - debug!( - "Found a better one: '{}' ('{}') and '{}' ('{}')", - MapKey::display(&our_key), - our_key[0].part_path, - MapKey::display(&foreign_key), - foreign_key[0].part_path, - ); - - let parent = self - .get_mut(&found_key[..&found_key.len() - 1]) - .expect("This will exist"); - - if let NodeValue::Parent { children } = &mut parent.value { - if let NodeValue::Child { - path: _, - extandable: _, - } = children - .get(found_key.last().expect("Exists")) - .expect("This node also exists") - .value - { - let old = children - .remove(found_key.last().expect("This will exist")) - .expect("This will be there"); - - let full_foreign_key: Vec<_> = found_key - .clone() - .into_iter() - .rev() - .skip(1) - .rev() - .chain(foreign_key.clone().into_iter()) - .collect(); - self.insert_node(&full_foreign_key, old.clone())?; - } - - let full_our_key: Vec<_> = key - .to_vec() - .into_iter() - .rev() - .skip(1) - .rev() - .chain(our_key.clone().into_iter()) - .collect(); - - self.insert_node(&full_our_key, node.clone())?; - } else { - unreachable!("This node will be a parent"); - } - } - - Ok(()) - } -} - -impl Node { - pub fn new_child(path: String) -> Self { - Self { - value: NodeValue::Child { - path, - extandable: true, - }, - } - } - pub fn new_parent() -> Self { - Self { - value: NodeValue::Parent { - children: HashMap::new(), - }, - } - } -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs deleted file mode 100644 index 114fdca0..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::{ - fmt::{Display, Write}, - hash::Hash, -}; - -use log::debug; - -pub mod map_tree; - -#[derive(Clone, Debug, Eq)] -pub struct MapKey { - pub key: char, - - resolution: usize, - - /// Part of the path, used to derive the key - part_path: String, -} - -impl Hash for MapKey { - fn hash(&self, state: &mut H) { - self.key.hash(state) - } -} - -impl PartialEq for MapKey { - fn eq(&self, other: &Self) -> bool { - self.key == other.key - } -} - -impl MapKey { - pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec { - let key = Self::part_path_to_key(&part_path, resolution); - - key.chars() - .map(|ch| Self { - key: ch, - resolution, - part_path: part_path.to_owned(), - }) - .collect() - } - - pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec { - let key: Vec = path - .split('/') - .map(|part| Self::new_from_part_path(part, number_of_chars)) - .flatten() - .collect(); - - debug!( - "Generated full MapKeys: '{}' -> '{}'", - path, - MapKey::display(&key) - ); - key - } - - pub fn increment(&self, target_resolution: usize) -> Vec { - let new_resolution = target_resolution; - - // debug!("Incrementing: '{}' ('{}')", &self, &self.part_path); - - let added_chars = if new_resolution < self.part_path.len() { - MapKey::part_path_to_key(&self.part_path, new_resolution) - } else { - let mut generated_chars = - MapKey::part_path_to_key(&self.part_path, self.part_path.len()); - - generated_chars.extend( - (0..(new_resolution - self.part_path.len())) - .into_iter() - .map(|_| self.part_path.chars().last().expect("This will exists")), - ); - - generated_chars - }; - - let part_path = self.part_path.clone(); - let output: Vec = added_chars - .chars() - .enumerate() - .map(|(res, ch)| MapKey { - key: ch, - resolution: res + 1, - part_path: part_path.clone(), - }) - .collect(); - - // debug!("Finished increment: '{}' ('{}')", MapKey::display(&output), output[0].part_path); - output - } - - pub fn display(values: &[Self]) -> String { - values.iter().map(|value| value.key.clone()).collect() - } - fn part_path_to_key(part: &str, number_of_chars: usize) -> String { - fn make(pat: char, part: &str, number_of_chars: usize) -> String { - let mut acc = String::new(); - - if !part.split(pat).all(|part| part.len() > 0) { - panic!( - "\ -Can't turn this path '{}' to a mapping. -This should not happen, please report the bug!", - part - ) - } - - let mut last_working = None; - for i in 0..number_of_chars { - for str in part.split(pat) { - if acc.len() != number_of_chars { - acc.push(match str.chars().nth(i) { - Some(ch) => ch, - None => { - if let Some(last) = last_working { - str.chars().nth(last).expect("This should always exist") - } else { - last_working = Some(i - 1); - str.chars().nth(i - 1).expect("This should always exist") - } - } - }) - } - } - } - - acc - } - - let value = if part.contains('_') && !part.starts_with('_') && !part.ends_with('_') { - make('_', part, number_of_chars) - } else if part.contains('-') && !part.starts_with('-') && !part.ends_with('-') { - make('-', part, number_of_chars) - } else { - part.chars().take(number_of_chars).collect::() - }; - - assert_eq!( - value.len(), - number_of_chars, - "'{}' does not have expected length of: {}", - value, - number_of_chars - ); - value - } -} - -impl Display for MapKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_char(self.key) - } -} diff --git a/sys/nixpkgs/pkgs/lf-make-map/update.sh b/sys/nixpkgs/pkgs/lf-make-map/update.sh deleted file mode 100755 index a0a029f4..00000000 --- a/sys/nixpkgs/pkgs/lf-make-map/update.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env sh - -nix flake update - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/README.md b/sys/nixpkgs/pkgs/plgs-pkgs/README.md deleted file mode 100644 index e8169951..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Fork - -All files in this repository where forked form [here](https://github.com/NixNeovim/NixNeovimPlugins) on commit `5010b91eb03696574c3c293f072a090618227e87`. -Below the original README. They were licensed under the MIT license. - -# All vim plugins, ready to go - -This repo auto generates nix packages for vim/neovim plugins. -Packages are automatically updated twice per week using a GitHub Actions. -Plugins are fetched from the `manifest.txt` and [awesome-neovim][0] repo. - -This is a fork of [this repo](https://github.com/m15a/nixpkgs-vim-extra-plugins); however, we fetch all additions from the original repo, so we will never have less plugins. -Further, the original deletes plugins that are available in the nixpkgs. We, instead, try to assemble a list of all available plugins. -Therefore, to access plugins you will never have to search in two places. - -This repo can be used as a stand-alone, by adding it to your inputs. -However, we recommend to use [NixNeovim](https://github.com/NixNeovim/NixNeovim) modules instead, and use this only when you need a plugins, which does not have a module, yet. - -## Available plugins - -The [plugins.md](plugins.md) contains an auto-generated list of all available plugins. - -## Usage - -- We recommend using [NixNeovim](https://github.com/NixNeovim/NixNeovim), and only access the plugins directly when they do not have a module in NixNeovim. - -However, you can also use this repo without NixNeovim: -To access the plugins, you need to add the overlay. -The overlay adds extra Vim plugins to `pkgs.vimExtraPlugins`. -First, add this repo to your inputs: - -``` -inputs.nixneovimplugins.url = github:jooooscha/nixpkgs-vim-extra-plugins -``` - -Next, apply the provided overlay: - -``` -nixpkgs.overlays = [ - inputs.nixneovimplugins.overlays.default -]; -``` - -Finally, you can add the packages to your vim/neovim config. For example you can use [NixNeovim](https://github.com/NixNeovim/Nixneovim) or you can add the plugins directly: - -``` - programs.neovim = { - plugins = [ - pkgs.vimExtraPlugins.nvim-colorizer-lua - ]; - } -``` - -More info on using neovim with nix can be found here: [NixOS Neovim](https://nixos.wiki/wiki/Neovim) - -## Contribution - -### How to add a new plugin - -#### 1. Add the plugin to manifest.txt: - -``` -# Examples - -haringsrob/nvim_context_vt -sourcehut:henriquehbr/ataraxis.lua -gitlab:yorickpeterse/nvim-pqf -williamboman/mason.nvim:45b9a4da776d9fb017960b3ac7241161fb7bc578 -foo/bar::baz --> renamed to baz -foo/bar:dev --> using dev branch -``` - -Supported are Github (default), SourceHut, and GitLab. - -#### 2. Create a Pull Request - -- Create a pull request with the changed manifest.txt (and blacklist.txt if neccessary). -- A GitHub action will check your contribution and generate all neccessary nix code for your new plugin. It will also take care of sorting and cleaning the manifest.txt -- After all checks have passed, I will merge your change. - -I am happy for any contribution. :) - -### How to remove a new plugin - -Copy the entry from manifest.txt to blacklist.txt and create a PR. -The GitHub Actions will do the rest, including removing the entry from manifest.txt - -## Credits - -This is originally based on work by [m15a](https://github.com/m15a/nixpkgs-vim-extra-plugins) - -[0]: https://github.com/rockerBOO/awesome-neovim diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/check.nix b/sys/nixpkgs/pkgs/plgs-pkgs/check.nix deleted file mode 100644 index ad23e2c7..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/check.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - pkgs, - lib, - ... -}: let - # checks if a plugin has a license - hasLicense = _: pkg: let - warn = x: lib.warn x x; - - msg = - if builtins.hasAttr "license" pkg.meta - then "${pkg.name} has license" - else warn "${pkg.name} has no license"; - - msg' = lib.replaceStrings [" "] ["-"] msg; - in - pkgs.runCommandNoCC msg' {} "echo : > $out "; - - # function to check License for all packages - check-missing-licenses = let - buildInputs = - lib.mapAttrsToList - hasLicense - pkgs.vimExtraPlugins; - in - pkgs.runCommandNoCC - "check-missing-licenses" - {inherit buildInputs;} - "echo : > $out"; -in { - checks = - pkgs.vimExtraPlugins - // { - inherit check-missing-licenses; - inherit (pkgs) update-vim-plugins; - }; -} diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/default.nix b/sys/nixpkgs/pkgs/plgs-pkgs/default.nix deleted file mode 100644 index 0f7cd485..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -[ - (final: prev: - prev.lib.composeManyExtensions [ - (self: super: let - origin = import ./plugins { - inherit (super.vimUtils) buildVimPlugin; - inherit (super) lib fetchurl fetchgit; - }; - in { - vimExtraPlugins = super.lib.makeExtensible (_: super.lib.recurseIntoAttrs origin); - }) - ] - final - prev) -] diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/overrides.nix b/sys/nixpkgs/pkgs/plgs-pkgs/overrides.nix deleted file mode 100644 index e03a78b1..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/overrides.nix +++ /dev/null @@ -1,34 +0,0 @@ -final: prev: let - inherit (final) lib; - - /* - * Mark broken packages here. - */ - markBrokenPackages = self: super: - lib.mapAttrs (attrName: broken: - super.${attrName}.overrideAttrs (old: { - meta = old.meta // {inherit broken;}; - })) - { - # = true; - }; - - /* - * Add licenses if missing or incorrect in generated ./pkgs/vim-plugins.nix. - */ - fixLicenses = self: super: - lib.mapAttrs (attrName: license: - super.${attrName}.overrideAttrs (old: { - meta = old.meta // {inherit license;}; - })) (with lib.licenses; { - /* - * Example: - * plugin-name = [] - */ - }); -in { - vimExtraPlugins = prev.vimExtraPlugins.extend (lib.composeManyExtensions [ - markBrokenPackages - fixLicenses - ]); -} diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/.plugins.json b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/.plugins.json deleted file mode 100644 index 9331bc8f..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/.plugins.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ThePrimeagen/harpoon:master": "{\"description\": \"\", \"homepage\": \"https://github.com/ThePrimeagen/harpoon\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"harpoon\", \"owner\": \"ThePrimeagen\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1w4hi9hbdjwdhb4vwa0x08a25vbcxqg1d5cskm2qvjy5fdlqils0\", \"url\": \"https://github.com/ThePrimeagen/harpoon/archive/ccae1b9bec717ae284906b0bf83d720e59d12b91.tar.gz\"}, \"source_line\": \"ThePrimeagen/harpoon:master\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cMGg==\"]], \"py/object\": \"datetime.date\"}}", - "akinsho/toggleterm.nvim": "{\"description\": \"A neovim lua plugin to help easily manage multiple terminal windows\", \"homepage\": \"https://github.com/akinsho/toggleterm.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"gpl3Only\"]}]}, \"name\": \"toggleterm-nvim\", \"owner\": \"akinsho\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"0nx69q9597vy7lzvvh58fnjyin23ns6apmyp532sgf547bw7mld6\", \"url\": \"https://github.com/akinsho/toggleterm.nvim/archive/cbd041d91b90cd3c02df03fe6133208888f8e008.tar.gz\"}, \"source_line\": \"akinsho/toggleterm.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cMBg==\"]], \"py/object\": \"datetime.date\"}}", - "andrewferrier/debugprint.nvim": "{\"description\": \"Debugging in NeoVim the print() way!\", \"homepage\": \"https://github.com/andrewferrier/debugprint.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"debugprint-nvim\", \"owner\": \"andrewferrier\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"06r1jhx7jd15q8wvnw0xqwk3bkx39pm4pbv70hf9ggd6zsnmsrmn\", \"url\": \"https://github.com/andrewferrier/debugprint.nvim/archive/54297dd0a4f318b279a1cb954e7714f3942df123.tar.gz\"}, \"source_line\": \"andrewferrier/debugprint.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHQ==\"]], \"py/object\": \"datetime.date\"}}", - "lmburns/lf.nvim": "{\"description\": \"Lf file manager for Neovim (in Lua)\", \"homepage\": \"https://github.com/lmburns/lf.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"lf-nvim\", \"owner\": \"lmburns\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px\", \"url\": \"https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz\"}, \"source_line\": \"lmburns/lf.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cKAw==\"]], \"py/object\": \"datetime.date\"}}", - "nvim-telescope/telescope-bibtex.nvim": "{\"description\": \"A telescope.nvim extension to search and paste bibtex entries into your TeX files.\", \"homepage\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"telescope-bibtex-nvim\", \"owner\": \"nvim-telescope\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs\", \"url\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz\"}, \"source_line\": \"nvim-telescope/telescope-bibtex.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHA==\"]], \"py/object\": \"datetime.date\"}}" -} \ No newline at end of file diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/blacklist.txt b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/blacklist.txt deleted file mode 100644 index 8b137891..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/blacklist.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/default.nix b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/default.nix deleted file mode 100644 index df09e446..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/default.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ - lib, - buildVimPlugin, - fetchurl, - fetchgit, -}: { - /* - Generated from: ThePrimeagen/harpoon:master - */ - harpoon = buildVimPlugin { - pname = "harpoon"; - version = "2023-12-26"; - src = fetchurl { - url = "https://github.com/ThePrimeagen/harpoon/archive/ccae1b9bec717ae284906b0bf83d720e59d12b91.tar.gz"; - sha256 = "1w4hi9hbdjwdhb4vwa0x08a25vbcxqg1d5cskm2qvjy5fdlqils0"; - }; - meta = with lib; { - description = ""; - homepage = "https://github.com/ThePrimeagen/harpoon"; - license = with licenses; [mit]; - }; - }; - /* - Generated from: lmburns/lf.nvim - */ - lf-nvim = buildVimPlugin { - pname = "lf-nvim"; - version = "2023-10-03"; - src = fetchurl { - url = "https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz"; - sha256 = "1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px"; - }; - meta = with lib; { - description = "Lf file manager for Neovim (in Lua)"; - homepage = "https://github.com/lmburns/lf.nvim"; - license = with licenses; [mit]; - }; - }; - /* - Generated from: nvim-telescope/telescope-bibtex.nvim - */ - telescope-bibtex-nvim = buildVimPlugin { - pname = "telescope-bibtex-nvim"; - version = "2024-03-28"; - src = fetchurl { - url = "https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz"; - sha256 = "1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs"; - }; - meta = with lib; { - description = "A telescope.nvim extension to search and paste bibtex entries into your TeX files."; - homepage = "https://github.com/nvim-telescope/telescope-bibtex.nvim"; - license = with licenses; [mit]; - }; - }; -} diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/manifest.txt b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/manifest.txt deleted file mode 100644 index 615083c8..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/manifest.txt +++ /dev/null @@ -1,3 +0,0 @@ -lmburns/lf.nvim -nvim-telescope/telescope-bibtex.nvim -ThePrimeagen/harpoon:master diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/plugins.md b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/plugins.md deleted file mode 100644 index 4f73f811..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/plugins.md +++ /dev/null @@ -1,7 +0,0 @@ -- Plugin count: 3 - -| Repo | Last Update | Nix package name | Last checked | -|:---|:---|:---|:---| -| [ThePrimeagen/harpoon:master](https://github.com/ThePrimeagen/harpoon) | 2023-12-26 | `harpoon` | 2024-05-09 | -| [lmburns/lf.nvim](https://github.com/lmburns/lf.nvim) | 2023-10-03 | `lf-nvim` | 2024-05-09 | -| [nvim-telescope/telescope-bibtex.nvim](https://github.com/nvim-telescope/telescope-bibtex.nvim) | 2024-03-28 | `telescope-bibtex-nvim` | 2024-05-09 | diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/plugins/whitelist.txt b/sys/nixpkgs/pkgs/plgs-pkgs/plugins/whitelist.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/sys/nixpkgs/pkgs/plgs-pkgs/update.sh b/sys/nixpkgs/pkgs/plgs-pkgs/update.sh deleted file mode 100755 index 6a0d3452..00000000 --- a/sys/nixpkgs/pkgs/plgs-pkgs/update.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env sh - -BASE_DIR="$(readlink -f "$(dirname "$0")/plugins")" - -# Fetch plugins -cd "$BASE_DIR" || (echo "BUG: No '$BASE_DIR'" && exit 1) - -# Cleanup manifest -sort -o "$BASE_DIR/manifest.txt" "$BASE_DIR/manifest.txt" -sort -o "$BASE_DIR/blacklist.txt" "$BASE_DIR/blacklist.txt" -## Remove all plugins, which are on the blacklist -# The same file is read and written to -# shellcheck disable=SC2005 -echo "$(comm -23 "$BASE_DIR/manifest.txt" "$BASE_DIR/blacklist.txt")" >"$BASE_DIR/manifest.txt" - -# Backup vim-plugins.nix -mv "$BASE_DIR/default.nix" "$BASE_DIR/default.nix.bak" -echo "{...} : {}" >"$BASE_DIR/default.nix" - -# Generate derivations for new plugins (this binary is provided by the dev-environment) -update-vim-plugins cleanup "$BASE_DIR" - -# Restore vim-plugins.nix -mv "$BASE_DIR/default.nix.bak" "$BASE_DIR/default.nix" - -# Update new plugins -update-vim-plugins update "$BASE_DIR" --all diff --git a/sys/nixpkgs/pkgs/scripts/default.nix b/sys/nixpkgs/pkgs/scripts/default.nix deleted file mode 100644 index 5279b241..00000000 --- a/sys/nixpkgs/pkgs/scripts/default.nix +++ /dev/null @@ -1,392 +0,0 @@ -{ - sysLib, - config, -}: [ - ( - final: prev: let - inherit (prev) lib; - - write_shell = { - name, - path, - dependencies ? [], - keepPath ? false, - completions ? false, - }: - sysLib.writeShellScript { - inherit name keepPath; - src = ./source/${path}/${name}.sh; - dependencies = dependencies ++ [prev.dash]; - generateCompletions = completions; - }; - write_python = { - name, - path, - dependencies_system ? [], - dependencies_python ? _: [], - keepPath ? false, - }: let - src = ./source/${path}/${name}.py; - dependencies = - [(prev.python3.withPackages dependencies_python)] - ++ dependencies_system; - path_setting = - if keepPath - then "--prefix PATH :" - else "--set PATH"; - in - prev.runCommandLocal name { - nativeBuildInputs = [prev.makeWrapper] ++ dependencies; - } - '' - install -m755 ${src} -D "$out/bin/${name}" - patchShebangs "$out/bin/${name}" - wrapProgram "$out/bin/${name}" ${path_setting} ${prev.lib.makeBinPath dependencies}; - ''; - - ## Begin of shell scripts - - aumo-scr = write_shell { - name = "aumo"; - path = "apps"; - dependencies = builtins.attrValues { - inherit - (prev) - udisks - findutils - rofi - ; - }; - }; - - battery-scr = write_shell { - name = "battery"; - path = "wrappers"; - dependencies = []; - }; - - con2pdf-scr = sysLib.writeShellScript { - name = "con2pdf"; - src = ./source/apps/con2pdf.sh; - dependencies = builtins.attrValues {inherit (prev) sane-backends imagemagick coreutils fd;}; - generateCompletions = true; - replacementStrings = { - DEVICE_FUNCTION = - # This is here, because escaping the whole function, to use it in the shell script - # directly just isn't possible - prev.writeText "DEVICE_FUNCTION" - /* - bash - */ - '' - scanimage -L | awk 'BEGIN { FS = "`" } { gsub(/'.*/, "", $2); print $2 }' - ''; - }; - }; - - description-scr = write_shell { - name = "description"; - path = "specific/ytcc"; - dependencies = builtins.attrValues { - inherit (prev) jq fmt less locale; - }; - }; - - fupdate-scr = write_shell { - name = "fupdate"; - path = "apps"; - keepPath = true; - completions = true; - dependencies = builtins.attrValues { - inherit - (prev) - dash - nix - gnugrep - fd - coreutils - bat # used by batgrep - gnused # required by batgrep - git # needed to fetch through git - ; - inherit (prev.bat-extras) batgrep; - }; - }; - - git-edit-index-scr = write_shell { - name = "git-edit-index"; - path = "apps"; - completions = true; - # This starts neovim, wich might want to shell out - keepPath = true; - dependencies = builtins.attrValues { - inherit - (prev) - git - gnused - # $EDITOR - - ; - }; - }; - - hibernate-scr = write_shell { - name = "hibernate"; - path = "wrappers"; - dependencies = builtins.attrValues { - inherit - (prev) - systemd - taskwarrior - ; - }; - }; - - ll-scr = sysLib.writeShellScript { - name = "ll"; - src = ./source/wrappers/ll.sh; - wrap = false; - }; - - # TODO: this need to be replaced with a wayland alternative - # llp-scr = write_shell { - # name = "llp"; - # path = "wrappers"; - # dependencies = builtins.attrValues {inherit (prev) lf ueberzug;}; - # }; - - lock-scr = write_shell { - name = "lock"; - path = "wrappers"; - dependencies = builtins.attrValues { - inherit - (prev) - taskwarrior - swaylock - ; - }; - }; - - lyrics-scr = write_shell { - name = "lyrics"; - path = "wrappers"; - dependencies = builtins.attrValues { - inherit - (prev) - exiftool - mpc-cli - jq - less - locale # dependency of less - ; - }; - }; - - mpc-fav-scr = write_shell { - name = "mpc-fav"; - path = "wrappers"; - dependencies = builtins.attrValues { - inherit - (prev) - mpc-cli - ; - }; - }; - - mpc-rm-scr = write_shell { - name = "mpc-rm"; - path = "wrappers"; - dependencies = builtins.attrValues { - inherit - (prev) - mpc-cli - trash-cli - ; - }; - }; - - mpc-scr = write_shell { - name = "mpc"; - path = "wrappers"; - dependencies = [ - mpc-fav-scr - mpc-rm-scr - prev.mpc-cli - ]; - }; - - nato-scr = write_python { - name = "nato"; - path = "small_functions"; - dependencies_python = ps: []; - }; - - neorg-scr = sysLib.writeShellScriptMultiPart { - name = "neorg"; - keepPath = true; - src = ./source/specific/neorg/sh; - baseName = "main.sh"; - cmdPrefix = "functions"; - cmdNames = [ - "add.sh" - "context.sh" - "dmenu.sh" - "f_start.sh" - "f_stop.sh" - "list.sh" - "project.sh" - "review.sh" - "utils.sh" - "workspace.sh" - ]; - dependencies = with prev; [ - cocogitto - rofi - libnotify - ]; - generateCompletions = true; - replacementStrings = { - DEFAULT_NEORG_PROJECT_DIR = - config.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces.projects; - HOME_TASKRC = "${config.xdg.configHome}/task/home-manager-taskrc"; - NEORG_REVIEW_PATH = "${config.xdg.dataHome}/neorg/review"; - ALL_PROJECTS_NEWLINE = "${config.soispha.taskwarrior.projects.projects_newline}"; - ALL_PROJECTS_COMMA = "${config.soispha.taskwarrior.projects.projects_comma}"; - ALL_PROJECTS_PIPE = "${config.soispha.taskwarrior.projects.projects_pipe}"; - ALL_WORKSPACES = "${lib.strings.concatStringsSep "|" (builtins.attrNames config.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces)}"; - ID_GENERATION_FUNCTION = "${sysLib.writeShellScript { - name = "neorg_id_function"; - src = ./source/specific/neorg/neorg_id_function.sh; - dependencies = with prev; [ - taskwarrior - gawk - findutils # xargs - ]; - }}/bin/neorg_id_function"; - - # TODO: Replace the hard-coded path here with some reference <2023-10-20> - TASK_PROJECT_FILE = "/home/soispha/repos/nix/nixos-config/hm/soispha/conf/taskwarrior/projects/default.nix"; - }; - }; - - screenshot_persistent-scr = write_shell { - name = "screenshot_persistent"; - path = "small_functions"; - keepPath = true; - dependencies = builtins.attrValues { - inherit - (prev) - grim - slurp - alacritty - rofi - libnotify - lf # TODO: add llp - ; - }; - }; - - screenshot_temporary-scr = write_shell { - name = "screenshot_temporary"; - path = "small_functions"; - dependencies = builtins.attrValues {inherit (prev) grim slurp wl-clipboard;}; - }; - - show-scr = write_shell { - name = "show"; - path = "wrappers"; - keepPath = true; # I might want to use nvim in less (and shell escapes) - dependencies = builtins.attrValues {inherit (prev) less locale;}; - }; - - sort_song-scr = write_shell { - name = "sort_song"; - path = "wrappers"; - dependencies = builtins.attrValues {inherit (prev) mediainfo jq gawk;}; - }; - - spodi-scr = sysLib.writeShellScriptMultiPart { - name = "spodi"; - keepPath = false; - src = ./source/specific/spodi; - baseName = "spodi.sh"; - cmdPrefix = "sh"; - cmdNames = [ - "download.sh" - "update.sh" - ]; - dependencies = with prev; [ - gawk - expect - spotdl - fd - coreutils - ]; - generateCompletions = true; - replacementStrings = { - XDG_CACHE_HOME = config.xdg.cacheHome; - XDG_MUSIC_DIR = config.xdg.userDirs.music; - }; - }; - - update-sys-scr = write_shell { - name = "update-sys"; - path = "small_functions"; - completions = true; - dependencies = builtins.attrValues { - inherit - (prev) - git - nixos-rebuild - sudo - openssh - coreutils - mktemp - gnugrep - gnused - systemd - ; - }; - }; - - virsh-del-scr = write_shell { - name = "virsh-del"; - path = "wrappers"; - dependencies = builtins.attrValues {inherit (prev) libvirt;}; - }; - - yti-scr = write_shell { - name = "yti"; - path = "wrappers"; - dependencies = builtins.attrValues {inherit (prev) gawk expect yt-dlp;}; - }; - in { - scripts = { - # llp = llp-scr; # TODO: see above - aumo = aumo-scr; - battery = battery-scr; - con2pdf = con2pdf-scr; - description = description-scr; - fupdate = fupdate-scr; - git-edit-index = git-edit-index-scr; - hibernate = hibernate-scr; - ll = ll-scr; - lock = lock-scr; - lyrics = lyrics-scr; - mpc-fav = mpc-fav-scr; - mpc-rm = mpc-rm-scr; - mpc = mpc-scr; - nato = nato-scr; - neorg = neorg-scr; - screenshot_persistent = screenshot_persistent-scr; - screenshot_temporary = screenshot_temporary-scr; - show = show-scr; - sort_song = sort_song-scr; - spodi = spodi-scr; - update-sys = update-sys-scr; - virsh-del = virsh-del-scr; - yti = yti-scr; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/scripts/source/apps/aumo.sh b/sys/nixpkgs/pkgs/scripts/source/apps/aumo.sh deleted file mode 100755 index 84d39deb..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/apps/aumo.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -unmounting() { - disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" - - udisksctl unmount --block-device "/dev/disk/by-label/$disk_name" -} - -mounting() { - disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" - - udisksctl mount --block-device "/dev/disk/by-label/$disk_name" -} - -case "$1" in -"mount") - mounting - ;; -"unmount" | "umount") - unmounting - ;; -*) - die "Usage: $NAME mount|unmount" - ;; -esac diff --git a/sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh b/sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh deleted file mode 100755 index 08bf8998..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/apps/con2pdf.sh +++ /dev/null @@ -1,234 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# needed for help() and version -# shellcheck disable=2034 -AUTHORS="Soispha" -# shellcheck disable=2034 -YEARS="2023" -# shellcheck disable=2034 -VERSION="1.0.0" - -# NAME is from the wrapper -# shellcheck disable=SC2269 -NAME="$NAME" -help() { - cat <_1.pdf). - - --num-pages | -p NUM - Number of pages to merge into one pdf (default: 1). - - --device | -d DEVICE - Device used for scanning. - - --method | -m METHOD - Method to use for scanning (default: ADF). - - --help | -h - Display this help and exit. - - --version | -v - Display version and copyright information and exit. -ARGUMENTS: - FILE := [[fd . --max-depth 3]] - A name of a file to store, default is: ./pdf - - NAME | * := [[fd . --max-depth 3]] - The basename of the generated files - - NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4 - Possible numbers of pages, can be more than 4 - - DEVICE := [[$(cat %DEVICE_FUNCTION)]] - Possible scanner names - - METHOD := ADF | Flatbed - The scanning method to use, not all scanners support both of - these. The default is ADF -EOF -} - -scan_adf() { - device="$1" - sides_per_page="$2" - method="ADF" - for i in $(seq "$sides_per_page"); do - do_until_success \ - "scanimage --format=tiff --progress --source='$method' --device='$device' --batch=%d.tif --batch-increment='$sides_per_page' --batch-start='$i'" \ - "warn 'Retrying scan, as we assume a network error!'" - - if [ "$sides_per_page" -ne 1 ]; then - msg "Finished turn, please change side!" - readp "Press enter to continue" noop - fi - done -} -process_images_adf() { - tiff_temp_path="$1" - output_directory="$2" - name="$3" - - counter=0 - pdf_counter=0 - image_cache="$(mktmp)" - while read -r scanned_image; do - dbg "$scanned_image (scanned_image) at $counter (counter)" - echo "$scanned_image" >>"$image_cache" - : $((counter += 1)) - if [ "$counter" = "$number_of_pages" ]; then - dbg "$counter == $number_of_pages" - counter=0 - convert_images "$image_cache" "${name}_$pdf_counter" "$output_directory" - : $((pdf_counter += 1)) - printf "" >"$image_cache" - fi - done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" -} - -scan_flatbed() { - device="$1" - number_of_pages"$2" - method="Flatbed" - for i in $(seq "$number_of_pages"); do - do_until_success \ - "scanimage --format=tiff --progress --source='$method' --device='$device' --output-file=$i.tiff" \ - "warn 'Retrying scan, as we assume a network error!'" - if [ "$number_of_pages" -ne 1 ]; then - msg "Finished turn, please change side!" - readp "Press enter to continue" noop - fi - done -} -process_images_flatbed() { - tiff_temp_path="$1" - output_directory="$2" - name="$3" - - counter=0 - image_cache="$(mktmp)" - while read -r scanned_image; do - echo "$scanned_image" >>"$image_cache" - : $((counter += 1)) - if [ "$counter" = "$number_of_pages" ]; then - counter=0 - convert_images "$image_cache" "$name" "$output_directory" - printf "" >"$image_cache" - fi - done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" -} -convert_images() { - image_cache="$1" - pdf_name="$2" - output_dir="$3" - - set -- - while read -r image; do - dbg "setting image: $image" - set -- "$@" "$image" - done <"$image_cache" - - while [ -e "$output_dir/${pdf_name}.pdf" ]; do - pdf_name="${pdf_name}_$(tr -dc 'A-Za-z0-9' *|*--help*|*-h*\] - -# DESCRIPTION - -Argument can be stacked, this makes it possible to specify multiple targets to be updated in succession. See the Examples section for further details. - -No argument or *flake* -: **fupdate**, when executed without arguments or with *flake*, will update your *flake.lock*, check for duplicate flake inputs, i.e., an input has an input declared, which you have also declared as input, and will run a script called *update.sh*, if you allow it. -The allowance for the script is asked, when you run **fupdate** and the found script is not yet allowed. Furthermore, the allowance is based on the concrete sha256 hash of the script, so any changes will require another allowance. - -**\** as argument -: If the executable **update-\** is reachable thought the PATH variable, than this is run. Otherwise, the program will exit. - -# OPTIONS - -**--help**, **-h** -: Displays a help message and exit. - -**--version**, **-v** -: Displays the software version and exit. - -# EXAMPLES - -**fupdate** or **fupdate flake** -: Updates your *flake.lock*. See the Description section for further details. - -**fupdate sys** -: Run the executable **update-sys**, if it exists. See the Description section for further details. - -**fupdate flake sys docs** -: First updates your flake, then, if the command succeeded, runs **update-sys**, afterweich **update-docs** is run. - -# FILES - -*update.sh* -: This is supposed to be a shell script located in your flake base directory, i.e., the directory which contains both a *flake.nix* and a *flake.lock* file. - -*~/.local/share/flake-update/* -: **fupdate** will store the hashes to the allowed *update.sh* files here. - -# BUGS - -Report bugs to . - -# COPYRIGHT - -Copyright (C) 2023 Soispha - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . diff --git a/sys/nixpkgs/pkgs/scripts/source/apps/fupdate.sh b/sys/nixpkgs/pkgs/scripts/source/apps/fupdate.sh deleted file mode 100755 index 4322610a..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/apps/fupdate.sh +++ /dev/null @@ -1,197 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -UPDATE_SCRIPT_NAME="update.sh" -CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update" - -# Both are used in version() -# shellcheck disable=SC2034 -AUTHORS="Soispha" -# shellcheck disable=SC2034 -YEARS="2023" - -UPDATE_SCRIPT_NOT_WANTED=false - -# Searches upward for a `UPDATE_SCRIPT_NAME` script -# Returns a path to the script if it exists, otherwise nothing is returned -check_for_update_script() { - dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")" - if [ "$dirname" ]; then - printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME" - fi -} - -# Checks if a given path to the update script is allowed. -# Takes the path as input -# Return 0, if allowed, 1 if not. -check_for_allowed_update_script() { - update_script="$1" - config_path="${CONFIG_DIRECTORY_PATH}${update_script}" - update_script_hash="$(sha256sum "$update_script")" - if [ -f "$config_path" ]; then - if [ "$(cat "$config_path")" = "$update_script_hash" ]; then - dbg "Recorded hash matches" - return 0 - else - dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed" - return 1 - fi - else - dbg "Path \'$config_path\' does not exist, assuming not allowed" - return 1 - fi -} - -# Asks the user if they want to allow a given script. -# Takes the path as input -ask_to_allow_update_script() { - update_script="$1" - config_path="${CONFIG_DIRECTORY_PATH}${update_script}" - update_script_hash="$(sha256sum "$update_script")" - println "\033[2J" # clear the screen - cat "$update_script" - readp "Do you want to allow this script?[N/y]: " allow - # shellcheck disable=SC2154 - dbg "allow is: $allow" - case "$allow" in - [yY]) - dbg "allowed script" - dbg "storing contents in: $config_path" - mkdir --parents "$(dirname "$config_path")" - print "$update_script_hash" >"$config_path" - ;; - *) - UPDATE_SCRIPT_NOT_ALLOWED=true - ;; - esac -} - -# Runs the provided script and continues to update the nix flake -# Takes the path to the script and the directory to the flake as arguments -# If the path to the update script is empty, it will be ignored -update() { - update_script="$1" - flake_base_dir="$2" - shift 2 - dbg "Provided following args to update script: '$*'" - - cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed" - dbg "changed directory to: $flake_base_dir" - - nix flake update - - if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then - "$update_script" "$@" - fi - - if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then - batgrep '[^0-9]_[0-9]' flake.lock - die "Your flake.nix contains duplicate inputs!" - fi -} - -help() { - cat <] - -OPTIONS: - --help | -h - Display this help and exit. - - --version | -v - Display version and copyright information and exit. - - --no-script - Avoid running the 'update.sh' script -COMMANDS: - flake - update the flake project - - - runs a executable called "update-", if it exists -EOF -} - -main() { - if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then - update_script="$(check_for_update_script)" - flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir - dbg "update_script is: $update_script" - dbg "flake_base_dir is: $flake_base_dir" - - if [ "$update_script" = "" ]; then - update "" "$flake_base_dir" "$@" - elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then - update "$update_script" "$flake_base_dir" "$@" - else - ask_to_allow_update_script "$update_script" - main "$@" - fi - fi -} - -if [ "$#" -eq 0 ]; then - main - exit 0 -fi - -for input in "$@"; do - case "$input" in - "--help" | "-h") - help - exit 0 - ;; - "--version" | "-v") - version - exit 0 - ;; - "--no-script" | "-n") - UPDATE_SCRIPT_NOT_WANTED=true - ;; - "--") - end_of_cli_options=true - - # Stop processing args after that marker. - break - ;; - esac - [ "$end_of_cli_options" = "true" ] && break -done - -case "$1" in -"flake") - shift 1 - - # Filter out fupdate specific flags - while [ "$1" != "--" ]; do - # FIXME: This check allows to add a flag multiple times, but this should probably - # not be allowed <2024-03-29> - case "$1" in - "--no-script" | "-n") - shift 1 - ;; - *) - break - ;; - esac - done - - [ "$1" = "--" ] && shift 1 - main "$@" - ;; -*) - command="$1" - shift 1 - [ "$1" = "--" ] && shift 1 - if which update-"$command" >/dev/null 2>&1; then - update-"$command" "$@" - else - die "command \"update-$command\" is not executable, or does not exist" - fi - ;; -esac diff --git a/sys/nixpkgs/pkgs/scripts/source/apps/git-edit-index.sh b/sys/nixpkgs/pkgs/scripts/source/apps/git-edit-index.sh deleted file mode 100755 index e73dc53c..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/apps/git-edit-index.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# needed for help() and version -# shellcheck disable=2034 -AUTHORS="Soispha" -# shellcheck disable=2034 -YEARS="2024" -# shellcheck disable=2034 -VERSION="1.0.0" - -# NAME is from the wrapper -# shellcheck disable=SC2269 -NAME="$NAME" - -help() { - cat <"$GIT_DIR/.git/EDIT_INDEX_PATCH" - - git add "$1" - git restore --staged "$1" - cat "$1" >"$GIT_DIR/.git/EDIT_INDEX_FILE" - git restore "$1" - - git apply "$GIT_DIR/.git/EDIT_INDEX_PATCH" - "$EDITOR" "$1" - - git add "$1" - mv "$GIT_DIR/.git/EDIT_INDEX_FILE" "$1" -} - -edit() { - files_to_add="$(mktmp)" - realpath --relative-to=. "$@" >"$files_to_add" - - index_files="$(mktmp)" - git diff --name-only --cached --diff-filter=AM >"$index_files" - - while read -r file; do - if grep -q "$file" "$files_to_add"; then - sed -i "s|$file||" "$files_to_add" - materialize_file "$file" - fi - done <"$index_files" - - files_to_check="$(mktmp)" - clean "$files_to_add" >"$files_to_check" - if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then - warn "Could not edit every file:" - cat "$files_to_add" - fi -} - -for arg in "$@"; do - case "$arg" in - "--help" | "-h") - help - exit 0 - ;; - "--version" | "-v") - version - exit 0 - ;; - "--") - end_of_cli_options=true - ;; - esac - [ "$end_of_cli_options" = "true" ] && break -done - -edit "$@" - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/small_functions/nato.py b/sys/nixpkgs/pkgs/scripts/source/small_functions/nato.py deleted file mode 100755 index e9d15f56..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/small_functions/nato.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -# originally from here: https://cgit.pacien.net/desktop-utilities/ - -import sys - -alphabet = { - "nato": { - "A": "Alfa", # No idea why this is not just 'Alpha' .. - "B": "Bravo", - "C": "Charlie", - "D": "Delta", - "E": "Echo", - "F": "Foxtrot", - "G": "Golf", - "H": "Hotel", - "I": "India", - "J": "Juliett", - "K": "Kilo", - "L": "Lima", - "M": "Mike", - "N": "November", - "O": "Oscar", - "P": "Papa", - "Q": "Quebec", - "R": "Romeo", - "S": "Sierra", - "T": "Tango", - "U": "Uniform", - "V": "Victor", - "W": "Whiskey", - "X": "X-ray", - "Y": "Yankee", - "Z": "Zulu", - "0": "Nadazero", - "1": "Unaone", - "2": "Bissotwo", - "3": "Terrathree", - "4": "Kartefour", - "5": "Pantafive", - "6": "Soxisix", - "7": "Setteseven", - "8": "Oktoeight", - "9": "Novenine", - ",": "Comma", - "/": "Forward slash", - ".": "Stop/Decimal", - }, - "german": { - "A": "Aachen", - "Ä": "Umlaut Aachen", - "B": "Berlin", - "C": "Chemnitz", - "D": "Düsseldorf", - "E": "Essen", - "F": "Frankfurt", - "G": "Goslar", - "H": "Hamburg", - "I": "Ingelheim", - "J": "Jena", - "K": "Köln", - "L": "Leipzig", - "M": "München", - "N": "Nürnberg", - "O": "Offenbach", - "Ö": "Umlaut Offenbach", - "P": "Potsdam", - "Q": "Quickborn", - "R": "Rostock", - "S": "Salzwedel", - "ẞ": "Eszett", - "T": "Tübingen", - "U": "Unna", - "Ü": "Umlaut Unna", - "V": "Völklingen", - "W": "Wuppertal", - "X": "Xanten", - "Y": "Ypsilon", - "Z": "Zwickau", - }, -} - - -def str_to_telephony(phrase, language): - language_alphabet = alphabet[language] - - return [ - language_alphabet[c] if c in language_alphabet else c for c in phrase.upper() - ] - - -language = sys.argv[1] -if language not in ["nato", "german"]: - print( - f"Langugae '{language}' is not a valid language, only 'nato' and 'german' are!", - file=sys.stderr, - ) - exit(1) - -print( - "\n".join( - str_to_telephony( - " ".join(sys.argv[2:]), - language, - ) - ) -) diff --git a/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_persistent.sh b/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_persistent.sh deleted file mode 100755 index 4308b8d2..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_persistent.sh +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# only generate a path (this could lead to a time-of-check/time-of-use bug) -tmp="$(mktmp --dry-run)" - -if grim -g "$(slurp)" "$tmp"; then - name="$(rofi -dmenu -p "Name of screenshot: " -l 0)" - screen_shot_path="$HOME/media/pictures/screenshots/$name.png" - while [ -f "$screen_shot_path" ]; do - notify-send "Warning" 'Screenshot name already in use!' - name="$(rofi -dmenu -p "New name of screenshot: " -l 0)" - screen_shot_path="$HOME/media/pictures/screenshots/$name.png" - done - - mv "$tmp" "$screen_shot_path" - alacritty -e lf -command ":{{ set sortby atime; set reverse!; }}" -fi - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_temporary.sh b/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_temporary.sh deleted file mode 100755 index 8968ca79..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/small_functions/screenshot_temporary.sh +++ /dev/null @@ -1,8 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -grim -g "$(slurp)" | wl-copy - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/small_functions/update-sys.sh b/sys/nixpkgs/pkgs/scripts/source/small_functions/update-sys.sh deleted file mode 100755 index d28247f6..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/small_functions/update-sys.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -help() { - cat <] [--help] - -OPTIONS: - --branch | -b BRANCHNAME - select a branch to update from. - - --mode | -m MODE - select a mode to update with - - --help | -h - output this help. -ARGUMENTS: - BRANCHNAME := [[ git branch --list --format '%(refname:short)' ]] - The name of the branch to deploy the config from - - MODE := switch|boot|test|build|dry-build|dry-activate|edit|repl|build-vm|build-vm-with-bootloader - See the 'nixos-rebuild' manpage for more information about these modes. -EOF - exit "$1" -} -default_branch=$(mktmp) -BRANCH="" - -while [ "$#" -gt 0 ]; do - case "$1" in - "--help" | "-h") - help 0 - ;; - "--branch" | "-b") - if [ -n "$2" ]; then - BRANCH="$2" - else - error "$1 requires an argument" - help 1 - fi - shift 2 - ;; - "--mode" | "-m") - if [ -n "$2" ]; then - MODE="$2" - else - error "$1 requires an argument" - help 1 - fi - shift 2 - ;; - *) - error "the option $1 does not exist!" - help 1 - ;; - esac -done - -cd /etc/nixos || die "No /etc/nixos" -msg "Starting system update..." -git remote update origin --prune >/dev/null 2>&1 -if ! [ "$BRANCH" = "" ]; then - git switch "$BRANCH" >/dev/null 2>&1 && msg2 "Switched to branch '$BRANCH'" -fi -msg2 "Updating git repository..." -git pull --rebase - -git remote show origin | grep 'HEAD' | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/ *$//g' >"$default_branch" & - -msg2 "Updating system..." -if [ -n "$MODE" ]; then - nixos-rebuild "$MODE" -else - nixos-rebuild switch -fi - -git switch "$(cat "$default_branch")" >/dev/null 2>&1 && msg2 "Switched to branch '$(cat "$default_branch")'" -msg "Finished Update!" - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/neorg_id_function.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/neorg_id_function.sh deleted file mode 100755 index 865ecacf..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/neorg_id_function.sh +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -context="$(task _get rc.context)" -if [ "$context" ]; then - filter="project:$context" -else - filter="0-10000" -fi -tasks="$(task "$filter" _ids)" - -if [ "$tasks" ]; then - echo "$tasks" | xargs task _zshids | awk -F: -v q="'" '{gsub(/'\''/, q "\\" q q ); print $1 ":" q $2 q}' -fi diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/add.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/add.sh deleted file mode 100755 index 5a830a10..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/add.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env dash - -add0open_taskwarrior_project_file() { - task_project_file="%TASK_PROJECT_FILE" - - cd "$(dirname $task_project_file)" || die "BUG: task_project_file ('$task_project_file') can't be accessed" - - git_dir="$(search_flake_base_dir)" - [ "$git_dir" ] || die "(BUG): No git directory?" - cd "$git_dir" || die "Unreachable, this MUST exists" - - nvim "$task_project_file" - git add "$task_project_file" - - base_task_project_file_path="$(awk "{ gsub(\"$git_dir/\", \"\", \$0); print }" "$(ptmp "$task_project_file")")" - git add $task_project_file - - # Check that only the project file has been added (and that our file is actually - # modified) - if git status --porcelain=v2 | awk -v path="$base_task_project_file_path" 'BEGIN { hit = 0 } { if ($2 ~ /A./ || $2 ~ /M./) { if ($NF ~ path) { hit = 1 } else { hit = 0; exit 1 } } } END { if (hit == 1) { exit 0 } else { exit 1 } }'; then - git commit --verbose --message="chore($(dirname "$base_task_project_file_path")): Update" - fi -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/context.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/context.sh deleted file mode 100755 index 7095847d..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/context.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env dash - -context0open_current_task_context() { - current_context="$(utils0get_current_context)" - - if [ "$current_context" ]; then - context_path="$(utils0get_current_context_path "$current_context")" - - extended_neorg_project_dir="$(utils0get_neorg_project_dir)" - cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir" - - nvim "$extended_neorg_project_dir/$context_path" - - git add . - git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign - else - warn "No context active" - fi -} - -context0open_current_task_context_at_task_id() { - task_id="$1" - current_context="$(utils0get_current_context)" - - if [ "$current_context" ]; then - context_path="$(utils0get_current_context_path "$current_context")" - extended_neorg_project_dir="$(utils0get_neorg_project_dir)" - task_uuid="$(task "$task_id" uuids)" - - cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir" - - if ! grep -q "% $task_uuid" "$extended_neorg_project_dir/$context_path"; then - echo "* TITLE (% $task_uuid)" >>"$extended_neorg_project_dir/$context_path" - fi - - nvim "$extended_neorg_project_dir/$context_path" -c "/% $task_uuid" - - git add . - git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign - else - warn "No context active" - fi -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/dmenu.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/dmenu.sh deleted file mode 100755 index 5a138982..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/dmenu.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env dash - -dmenu0open_context_in_browser() { - project="$(echo "%ALL_PROJECTS_PIPE" | rofi -sep "|" -dmenu)" - - if [ "$project" ]; then - [ -d "%NEORG_REVIEW_PATH" ] || mkdir --parents "%NEORG_REVIEW_PATH" - [ -f "%NEORG_REVIEW_PATH/$project.lock" ] || touch "%NEORG_REVIEW_PATH/$project.lock" - project0open_project_in_browser "$project" - else - notify-send "(neorg/dmenu) No project selected" - exit 1 - fi -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_start.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_start.sh deleted file mode 100755 index 2423dd44..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env dash - -fstart0start_new_task() { - task_id="$1" - fstop0stop_current_task - task start "$task_id" -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_stop.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_stop.sh deleted file mode 100755 index e4ff0b94..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/f_stop.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env dash - -fstop0stop_current_task() { - # we ensured that only one task may be active - active="$(task +ACTIVE _ids)" - [ "$active" ] && task stop "$active" -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/list.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/list.sh deleted file mode 100755 index 10659457..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/list.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env dash - -list0list_all_contexts_newline() { - print "%ALL_PROJECTS_NEWLINE" -} -list0list_all_contexts_comma() { - print "%ALL_PROJECTS_COMMA" -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/project.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/project.sh deleted file mode 100755 index 64591850..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/project.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env dash - -project0open_current_context_in_browser() { - current_context="$(utils0get_current_context)" - [ "$current_context" ] || die "No current context to use" - project0open_context_in_browser "$(utils0context2project "$current_context")" -} - -project0open_project_in_browser() { - project="$1" - [ "$project" ] || die "BUG: No context supplied to project0open_context_in_browser" - - old_context="$(utils0get_current_context)" - # We have ensured that only one task may be active - old_started_task="$(task +ACTIVE _ids)" - - tracking="$(mktmp)" - task "project:$project" _ids | xargs --no-run-if-empty task _zshids >"$tracking" - task context "$(utils0project2context "$project")" - - while read -r description; do - desc="$(echo "$description" | awk -F: '{print $2}')" - if [ "$desc" = "tracking" ]; then - task_id="$(echo "$description" | awk -F: '{print $1}')" - notify-send "(Neorg)" "Starting task $project -> $desc" - task start "$task_id" - break - fi - done <"$tracking" - - firefox -P "$project" - - task stop "$task_id" - [ "$old_started_task" ] && task start "$old_started_task" - - if [ "$old_context" ]; then - task context "$old_context" - else - task context none - fi -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/review.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/review.sh deleted file mode 100755 index a0a9ab8d..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/review.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env dash - -review0start() { - for project in $(list0list_all_contexts_newline); do - if [ -f "%NEORG_REVIEW_PATH/$project.lock" ]; then - msg "Reviewing '$project'" - notify-send "Neorg" "Reviewing '$project'" - firefox -P "$project" - rm "%NEORG_REVIEW_PATH/$project.lock" - fi - done -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/utils.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/utils.sh deleted file mode 100755 index c3843e8e..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/utils.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env dash - -# Runs it's first argument and then the second, regardless if the first failed or -# succeeded -utils0chain() { - eval "$1" - eval "$2" -} - -utils0get_current_context() { - current_context="$(task _get rc.context)" - printf "%s\n" "$current_context" -} - -utils0get_current_context_path() { - current_context="$1" - context_path="$(task _get rc.context."$current_context".rc.neorg_path 2>/dev/null)" - if ! [ "$context_path" ]; then - context_path="$(grep "context.$current_context.rc.neorg_path" "%HOME_TASKRC" | awk 'BEGIN {FS="="} {print $2}')" - [ "$context_path" ] || die "All contexts should have a 'neorg_path' set!" - fi - printf "%s\n" "$context_path" -} - -utils0get_neorg_project_dir() { - # Perform shell expansion of Tilde - neorg_project_dir="$(sed "s|^~|$HOME|" "$(ptmp "%DEFAULT_NEORG_PROJECT_DIR")")" - printf "%s\n" "$neorg_project_dir" -} - -utils0project2context() { - project="$1" - context="$(sed 's|\.|_|g' "$(ptmp "$project")")" - printf "%s\n" "$context" -} -utils0context2project() { - context="$1" - project="$(sed 's|_|\.|g' "$(ptmp "$context")")" - printf "%s\n" "$project" -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/workspace.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/workspace.sh deleted file mode 100755 index d5eb2fca..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/functions/workspace.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env dash - -workspace0open_neorg_workspace() { - workspace="$1" - nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace $workspace\n")" -} -workspace0open_neorg_workspace_prompt() { - nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace ")" -} diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/main.sh b/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/main.sh deleted file mode 100755 index 559351b9..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/neorg/sh/main.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# load dependencies -. ./functions/add.sh -. ./functions/context.sh -. ./functions/dmenu.sh -. ./functions/f_start.sh -. ./functions/f_stop.sh -. ./functions/list.sh -. ./functions/project.sh -. ./functions/utils.sh -. ./functions/workspace.sh -. ./functions/review.sh - -# these are used in version() -# shellcheck disable=2034 -AUTHORS="Soispha" -# shellcheck disable=2034 -YEARS="2023" - -NAME="neorg" - -help() { - cat <' - - workspace [WS] - The neorg workspace (WS) to open at startup, an empty value drops - you at a prompt to enter the workspace yourself. - - project [P] - Opens the webbrowser with either the context (P) or - the current active context as argument if no context is supplied - - list - Lists all available contexts - - add - Allows you to quickly add projects - - fstart ID - Starts the task (ID) but only after it stooped - the previous active task, if it existed. - - fstop - Stops the current active task - - review - Review all firefox tabs -ARGUMENTS: - ID | *([0-9]) := [[%ID_GENERATION_FUNCTION]] - The function displays all possible IDs of the eligable tasks. - - WS := %ALL_WORKSPACES - All possible workspaces - - P := %ALL_PROJECTS_PIPE - The possible project - -EOF -} - -for arg in "$@"; do - case "$arg" in - "--help" | "-h") - help - exit 0 - ;; - "--version" | "-v") - version - exit 0 - ;; - esac -done - -while [ "$#" -ne 0 ]; do - case "$1" in - "t"*) # task - shift 1 - task_id="$1" - [ "$task_id" ] || utils0chain context0open_current_task_context "exit 0" - context0open_current_task_context_at_task_id "$task_id" - exit 0 - ;; - "w"*) # workspace - shift 1 - workspace_to_open="$1" - # TODO: Exit with 1 on error, instead of the 0 <2023-10-20> - [ "$workspace_to_open" ] || utils0chain workspace0open_neorg_workspace_prompt "exit 0" - workspace0open_neorg_workspace "$workspace_to_open" - exit 0 - ;; - "p"*) # project - shift 1 - project_to_open="$1" - # TODO: Exit with 1 on error, instead of the 0 <2023-10-20> - [ "$project_to_open" ] || utils0chain project0open_current_context_in_browser "exit 0" - if ! grep -q "$project_to_open" "$(ptmp "%ALL_PROJECTS_NEWLINE")"; then - die "Your project ('$project_to_open') is not in the list of available projects: -%ALL_PROJECTS_COMMA" - fi - project0open_project_in_browser "$project_to_open" - exit 0 - ;; - "l"*) # list - list0list_all_contexts_newline - exit 0 - ;; - "a"*) # add-project - add0open_taskwarrior_project_file - exit 0 - ;; - "d"*) # dmenu - dmenu0open_context_in_browser - exit 0 - ;; - "fsta"*) # fstart - shift 1 - task_id="$1" - [ "$task_id" ] || die "No task id provided to fstart" - fstart0start_new_task "$task_id" - exit 0 - ;; - "fsto"*) # fstop - fstop0stop_current_task - exit 0 - ;; - "r"*) # review - shift 1 - review0start - exit 0 - ;; - *) - die "Command '$1' does not exist! Please look at:\n $NAME --help" - exit 0 - ;; - esac -done - -context0open_current_task_context -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/download.sh b/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/download.sh deleted file mode 100755 index fe9746c8..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/download.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env dash - -download_to_down() { - DOWNLOAD_DIRECTORY="%XDG_MUSIC_DIR/down/spotify" - - already_downloaded_files="$(mktmp)" - fd . "$DOWNLOAD_DIRECTORY" --exclude spotdl.log --exclude spotdl-errors.log >"$already_downloaded_files" - if [ -z "$NO_CHECK" ] && [ "$(wc -l <"$already_downloaded_files")" -ne 0 ]; then - die "something is already downloaded" - fi - # [ -e "$DOWNLOAD_DIRECTORY/spotdl.log" ] && rm "$DOWNLOAD_DIRECTORY/spotdl.log" - - download "$1" "$DOWNLOAD_DIRECTORY" -} - -download() { - download_url="$1" - output_path="$2" - - config="$(mktmp)" - cat <"$config" -# Main options ---audio slider-kz bandcamp youtube-music piped youtube soundcloud ---lyrics genius musixmatch azlyrics synced - -# FFmpeg options ---ffmpeg ffmpeg ---threads 16 ---bitrate 256k - -# Spotify options ---cache-path %XDG_CACHE_HOME/spotdl/.spotipy - -# Output options ---preload ---format opus ---output {artists}_-_{title} ---print-errors ---save-errors $output_path/spotdl-errors.log -# TODO: Reactive whence spotdl support for these has improved <2023-12-19> -# --generate-lrc ---overwrite skip - -# Misc options ---log-level INFO -EOF - - cd "$output_path" || die "BUG: no $output_path" - touch "$output_path/spotdl-errors.log" - - # The sub shell needs to be unquoted, as the arguments may not be treated as one. - # shellcheck disable=2046 - unbuffer spotdl $(cat "$config") download "$download_url" | tee "$output_path/spotdl.log" - - [ -d ~/.spotdl ] && rm -r ~/.spotdl -} - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/update.sh b/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/update.sh deleted file mode 100755 index a289cf58..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/sh/update.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env dash - -update() { - UPDATE_DIRECTORY="%XDG_MUSIC_DIR/artists" - UPDATE_CONFIG_FILE="%XDG_MUSIC_DIR/artists/update.conf" - - if ! [ -f "$UPDATE_CONFIG_FILE" ]; then - error="$( - cat </| - -All comments and empty lines are ignored -EOF - )" - die "$error" - fi - - config_file="$(mktmp)" - clean "$UPDATE_CONFIG_FILE" >"$config_file" - - while IFS="|" read -r artist url; do - full_artist="$UPDATE_DIRECTORY/$artist" - [ -d "$full_artist" ] || mkdir --parents "$full_artist" - [ -d "$full_artist/update" ] || mkdir --parents "$full_artist/update" - [ -d "$full_artist/all" ] || mkdir --parents "$full_artist/all" - [ -d "$full_artist/filtered" ] || mkdir --parents "$full_artist/filtered" - - while read -r file; do - ln --symbolic --relative "$file" "$full_artist/update/$(basename "$file")" - done <"$(tmp fd --type file --extension opus . "$full_artist/all")" - - msg2 "Updating $artist with url: '$url'" - download "$url" "$full_artist/update" - - while read -r file; do - mv "$file" "$full_artist/all" - ln --symbolic --relative "$full_artist/all/$(basename "$file")" "$full_artist/filtered/$(basename "$file")" - done <"$(tmp fd --type file --extension opus . "$full_artist/update")" - - while read -r file; do - rm "$file" - done <"$(tmp fd --type symlink --extension opus . "$full_artist/update")" - - cp "$full_artist/update/spotdl.log" "$full_artist/all/spotdl.$(date +%Y_%m_%d).log" - cp "$full_artist/update/spotdl-errors.log" "$full_artist/all/spotdl-errors.$(date +%Y_%m_%d).log" - done <"$config_file" -} - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/spodi.sh b/sys/nixpkgs/pkgs/scripts/source/specific/spodi/spodi.sh deleted file mode 100755 index 475fd48a..00000000 --- a/sys/nixpkgs/pkgs/scripts/source/specific/spodi/spodi.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# these are used in version() -# shellcheck disable=2034 -AUTHORS="Soispha" -# shellcheck disable=2034 -YEARS="2023" - -# load dependencies -. ./sh/update.sh -. ./sh/download.sh - -help() { - cat <>"$tmp"; done -[ "$(wc -l "$tmp" | awk '{print $1}')" -gt 2 ] && die "something is already downloaded" - -cat <"$config" ---paths home:"$DOWN_DIR" -#--output %(fulltitle) ---restrict-filenames ---no-overwrites ---no-write-info-json ---clean-info-json ---prefer-free-formats -#--format mp3 ---extract-audio ---audio-quality 0 ---audio-format best -EO - -rm "$DOWN_DIR/yt-dlp.log" -cd "$DOWN_DIR" || die "BUG: no $DOWN_DIR" - -unbuffer yt-dlp --config-location "$config" "$1" | tee "$DOWN_DIR/yt-dlp.log" - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/snap-sync-forked/default.nix b/sys/nixpkgs/pkgs/snap-sync-forked/default.nix deleted file mode 100644 index 5b086a5a..00000000 --- a/sys/nixpkgs/pkgs/snap-sync-forked/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{sysLib}: [ - (final: prev: { - snap-sync-forked = sysLib.writeShellScript { - name = "snap-sync-forked"; - src = ./snap-sync-forked.sh; - dependencies = with prev; [ - bash - btrfs-progs - coreutils - gawk - gnugrep - snapper - util-linux - - # optional: - libnotify - openssh - pv - rsync - sudo - ]; - }; - }) -] diff --git a/sys/nixpkgs/pkgs/snap-sync-forked/snap-sync-forked.sh b/sys/nixpkgs/pkgs/snap-sync-forked/snap-sync-forked.sh deleted file mode 100755 index 3d9c1ac9..00000000 --- a/sys/nixpkgs/pkgs/snap-sync-forked/snap-sync-forked.sh +++ /dev/null @@ -1,534 +0,0 @@ -#!/usr/bin/env bash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# -# snap-sync -# https://github.com/wesbarnett/snap-sync -# Copyright (C) 2016-2021 Wes Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., - -# ------------------------------------------------------------------------- - -# Takes snapshots of each snapper configuration. It then sends the snapshot to -# a location on an external drive. After the initial transfer, it does -# incremental snapshots on later calls. It's important not to delete the -# snapshot created on your system since that will be used to determine the -# difference for the next incremental snapshot. - -set -o errtrace - -version="0.7" -name="snap-sync" - -printf "\nsnap-sync version %s, Copyright (C) 2016-2021 Wes Barnett\n" "$version" -printf "snap-sync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the license for more information. \n\n" - -# The following line is modified by the Makefile or -# find_snapper_config script -SNAPPER_CONFIG=/etc/sysconfig/snapper - -donotify=0 -if ! command -v notify-send &>/dev/null; then - donotify=1 -fi - -doprogress=0 -if ! command -v pv &>/dev/null; then - doprogress=1 -fi - -error() { - printf "==> ERROR: %s\n" "$@" - notify_error 'Error' 'Check journal for more information.' -} >&2 - -die() { - error "$@" - exit 1 -} - -traperror() { - printf "Exited due to error on line %s.\n" "$1" - printf "exit status: %s\n" "$2" - printf "command: %s\n" "$3" - printf "bash line: %s\n" "$4" - printf "function name: %s\n" "$5" - exit 1 -} - -trapkill() { - die "Exited due to user intervention." -} - -trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCNAME[@]}"' ERR -trap trapkill SIGTERM SIGINT - -usage() { - cat < snapper configuration to backup - -d, --description snapper description - -h, --help print this message - -n, --noconfirm do not ask for confirmation - -k, --keepold keep old incremental snapshots instead of deleting them - after backup is performed - -p, --port remote port; used with '--remote'. - -q, --quiet do not send notifications; instead print them. - -r, --remote
ip address of a remote machine to backup to - --sudo use sudo on the remote machine - -s, --subvolid subvolume id of the mounted BTRFS subvolume to back up to - -u, --UUID UUID of the mounted BTRFS subvolume to back up to - -See 'man snap-sync' for more details. -EOF -} - -ssh="" -sudo=0 -while [[ $# -gt 0 ]]; do - key="$1" - case $key in - -d | --description) - description="$2" - shift 2 - ;; - -c | --config) - selected_configs="$2" - shift 2 - ;; - -u | --UUID) - uuid_cmdline="$2" - shift 2 - ;; - -s | --subvolid) - subvolid_cmdline="$2" - shift 2 - ;; - -k | --keepold) - keep="yes" - shift - ;; - -n | --noconfirm) - noconfirm="yes" - shift - ;; - -h | --help) - usage - exit 1 - ;; - -q | --quiet) - donotify=1 - shift - ;; - -r | --remote) - remote=$2 - shift 2 - ;; - -p | --port) - port=$2 - shift 2 - ;; - --sudo) - sudo=1 - shift - ;; - *) - die "Unknown option: '$key'. Run '$name -h' for valid options." - ;; - esac -done - -notify() { - for u in $(users | tr ' ' '\n' | sort -u); do - sudo -u "$u" DISPLAY=:0 \ - DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(sudo -u "$u" id -u)/bus" \ - notify-send -a $name "$1" "$2" --icon="dialog-$3" - done -} - -notify_info() { - if [[ $donotify -eq 0 ]]; then - notify "$1" "$2" "information" - else - printf '%s\n' "$1: $2" - fi -} - -notify_error() { - if [[ $donotify -eq 0 ]]; then - notify "$1" "$2" "error" - else - printf '%s\n' "$1: $2" - fi -} - -[[ $EUID -ne 0 ]] && die "Script must be run as root. See '$name -h' for a description of options" -! [[ -f $SNAPPER_CONFIG ]] && die "$SNAPPER_CONFIG does not exist." - -description=${description:-"latest incremental backup"} -uuid_cmdline=${uuid_cmdline:-"none"} -subvolid_cmdline=${subvolid_cmdline:-"5"} -noconfirm=${noconfirm:-"no"} - -if [[ -z $remote ]]; then - if ! command -v rsync &>/dev/null; then - die "--remote specified but rsync command not found" - fi -fi - -if [[ $uuid_cmdline != "none" ]]; then - if [[ -z $remote ]]; then - notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid=$subvolid_cmdline..." - else - notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid $subvolid_cmdline at $remote..." - fi -else - if [[ -z $remote ]]; then - notify_info "Backup started" "Starting backups. Use command line menu to select disk." - else - notify_info "Backup started" "Starting backups. Use command line menu to select disk on $remote." - fi -fi - -if [[ -n $remote ]]; then - ssh="ssh $remote" - if [[ -n $port ]]; then - ssh="$ssh -p $port" - fi - if [[ $sudo -eq 1 ]]; then - ssh="$ssh sudo" - fi -fi - -if [[ "$($ssh findmnt -n -v --target / -o FSTYPE)" == "btrfs" ]]; then - EXCLUDE_UUID=$($ssh findmnt -n -v -t btrfs --target / -o UUID) - TARGETS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $2}') - UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $1}') -else - TARGETS=$($ssh findmnt -n -v -t btrfs -o TARGET --list) - UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID --list) -fi - -declare -a TARGETS_ARRAY -declare -a UUIDS_ARRAY -declare -a SUBVOLIDS_ARRAY - -i=0 -for x in $TARGETS; do - SUBVOLIDS_ARRAY[i]=$($ssh btrfs subvolume show "$x" | awk '/Subvolume ID:/ { print $3 }') - TARGETS_ARRAY[i]=$x - i=$((i + 1)) -done - -i=0 -disk=-1 -disk_count=0 -for x in $UUIDS; do - UUIDS_ARRAY[i]=$x - if [[ $x == "$uuid_cmdline" && ${SUBVOLIDS_ARRAY[$((i))]} == "$subvolid_cmdline" ]]; then - disk=$i - disk_count=$((disk_count + 1)) - fi - i=$((i + 1)) -done - -if [[ ${#UUIDS_ARRAY[$@]} -eq 0 ]]; then - die "No external btrfs subvolumes found to backup to. Run '$name -h' for more options." -fi - -if [[ $disk_count -gt 1 ]]; then - printf "Multiple mount points were found with UUID %s and subvolid %s.\n" "$uuid_cmdline" "$subvolid_cmdline" - disk="-1" -fi - -if [[ $disk == -1 ]]; then - if [[ $disk_count == 0 && $uuid_cmdline != "none" ]]; then - error "A device with UUID $uuid_cmdline and subvolid $subvolid_cmdline was not found to be mounted, or it is not a BTRFS device." - fi - if [[ -z $ssh ]]; then - printf "Select a mounted BTRFS device on your local machine to backup to.\nFor more options, exit and run '%s -h'.\n" "$name" - else - printf "Select a mounted BTRFS device on %s to backup to.\nFor more options, exit and run '%s -h'.\n" "$remote" "$name" - fi - while [[ $disk -lt 0 || $disk -gt $i ]]; do - for x in "${!TARGETS_ARRAY[@]}"; do - printf "%4s) %s (uuid=%s, subvolid=%s)\n" "$((x + 1))" "${TARGETS_ARRAY[$x]}" "${UUIDS_ARRAY[$x]}" "${SUBVOLIDS_ARRAY[$x]}" - done - printf "%4s) Exit\n" "0" - read -e -r -p "Enter a number: " disk - if ! [[ $disk == ?(-)+([0-9]) ]] || [[ $disk -lt 0 || $disk -gt $i ]]; then - printf "\nNo disk selected. Select a disk to continue.\n" - disk=-1 - fi - done - if [[ $disk == 0 ]]; then - exit 0 - fi - disk=$((disk - 1)) -fi - -selected_subvolid="${SUBVOLIDS_ARRAY[$((disk))]}" -selected_uuid="${UUIDS_ARRAY[$((disk))]}" -selected_mnt="${TARGETS_ARRAY[$((disk))]}" -printf "\nYou selected the disk with uuid=%s, subvolid=%s.\n" "$selected_uuid" "$selected_subvolid" -if [[ -z $ssh ]]; then - printf "The disk is mounted at '%s'.\n" "$selected_mnt" -else - printf "The disk is mounted at '%s:%s'.\n" "$remote" "$selected_mnt" -fi - -# shellcheck source=/dev/null -source "$SNAPPER_CONFIG" - -if [[ -z $selected_configs ]]; then - printf "\nInteractively cycling through all snapper configurations...\n" -fi -selected_configs=${selected_configs:-$SNAPPER_CONFIGS} - -declare -a BACKUPDIRS_ARRAY -declare -a MYBACKUPDIR_ARRAY -declare -a OLD_NUM_ARRAY -declare -a OLD_SNAP_ARRAY -declare -a NEW_NUM_ARRAY -declare -a NEW_SNAP_ARRAY -declare -a NEW_INFO_ARRAY -declare -a BACKUPLOC_ARRAY -declare -a CONT_BACKUP_ARRAY - -# Initial configuration of where backup directories are -i=0 -for x in $selected_configs; do - - if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {cnt++} END {print cnt}')" -gt 1 ]]; then - error "More than one snapper entry found with UUID $selected_uuid subvolid $selected_subvolid for configuration $x. Skipping configuration $x." - continue - fi - - if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'$name' backup in progress/ {cnt++} END {print cnt}')" -gt 0 ]]; then - printf "\nNOTE: Previous failed %s backup snapshots found for '%s'.\n" "$name" "$x" - if [[ $noconfirm == "yes" ]]; then - printf "'noconfirm' option passed. Failed backups will not be deleted.\n" - else - read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N]? " delete_failed - while [[ -n $delete_failed && $delete_failed != [Yy]"es" && - $delete_failed != [Yy] && $delete_failed != [Nn]"o" && - $delete_failed != [Nn] ]]; do - read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N] " delete_failed - if [[ -n $delete_failed && $delete_failed != [Yy]"es" && - $delete_failed != [Yy] && $delete_failed != [Nn]"o" && - $delete_failed != [Nn] ]]; then - printf "Select 'y' or 'N'.\n" - fi - done - if [[ $delete_failed == [Yy]"es" || $delete_failed == [Yy] ]]; then - # explicit split list of snapshots (on whitespace) into multiple arguments - # shellcheck disable=SC2046 - snapper -c "$x" delete $(snapper -c "$x" list --disable-used-space | awk '/'$name' backup in progress/ {print $1}') - fi - fi - fi - - SNAP_SYNC_EXCLUDE=no - - if [[ -f "/etc/snapper/configs/$x" ]]; then - # shellcheck source=/dev/null - source "/etc/snapper/configs/$x" - else - die "Selected snapper configuration $x does not exist." - fi - - if [[ $SNAP_SYNC_EXCLUDE == "yes" ]]; then - continue - fi - - printf "\n" - - old_num=$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $1}') - old_snap=$SUBVOLUME/.snapshots/$old_num/snapshot - - OLD_NUM_ARRAY[i]=$old_num - OLD_SNAP_ARRAY[i]=$old_snap - - if [[ -z $old_num ]]; then - printf "No backups have been performed for '%s' on this disk.\n" "$x" - read -e -r -p "Enter name of subvolume to store backups, relative to $selected_mnt (to be created if not existing): " mybackupdir - printf "This will be the initial backup for snapper configuration '%s' to this disk. This could take awhile.\n" "$x" - BACKUPDIR="$selected_mnt/$mybackupdir" - $ssh test -d "$BACKUPDIR" || $ssh btrfs subvolume create "$BACKUPDIR" - else - mybackupdir=$(snapper -c "$x" list --disable-used-space -t single | awk -F"|" '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $5}' | awk -F "," '/backupdir/ {print $1}' | awk -F"=" '{print $2}') - BACKUPDIR="$selected_mnt/$mybackupdir" - $ssh test -d "$BACKUPDIR" || die "%s is not a directory on %s.\n" "$BACKUPDIR" "$selected_uuid" - fi - BACKUPDIRS_ARRAY[i]="$BACKUPDIR" - MYBACKUPDIR_ARRAY[i]="$mybackupdir" - - printf "Creating new local snapshot for '%s' configuration...\n" "$x" - new_num=$(snapper -c "$x" create --print-number -d "$name backup in progress") - new_snap=$SUBVOLUME/.snapshots/$new_num/snapshot - new_info=$SUBVOLUME/.snapshots/$new_num/info.xml - sync - backup_location=$BACKUPDIR/$x/$new_num/ - if [[ -z $ssh ]]; then - printf "Will backup %s to %s\n" "$new_snap" "$backup_location/snapshot" - else - printf "Will backup %s to %s\n" "$new_snap" "$remote":"$backup_location/snapshot" - fi - - if ($ssh test -d "$backup_location/snapshot"); then - printf "WARNING: Backup directory '%s' already exists. This configuration will be skipped!\n" "$backup_location/snapshot" - printf "Move or delete destination directory and try backup again.\n" - fi - - NEW_NUM_ARRAY[i]="$new_num" - NEW_SNAP_ARRAY[i]="$new_snap" - NEW_INFO_ARRAY[i]="$new_info" - BACKUPLOC_ARRAY[i]="$backup_location" - - cont_backup="K" - CONT_BACKUP_ARRAY[i]="yes" - if [[ $noconfirm == "yes" ]]; then - cont_backup="yes" - else - while [[ -n $cont_backup && $cont_backup != [Yy]"es" && - $cont_backup != [Yy] && $cont_backup != [Nn]"o" && - $cont_backup != [Nn] ]]; do - read -e -r -p "Proceed with backup of '$x' configuration [Y/n]? " cont_backup - if [[ -n $cont_backup && $cont_backup != [Yy]"es" && - $cont_backup != [Yy] && $cont_backup != [Nn]"o" && - $cont_backup != [Nn] ]]; then - printf "Select 'Y' or 'n'.\n" - fi - done - fi - - if [[ $cont_backup != [Yy]"es" && $cont_backup != [Yy] && -n $cont_backup ]]; then - CONT_BACKUP_ARRAY[i]="no" - printf "Not backing up '%s' configuration.\n" "$x" - snapper -c "$x" delete "$new_num" - fi - - i=$((i + 1)) - -done - -# Actual backing up -printf "\nPerforming backups...\n" -i=-1 -for x in $selected_configs; do - - i=$((i + 1)) - - SNAP_SYNC_EXCLUDE=no - - if [[ -f "/etc/snapper/configs/$x" ]]; then - # shellcheck source=/dev/null - source "/etc/snapper/configs/$x" - else - die "Selected snapper configuration $x does not exist." - fi - - cont_backup=${CONT_BACKUP_ARRAY[$i]} - if [[ $cont_backup == "no" || $SNAP_SYNC_EXCLUDE == "yes" ]]; then - notify_info "Backup in progress" "NOTE: Skipping $x configuration." - continue - fi - - notify_info "Backup in progress" "Backing up $x configuration." - - printf "\n" - - old_num="${OLD_NUM_ARRAY[$i]}" - old_snap="${OLD_SNAP_ARRAY[$i]}" - BACKUPDIR="${BACKUPDIRS_ARRAY[$i]}" - mybackupdir="${MYBACKUPDIR_ARRAY[$i]}" - new_num="${NEW_NUM_ARRAY[$i]}" - new_snap="${NEW_SNAP_ARRAY[$i]}" - new_info="${NEW_INFO_ARRAY[$i]}" - backup_location="${BACKUPLOC_ARRAY[$i]}" - - if ($ssh test -d "$backup_location/snapshot"); then - printf "ERROR: Backup directory '%s' already exists. Skipping backup of this configuration!\n" "$backup_location/snapshot" - continue - fi - - $ssh mkdir -p "$backup_location" - - if [[ -z $old_num ]]; then - printf "Sending first snapshot for '%s' configuration...\n" "$x" - if [[ $doprogress -eq 0 ]]; then - btrfs send "$new_snap" | pv | $ssh btrfs receive "$backup_location" &>/dev/null - else - btrfs send "$new_snap" | $ssh btrfs receive "$backup_location" &>/dev/null - fi - else - - printf "Sending incremental snapshot for '%s' configuration...\n" "$x" - # Sends the difference between the new snapshot and old snapshot to the - # backup location. Using the -c flag instead of -p tells it that there - # is an identical subvolume to the old snapshot at the receiving - # location where it can get its data. This helps speed up the transfer. - - if [[ $doprogress -eq 0 ]]; then - btrfs send -c "$old_snap" "$new_snap" | pv | $ssh btrfs receive "$backup_location" - else - btrfs send -c "$old_snap" "$new_snap" | $ssh btrfs receive "$backup_location" - fi - - if [[ $keep == "yes" ]]; then - printf "Modifying data for old local snapshot for '%s' configuration...\n" "$x" - snapper -v -c "$x" modify -d "old snap-sync snapshot (you may remove)" -u "backupdir=,subvolid=,uuid=" -c "number" "$old_num" - else - printf "Deleting old snapshot for %s...\n" "$x" - snapper -c "$x" delete "$old_num" - fi - - fi - - if [[ -z $remote ]]; then - cp "$new_info" "$backup_location" - else - if [[ -z $port ]]; then - rsync -avzq "$new_info" "$remote":"$backup_location" - else - rsync -avzqe "ssh -p $port" "$new_info" "$remote":"$backup_location" - fi - fi - - # It's important not to change this userdata in the snapshots, since that's how - # we find the previous one. - - userdata="backupdir=$mybackupdir, subvolid=$selected_subvolid, uuid=$selected_uuid" - - # Tag new snapshot as the latest - printf "Tagging local snapshot as latest backup for '%s' configuration...\n" "$x" - snapper -v -c "$x" modify -d "$description" -u "$userdata" "$new_num" - - printf "Backup complete for '%s' configuration.\n" "$x" - -done - -printf "\nDone!\n" - -if [[ $uuid_cmdline != "none" ]]; then - notify_info "Finished" "Backups to $uuid_cmdline complete!" -else - notify_info "Finished" "Backups complete!" -fi diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/.editorconfig b/sys/nixpkgs/pkgs/tree-sitter-yts/.editorconfig deleted file mode 100644 index 919c78fa..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = false - -# for testing purposes, the corpus may have trailing whitespace -# and may have mixed EOL. -# Still want a final newline though, as that makes no semantic difference. -[corpus/*] -trim_trailing_whitespace = false -end_of_line = unset - -[**.{js,json,cc,css}] -indent_style = space -indent_size = 2 - -# tree-sitter generate emits json with no trailing newline -[src/node-types.json] -insert_final_newline = false diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/.envrc b/sys/nixpkgs/pkgs/tree-sitter-yts/.envrc deleted file mode 100644 index 3550a30f..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/.gitignore b/sys/nixpkgs/pkgs/tree-sitter-yts/.gitignore deleted file mode 100644 index c4e2e389..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.direnv -/result -/node_modules diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/Cargo.toml b/sys/nixpkgs/pkgs/tree-sitter-yts/Cargo.toml deleted file mode 100644 index 5287c420..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "tree-sitter-yts" -description = "yts grammar for the tree-sitter parsing library" -version = "0.0.1" -keywords = ["incremental", "parsing", "yts"] -categories = ["parsing", "text-editors"] -repository = "https://github.com/tree-sitter/tree-sitter-yts" -edition = "2018" -license = "MIT" - -build = "bindings/rust/build.rs" -include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"] - -[lib] -path = "bindings/rust/lib.rs" - -[dependencies] -tree-sitter = "~0.20.10" - -[build-dependencies] -cc = "1.0" diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/binding.gyp b/sys/nixpkgs/pkgs/tree-sitter-yts/binding.gyp deleted file mode 100644 index b05038b4..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/binding.gyp +++ /dev/null @@ -1,19 +0,0 @@ -{ - "targets": [ - { - "target_name": "tree_sitter_yts_binding", - "include_dirs": [ - " - -using namespace v8; - -extern "C" TSLanguage *tree_sitter_yts (); - -namespace -{ - -NAN_METHOD (New) {} - -void -Init (Local exports, Local module) -{ - Local tpl = Nan::New (New); - tpl->SetClassName (Nan::New ("Language").ToLocalChecked ()); - tpl->InstanceTemplate ()->SetInternalFieldCount (1); - - Local constructor = Nan::GetFunction (tpl).ToLocalChecked (); - Local instance - = constructor->NewInstance (Nan::GetCurrentContext ()).ToLocalChecked (); - Nan::SetInternalFieldPointer (instance, 0, tree_sitter_yts ()); - - Nan::Set (instance, Nan::New ("name").ToLocalChecked (), - Nan::New ("yts").ToLocalChecked ()); - Nan::Set (module, Nan::New ("exports").ToLocalChecked (), instance); -} - -NODE_MODULE (tree_sitter_yts_binding, Init) - -} // namespace diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/node/index.js b/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/node/index.js deleted file mode 100644 index 32179742..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/node/index.js +++ /dev/null @@ -1,19 +0,0 @@ -try { - module.exports = require("../../build/Release/tree_sitter_yts_binding"); -} catch (error1) { - if (error1.code !== "MODULE_NOT_FOUND") { - throw error1; - } - try { - module.exports = require("../../build/Debug/tree_sitter_yts_binding"); - } catch (error2) { - if (error2.code !== "MODULE_NOT_FOUND") { - throw error2; - } - throw error1; - } -} - -try { - module.exports.nodeTypeInfo = require("../../src/node-types.json"); -} catch (_) {} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/build.rs b/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/build.rs deleted file mode 100644 index c6061f09..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/build.rs +++ /dev/null @@ -1,40 +0,0 @@ -fn main() { - let src_dir = std::path::Path::new("src"); - - let mut c_config = cc::Build::new(); - c_config.include(&src_dir); - c_config - .flag_if_supported("-Wno-unused-parameter") - .flag_if_supported("-Wno-unused-but-set-variable") - .flag_if_supported("-Wno-trigraphs"); - let parser_path = src_dir.join("parser.c"); - c_config.file(&parser_path); - - // If your language uses an external scanner written in C, - // then include this block of code: - - /* - let scanner_path = src_dir.join("scanner.c"); - c_config.file(&scanner_path); - println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); - */ - - c_config.compile("parser"); - println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); - - // If your language uses an external scanner written in C++, - // then include this block of code: - - /* - let mut cpp_config = cc::Build::new(); - cpp_config.cpp(true); - cpp_config.include(&src_dir); - cpp_config - .flag_if_supported("-Wno-unused-parameter") - .flag_if_supported("-Wno-unused-but-set-variable"); - let scanner_path = src_dir.join("scanner.cc"); - cpp_config.file(&scanner_path); - cpp_config.compile("scanner"); - println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); - */ -} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/lib.rs b/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/lib.rs deleted file mode 100644 index f1868b2d..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/bindings/rust/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! This crate provides yts language support for the [tree-sitter][] parsing library. -//! -//! Typically, you will use the [language][language func] function to add this language to a -//! tree-sitter [Parser][], and then use the parser to parse some code: -//! -//! ``` -//! let code = ""; -//! let mut parser = tree_sitter::Parser::new(); -//! parser.set_language(tree_sitter_yts::language()).expect("Error loading yts grammar"); -//! let tree = parser.parse(code, None).unwrap(); -//! ``` -//! -//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -//! [language func]: fn.language.html -//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html -//! [tree-sitter]: https://tree-sitter.github.io/ - -use tree_sitter::Language; - -extern "C" { - fn tree_sitter_yts() -> Language; -} - -/// Get the tree-sitter [Language][] for this grammar. -/// -/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -pub fn language() -> Language { - unsafe { tree_sitter_yts() } -} - -/// The content of the [`node-types.json`][] file for this grammar. -/// -/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types -pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json"); - -// Uncomment these to include any queries that this grammar contains - -// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm"); -// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm"); -// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm"); -// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm"); - -#[cfg(test)] -mod tests { - #[test] - fn test_can_load_grammar() { - let mut parser = tree_sitter::Parser::new(); - parser - .set_language(super::language()) - .expect("Error loading yts language"); - } -} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments.txt b/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments.txt deleted file mode 100644 index 0070baf8..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments.txt +++ /dev/null @@ -1,51 +0,0 @@ -================================================================================ -Parse multiple lines -================================================================================ - -pick 6221 "Name" "2024-01-17" "A" "[0m 0s]" "url" -pick 6181 "Name2" "2024-01-16" "A2" "[0m 0s]" "url" - -# This is a comment -# it contains information - --------------------------------------------------------------------------------- - -(source_file - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (comment) - (comment)) diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments_correct.txt b/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments_correct.txt deleted file mode 100644 index 40cdab7d..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/comments_correct.txt +++ /dev/null @@ -1,27 +0,0 @@ -================================================================================ -Disregard comments in title -================================================================================ - -pick 6094 "#100 Name" "2024-01-12" "A" "[133m 29s]" "url" - --------------------------------------------------------------------------------- - -(source_file - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote)))) diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/duration.txt b/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/duration.txt deleted file mode 100644 index 59476b98..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/duration.txt +++ /dev/null @@ -1,84 +0,0 @@ -================================================================================ -Parse multiple lines with different durations -================================================================================ - -pick 6221 "Name" "2024-01-17" "A" "[1h 0m]" "url" -pick 6181 "Name2" "2024-01-16" "A2" "[20m 02s]" "url2" -pick 6184 "Name3" "2024-01-16" "A3" "[20h 0m]" "url3" -pick 6206 "Name4" "2024-01-16" "A4" "[No Duration]" "url4" - --------------------------------------------------------------------------------- - -(source_file - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote)))) diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/url.txt b/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/url.txt deleted file mode 100644 index 1ae3d106..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/corpus/url.txt +++ /dev/null @@ -1,84 +0,0 @@ -================================================================================ -Parse multiple lines with url -================================================================================ - -pick 6221 "Name" "2024-01-17" "A" "[0h 0m]" "url" -pick 6181 "Name2" "2024-01-16" "A2" "[0h 0m]" "url2" -pick 6184 "Name3" "2024-01-16" "A3" "[0h 0m]" "url3" -pick 6206 "Name4" "2024-01-16" "A4" "[0h 0m]" "url4" - --------------------------------------------------------------------------------- - -(source_file - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote))) - (line - (command) - (id) - (title - (quote) - (quote)) - (date - (quote) - (quote)) - (author - (quote) - (quote)) - (duration - (quote) - (quote)) - (url - (quote) - (quote)))) diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/default.nix b/sys/nixpkgs/pkgs/tree-sitter-yts/default.nix deleted file mode 100644 index 7e15481c..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -[ - ( - final: prev: { - yts-grammar = (prev.callPackage ./package.nix {}) { - language = "yts"; - version = "1.0"; - src = ./.; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/flake.lock b/sys/nixpkgs/pkgs/tree-sitter-yts/flake.lock deleted file mode 100644 index bff9f1fa..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/flake.lock +++ /dev/null @@ -1,97 +0,0 @@ -{ - "nodes": { - "crane": { - "inputs": { - "nixpkgs": ["nixpkgs"] - }, - "locked": { - "lastModified": 1704819371, - "narHash": "sha256-oFUfPWrWGQTZaCM3byxwYwrMLwshDxVGOrMH5cVP/X8=", - "owner": "ipetkov", - "repo": "crane", - "rev": "5c234301a1277e4cc759c23a2a7a00a06ddd7111", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1705133751, - "narHash": "sha256-rCIsyE80jgiOU78gCWN3A0wE0tR2GI5nH6MlS+HaaSQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9b19f5e77dd906cb52dade0b7bd280339d2a1f3d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "npmlock2nix": { - "flake": false, - "locked": { - "lastModified": 1673447413, - "narHash": "sha256-sJM82Sj8yfQYs9axEmGZ9Evzdv/kDcI9sddqJ45frrU=", - "owner": "nix-community", - "repo": "npmlock2nix", - "rev": "9197bbf397d76059a76310523d45df10d2e4ca81", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "npmlock2nix", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "npmlock2nix": "npmlock2nix" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/flake.nix b/sys/nixpkgs/pkgs/tree-sitter-yts/flake.nix deleted file mode 100644 index 1b6f8ab0..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/flake.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ - description = "tree-sitter-yts"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - - flake-utils.url = "github:numtide/flake-utils"; - - npmlock2nix = { - url = "github:nix-community/npmlock2nix"; - flake = false; - }; - - crane = { - url = "github:ipetkov/crane"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - npmlock2nix, - crane, - }: (flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; - inherit (pkgs) lib; - - npmlock2nix' = pkgs.callPackage npmlock2nix {}; - craneLib = crane.lib.${system}; - in { - build = self.packages.${system}.tree-sitter-nix; - - rust-bindings = craneLib.buildPackage { - src = self; - }; - - # Requires xcode - node-bindings = npmlock2nix'.v2.build { - src = self; - inherit (self.devShells.${system}.default) nativeBuildInputs; - inherit (pkgs) nodejs; - - buildCommands = [ - "${pkgs.nodePackages.node-gyp}/bin/node-gyp configure" - "npm run build" - ]; - - installPhase = '' - touch $out - ''; - }; - - packages.tree-sitter-yts = (pkgs.callPackage ./grammar.nix {}) { - language = "yts"; - version = "1.0"; - src = self; - }; - - packages.default = self.packages.${system}.tree-sitter-yts; - devShells.default = pkgs.mkShell { - packages = [ - pkgs.nodejs - pkgs.python3 - - pkgs.tree-sitter - pkgs.editorconfig-checker - - pkgs.rustc - pkgs.cargo - - # Formatters - pkgs.treefmt - pkgs.nixpkgs-fmt - pkgs.nodePackages.prettier - pkgs.rustfmt - pkgs.clang-tools - ]; - }; - })); -} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/grammar.js b/sys/nixpkgs/pkgs/tree-sitter-yts/grammar.js deleted file mode 100644 index 655f6dea..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/grammar.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = grammar({ - name: "yts", - - rules: { - source_file: ($) => repeat(choice($.line, $.comment)), - line: ($) => - seq($.command, $.id, $.title, $.date, $.author, $.duration, $.url, "\n"), - - command: ($) => choice("pick", "p", "watch", "w", "drop", "d", "url", "u"), - id: ($) => /[0-9]+/, - title: ($) => seq($._q, /[^"]+/, $._q), - date: ($) => seq($._q, /\d{4}-\d{2}-\d{2}/, $._q), - author: ($) => seq($._q, /[^"]+/, $._q), - duration: ($) => - seq( - $._q, - seq("[", choice("No Duration", /\d+m \d+s/, /\d+h \d+m/), "]"), - $._q, - ), - url: ($) => seq($._q, /[^"]+/, $._q), - comment: ($) => /#.*/, - _q: ($) => $.quote, - quote: ($) => /"/, - }, - extras: ($) => [/\s/, /\\\r?\n/], -}); diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/highlight.yts b/sys/nixpkgs/pkgs/tree-sitter-yts/highlight.yts deleted file mode 100644 index 319ee95c..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/highlight.yts +++ /dev/null @@ -1,4 +0,0 @@ -pick 6221 "Name" "2024-01-17" "A" "0:00" "url" -pick 6181 "Name2" "2024-01-16" "A2" "0:00" "url2" -pick 6184 "Name3" "2024-01-16" "A3" "0:00" "url3" -pick 6206 "Name4" "2024-01-16" "A4" "299:36" "url4" diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/package.json b/sys/nixpkgs/pkgs/tree-sitter-yts/package.json deleted file mode 100644 index 2511ccb7..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "tree-sitter-yts", - "version": "0.0.1", - "description": "yts grammar for tree-sitter", - "main": "bindings/node", - "keywords": [ - "parsing", - "incremental" - ], - "dependencies": { - "nan": "^2.12.1" - }, - "devDependencies": { - "tree-sitter-cli": "^0.20.8" - }, - "scripts": { - "test": "tree-sitter test" - }, - "tree-sitter": [ - { - "scope": "source.yts", - "file-types": [ - "yts" - ], - "highlights": [ - "queries/highlights.scm" - ], - "injection-regex": "^(yts)$" - } - ] -} diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/package.nix b/sys/nixpkgs/pkgs/tree-sitter-yts/package.nix deleted file mode 100644 index fe9a7326..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/package.nix +++ /dev/null @@ -1,63 +0,0 @@ -# taken from nixpgks: pkgs/development/tools/parsing/tree-sitter/grammar.nix -{ - stdenv, - nodejs, - tree-sitter, - lib, -}: -# Build a parser grammar and put the resulting shared object in `$out/parser` -{ - # language name - language, - version, - src, - location ? null, - generate ? false, - ... -} @ args: -stdenv.mkDerivation ({ - pname = "${language}-grammar"; - - inherit src version; - - nativeBuildInputs = lib.optionals generate [nodejs tree-sitter]; - - CFLAGS = ["-Isrc" "-O2"]; - CXXFLAGS = ["-Isrc" "-O2"]; - - stripDebugList = ["parser"]; - - configurePhase = - lib.optionalString (location != null) '' - cd ${location} - '' - + lib.optionalString generate '' - tree-sitter generate - ''; - - # When both scanner.{c,cc} exist, we should not link both since they may be the same but in - # different languages. Just randomly prefer C++ if that happens. - buildPhase = '' - runHook preBuild - if [[ -e src/scanner.cc ]]; then - $CXX -fPIC -c src/scanner.cc -o scanner.o $CXXFLAGS - elif [[ -e src/scanner.c ]]; then - $CC -fPIC -c src/scanner.c -o scanner.o $CFLAGS - fi - $CC -fPIC -c src/parser.c -o parser.o $CFLAGS - rm -rf parser - $CXX -shared -o parser *.o - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - mkdir $out - mv parser $out/ - if [[ -d queries ]]; then - cp -r queries $out - fi - runHook postInstall - ''; - } - // removeAttrs args ["language" "location" "generate"]) diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/queries/highlights.scm b/sys/nixpkgs/pkgs/tree-sitter-yts/queries/highlights.scm deleted file mode 100644 index 674cbf18..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/queries/highlights.scm +++ /dev/null @@ -1,11 +0,0 @@ -(command) @keyword -(id) @constant -(title) @text.title -(date) @number -(author) @operator -(duration) @property -((url) @conceal (#set! conceal "")) - - -((quote) @conceal (#set! conceal "")) -(comment) @comment @spell diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/src/grammar.json b/sys/nixpkgs/pkgs/tree-sitter-yts/src/grammar.json deleted file mode 100644 index a35a5464..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/src/grammar.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "name": "yts", - "rules": { - "source_file": { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "line" - }, - { - "type": "SYMBOL", - "name": "comment" - } - ] - } - }, - "line": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "command" - }, - { - "type": "SYMBOL", - "name": "id" - }, - { - "type": "SYMBOL", - "name": "title" - }, - { - "type": "SYMBOL", - "name": "date" - }, - { - "type": "SYMBOL", - "name": "author" - }, - { - "type": "SYMBOL", - "name": "duration" - }, - { - "type": "SYMBOL", - "name": "url" - }, - { - "type": "STRING", - "value": "\n" - } - ] - }, - "command": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "pick" - }, - { - "type": "STRING", - "value": "p" - }, - { - "type": "STRING", - "value": "watch" - }, - { - "type": "STRING", - "value": "w" - }, - { - "type": "STRING", - "value": "drop" - }, - { - "type": "STRING", - "value": "d" - }, - { - "type": "STRING", - "value": "url" - }, - { - "type": "STRING", - "value": "u" - } - ] - }, - "id": { - "type": "PATTERN", - "value": "[0-9]+" - }, - "title": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "date": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "\\d{4}-\\d{2}-\\d{2}" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "author": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "duration": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "No Duration" - }, - { - "type": "PATTERN", - "value": "\\d+m \\d+s" - }, - { - "type": "PATTERN", - "value": "\\d+h \\d+m" - } - ] - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "url": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "comment": { - "type": "PATTERN", - "value": "#.*" - }, - "_q": { - "type": "SYMBOL", - "name": "quote" - }, - "quote": { - "type": "PATTERN", - "value": "\"" - } - }, - "extras": [ - { - "type": "PATTERN", - "value": "\\s" - }, - { - "type": "PATTERN", - "value": "\\\\\\r?\\n" - } - ], - "conflicts": [], - "precedences": [], - "externals": [], - "inline": [], - "supertypes": [] -} - diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/src/node-types.json b/sys/nixpkgs/pkgs/tree-sitter-yts/src/node-types.json deleted file mode 100644 index 1a63a552..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/src/node-types.json +++ /dev/null @@ -1,200 +0,0 @@ -[ - { - "type": "author", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "command", - "named": true, - "fields": {} - }, - { - "type": "date", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "duration", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "line", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "author", - "named": true - }, - { - "type": "command", - "named": true - }, - { - "type": "date", - "named": true - }, - { - "type": "duration", - "named": true - }, - { - "type": "id", - "named": true - }, - { - "type": "title", - "named": true - }, - { - "type": "url", - "named": true - } - ] - } - }, - { - "type": "source_file", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "comment", - "named": true - }, - { - "type": "line", - "named": true - } - ] - } - }, - { - "type": "title", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "url", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "\n", - "named": false - }, - { - "type": "No Duration", - "named": false - }, - { - "type": "[", - "named": false - }, - { - "type": "]", - "named": false - }, - { - "type": "comment", - "named": true - }, - { - "type": "d", - "named": false - }, - { - "type": "drop", - "named": false - }, - { - "type": "id", - "named": true - }, - { - "type": "p", - "named": false - }, - { - "type": "pick", - "named": false - }, - { - "type": "quote", - "named": true - }, - { - "type": "u", - "named": false - }, - { - "type": "url", - "named": false - }, - { - "type": "w", - "named": false - }, - { - "type": "watch", - "named": false - } -] \ No newline at end of file diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/src/parser.c b/sys/nixpkgs/pkgs/tree-sitter-yts/src/parser.c deleted file mode 100644 index ded5c342..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/src/parser.c +++ /dev/null @@ -1,1108 +0,0 @@ -#include - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -#define LANGUAGE_VERSION 14 -#define STATE_COUNT 31 -#define LARGE_STATE_COUNT 2 -#define SYMBOL_COUNT 30 -#define ALIAS_COUNT 0 -#define TOKEN_COUNT 20 -#define EXTERNAL_TOKEN_COUNT 0 -#define FIELD_COUNT 0 -#define MAX_ALIAS_SEQUENCE_LENGTH 8 -#define PRODUCTION_ID_COUNT 1 - -enum -{ - anon_sym_LF = 1, - anon_sym_pick = 2, - anon_sym_p = 3, - anon_sym_watch = 4, - anon_sym_w = 5, - anon_sym_drop = 6, - anon_sym_d = 7, - anon_sym_url = 8, - anon_sym_u = 9, - sym_id = 10, - aux_sym_title_token1 = 11, - aux_sym_date_token1 = 12, - anon_sym_LBRACK = 13, - anon_sym_NoDuration = 14, - aux_sym_duration_token1 = 15, - aux_sym_duration_token2 = 16, - anon_sym_RBRACK = 17, - sym_comment = 18, - sym_quote = 19, - sym_source_file = 20, - sym_line = 21, - sym_command = 22, - sym_title = 23, - sym_date = 24, - sym_author = 25, - sym_duration = 26, - sym_url = 27, - sym__q = 28, - aux_sym_source_file_repeat1 = 29, -}; - -static const char *const ts_symbol_names[] = { - [ts_builtin_sym_end] = "end", - [anon_sym_LF] = "\n", - [anon_sym_pick] = "pick", - [anon_sym_p] = "p", - [anon_sym_watch] = "watch", - [anon_sym_w] = "w", - [anon_sym_drop] = "drop", - [anon_sym_d] = "d", - [anon_sym_url] = "url", - [anon_sym_u] = "u", - [sym_id] = "id", - [aux_sym_title_token1] = "title_token1", - [aux_sym_date_token1] = "date_token1", - [anon_sym_LBRACK] = "[", - [anon_sym_NoDuration] = "No Duration", - [aux_sym_duration_token1] = "duration_token1", - [aux_sym_duration_token2] = "duration_token2", - [anon_sym_RBRACK] = "]", - [sym_comment] = "comment", - [sym_quote] = "quote", - [sym_source_file] = "source_file", - [sym_line] = "line", - [sym_command] = "command", - [sym_title] = "title", - [sym_date] = "date", - [sym_author] = "author", - [sym_duration] = "duration", - [sym_url] = "url", - [sym__q] = "_q", - [aux_sym_source_file_repeat1] = "source_file_repeat1", -}; - -static const TSSymbol ts_symbol_map[] = { - [ts_builtin_sym_end] = ts_builtin_sym_end, - [anon_sym_LF] = anon_sym_LF, - [anon_sym_pick] = anon_sym_pick, - [anon_sym_p] = anon_sym_p, - [anon_sym_watch] = anon_sym_watch, - [anon_sym_w] = anon_sym_w, - [anon_sym_drop] = anon_sym_drop, - [anon_sym_d] = anon_sym_d, - [anon_sym_url] = anon_sym_url, - [anon_sym_u] = anon_sym_u, - [sym_id] = sym_id, - [aux_sym_title_token1] = aux_sym_title_token1, - [aux_sym_date_token1] = aux_sym_date_token1, - [anon_sym_LBRACK] = anon_sym_LBRACK, - [anon_sym_NoDuration] = anon_sym_NoDuration, - [aux_sym_duration_token1] = aux_sym_duration_token1, - [aux_sym_duration_token2] = aux_sym_duration_token2, - [anon_sym_RBRACK] = anon_sym_RBRACK, - [sym_comment] = sym_comment, - [sym_quote] = sym_quote, - [sym_source_file] = sym_source_file, - [sym_line] = sym_line, - [sym_command] = sym_command, - [sym_title] = sym_title, - [sym_date] = sym_date, - [sym_author] = sym_author, - [sym_duration] = sym_duration, - [sym_url] = sym_url, - [sym__q] = sym__q, - [aux_sym_source_file_repeat1] = aux_sym_source_file_repeat1, -}; - -static const TSSymbolMetadata ts_symbol_metadata[] = { - [ts_builtin_sym_end] = { - .visible = false, - .named = true, - }, - [anon_sym_LF] = { - .visible = true, - .named = false, - }, - [anon_sym_pick] = { - .visible = true, - .named = false, - }, - [anon_sym_p] = { - .visible = true, - .named = false, - }, - [anon_sym_watch] = { - .visible = true, - .named = false, - }, - [anon_sym_w] = { - .visible = true, - .named = false, - }, - [anon_sym_drop] = { - .visible = true, - .named = false, - }, - [anon_sym_d] = { - .visible = true, - .named = false, - }, - [anon_sym_url] = { - .visible = true, - .named = false, - }, - [anon_sym_u] = { - .visible = true, - .named = false, - }, - [sym_id] = { - .visible = true, - .named = true, - }, - [aux_sym_title_token1] = { - .visible = false, - .named = false, - }, - [aux_sym_date_token1] = { - .visible = false, - .named = false, - }, - [anon_sym_LBRACK] = { - .visible = true, - .named = false, - }, - [anon_sym_NoDuration] = { - .visible = true, - .named = false, - }, - [aux_sym_duration_token1] = { - .visible = false, - .named = false, - }, - [aux_sym_duration_token2] = { - .visible = false, - .named = false, - }, - [anon_sym_RBRACK] = { - .visible = true, - .named = false, - }, - [sym_comment] = { - .visible = true, - .named = true, - }, - [sym_quote] = { - .visible = true, - .named = true, - }, - [sym_source_file] = { - .visible = true, - .named = true, - }, - [sym_line] = { - .visible = true, - .named = true, - }, - [sym_command] = { - .visible = true, - .named = true, - }, - [sym_title] = { - .visible = true, - .named = true, - }, - [sym_date] = { - .visible = true, - .named = true, - }, - [sym_author] = { - .visible = true, - .named = true, - }, - [sym_duration] = { - .visible = true, - .named = true, - }, - [sym_url] = { - .visible = true, - .named = true, - }, - [sym__q] = { - .visible = false, - .named = true, - }, - [aux_sym_source_file_repeat1] = { - .visible = false, - .named = false, - }, -}; - -static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT] - [MAX_ALIAS_SEQUENCE_LENGTH] - = { - [0] = { 0 }, - }; - -static const uint16_t ts_non_terminal_alias_map[] = { - 0, -}; - -static const TSStateId ts_primary_state_ids[STATE_COUNT] = { - [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, - [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, - [14] = 14, [15] = 15, [16] = 16, [17] = 17, [18] = 18, [19] = 19, [20] = 20, - [21] = 21, [22] = 22, [23] = 23, [24] = 24, [25] = 25, [26] = 26, [27] = 27, - [28] = 28, [29] = 29, [30] = 30, -}; - -static bool -ts_lex (TSLexer *lexer, TSStateId state) -{ - START_LEXER (); - eof = lexer->eof (lexer); - switch (state) - { - case 0: - if (eof) - ADVANCE (47); - if (lookahead == '"') - ADVANCE (74); - if (lookahead == '#') - ADVANCE (73); - if (lookahead == 'N') - ADVANCE (30); - if (lookahead == '[') - ADVANCE (68); - if (lookahead == '\\') - SKIP (46) - if (lookahead == ']') - ADVANCE (72); - if (lookahead == 'd') - ADVANCE (54); - if (lookahead == 'p') - ADVANCE (50); - if (lookahead == 'u') - ADVANCE (56); - if (lookahead == 'w') - ADVANCE (52); - if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' - || lookahead == ' ') - SKIP (0) - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (60); - END_STATE (); - case 1: - if (lookahead == '\n') - SKIP (14) - END_STATE (); - case 2: - if (lookahead == '\n') - SKIP (14) - if (lookahead == '\r') - SKIP (1) - END_STATE (); - case 3: - if (lookahead == '\n') - SKIP (16) - END_STATE (); - case 4: - if (lookahead == '\n') - SKIP (16) - if (lookahead == '\r') - SKIP (3) - END_STATE (); - case 5: - if (lookahead == '\n') - SKIP (7) - END_STATE (); - case 6: - if (lookahead == '\n') - SKIP (7) - if (lookahead == '\r') - SKIP (5) - END_STATE (); - case 7: - if (lookahead == '\n') - ADVANCE (48); - if (lookahead == '\\') - SKIP (6) - if (lookahead == '\t' || lookahead == '\r' || lookahead == ' ') - SKIP (7) - END_STATE (); - case 8: - if (lookahead == ' ') - ADVANCE (13); - END_STATE (); - case 9: - if (lookahead == ' ') - ADVANCE (39); - END_STATE (); - case 10: - if (lookahead == ' ') - ADVANCE (40); - END_STATE (); - case 11: - if (lookahead == '-') - ADVANCE (43); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (24); - END_STATE (); - case 12: - if (lookahead == '-') - ADVANCE (44); - END_STATE (); - case 13: - if (lookahead == 'D') - ADVANCE (38); - END_STATE (); - case 14: - if (lookahead == 'N') - ADVANCE (30); - if (lookahead == '\\') - SKIP (2) - if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' - || lookahead == ' ') - SKIP (14) - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (23); - END_STATE (); - case 15: - if (lookahead == '\\') - ADVANCE (63); - if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' - || lookahead == ' ') - ADVANCE (65); - if (lookahead != 0 && lookahead != '"') - ADVANCE (66); - END_STATE (); - case 16: - if (lookahead == '\\') - SKIP (4) - if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' - || lookahead == ' ') - SKIP (16) - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (62); - END_STATE (); - case 17: - if (lookahead == 'a') - ADVANCE (36); - END_STATE (); - case 18: - if (lookahead == 'c') - ADVANCE (26); - END_STATE (); - case 19: - if (lookahead == 'c') - ADVANCE (20); - END_STATE (); - case 20: - if (lookahead == 'h') - ADVANCE (51); - END_STATE (); - case 21: - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (11); - END_STATE (); - case 22: - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (21); - END_STATE (); - case 23: - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (22); - END_STATE (); - case 24: - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (24); - END_STATE (); - case 25: - if (lookahead == 'i') - ADVANCE (32); - END_STATE (); - case 26: - if (lookahead == 'k') - ADVANCE (49); - END_STATE (); - case 27: - if (lookahead == 'l') - ADVANCE (55); - END_STATE (); - case 28: - if (lookahead == 'm') - ADVANCE (71); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (28); - END_STATE (); - case 29: - if (lookahead == 'n') - ADVANCE (69); - END_STATE (); - case 30: - if (lookahead == 'o') - ADVANCE (8); - END_STATE (); - case 31: - if (lookahead == 'o') - ADVANCE (33); - END_STATE (); - case 32: - if (lookahead == 'o') - ADVANCE (29); - END_STATE (); - case 33: - if (lookahead == 'p') - ADVANCE (53); - END_STATE (); - case 34: - if (lookahead == 'r') - ADVANCE (17); - END_STATE (); - case 35: - if (lookahead == 's') - ADVANCE (70); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (35); - END_STATE (); - case 36: - if (lookahead == 't') - ADVANCE (25); - END_STATE (); - case 37: - if (lookahead == 't') - ADVANCE (19); - END_STATE (); - case 38: - if (lookahead == 'u') - ADVANCE (34); - END_STATE (); - case 39: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (28); - END_STATE (); - case 40: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (35); - END_STATE (); - case 41: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (12); - END_STATE (); - case 42: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (67); - END_STATE (); - case 43: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (41); - END_STATE (); - case 44: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (42); - END_STATE (); - case 45: - if (eof) - ADVANCE (47); - if (lookahead == '\n') - SKIP (0) - END_STATE (); - case 46: - if (eof) - ADVANCE (47); - if (lookahead == '\n') - SKIP (0) - if (lookahead == '\r') - SKIP (45) - END_STATE (); - case 47: - ACCEPT_TOKEN (ts_builtin_sym_end); - END_STATE (); - case 48: - ACCEPT_TOKEN (anon_sym_LF); - if (lookahead == '\n') - ADVANCE (48); - END_STATE (); - case 49: - ACCEPT_TOKEN (anon_sym_pick); - END_STATE (); - case 50: - ACCEPT_TOKEN (anon_sym_p); - if (lookahead == 'i') - ADVANCE (18); - END_STATE (); - case 51: - ACCEPT_TOKEN (anon_sym_watch); - END_STATE (); - case 52: - ACCEPT_TOKEN (anon_sym_w); - if (lookahead == 'a') - ADVANCE (37); - END_STATE (); - case 53: - ACCEPT_TOKEN (anon_sym_drop); - END_STATE (); - case 54: - ACCEPT_TOKEN (anon_sym_d); - if (lookahead == 'r') - ADVANCE (31); - END_STATE (); - case 55: - ACCEPT_TOKEN (anon_sym_url); - END_STATE (); - case 56: - ACCEPT_TOKEN (anon_sym_u); - if (lookahead == 'r') - ADVANCE (27); - END_STATE (); - case 57: - ACCEPT_TOKEN (sym_id); - if (lookahead == '-') - ADVANCE (43); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (61); - END_STATE (); - case 58: - ACCEPT_TOKEN (sym_id); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (57); - END_STATE (); - case 59: - ACCEPT_TOKEN (sym_id); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (58); - END_STATE (); - case 60: - ACCEPT_TOKEN (sym_id); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (59); - END_STATE (); - case 61: - ACCEPT_TOKEN (sym_id); - if (lookahead == 'h') - ADVANCE (9); - if (lookahead == 'm') - ADVANCE (10); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (61); - END_STATE (); - case 62: - ACCEPT_TOKEN (sym_id); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (62); - END_STATE (); - case 63: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == '\n') - ADVANCE (65); - if (lookahead == '\r') - ADVANCE (64); - if (lookahead != 0 && lookahead != '"') - ADVANCE (66); - END_STATE (); - case 64: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == '\n') - ADVANCE (65); - if (lookahead != 0 && lookahead != '"') - ADVANCE (66); - END_STATE (); - case 65: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == '\\') - ADVANCE (63); - if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' - || lookahead == ' ') - ADVANCE (65); - if (lookahead != 0 && lookahead != '"') - ADVANCE (66); - END_STATE (); - case 66: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead != 0 && lookahead != '"') - ADVANCE (66); - END_STATE (); - case 67: - ACCEPT_TOKEN (aux_sym_date_token1); - END_STATE (); - case 68: - ACCEPT_TOKEN (anon_sym_LBRACK); - END_STATE (); - case 69: - ACCEPT_TOKEN (anon_sym_NoDuration); - END_STATE (); - case 70: - ACCEPT_TOKEN (aux_sym_duration_token1); - END_STATE (); - case 71: - ACCEPT_TOKEN (aux_sym_duration_token2); - END_STATE (); - case 72: - ACCEPT_TOKEN (anon_sym_RBRACK); - END_STATE (); - case 73: - ACCEPT_TOKEN (sym_comment); - if (lookahead != 0 && lookahead != '\n') - ADVANCE (73); - END_STATE (); - case 74: - ACCEPT_TOKEN (sym_quote); - END_STATE (); - default: - return false; - } -} - -static const TSLexMode ts_lex_modes[STATE_COUNT] = { - [0] = { .lex_state = 0 }, [1] = { .lex_state = 0 }, - [2] = { .lex_state = 0 }, [3] = { .lex_state = 0 }, - [4] = { .lex_state = 0 }, [5] = { .lex_state = 0 }, - [6] = { .lex_state = 0 }, [7] = { .lex_state = 0 }, - [8] = { .lex_state = 14 }, [9] = { .lex_state = 0 }, - [10] = { .lex_state = 0 }, [11] = { .lex_state = 0 }, - [12] = { .lex_state = 0 }, [13] = { .lex_state = 0 }, - [14] = { .lex_state = 0 }, [15] = { .lex_state = 0 }, - [16] = { .lex_state = 15 }, [17] = { .lex_state = 0 }, - [18] = { .lex_state = 0 }, [19] = { .lex_state = 16 }, - [20] = { .lex_state = 0 }, [21] = { .lex_state = 7 }, - [22] = { .lex_state = 15 }, [23] = { .lex_state = 14 }, - [24] = { .lex_state = 0 }, [25] = { .lex_state = 15 }, - [26] = { .lex_state = 16 }, [27] = { .lex_state = 0 }, - [28] = { .lex_state = 7 }, [29] = { .lex_state = 0 }, - [30] = { .lex_state = 0 }, -}; - -static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { - [0] = { - [ts_builtin_sym_end] = ACTIONS(1), - [anon_sym_pick] = ACTIONS(1), - [anon_sym_p] = ACTIONS(1), - [anon_sym_watch] = ACTIONS(1), - [anon_sym_w] = ACTIONS(1), - [anon_sym_drop] = ACTIONS(1), - [anon_sym_d] = ACTIONS(1), - [anon_sym_url] = ACTIONS(1), - [anon_sym_u] = ACTIONS(1), - [sym_id] = ACTIONS(1), - [aux_sym_date_token1] = ACTIONS(1), - [anon_sym_LBRACK] = ACTIONS(1), - [anon_sym_NoDuration] = ACTIONS(1), - [aux_sym_duration_token1] = ACTIONS(1), - [aux_sym_duration_token2] = ACTIONS(1), - [anon_sym_RBRACK] = ACTIONS(1), - [sym_comment] = ACTIONS(1), - [sym_quote] = ACTIONS(1), - }, - [1] = { - [sym_source_file] = STATE(29), - [sym_line] = STATE(2), - [sym_command] = STATE(26), - [aux_sym_source_file_repeat1] = STATE(2), - [ts_builtin_sym_end] = ACTIONS(3), - [anon_sym_pick] = ACTIONS(5), - [anon_sym_p] = ACTIONS(7), - [anon_sym_watch] = ACTIONS(5), - [anon_sym_w] = ACTIONS(7), - [anon_sym_drop] = ACTIONS(5), - [anon_sym_d] = ACTIONS(7), - [anon_sym_url] = ACTIONS(5), - [anon_sym_u] = ACTIONS(7), - [sym_comment] = ACTIONS(9), - }, -}; - -static const uint16_t ts_small_parse_table[] = { - [0] = 6, - ACTIONS (11), - 1, - ts_builtin_sym_end, - ACTIONS (13), - 1, - sym_comment, - STATE (26), - 1, - sym_command, - STATE (3), - 2, - sym_line, - aux_sym_source_file_repeat1, - ACTIONS (5), - 4, - anon_sym_pick, - anon_sym_watch, - anon_sym_drop, - anon_sym_url, - ACTIONS (7), - 4, - anon_sym_p, - anon_sym_w, - anon_sym_d, - anon_sym_u, - [26] = 6, - ACTIONS (15), - 1, - ts_builtin_sym_end, - ACTIONS (23), - 1, - sym_comment, - STATE (26), - 1, - sym_command, - STATE (3), - 2, - sym_line, - aux_sym_source_file_repeat1, - ACTIONS (17), - 4, - anon_sym_pick, - anon_sym_watch, - anon_sym_drop, - anon_sym_url, - ACTIONS (20), - 4, - anon_sym_p, - anon_sym_w, - anon_sym_d, - anon_sym_u, - [52] = 2, - ACTIONS (28), - 4, - anon_sym_p, - anon_sym_w, - anon_sym_d, - anon_sym_u, - ACTIONS (26), - 6, - ts_builtin_sym_end, - anon_sym_pick, - anon_sym_watch, - anon_sym_drop, - anon_sym_url, - sym_comment, - [67] = 3, - ACTIONS (30), - 1, - sym_quote, - STATE (21), - 1, - sym_url, - STATE (22), - 1, - sym__q, - [77] = 3, - ACTIONS (32), - 1, - sym_quote, - STATE (7), - 1, - sym_title, - STATE (25), - 1, - sym__q, - [87] = 3, - ACTIONS (34), - 1, - sym_quote, - STATE (9), - 1, - sym_date, - STATE (23), - 1, - sym__q, - [97] = 1, - ACTIONS (36), - 3, - anon_sym_NoDuration, - aux_sym_duration_token1, - aux_sym_duration_token2, - [103] = 3, - ACTIONS (38), - 1, - sym_quote, - STATE (10), - 1, - sym_author, - STATE (16), - 1, - sym__q, - [113] = 3, - ACTIONS (40), - 1, - sym_quote, - STATE (5), - 1, - sym_duration, - STATE (18), - 1, - sym__q, - [123] = 2, - ACTIONS (42), - 1, - sym_quote, - STATE (30), - 1, - sym__q, - [130] = 2, - ACTIONS (44), - 1, - sym_quote, - STATE (28), - 1, - sym__q, - [137] = 2, - ACTIONS (46), - 1, - sym_quote, - STATE (24), - 1, - sym__q, - [144] = 2, - ACTIONS (48), - 1, - sym_quote, - STATE (17), - 1, - sym__q, - [151] = 2, - ACTIONS (50), - 1, - sym_quote, - STATE (20), - 1, - sym__q, - [158] = 1, - ACTIONS (52), - 1, - aux_sym_title_token1, - [162] = 1, - ACTIONS (54), - 1, - sym_quote, - [166] = 1, - ACTIONS (56), - 1, - anon_sym_LBRACK, - [170] = 1, - ACTIONS (58), - 1, - sym_id, - [174] = 1, - ACTIONS (60), - 1, - sym_quote, - [178] = 1, - ACTIONS (62), - 1, - anon_sym_LF, - [182] = 1, - ACTIONS (64), - 1, - aux_sym_title_token1, - [186] = 1, - ACTIONS (66), - 1, - aux_sym_date_token1, - [190] = 1, - ACTIONS (68), - 1, - sym_quote, - [194] = 1, - ACTIONS (70), - 1, - aux_sym_title_token1, - [198] = 1, - ACTIONS (72), - 1, - sym_id, - [202] = 1, - ACTIONS (74), - 1, - anon_sym_RBRACK, - [206] = 1, - ACTIONS (76), - 1, - anon_sym_LF, - [210] = 1, - ACTIONS (78), - 1, - ts_builtin_sym_end, - [214] = 1, - ACTIONS (80), - 1, - sym_quote, -}; - -static const uint32_t ts_small_parse_table_map[] = { - [SMALL_STATE (2)] = 0, [SMALL_STATE (3)] = 26, [SMALL_STATE (4)] = 52, - [SMALL_STATE (5)] = 67, [SMALL_STATE (6)] = 77, [SMALL_STATE (7)] = 87, - [SMALL_STATE (8)] = 97, [SMALL_STATE (9)] = 103, [SMALL_STATE (10)] = 113, - [SMALL_STATE (11)] = 123, [SMALL_STATE (12)] = 130, [SMALL_STATE (13)] = 137, - [SMALL_STATE (14)] = 144, [SMALL_STATE (15)] = 151, [SMALL_STATE (16)] = 158, - [SMALL_STATE (17)] = 162, [SMALL_STATE (18)] = 166, [SMALL_STATE (19)] = 170, - [SMALL_STATE (20)] = 174, [SMALL_STATE (21)] = 178, [SMALL_STATE (22)] = 182, - [SMALL_STATE (23)] = 186, [SMALL_STATE (24)] = 190, [SMALL_STATE (25)] = 194, - [SMALL_STATE (26)] = 198, [SMALL_STATE (27)] = 202, [SMALL_STATE (28)] = 206, - [SMALL_STATE (29)] = 210, [SMALL_STATE (30)] = 214, -}; - -static const TSParseActionEntry ts_parse_actions[] = { - [0] = { .entry = { .count = 0, .reusable = false } }, - [1] = { .entry = { .count = 1, .reusable = false } }, - RECOVER (), - [3] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_source_file, 0), - [5] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (19), - [7] = { .entry = { .count = 1, .reusable = false } }, - SHIFT (19), - [9] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (2), - [11] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_source_file, 1), - [13] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (3), - [15] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2), - [17] = { .entry = { .count = 2, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2), - SHIFT_REPEAT (19), - [20] = { .entry = { .count = 2, .reusable = false } }, - REDUCE (aux_sym_source_file_repeat1, 2), - SHIFT_REPEAT (19), - [23] = { .entry = { .count = 2, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2), - SHIFT_REPEAT (3), - [26] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_line, 8), - [28] = { .entry = { .count = 1, .reusable = false } }, - REDUCE (sym_line, 8), - [30] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (22), - [32] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (25), - [34] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (23), - [36] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (27), - [38] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (16), - [40] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (18), - [42] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (30), - [44] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (28), - [46] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (24), - [48] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (17), - [50] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (20), - [52] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (13), - [54] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_title, 3), - [56] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (8), - [58] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_command, 1), - [60] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_date, 3), - [62] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (4), - [64] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (12), - [66] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (15), - [68] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_author, 3), - [70] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (14), - [72] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (6), - [74] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (11), - [76] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_url, 3), - [78] = { .entry = { .count = 1, .reusable = true } }, - ACCEPT_INPUT (), - [80] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_duration, 5), -}; - -#ifdef __cplusplus -extern "C" -{ -#endif -#ifdef _WIN32 -#define extern __declspec (dllexport) -#endif - - extern const TSLanguage * - tree_sitter_yts (void) - { - static const TSLanguage language = { - .version = LANGUAGE_VERSION, - .symbol_count = SYMBOL_COUNT, - .alias_count = ALIAS_COUNT, - .token_count = TOKEN_COUNT, - .external_token_count = EXTERNAL_TOKEN_COUNT, - .state_count = STATE_COUNT, - .large_state_count = LARGE_STATE_COUNT, - .production_id_count = PRODUCTION_ID_COUNT, - .field_count = FIELD_COUNT, - .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, - .parse_table = &ts_parse_table[0][0], - .small_parse_table = ts_small_parse_table, - .small_parse_table_map = ts_small_parse_table_map, - .parse_actions = ts_parse_actions, - .symbol_names = ts_symbol_names, - .symbol_metadata = ts_symbol_metadata, - .public_symbol_map = ts_symbol_map, - .alias_map = ts_non_terminal_alias_map, - .alias_sequences = &ts_alias_sequences[0][0], - .lex_modes = ts_lex_modes, - .lex_fn = ts_lex, - .primary_state_ids = ts_primary_state_ids, - }; - return &language; - } -#ifdef __cplusplus -} -#endif diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/src/tree_sitter/parser.h b/sys/nixpkgs/pkgs/tree-sitter-yts/src/tree_sitter/parser.h deleted file mode 100644 index 972913cf..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/src/tree_sitter/parser.h +++ /dev/null @@ -1,241 +0,0 @@ -#ifndef TREE_SITTER_PARSER_H_ -#define TREE_SITTER_PARSER_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include -#include - -#define ts_builtin_sym_error ((TSSymbol)-1) -#define ts_builtin_sym_end 0 -#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 - - typedef uint16_t TSStateId; - -#ifndef TREE_SITTER_API_H_ - typedef uint16_t TSSymbol; - typedef uint16_t TSFieldId; - typedef struct TSLanguage TSLanguage; -#endif - - typedef struct - { - TSFieldId field_id; - uint8_t child_index; - bool inherited; - } TSFieldMapEntry; - - typedef struct - { - uint16_t index; - uint16_t length; - } TSFieldMapSlice; - - typedef struct - { - bool visible; - bool named; - bool supertype; - } TSSymbolMetadata; - - typedef struct TSLexer TSLexer; - - struct TSLexer - { - int32_t lookahead; - TSSymbol result_symbol; - void (*advance) (TSLexer *, bool); - void (*mark_end) (TSLexer *); - uint32_t (*get_column) (TSLexer *); - bool (*is_at_included_range_start) (const TSLexer *); - bool (*eof) (const TSLexer *); - }; - - typedef enum - { - TSParseActionTypeShift, - TSParseActionTypeReduce, - TSParseActionTypeAccept, - TSParseActionTypeRecover, - } TSParseActionType; - - typedef union - { - struct - { - uint8_t type; - TSStateId state; - bool extra; - bool repetition; - } shift; - struct - { - uint8_t type; - uint8_t child_count; - TSSymbol symbol; - int16_t dynamic_precedence; - uint16_t production_id; - } reduce; - uint8_t type; - } TSParseAction; - - typedef struct - { - uint16_t lex_state; - uint16_t external_lex_state; - } TSLexMode; - - typedef union - { - TSParseAction action; - struct - { - uint8_t count; - bool reusable; - } entry; - } TSParseActionEntry; - - struct TSLanguage - { - uint32_t version; - uint32_t symbol_count; - uint32_t alias_count; - uint32_t token_count; - uint32_t external_token_count; - uint32_t state_count; - uint32_t large_state_count; - uint32_t production_id_count; - uint32_t field_count; - uint16_t max_alias_sequence_length; - const uint16_t *parse_table; - const uint16_t *small_parse_table; - const uint32_t *small_parse_table_map; - const TSParseActionEntry *parse_actions; - const char *const *symbol_names; - const char *const *field_names; - const TSFieldMapSlice *field_map_slices; - const TSFieldMapEntry *field_map_entries; - const TSSymbolMetadata *symbol_metadata; - const TSSymbol *public_symbol_map; - const uint16_t *alias_map; - const TSSymbol *alias_sequences; - const TSLexMode *lex_modes; - bool (*lex_fn) (TSLexer *, TSStateId); - bool (*keyword_lex_fn) (TSLexer *, TSStateId); - TSSymbol keyword_capture_token; - struct - { - const bool *states; - const TSSymbol *symbol_map; - void *(*create) (void); - void (*destroy) (void *); - bool (*scan) (void *, TSLexer *, const bool *symbol_whitelist); - unsigned (*serialize) (void *, char *); - void (*deserialize) (void *, const char *, unsigned); - } external_scanner; - const TSStateId *primary_state_ids; - }; - - /* - * Lexer Macros - */ - -#define START_LEXER() \ - bool result = false; \ - bool skip = false; \ - bool eof = false; \ - int32_t lookahead; \ - goto start; \ - next_state: \ - lexer->advance (lexer, skip); \ - start: \ - skip = false; \ - lookahead = lexer->lookahead; - -#define ADVANCE(state_value) \ - { \ - state = state_value; \ - goto next_state; \ - } - -#define SKIP(state_value) \ - { \ - skip = true; \ - state = state_value; \ - goto next_state; \ - } - -#define ACCEPT_TOKEN(symbol_value) \ - result = true; \ - lexer->result_symbol = symbol_value; \ - lexer->mark_end (lexer); - -#define END_STATE() return result; - - /* - * Parse Table Macros - */ - -#define SMALL_STATE(id) id - LARGE_STATE_COUNT - -#define STATE(id) id - -#define ACTIONS(id) id - -#define SHIFT(state_value) \ - { \ - { \ - .shift = {.type = TSParseActionTypeShift, .state = state_value } \ - } \ - } - -#define SHIFT_REPEAT(state_value) \ - { \ - { \ - .shift \ - = {.type = TSParseActionTypeShift, \ - .state = state_value, \ - .repetition = true } \ - } \ - } - -#define SHIFT_EXTRA() \ - { \ - { \ - .shift = {.type = TSParseActionTypeShift, .extra = true } \ - } \ - } - -#define REDUCE(symbol_val, child_count_val, ...) \ - { \ - { \ - .reduce = { .type = TSParseActionTypeReduce, \ - .symbol = symbol_val, \ - .child_count = child_count_val, \ - __VA_ARGS__ }, \ - } \ - } - -#define RECOVER() \ - { \ - { \ - .type = TSParseActionTypeRecover \ - } \ - } - -#define ACCEPT_INPUT() \ - { \ - { \ - .type = TSParseActionTypeAccept \ - } \ - } - -#ifdef __cplusplus -} -#endif - -#endif // TREE_SITTER_PARSER_H_ diff --git a/sys/nixpkgs/pkgs/tree-sitter-yts/treefmt.toml b/sys/nixpkgs/pkgs/tree-sitter-yts/treefmt.toml deleted file mode 100644 index 3d604b40..00000000 --- a/sys/nixpkgs/pkgs/tree-sitter-yts/treefmt.toml +++ /dev/null @@ -1,35 +0,0 @@ -[formatter.nix] -command = "nixpkgs-fmt" -includes = ["*.nix"] -excludes = ["test/**.nix"] - -[formatter.prettier] -command = "prettier" -options = ["--write"] -includes = [ - "*.css", - "*.html", - "*.js", - "*.json", - "*.jsx", - "*.md", - "*.mdx", - "*.scss", - "*.ts", -] -excludes = ["src/**.json"] - -[formatter.rust] -command = "rustfmt" -options = ["--edition", "2018"] -includes = ["*.rs"] - -[formatter.c] -command = "clang-format" -options = ["-i"] -includes = ["*.c", "*.cpp", "*.cc", "*.h", "*.hpp"] -excludes = [ - "bindings/node/binding.cc", - "src/parser.c", - "src/tree_sitter/parser.h", -] diff --git a/sys/nixpkgs/pkgs/update_pkgs.sh b/sys/nixpkgs/pkgs/update_pkgs.sh deleted file mode 100755 index be1573c6..00000000 --- a/sys/nixpkgs/pkgs/update_pkgs.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env sh - -die() { - printf "\033[31;1mError: \033[0m%s" "$1" - exit 1 -} - -cd "$(dirname "$0")" || die "Bug: run with false dirname ('$0')!" - -fd . --type directory --max-depth 1 | while read -r dir; do - cd "$dir" || die "Dir '$dir' does not exist" - - if [ -f update.sh ]; then - printf "\033[34;1m> \033[0m\033[34;1m%s\033[0m\n" "Running '${dir}update.sh'" - - [ -f flake.nix ] && nix flake update - - direnv allow - eval "$(direnv export bash 2>/dev/null)" - ./update.sh "$@" - fi - cd - >/dev/null || die "Bug: Last dir does not exist" -done - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/.envrc b/sys/nixpkgs/pkgs/update_vim_plugins/.envrc deleted file mode 100644 index 3550a30f..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/check-duplicates.sh b/sys/nixpkgs/pkgs/update_vim_plugins/check-duplicates.sh deleted file mode 100755 index 781b8aeb..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/check-duplicates.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -plugins="$(grep -E "^ [a-zA-Z-]+ =" ./pkgs/vim-plugins.nix | sed -E 's/^ ([a-zA-Z-]+) =.*$/\1/' | sort)" -count=$(echo "$plugins" | uniq -d | wc -l) - -echo "duplicates count: $count" - -if [ "$count" -gt 0 ]; then - filtered_plugins=$(echo "$plugins" | uniq -d) - - if [ "$1" == "check-only" ]; then - echo "$filtered_plugins" - exit 1 - else - known_issues=$(gh issue list --state "open" --label "bot" --json "body" | jq -r ".[].body") - - echo "known_issues: $known_issues" - - # iterate over plugins we found missing and - # compare them to all open issues. - # We no matching issue was found, we create a new one - for f in $filtered_plugins; do # do not add " " here. It would break the plugin - found=false - - for k in $known_issues; do - if [[ $f == "$k" ]]; then - found=true - break - fi - done - - # test if matching issue was found - if ! $found; then - echo "Did not find an issue for $f. Creating a new one ..." - gh issue create --title "Detected broken plugin: $f" --label "bot" --body "$f" - else - echo "Issue for $f already exists" - fi - done - fi -else - echo "No duplicates found" -fi diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/default.nix b/sys/nixpkgs/pkgs/update_vim_plugins/default.nix deleted file mode 100644 index 7f0b3f0d..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -[ - ( - final: prev: { - update-vim-plugins = import ./package.nix { - inherit - (prev) - python3 - # dependencies - - nix - alejandra - nix-prefetch-git - ; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/flake.lock b/sys/nixpkgs/pkgs/update_vim_plugins/flake.lock deleted file mode 100644 index 50494465..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1715087517, - "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/flake.nix b/sys/nixpkgs/pkgs/update_vim_plugins/flake.nix deleted file mode 100644 index ef440af0..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/flake.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - description = "update_vim_plugins"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - }: (flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; - in { - devShells.default = pkgs.mkShell { - packages = [ - pkgs.python3 - pkgs.poetry - ]; - }; - })); -} diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/package.nix b/sys/nixpkgs/pkgs/update_vim_plugins/package.nix deleted file mode 100644 index e74a29b1..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/package.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ - python3, - # dependencies - nix, - alejandra, - nix-prefetch-git, -}: -python3.pkgs.buildPythonApplication { - pname = "update-vim-plugins"; - version = "0.1.0"; - format = "pyproject"; - - src = ./.; - - # NOTE: The test are not really meant to work <2023-12-09> - doCheck = false; - - nativeBuildInputs = [ - python3.pkgs.poetry-core - ]; - buildInputs = [ - alejandra - nix-prefetch-git - nix - ]; - propagatedBuildInputs = with python3.pkgs; [ - requests - cleo - jsonpickle - dateparser - ]; - nativeCheckInputs = with python3.pkgs; [ - pytestCheckHook - - pytest-cov - pytest-mock - ]; - pytestFlagsArray = [ - "--cov" - "update_vim_plugins" - "--cov-report" - "term-missing:skip-covered" - "--cov-fail-under" - "50" - "update_vim_plugins/tests" - ]; -} diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/poetry.lock b/sys/nixpkgs/pkgs/update_vim_plugins/poetry.lock deleted file mode 100644 index f4764b42..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/poetry.lock +++ /dev/null @@ -1,680 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. - -[[package]] -name = "certifi" -version = "2024.2.2" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - -[[package]] -name = "cleo" -version = "2.1.0" -description = "Cleo allows you to create beautiful and testable command-line interfaces." -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "cleo-2.1.0-py3-none-any.whl", hash = "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e"}, - {file = "cleo-2.1.0.tar.gz", hash = "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523"}, -] - -[package.dependencies] -crashtest = ">=0.4.1,<0.5.0" -rapidfuzz = ">=3.0.0,<4.0.0" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.5.1" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, - {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, - {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, - {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, - {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, - {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, - {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, - {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, - {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, - {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, - {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, - {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, - {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, - {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "crashtest" -version = "0.4.1" -description = "Manage Python errors with ease" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, - {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, -] - -[[package]] -name = "dateparser" -version = "1.2.0" -description = "Date parsing library designed to parse dates from HTML pages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"}, - {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"}, -] - -[package.dependencies] -python-dateutil = "*" -pytz = "*" -regex = "<2019.02.19 || >2019.02.19,<2021.8.27 || >2021.8.27" -tzlocal = "*" - -[package.extras] -calendars = ["convertdate", "hijri-converter"] -fasttext = ["fasttext"] -langdetect = ["langdetect"] - -[[package]] -name = "exceptiongroup" -version = "1.2.1" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "jsonpickle" -version = "3.0.4" -description = "Serialize any Python object to JSON" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpickle-3.0.4-py3-none-any.whl", hash = "sha256:04ae7567a14269579e3af66b76bda284587458d7e8a204951ca8f71a3309952e"}, - {file = "jsonpickle-3.0.4.tar.gz", hash = "sha256:a1b14c8d6221cd8f394f2a97e735ea1d7edc927fbd135b26f2f8700657c8c62b"}, -] - -[package.extras] -docs = ["furo", "rst.linker (>=1.9)", "sphinx"] -packaging = ["build", "twine"] -testing = ["bson", "ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-benchmark", "pytest-benchmark[histogram]", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-ruff (>=0.2.1)", "scikit-learn", "scipy", "scipy (>=1.9.3)", "simplejson", "sqlalchemy", "ujson"] - -[[package]] -name = "packaging" -version = "24.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.1.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "rapidfuzz" -version = "3.9.0" -description = "rapid fuzzy string matching" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bd375c4830fee11d502dd93ecadef63c137ae88e1aaa29cc15031fa66d1e0abb"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:55e2c5076f38fc1dbaacb95fa026a3e409eee6ea5ac4016d44fb30e4cad42b20"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:488f74126904db6b1bea545c2f3567ea882099f4c13f46012fe8f4b990c683df"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3f2d1ea7cd57dfcd34821e38b4924c80a31bcf8067201b1ab07386996a9faee"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b11e602987bcb4ea22b44178851f27406fca59b0836298d0beb009b504dba266"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3083512e9bf6ed2bb3d25883922974f55e21ae7f8e9f4e298634691ae1aee583"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b33c6d4b3a1190bc0b6c158c3981535f9434e8ed9ffa40cf5586d66c1819fb4b"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcb95fde22f98e6d0480db8d6038c45fe2d18a338690e6f9bba9b82323f3469"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:08d8b49b3a4fb8572e480e73fcddc750da9cbb8696752ee12cca4bf8c8220d52"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e721842e6b601ebbeb8cc5e12c75bbdd1d9e9561ea932f2f844c418c31256e82"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7988363b3a415c5194ce1a68d380629247f8713e669ad81db7548eb156c4f365"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2d267d4c982ab7d177e994ab1f31b98ff3814f6791b90d35dda38307b9e7c989"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bb28ab5300cf974c7eb68ea21125c493e74b35b1129e629533468b2064ae0a2"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win32.whl", hash = "sha256:1b1f74997b6d94d66375479fa55f70b1c18e4d865d7afcd13f0785bfd40a9d3c"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:c56d2efdfaa1c642029f3a7a5bb76085c5531f7a530777be98232d2ce142553c"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win_arm64.whl", hash = "sha256:6a83128d505cac76ea560bb9afcb3f6986e14e50a6f467db9a31faef4bd9b347"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e2218d62ab63f3c5ad48eced898854d0c2c327a48f0fb02e2288d7e5332a22c8"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36bf35df2d6c7d5820da20a6720aee34f67c15cd2daf8cf92e8141995c640c25"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:905b01a9b633394ff6bb5ebb1c5fd660e0e180c03fcf9d90199cc6ed74b87cf7"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33cfabcb7fd994938a6a08e641613ce5fe46757832edc789c6a5602e7933d6fa"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1179dcd3d150a67b8a678cd9c84f3baff7413ff13c9e8fe85e52a16c97e24c9b"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47d97e28c42f1efb7781993b67c749223f198f6653ef177a0c8f2b1c516efcaf"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28da953eb2ef9ad527e536022da7afff6ace7126cdd6f3e21ac20f8762e76d2c"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:182b4e11de928fb4834e8f8b5ecd971b5b10a86fabe8636ab65d3a9b7e0e9ca7"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c74f2da334ce597f31670db574766ddeaee5d9430c2c00e28d0fbb7f76172036"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:014ac55b03f4074f903248ded181f3000f4cdbd134e6155cbf643f0eceb4f70f"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c4ef34b2ddbf448f1d644b4ec6475df8bbe5b9d0fee173ff2e87322a151663bd"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fc02157f521af15143fae88f92ef3ddcc4e0cff05c40153a9549dc0fbdb9adb3"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ff08081c49b18ba253a99e6a47f492e6ee8019e19bbb6ddc3ed360cd3ecb2f62"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win32.whl", hash = "sha256:b9bf90b3d96925cbf8ef44e5ee3cf39ef0c422f12d40f7a497e91febec546650"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5d5684f54d82d9b0cf0b2701e55a630527a9c3dd5ddcf7a2e726a475ac238f2"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:a2de844e0e971d7bd8aa41284627dbeacc90e750b90acfb016836553c7a63192"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f81fe99a69ac8ee3fd905e70c62f3af033901aeb60b69317d1d43d547b46e510"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:633b9d03fc04abc585c197104b1d0af04b1f1db1abc99f674d871224cd15557a"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab872cb57ae97c54ba7c71a9e3c9552beb57cb907c789b726895576d1ea9af6f"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdd8c15c3a14e409507fdf0c0434ec481d85c6cbeec8bdcd342a8cd1eda03825"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2444d8155d9846f206e2079bb355b85f365d9457480b0d71677a112d0a7f7128"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83bd3d01f04061c3660742dc85143a89d49fd23eb31eccbf60ad56c4b955617"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ca799f882364e69d0872619afb19efa3652b7133c18352e4a3d86a324fb2bb1"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6993d361f28b9ef5f0fa4e79b8541c2f3507be7471b9f9cb403a255e123b31e1"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:170822a1b1719f02b58e3dce194c8ad7d4c5b39be38c0fdec603bd19c6f9cf81"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e86e39c1c1a0816ceda836e6f7bd3743b930cbc51a43a81bb433b552f203f25"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:731269812ea837e0b93d913648e404736407408e33a00b75741e8f27c590caa2"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8e5ff882d3a3d081157ceba7e0ebc7fac775f95b08cbb143accd4cece6043819"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2003071aa633477a01509890c895f9ef56cf3f2eaa72c7ec0b567f743c1abcba"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win32.whl", hash = "sha256:13857f9070600ea1f940749f123b02d0b027afbaa45e72186df0f278915761d0"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:134b7098ac109834eeea81424b6822f33c4c52bf80b81508295611e7a21be12a"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:2a96209f046fe328be30fc43f06e3d4b91f0d5b74e9dcd627dbfd65890fa4a5e"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:544b0bf9d17170720809918e9ccd0d482d4a3a6eca35630d8e1459f737f71755"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d536f8beb8dd82d6efb20fe9f82c2cfab9ffa0384b5d184327e393a4edde91d"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:30f7609da871510583f87484a10820b26555a473a90ab356cdda2f3b4456256c"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f4a2468432a1db491af6f547fad8f6d55fa03e57265c2f20e5eaceb68c7907e"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a7ec4676242c8a430509cff42ce98bca2fbe30188a63d0f60fdcbfd7e84970"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dcb523243e988c849cf81220164ec3bbed378a699e595a8914fffe80596dc49f"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4eea3bf72c4fe68e957526ffd6bcbb403a21baa6b3344aaae2d3252313df6199"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4514980a5d204c076dd5b756960f6b1b7598f030009456e6109d76c4c331d03c"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9a06a99f1335fe43464d7121bc6540de7cd9c9475ac2025babb373fe7f27846b"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6c1ed63345d1581c39d4446b1a8c8f550709656ce2a3c88c47850b258167f3c2"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cd2e6e97daf17ebb3254285cf8dd86c60d56d6cf35c67f0f9a557ef26bd66290"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:9bc0f7e6256a9c668482c41c8a3de5d0aa12e8ca346dcc427b97c7edb82cba48"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c09f4e87e82a164c9db769474bc61f8c8b677f2aeb0234b8abac73d2ecf9799"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-win32.whl", hash = "sha256:e65b8f7921bf60cbb207c132842a6b45eefef48c4c3b510eb16087d6c08c70af"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9d6478957fb35c7844ad08f2442b62ba76c1857a56370781a707eefa4f4981e1"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:65d9250a4b0bf86320097306084bc3ca479c8f5491927c170d018787793ebe95"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47b7c0840afa724db3b1a070bc6ed5beab73b4e659b1d395023617fc51bf68a2"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a16c48c6df8fb633efbbdea744361025d01d79bca988f884a620e63e782fe5b"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48105991ff6e4a51c7f754df500baa070270ed3d41784ee0d097549bc9fcb16d"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a7f273906b3c7cc6d63a76e088200805947aa0bc1ada42c6a0e582e19c390d7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c396562d304e974b4b0d5cd3afc4f92c113ea46a36e6bc62e45333d6aa8837e"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68da1b70458fea5290ec9a169fcffe0c17ff7e5bb3c3257e63d7021a50601a8e"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c5b8f9a7b177af6ce7c6ad5b95588b4b73e37917711aafa33b2e79ee80fe709"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3c42a238bf9dd48f4ccec4c6934ac718225b00bb3a438a008c219e7ccb3894c7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a365886c42177b2beab475a50ba311b59b04f233ceaebc4c341f6f91a86a78e2"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ce897b5dafb7fb7587a95fe4d449c1ea0b6d9ac4462fbafefdbbeef6eee4cf6a"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:413ac49bae291d7e226a5c9be65c71b2630b3346bce39268d02cb3290232e4b7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8982fc3bd49d55a91569fc8a3feba0de4cef0b391ff9091be546e9df075b81"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win32.whl", hash = "sha256:3904d0084ab51f82e9f353031554965524f535522a48ec75c30b223eb5a0a488"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:3733aede16ea112728ffeafeb29ccc62e095ed8ec816822fa2a82e92e2c08696"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win_arm64.whl", hash = "sha256:fc4e26f592b51f97acf0a3f8dfed95e4d830c6a8fbf359361035df836381ab81"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e33362e98c7899b5f60dcb06ada00acd8673ce0d59aefe9a542701251fd00423"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb67cf43ad83cb886cbbbff4df7dcaad7aedf94d64fca31aea0da7d26684283c"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2e106cc66453bb80d2ad9c0044f8287415676df5c8036d737d05d4b9cdbf8e"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1256915f7e7a5cf2c151c9ac44834b37f9bd1c97e8dec6f936884f01b9dfc7d"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ae643220584518cbff8bf2974a0494d3e250763af816b73326a512c86ae782ce"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:491274080742110427f38a6085bb12dffcaff1eef12dccf9e8758398c7e3957e"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bc5559b9b94326922c096b30ae2d8e5b40b2e9c2c100c2cc396ad91bcb84d30"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:849160dc0f128acb343af514ca827278005c1d00148d025e4035e034fc2d8c7f"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:623883fb78e692d54ed7c43b09beec52c6685f10a45a7518128e25746667403b"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d20ab9abc7e19767f1951772a6ab14cb4eddd886493c2da5ee12014596ad253f"}, - {file = "rapidfuzz-3.9.0.tar.gz", hash = "sha256:b182f0fb61f6ac435e416eb7ab330d62efdbf9b63cf0c7fa12d1f57c2eaaf6f3"}, -] - -[package.extras] -full = ["numpy"] - -[[package]] -name = "regex" -version = "2024.4.28" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.8" -files = [ - {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61"}, - {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f"}, - {file = "regex-2024.4.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea"}, - {file = "regex-2024.4.28-cp310-cp310-win32.whl", hash = "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d"}, - {file = "regex-2024.4.28-cp310-cp310-win_amd64.whl", hash = "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f"}, - {file = "regex-2024.4.28-cp311-cp311-win32.whl", hash = "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630"}, - {file = "regex-2024.4.28-cp311-cp311-win_amd64.whl", hash = "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6"}, - {file = "regex-2024.4.28-cp312-cp312-win32.whl", hash = "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17"}, - {file = "regex-2024.4.28-cp312-cp312-win_amd64.whl", hash = "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150"}, - {file = "regex-2024.4.28-cp38-cp38-win32.whl", hash = "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58"}, - {file = "regex-2024.4.28-cp38-cp38-win_amd64.whl", hash = "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1"}, - {file = "regex-2024.4.28-cp39-cp39-win32.whl", hash = "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc"}, - {file = "regex-2024.4.28-cp39-cp39-win_amd64.whl", hash = "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962"}, - {file = "regex-2024.4.28.tar.gz", hash = "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4"}, -] - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "tzdata" -version = "2024.1" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, -] - -[[package]] -name = "tzlocal" -version = "5.2" -description = "tzinfo object for the local timezone" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, - {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, -] - -[package.dependencies] -tzdata = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] - -[[package]] -name = "urllib3" -version = "2.2.1" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.10" -content-hash = "f65cd66387236673e2a5afb3b2a75362c97815cdde592a86712737fb9ca71695" diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/pyproject.toml b/sys/nixpkgs/pkgs/update_vim_plugins/pyproject.toml deleted file mode 100644 index 38caf76d..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/pyproject.toml +++ /dev/null @@ -1,45 +0,0 @@ -[tool.poetry] -name = "update_vim_plugins" -version = "0.1.0" -description = "" -authors = ["Your Name "] -packages = [{ include = "update_vim_plugins" }] - -[tool.poetry.scripts] -update-vim-plugins = "update_vim_plugins.__main__:main" - -[tool.poetry.dependencies] -python = "^3.10" -requests = "^2.28.2" -cleo = "^2.0.1" -jsonpickle = "*" -dateparser = "^1.1.8" - -[tool.poetry.group.test.dependencies] -pytest-cov = "^4.0.0" -pytest = "^7.3.1" -pytest-mock = "^3.10.0" - -[tool.poetry.group.dev] -optional = true - -[tool.poetry.group.dev.dependencies] -# black = "^23.3.0" -# ruff-lsp = "^0.0.24" -# mypy = "^1.2.0" -# types-requests = "^2.28.11.17" -# isort = "^5.12.0" -# ruff = "^0.0.262" - -[tool.isort] -profile = "black" - -[tool.black] -line-length = 120 - -[tool.ruff] -line-length = 120 - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update.sh b/sys/nixpkgs/pkgs/update_vim_plugins/update.sh deleted file mode 100755 index 1bad12a9..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh - -poetry update --lock - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__init__.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__main__.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__main__.py deleted file mode 100644 index a8d9e06f..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/__main__.py +++ /dev/null @@ -1,15 +0,0 @@ -from cleo.application import Application - -from .update import UpdateCommand -from .cleanup import CleanUpCommand - - -def main(): - application = Application() - application.add(UpdateCommand()) - application.add(CleanUpCommand()) - application.run() - - -if __name__ == "__main__": - main() diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/cleanup.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/cleanup.py deleted file mode 100644 index fd313ed0..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/cleanup.py +++ /dev/null @@ -1,100 +0,0 @@ -from cleo.commands.command import Command -from cleo.helpers import argument - -from .helpers import read_manifest_to_spec, read_blacklist_to_spec, write_manifest_from_spec - - -class CleanUpCommand(Command): - name = "cleanup" - description = "Clean up manifest" - arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)] - - def handle(self): - """Main command function""" - - plug_dir = self.argument("plug_dir") - self.line("Checking manifest file") - # all cleaning up will be done during reading and writing automatically - manifest = read_manifest_to_spec(plug_dir) - blacklist = read_blacklist_to_spec(plug_dir) - - new_manifest = [spec for spec in manifest if spec not in blacklist] - - new_manifest_filterd = self.filter_renamed(new_manifest) - - write_manifest_from_spec(new_manifest_filterd, plug_dir) - - self.line("Done") - - def filter_renamed(self, specs): - """Filter specs that define the same plugin (same owner and same repo) but with different properties. - This could be a different name, source, or branch - """ - - error = False - for i, p in enumerate(specs): - for p2 in specs: - same_owner = p.owner.lower() == p2.owner.lower() - same_repo = p.repo.lower() == p2.repo.lower() - different_specs = p != p2 - marked_duplicate = p.marked_duplicate or p2.marked_duplicate - - if same_owner and same_repo and different_specs and not marked_duplicate: - self.line("The following lines appear to define the same plugin") - - p_props_defined = p.branch is not None or p.custom_name is not None - p2_props_defined = p2.branch is not None or p2.custom_name is not None - p_is_lower_case = p.owner == p.owner.lower() and p.name == p.name.lower() - p2_is_lower_case = p2.owner == p2.owner.lower() and p2.name == p2.name.lower() - - # list of conditions for selecting p - select_p = p_props_defined and not p2_props_defined or p2_is_lower_case and not p_is_lower_case - # list of conditions for selecting p2 - select_p2 = p2_props_defined and not p_props_defined or p_is_lower_case and not p2_is_lower_case - - # one is more defined and is all lower, but the other is not all lower - # (we assume the not all lower case is the correct naming) - error_props_lower = ( - p_props_defined and p_is_lower_case and not p2_props_defined and not p2_is_lower_case - ) - error_props_lower2 = ( - p2_props_defined and p2_is_lower_case and not p_props_defined and not p_is_lower_case - ) - - # both props are defined - error_props = p_props_defined and p2_props_defined - - # the sources are different - error_source = p.repository_host != p2.repository_host - - if error_props_lower or error_props_lower2 or error_props or error_source: - self.line(" • Cannot determine which is the correct plugin") - self.line(f" - {p.line}") - self.line(f" - {p2.line}") - error = True - # remove second spec to not encounter the error twice - # this will not be written to the manifest.txt because we set - # the error flag and will exit after the loop - specs.remove(p2) - elif select_p: - self.line(f" - {p.line}") - self.line(f" - {p2.line}") - specs.remove(p2) - elif select_p2: - self.line(f" - {p.line}") - self.line(f" - {p2.line}") - specs.remove(p) - else: - self.line(" • Logic error in correct spec determination") - self.line(f" - {p.line}") - self.line(f" - {p2.line}") - error = True - # remove second spec to not encounter the error twice - # this will not be written to the manifest.txt because we set - # the error flag and will exit after the loop - specs.remove(p) - if error: - # exit after all errors have been found - exit(1) - - return specs diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/helpers.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/helpers.py deleted file mode 100644 index 8a28b0e8..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/helpers.py +++ /dev/null @@ -1,61 +0,0 @@ -from .spec import PluginSpec - -MANIFEST_FILE = "manifest.txt" -BLACKLIST_FILE = "blacklist.txt" -PKGS_FILE = "default.nix" -JSON_FILE = ".plugins.json" -PLUGINS_LIST_FILE = "plugins.md" - - -def get_const(const: str, plug_dir: str) -> str: - out = plug_dir + "/" + const - return out - - -def read_manifest(plug_dir: str) -> list[str]: - with open(get_const(MANIFEST_FILE, plug_dir), "r") as file: - specs = set([spec.strip() for spec in file.readlines()]) - - return sorted(specs) - - -def read_manifest_to_spec(plug_dir: str) -> list[PluginSpec]: - manifest = read_manifest(plug_dir) - specs = [PluginSpec.from_spec(spec.strip()) for spec in manifest] - - return sorted(specs) - - -def read_blacklist(plug_dir: str) -> list[str]: - with open(get_const(BLACKLIST_FILE, plug_dir), "r") as file: - if len(file.readlines()) == 0: - return [""] - else: - blacklisted_specs = set([spec.strip() for spec in file.readlines()]) - - return sorted(blacklisted_specs) - - -def read_blacklist_to_spec(plug_dir: str) -> list[PluginSpec]: - blacklist = read_blacklist(plug_dir) - specs = [PluginSpec.from_spec(spec.strip()) for spec in blacklist] - - return sorted(specs) - - -def write_manifest(specs: list[str] | set[str], plug_dir: str): - """write specs to manifest file. Does some cleaning up""" - - with open(get_const(MANIFEST_FILE, plug_dir), "w") as file: - specs = sorted(set(specs), key=lambda x: x.lower()) - specs = [p for p in specs] - - for s in specs: - file.write(f"{s}\n") - - -def write_manifest_from_spec(specs: list[PluginSpec], plug_dir: str): - """write specs to manifest file. Does some cleaning up""" - - strings = [f"{spec}" for spec in specs] - write_manifest(strings, plug_dir) diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/nix.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/nix.py deleted file mode 100644 index 66a8df4c..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/nix.py +++ /dev/null @@ -1,121 +0,0 @@ -import abc -import enum -import json -import subprocess - - -def nix_prefetch_url(url): - """Return the sha256 hash of the given url.""" - subprocess_output = subprocess.check_output( - ["nix-prefetch-url", "--type", "sha256", url], - stderr=subprocess.DEVNULL, - ) - sha256 = subprocess_output.decode("utf-8").strip() - return sha256 - - -def nix_prefetch_git(url): - """Return the sha256 hash of the given git url.""" - subprocess_output = subprocess.check_output(["nix-prefetch-git", url], stderr=subprocess.DEVNULL) - sha256 = json.loads(subprocess_output)["sha256"] - return sha256 - - -class Source(abc.ABC): - """Abstract base class for sources.""" - - url: str - sha256: str - - @abc.abstractmethod - def __init__(self, url: str) -> None: - """Initialize a Source.""" - - @abc.abstractmethod - def get_nix_expression(self): - """Return the nix expression for this source.""" - - def __repr__(self): - """Return the representation of this source.""" - return self.get_nix_expression() - - -class UrlSource(Source): - """A source that is a url.""" - - def __init__(self, url: str) -> None: - """Initialize a UrlSource.""" - self.url = url - self.sha256 = nix_prefetch_url(url) - - def get_nix_expression(self): - """Return the nix expression for this source.""" - return f'fetchurl {{ url = "{self.url}"; sha256 = "{self.sha256}"; }}' - - -class GitSource(Source): - """A source that is a git repository.""" - - def __init__(self, url: str, rev: str) -> None: - """Initialize a GitSource.""" - self.url = url - self.rev = rev - self.sha256 = nix_prefetch_git(url) - - def get_nix_expression(self): - """Return the nix expression for this source.""" - return f'fetchgit {{ url = "{self.url}"; rev = "{self.rev}"; sha256 = "{self.sha256}"; }}' - - -class License(enum.Enum): - """An enumeration of licenses.""" - - AGPL_3_0 = "agpl3Only" - APACHE_2_0 = "asf20" - BSD_2_CLAUSE = "bsd2" - BSD_3_CLAUSE = "bsd3" - BSL_1_0 = "bsl1_0" - CC0_1_0 = "cc0" - EPL_2_0 = "epl20" - GPL_2_0 = "gpl2Only" - GPL_3_0 = "gpl3Only" - ISCLGPL_2_1 = "lgpl21Only" - MIT = "mit" - MPL_2_0 = "mpl20" - UNLUNLICENSE = "unlicense" - WTFPL = "wtfpl" - UNFREE = "unfree" - UNKNOWN = "" - - @classmethod - def from_spdx_id(cls, spdx_id: str | None) -> "License": - """Return the License from the given spdx_id.""" - mapping = { - "AGPL-3.0": cls.AGPL_3_0, - "AGPL-3.0-only": cls.AGPL_3_0, - "Apache-2.0": cls.APACHE_2_0, - "BSD-2-Clause": cls.BSD_2_CLAUSE, - "BSD-3-Clause": cls.BSD_3_CLAUSE, - "BSL-1.0": cls.BSL_1_0, - "CC0-1.0": cls.CC0_1_0, - "EPL-2.0": cls.EPL_2_0, - "GPL-2.0": cls.GPL_2_0, - "GPL-2.0-only": cls.GPL_2_0, - "GPL-3.0": cls.GPL_3_0, - "GPL-3.0-only": cls.GPL_3_0, - "LGPL-2.1-only": cls.ISCLGPL_2_1, - "MIT": cls.MIT, - "MPL-2.0": cls.MPL_2_0, - "Unlicense": cls.UNLUNLICENSE, - "WTFPL": cls.WTFPL, - } - - if spdx_id is None: - return cls.UNKNOWN - - spdx_id = spdx_id.upper() - return mapping.get(spdx_id, cls.UNKNOWN) - - def __str__(self): - """Return the string representation of this license.""" - return self.value diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/plugin.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/plugin.py deleted file mode 100644 index 8334ad53..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/plugin.py +++ /dev/null @@ -1,182 +0,0 @@ -import logging -import os -import urllib - -import requests -import jsonpickle -from datetime import datetime, date -from dateparser import parse - -from .nix import GitSource, License, Source, UrlSource -from .spec import PluginSpec, RepositoryHost - - -logger = logging.getLogger(__name__) - - -class VimPlugin: - """Abstract base class for vim plugins.""" - - name: str - owner: str - repo: str - version: date - source: Source - description: str = "No description" - homepage: str - license: License - source_line: str - checked: date = datetime.now().date() - - def to_nix(self): - """Return the nix expression for this plugin.""" - meta = f'with lib; {{ description = "{self.description}"; homepage = "{self.homepage}"; license = with licenses; [ {self.license.value} ]; }}' - return f'/* Generated from: {self.source_line} */ {self.name} = buildVimPlugin {{ pname = "{self.name}"; version = "{self.version}"; src = {self.source.get_nix_expression()}; meta = {meta}; }};' - - def to_json(self): - """Serizalize the plugin to json""" - return jsonpickle.encode(self) - - def to_markdown(self): - link = f"[{self.source_line}]({self.homepage})" - version = f"{self.version}" - package_name = f"{self.name}" - checked = f"{self.checked}" - - return f"| {link} | {version} | `{package_name}` | {checked} |" - - def __lt__(self, o: object) -> bool: - if not isinstance(o, VimPlugin): - return False - - return self.name.lower() < o.name.lower() - - def __repr__(self): - """Return the representation of this plugin.""" - return f"VimPlugin({self.name!r}, {self.version.strftime('%Y-%m-%d')})" - - -def _get_github_token(): - token = os.environ.get("GITHUB_TOKEN") - if token is None: - # NOTE: This should never use more than the free api requests <2023-12-09> - pass - # logger.warning("GITHUB_TOKEN environment variable not set") - return token - - -class GitHubPlugin(VimPlugin): - def __init__(self, plugin_spec: PluginSpec) -> None: - """Initialize a GitHubPlugin.""" - - full_name = f"{plugin_spec.owner}/{plugin_spec.repo}" - repo_info = self._api_call(f"repos/{full_name}") - default_branch = plugin_spec.branch or repo_info["default_branch"] - api_callback = self._api_call(f"repos/{full_name}/commits/{default_branch}") - latest_commit = api_callback["commit"] - sha = api_callback["sha"] - - self.name = plugin_spec.name - self.owner = plugin_spec.owner - self.version = parse(latest_commit["committer"]["date"]).date() - self.source = UrlSource(f"https://github.com/{full_name}/archive/{sha}.tar.gz") - self.description = (repo_info.get("description") or "").replace('"', '\\"') - self.homepage = repo_info["html_url"] - self.license = plugin_spec.license or License.from_spdx_id((repo_info.get("license") or {}).get("spdx_id")) - self.source_line = plugin_spec.line - - def _api_call(self, path: str, token: str | None = _get_github_token()): - """Call the GitHub API.""" - url = f"https://api.github.com/{path}" - headers = {"Content-Type": "application/json"} - if token is not None: - headers["Authorization"] = f"token {token}" - response = requests.get(url, headers=headers) - if response.status_code != 200: - raise RuntimeError(f"GitHub API call failed: {response.text}") - return response.json() - - -class GitlabPlugin(VimPlugin): - def __init__(self, plugin_spec: PluginSpec) -> None: - """Initialize a GitlabPlugin.""" - - full_name = urllib.parse.quote(f"{plugin_spec.owner}/{plugin_spec.repo}", safe="") - repo_info = self._api_call(f"projects/{full_name}") - default_branch = plugin_spec.branch or repo_info["default_branch"] - api_callback = self._api_call(f"projects/{full_name}/repository/branches/{default_branch}") - latest_commit = api_callback["commit"] - sha = latest_commit["id"] - - self.name = plugin_spec.name - self.owner = plugin_spec.owner - self.version = parse(latest_commit["created_at"]).date() - self.source = UrlSource(f"https://gitlab.com/api/v4/projects/{full_name}/repository/archive.tar.gz?sha={sha}") - self.description = (repo_info.get("description") or "").replace('"', '\\"') - self.homepage = repo_info["web_url"] - self.license = plugin_spec.license or License.from_spdx_id(repo_info.get("license", {}).get("key")) - self.source_line = plugin_spec.line - - def _api_call(self, path: str) -> dict: - """Call the Gitlab API.""" - url = f"https://gitlab.com/api/v4/{path}" - response = requests.get(url) - if response.status_code != 200: - raise RuntimeError(f"Gitlab API call failed: {response.text}") - return response.json() - - -def _get_sourcehut_token(): - token = os.environ.get("SOURCEHUT_TOKEN") - if token is None: - # NOTE: This should never use more than the free requests <2023-12-09> - pass - # logger.warning("SOURCEHUT_TOKEN environment variable not set") - return token - - -class SourceHutPlugin(VimPlugin): - def __init__(self, plugin_spec: PluginSpec) -> None: - """Initialize a SourceHutPlugin.""" - - repo_info = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}") - if plugin_spec.branch is None: - commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log") - else: - commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log/{plugin_spec.branch}") - latest_commit = commits["results"][0] - sha = latest_commit["id"] - - self.name = plugin_spec.name - self.owner = plugin_spec.owner - self.version = parse(latest_commit["timestamp"]).date() - self.description = (repo_info.get("description") or "").replace('"', '\\"') - self.homepage = f"https://git.sr.ht/~{plugin_spec.owner}/{plugin_spec.repo}" - self.source = GitSource(self.homepage, sha) - self.license = plugin_spec.license or License.UNKNOWN # cannot be determined via API - self.source_line = plugin_spec.line - - def _api_call(self, path: str, token: str | None = _get_sourcehut_token()): - """Call the SourceHut API.""" - - url = f"https://git.sr.ht/api/{path}" - headers = {"Content-Type": "application/json"} - if token is not None: - headers["Authorization"] = f"token {token}" - response = requests.get(url, headers=headers) - if response.status_code != 200: - raise RuntimeError(f"SourceHut API call failed: {response.json()}") - return response.json() - - -def plugin_from_spec(plugin_spec: PluginSpec) -> VimPlugin: - """Initialize a VimPlugin.""" - - if plugin_spec.repository_host == RepositoryHost.GITHUB: - return GitHubPlugin(plugin_spec) - elif plugin_spec.repository_host == RepositoryHost.GITLAB: - return GitlabPlugin(plugin_spec) - elif plugin_spec.repository_host == RepositoryHost.SOURCEHUT: - return SourceHutPlugin(plugin_spec) - else: - raise NotImplementedError(f"Unsupported source: {plugin_spec.repository_host}") diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/spec.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/spec.py deleted file mode 100644 index 0f2fb29c..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/spec.py +++ /dev/null @@ -1,143 +0,0 @@ -import enum -import re - -from .nix import License - - -class RepositoryHost(enum.Enum): - """A repository host.""" - - GITHUB = "github" - GITLAB = "gitlab" - SOURCEHUT = "sourcehut" - - -class PluginSpec: - """A Vim plugin Spec.""" - - @classmethod - def from_spec(cls, spec): - """The spec line must be in the format: - [:]/[:][:name]. - - repository_host is one of github (default), gitlab, or sourcehut. - owner is the repository owner. - repo is the repository name. - branch is the git branch. - name is the name to use for the plugin (default is value of repo). - """ - repository_host = RepositoryHost.GITHUB - # gitref = "master" - - repository_host_regex = r"((?P[^:]+):)" - owner_regex = r"(?P[^/:]+)" - repo_regex = r"(?P[^:]+)" - branch_regex = r"(:(?P[^:]+)?)" - name_regex = r"(:(?P[^:]+)?)" - license_regex = r"(:(?P[^:]+)?)" - marked_duplicate_regex = r"(:(?Pduplicate))" - - spec_regex = re.compile( - f"^{repository_host_regex}?{owner_regex}/{repo_regex}{branch_regex}?{name_regex}?{license_regex}?{marked_duplicate_regex}?$", - ) - - match = spec_regex.match(spec) - if match is None: - raise ValueError(f"Invalid spec: {spec}") - - group_dict = match.groupdict() - - repository_host = RepositoryHost(group_dict.get("repository_host") or "github") - - owner = group_dict.get("owner") - if owner is None: - raise RuntimeError("Could not get owner") - - repo = group_dict.get("repo") - if repo is None: - raise RuntimeError("Could not get repo") - - branch = group_dict.get("branch") - name = group_dict.get("name") - license = group_dict.get("license") - marked_duplicate = bool(group_dict.get("duplicate")) # True if 'duplicate', False if None - - line = spec - - return cls(repository_host, owner, repo, line, branch, name, license, marked_duplicate) - - def __init__( - self, - repository_host: RepositoryHost, - owner: str, - repo: str, - line: str, - branch: str | None = None, - name: str | None = None, - license: str | None = None, - marked_duplicate: bool = False, - ) -> None: - """Initialize a VimPluginSpec.""" - self.repository_host = repository_host - self.owner = owner - self.repo = repo - self.branch = branch - self.custom_name = name - self.name = name or repo.replace(".", "-").replace("_", "-") - self.license = License(license) if license else None - self.line = line - self.marked_duplicate = marked_duplicate - - def __str__(self) -> str: - """Return a string representation of a VimPluginSpec.""" - spec = "" - - if self.repository_host != RepositoryHost.GITHUB: - spec += f"{self.repository_host.value}:" - - spec += f"{self.owner}/{self.repo}" - - spec += ":" - if self.branch is not None: - spec += self.branch - - spec += ":" - if self.custom_name is not None: - spec += self.custom_name - - spec += ":" - if self.license is not None: - spec += str(self.license) - - spec += ":" - if self.marked_duplicate: - spec += "duplicate" - - return spec.rstrip(":") - - def __repr__(self): - """Return the representation of the specs""" - return f"PluginSpec({self.owner}/{self.repo}, {self.name})" - - def to_spec(self): - """Return a spec line for a VimPluginSpec.""" - return str(self) - - def __lt__(self, o: object) -> bool: - if not isinstance(o, PluginSpec): - return False - - return self.name.lower() < o.name.lower() - - def __eq__(self, o: object) -> bool: - """Return True if the two specs are equal.""" - if not isinstance(o, PluginSpec): - return False - - return ( - self.repository_host == o.repository_host - and self.owner == o.owner - and self.repo == o.repo - and self.branch == o.branch - and self.name == o.name - ) diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/__init__.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/fixtures.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/fixtures.py deleted file mode 100644 index 75dd251a..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/fixtures.py +++ /dev/null @@ -1,44 +0,0 @@ -import json - -import pytest -from pytest_mock import MockerFixture - -from update_vim_plugins.nix import GitSource, UrlSource - - -@pytest.fixture() -def url(): - return "https://example.com" - - -@pytest.fixture() -def rev(): - return "1234567890abcdef" - - -@pytest.fixture() -def sha256(): - return "sha256-1234567890abcdef" - - -@pytest.fixture() -def url_source(mocker: MockerFixture, url: str, sha256: str): - mocker.patch("subprocess.check_output", return_value=bytes(sha256, "utf-8")) - return UrlSource(url) - - -@pytest.fixture() -def git_source(mocker: MockerFixture, url: str, rev: str, sha256: str): - return_value = { - "url": url, - "rev": rev, - "date": "1970-01-01T00:00:00+00:00", - "path": "", - "sha256": sha256, - "fetchLFS": False, - "fetchSubmodules": False, - "deepClone": False, - "leaveDotGit": False, - } - mocker.patch("subprocess.check_output", return_value=json.dumps(return_value).encode("utf-8")) - return GitSource(url, rev) diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_nix.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_nix.py deleted file mode 100644 index 46e59f76..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_nix.py +++ /dev/null @@ -1,32 +0,0 @@ -from update_vim_plugins.nix import GitSource, License, UrlSource - - -def test_url_source(url_source: UrlSource, url: str, sha256: str): - assert url_source.url == url - assert url_source.sha256 == sha256 - - -def test_url_source_nix_expression(url_source: UrlSource, url: str, sha256: str): - assert url_source.get_nix_expression() == f'fetchurl {{ url = "{url}"; sha256 = "{sha256}"; }}' - - -def test_git_source(git_source: GitSource, url: str, rev: str, sha256: str): - assert git_source.url == url - assert git_source.sha256 == sha256 - assert git_source.rev == rev - - -def test_git_source_nix_expression(git_source: GitSource, url: str, rev: str, sha256: str): - assert git_source.get_nix_expression() == f'fetchgit {{ url = "{url}"; rev = "{rev}"; sha256 = "{sha256}"; }}' - - -def test_license_github(): - github_license = "MIT" - license = License.from_spdx_id(github_license) - assert license == License.MIT - - -def test_license_gitlab(): - gitlab_license = "mit" - license = License.from_spdx_id(gitlab_license) - assert license == License.MIT diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_plugin.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_plugin.py deleted file mode 100644 index 32377e24..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_plugin.py +++ /dev/null @@ -1,144 +0,0 @@ -import json -from typing import Callable - -import pytest -from pytest_mock import MockFixture - -from update_vim_plugins.nix import License, UrlSource -from update_vim_plugins.plugin import GitHubPlugin, VimPlugin -from update_vim_plugins.spec import PluginSpec - - -@pytest.fixture() -def mock_source(sha256: str): - class MockSource: - def __init__(self, *args, **kwargs): - pass - - def get_nix_expression(self): - return "src" - - return MockSource() - - -@pytest.fixture() -def mock_plugin(mock_source): - class MockVimPlugin(VimPlugin): - def __init__(self): - self.name = "test" - self.version = "1.0.0" - self.source = mock_source - self.description = "No description" - self.homepage = "https://example.com" - self.license = License.UNKNOWN - - return MockVimPlugin() - - -def test_vim_plugin_nix_expression(mock_plugin): - assert ( - mock_plugin.get_nix_expression() - == 'test = buildVimPluginFrom2Nix { pname = "test"; version = "1.0.0"; src = src; meta = with lib; { description = "No description"; homepage = "https://example.com"; license = with licenses; [ ]; }; };' - ) - - -class MockResponse: - def __init__(self, status_code: int, content: bytes): - self.status_code = status_code - self.content = content - - def json(self): - return json.loads(self.content) - - -def mock_request_get(repsonses: dict[str, MockResponse]): - respones_not_found = MockResponse(404, b'{"message": "Not Found"}') - - def mock_get(url: str, *args, **kwargs): - return repsonses.get(url, respones_not_found) - - return mock_get - - -@pytest.fixture() -def github_commits_response(): - return MockResponse( - 200, - json.dumps( - { - "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", - "commit": { - "committer": { - "date": "2011-04-14T16:00:49Z", - }, - }, - } - ), - ) - - -@pytest.fixture() -def github_get(github_commits_response: MockResponse): - repos_response = MockResponse( - 200, - json.dumps( - { - "html_url": "https://github.com/octocat/Hello-World", - "description": "This your first repo!", - "fork": False, - "default_branch": "master", - "license": { - "spdx_id": "MIT", - }, - } - ), - ) - responses = { - "https://api.github.com/repos/octocat/Hello-World": repos_response, - "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response, - } - return mock_request_get(responses) - - -@pytest.fixture() -def github_get_no_license(github_commits_response: MockResponse): - repos_response = MockResponse( - 200, - json.dumps( - { - "html_url": "https://github.com/octocat/Hello-World", - "description": "This your first repo!", - "fork": False, - "default_branch": "master", - } - ), - ) - responses = { - "https://api.github.com/repos/octocat/Hello-World": repos_response, - "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response, - } - return mock_request_get(responses) - - -def test_github_plugin(mocker: MockFixture, github_get: Callable, url_source: UrlSource): - mocker.patch("requests.get", github_get) - url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source) - - spec = PluginSpec.from_spec("octocat/Hello-World") - plugin = GitHubPlugin(spec) - - assert plugin.name == "Hello-World" - assert plugin.version == "2011-04-14" - assert plugin.description == "This your first repo!" - assert plugin.homepage == "https://github.com/octocat/Hello-World" - assert plugin.license == License.MIT - - -def test_github_plugin_no_license(mocker: MockFixture, github_get_no_license: Callable, url_source: UrlSource): - mocker.patch("requests.get", github_get_no_license) - url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source) - - spec = PluginSpec.from_spec("octocat/Hello-World") - plugin = GitHubPlugin(spec) - - assert plugin.license == License.UNKNOWN diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_spec.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_spec.py deleted file mode 100644 index 2b9a1d24..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/tests/test_spec.py +++ /dev/null @@ -1,136 +0,0 @@ -import pytest - -from update_vim_plugins.spec import PluginSpec, RepositoryHost - - -@pytest.fixture() -def owner(): - return "owner" - - -@pytest.fixture() -def repo(): - return "repo.nvim" - - -@pytest.fixture() -def branch(): - return "main" - - -@pytest.fixture() -def name(): - return "repo-nvim" - - -@pytest.fixture() -def license(): - return "mit" - - -def test_from_spec_simple(owner: str, repo: str): - vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}") - - assert vim_plugin.owner == owner - assert vim_plugin.repo == repo - - -def test_from_spec_with_gitref(owner: str, repo: str, branch: str): - vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}:{branch}") - - assert vim_plugin.branch == branch - - -def test_from_spec_with_name(owner: str, repo: str, name: str): - vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}::{name}") - - assert vim_plugin.name == name - - -@pytest.mark.parametrize("host", RepositoryHost) -def test_from_spec_with_repository_host(owner: str, repo: str, host: RepositoryHost): - vim_plugin = PluginSpec.from_spec(f"{host.value}:{owner}/{repo}") - - assert vim_plugin.repository_host == host - - -def test_from_spec_without_repository_host(owner: str, repo: str): - vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}") - - assert vim_plugin.repository_host == RepositoryHost.GITHUB - - -def test_from_spec_complex(owner: str, repo: str, branch: str, name: str): - vim_plugin = PluginSpec.from_spec(f"gitlab:{owner}/{repo}:{branch}:{name}") - - assert vim_plugin.repository_host == RepositoryHost.GITLAB - assert vim_plugin.owner == owner - assert vim_plugin.repo == repo - assert vim_plugin.branch == branch - assert vim_plugin.name == name - - -def test_from_spec_invalid_spec(): - with pytest.raises(ValueError): - PluginSpec.from_spec("invalid_spec") - - -def test_to_spec_simple(owner: str, repo: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) - - assert vim_plugin.to_spec() == f"{owner}/{repo}" - - -def test_to_spec_with_branch(owner: str, repo: str, branch: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch=branch) - assert vim_plugin.to_spec() == f"{owner}/{repo}:{branch}" - - -def test_to_spec_with_name(owner: str, repo: str, name: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name) - - assert vim_plugin.to_spec() == f"{owner}/{repo}::{name}" - - -@pytest.mark.parametrize("host", [RepositoryHost.GITLAB, RepositoryHost.SOURCEHUT]) -def test_to_spec_with_repository_host(host: RepositoryHost, owner: str, repo: str): - vim_plugin = PluginSpec(host, owner, repo) - - assert vim_plugin.to_spec() == f"{host.value}:{owner}/{repo}" - - -def test_to_spec_complex(owner: str, repo: str, branch: str, name: str, license: str): - vim_plugin = PluginSpec(RepositoryHost.GITLAB, owner, repo, branch=branch, name=name, license=license) - - assert vim_plugin.to_spec() == f"gitlab:{owner}/{repo}:{branch}:{name}:{license}" - - -def test_spec_equal(owner: str, repo: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) - vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo) - - assert vim_plugin == vim_plugin2 - - -def test_spec_not_equal_different_branch(owner: str, repo: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) - vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch="main") - - assert vim_plugin != vim_plugin2 - - -def test_spec_not_equal_different_name(owner: str, repo: str): - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) - vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name="renamed") - - assert vim_plugin != vim_plugin2 - - -def test_spec_equal_same_normalized_name(owner: str): - repo = "repo.nvim" - name = "repo-nvim" - - vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo) - vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name) - - assert vim_plugin == vim_plugin2 diff --git a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/update.py b/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/update.py deleted file mode 100644 index 7eb3eeb4..00000000 --- a/sys/nixpkgs/pkgs/update_vim_plugins/update_vim_plugins/update.py +++ /dev/null @@ -1,212 +0,0 @@ -import subprocess -from random import shuffle -from cleo.helpers import argument, option -from cleo.commands.command import Command -from concurrent.futures import ThreadPoolExecutor, as_completed - -from pprint import pprint - -from .plugin import plugin_from_spec - -from .helpers import read_manifest_to_spec, get_const -from .helpers import JSON_FILE, PLUGINS_LIST_FILE, PKGS_FILE - -import json -import jsonpickle - -jsonpickle.set_encoder_options("json", sort_keys=True) - - -class UpdateCommand(Command): - name = "update" - description = "Generate nix module from input file" - arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)] - options = [ - option("all", "a", description="Update all plugins. Else only update new plugins", flag=True), - option("dry-run", "d", description="Show which plugins would be updated", flag=True), - ] - - def handle(self): - """Main command function""" - - plug_dir = self.argument("plug_dir") - self.specs = read_manifest_to_spec(plug_dir) - - if self.option("all"): - # update all plugins - spec_list = self.specs - known_plugins = [] - else: - # filter plugins we already know - spec_list = self.specs - - with open(get_const(JSON_FILE, plug_dir), "r") as json_file: - data = json.load(json_file) - - known_specs = list(filter(lambda x: x.line in data, spec_list)) - known_plugins = [jsonpickle.decode(data[x.line]) for x in known_specs] - - spec_list = list(filter(lambda x: x.line not in data, spec_list)) - - if self.option("dry-run"): - self.line("These plugins would be updated") - pprint(spec_list) - self.line(f"Total: {len(spec_list)}") - exit(0) - - processed_plugins, failed_plugins, failed_but_known = self.process_manifest(spec_list, plug_dir) - - processed_plugins += known_plugins # add plugins from .plugins.json - processed_plugins: list = sorted(set(processed_plugins)) # remove duplicates based only on source line - - self.check_duplicates(processed_plugins) - - if failed_plugins != []: - self.line("Not processed: The following plugins could not be updated") - for s, e in failed_plugins: - self.line(f" - {s!r} - {e}") - - if failed_but_known != []: - self.line( - "Not updated: The following plugins could not be updated but an older version is known" - ) - for s, e in failed_but_known: - self.line(f" - {s!r} - {e}") - - # update plugin "database" - self.write_plugins_json(processed_plugins, plug_dir) - - # generate output - self.write_plugins_nix(processed_plugins, plug_dir) - - self.write_plugins_markdown(processed_plugins, plug_dir) - - self.line("Done") - - def write_plugins_markdown(self, plugins, plug_dir): - """Write the list of all plugins to PLUGINS_LIST_FILE in markdown""" - - plugins.sort() - - self.line("Updating plugins.md") - - header = f" - Plugin count: {len(plugins)}\n\n| Repo | Last Update | Nix package name | Last checked |\n|:---|:---|:---|:---|\n" - - with open(get_const(PLUGINS_LIST_FILE, plug_dir), "w") as file: - file.write(header) - for plugin in plugins: - file.write(f"{plugin.to_markdown()}\n") - - def write_plugins_nix(self, plugins, plug_dir): - self.line("Generating nix output") - - plugins.sort() - - header = "{ lib, buildVimPlugin, fetchurl, fetchgit }: {" - footer = "}" - - with open(get_const(PKGS_FILE, plug_dir), "w") as file: - file.write(header) - for plugin in plugins: - file.write(f"{plugin.to_nix()}\n") - file.write(footer) - - self.line("Formatting nix output") - - subprocess.run( - ["alejandra", get_const(PKGS_FILE, plug_dir)], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - - def write_plugins_json(self, plugins, plug_dir): - self.line("Storing results in .plugins.json") - - plugins.sort() - - with open(get_const(JSON_FILE, plug_dir), "r+") as json_file: - data = json.load(json_file) - - for plugin in plugins: - data.update({f"{plugin.source_line}": plugin.to_json()}) - - json_file.seek(0) - json_file.write(json.dumps(data, indent=2, sort_keys=True)) - json_file.truncate() - - def check_duplicates(self, plugins): - """check for duplicates in proccesed_plugins""" - error = False - for i, plugin in enumerate(plugins): - for p in plugins[i + 1 :]: - if plugin.name == p.name: - self.line( - f"Error: The following two lines produce the same plugin name:\n - {plugin.source_line}\n - {p.source_line}\n -> {p.name}" - ) - error = True - - # We want to exit if the resulting nix file would be broken - # But we want to go through all plugins before we do so - if error: - exit(1) - - def generate_plugin(self, spec, i, size, plug_dir): - debug_string = "" - - processed_plugin = None - failed_but_known = None - failed_plugin = None - try: - debug_string += f" - ({i+1}/{size}) Processing {spec!r}\n" - vim_plugin = plugin_from_spec(spec) - debug_string += f" • Success {vim_plugin!r}\n" - processed_plugin = vim_plugin - except Exception as e: - debug_string += f" • Error: Could not update {spec.name}. Keeping old values. Reason: {e}\n" - with open(get_const(JSON_FILE, plug_dir), "r") as json_file: - data = json.load(json_file) - - plugin_json = data.get(spec.line) - if plugin_json: - vim_plugin = jsonpickle.decode(plugin_json) - processed_plugin = vim_plugin - failed_but_known = (vim_plugin, e) - else: - debug_string += f" • Error: No entries for {spec.name} in '.plugins.json'. Skipping...\n" - failed_plugin = (spec, e) - - self.line(debug_string.strip()) - - return processed_plugin, failed_plugin, failed_but_known - - def process_manifest(self, spec_list, plug_dir): - """Read specs in 'spec_list' and generate plugins""" - - size = len(spec_list) - - # We have to assume that we will reach an api limit. Therefore - # we randomize the spec list to give every entry the same change to be updated and - # not favor those at the start of the list - shuffle(spec_list) - - with ThreadPoolExecutor() as executor: - futures = [ - executor.submit(self.generate_plugin, spec, i, size, plug_dir) for i, spec in enumerate(spec_list) - ] - results = [future.result() for future in as_completed(futures)] - - processed_plugins = [r[0] for r in results] - failed_plugins = [r[1] for r in results] - failed_but_known = [r[2] for r in results] - - processed_plugins = list(filter(lambda x: x is not None, processed_plugins)) - failed_plugins = list(filter(lambda x: x is not None, failed_plugins)) - failed_but_known = list(filter(lambda x: x is not None, failed_but_known)) - - processed_plugins.sort() - failed_plugins.sort() - failed_but_known.sort() - - assert len(processed_plugins) == len(spec_list) - len(failed_plugins) - - return processed_plugins, failed_plugins, failed_but_known diff --git a/sys/nixpkgs/pkgs/yt/.env b/sys/nixpkgs/pkgs/yt/.env deleted file mode 100755 index 8018a738..00000000 --- a/sys/nixpkgs/pkgs/yt/.env +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -PATH="$(pwd)/target/release/:$(pwd)/target/debug/:$PATH" diff --git a/sys/nixpkgs/pkgs/yt/.envrc b/sys/nixpkgs/pkgs/yt/.envrc deleted file mode 100644 index 3550a30f..00000000 --- a/sys/nixpkgs/pkgs/yt/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/sys/nixpkgs/pkgs/yt/.gitignore b/sys/nixpkgs/pkgs/yt/.gitignore deleted file mode 100644 index c84fa049..00000000 --- a/sys/nixpkgs/pkgs/yt/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# build dirs -/target -/result diff --git a/sys/nixpkgs/pkgs/yt/Cargo.lock b/sys/nixpkgs/pkgs/yt/Cargo.lock deleted file mode 100644 index ef2a53fd..00000000 --- a/sys/nixpkgs/pkgs/yt/Cargo.lock +++ /dev/null @@ -1,640 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "anyhow" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets", -] - -[[package]] -name = "clap" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "cli-log" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d2ab00dc4c82ec28af25ac085aecc11ffeabf353755715a3113a7aa044ca5cc" -dependencies = [ - "chrono", - "file-size", - "log", - "proc-status", -] - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "file-size" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9544f10105d33957765016b8a9baea7e689bf1f0f2f32c2fa2f568770c38d2b3" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.154" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "proc-macro2" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-status" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e0c0ac915e7b76b47850ba4ffc377abde6c6ff9eeace61d0a89623db449712" -dependencies = [ - "thiserror", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys", -] - -[[package]] -name = "thiserror" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -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.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "yt" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "cli-log", - "log", - "serde", - "serde_json", - "tempfile", - "url", -] diff --git a/sys/nixpkgs/pkgs/yt/Cargo.toml b/sys/nixpkgs/pkgs/yt/Cargo.toml deleted file mode 100644 index 7c17d20b..00000000 --- a/sys/nixpkgs/pkgs/yt/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "yt" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.83" -clap = { version = "4.5.4", features = ["derive"] } -cli-log = "2.0.0" -log = "0.4.21" -serde = { version = "1.0.201", features = ["derive"] } -serde_json = "1.0.117" -tempfile = "3.10.1" -url = "2.5.0" - -# This is here to be able to tell nix which binary to build -[features] -yts = [] -ytc = [] -yt = [] -default = ["yt", "yts", "ytc"] - -[[bin]] -name = "yts" -required-features = ["yts"] - -[[bin]] -name = "ytc" -required-features = ["ytc"] - -[[bin]] -name = "yt" -required-features = ["yt"] diff --git a/sys/nixpkgs/pkgs/yt/default.nix b/sys/nixpkgs/pkgs/yt/default.nix deleted file mode 100644 index 32396051..00000000 --- a/sys/nixpkgs/pkgs/yt/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -[ - ( - final: prev: { - yt = import ./yt.nix { - inherit - (prev) - lib - makeWrapper - rustPlatform - # dependencies - - ytcc - yt-dlp - mpv - ; - }; - } - ) - ( - final: prev: { - yts = import ./yts.nix { - inherit - (prev) - lib - makeWrapper - rustPlatform - # dependencies - - ytcc - ; - }; - } - ) - ( - final: prev: { - ytc = import ./ytc.nix { - inherit - (prev) - lib - makeWrapper - rustPlatform - # dependencies - - ytcc - yt-dlp - mpv - ; - }; - } - ) -] diff --git a/sys/nixpkgs/pkgs/yt/flake.lock b/sys/nixpkgs/pkgs/yt/flake.lock deleted file mode 100644 index 50494465..00000000 --- a/sys/nixpkgs/pkgs/yt/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1715087517, - "narHash": "sha256-CLU5Tsg24Ke4+7sH8azHWXKd0CFd4mhLWfhYgUiDBpQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b211b392b8486ee79df6cdfb1157ad2133427a29", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/sys/nixpkgs/pkgs/yt/flake.nix b/sys/nixpkgs/pkgs/yt/flake.nix deleted file mode 100644 index 561b1c0d..00000000 --- a/sys/nixpkgs/pkgs/yt/flake.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - description = "yt"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - }: (flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages."${system}"; - in { - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - # rust stuff - cargo - clippy - rustc - rustfmt - - cargo-edit - cargo-expand - ]; - }; - })); -} diff --git a/sys/nixpkgs/pkgs/yt/src/bin/yt/main.rs b/sys/nixpkgs/pkgs/yt/src/bin/yt/main.rs deleted file mode 100644 index 37348834..00000000 --- a/sys/nixpkgs/pkgs/yt/src/bin/yt/main.rs +++ /dev/null @@ -1,91 +0,0 @@ -use anyhow::{bail, Context, Result}; -use std::{ - env, fs, - io::{BufRead, BufReader, BufWriter, Write}, - process::Command as StdCmd, -}; -use tempfile::Builder; -use yt::{ - constants::{last_select, HELP_STR}, - downloader::Downloader, - filter_line, YtccListData, -}; - -fn main() -> Result<()> { - cli_log::init_cli_log!(); - - let json_map = { - let mut ytcc = StdCmd::new("ytcc"); - ytcc.args([ - "--output", - "json", - "list", - "--order-by", - "publish_date", - "desc", - ]); - - serde_json::from_slice::>( - &ytcc.output().context("Failed to json from ytcc")?.stdout, - ) - .context("Failed to deserialize json output")? - }; - - let temp_file = Builder::new() - .prefix("yt_video_select-") - .suffix(".yts") - .rand_bytes(6) - .tempfile() - .context("Failed to get tempfile")?; - - { - let mut edit_file = BufWriter::new(&temp_file); - - json_map.iter().for_each(|line| { - let line = line.to_string(); - edit_file - .write_all(line.as_bytes()) - .expect("This write should not fail"); - }); - - edit_file.write_all(HELP_STR.as_bytes())?; - edit_file.flush().context("Failed to flush edit file")?; - - let mut nvim = StdCmd::new("nvim"); - nvim.arg(temp_file.path()); - let status = nvim.status().context("Falied to run nvim")?; - if !status.success() { - bail!("nvim exited with error status: {}", status) - } - } - - let read_file = temp_file.reopen()?; - fs::copy( - temp_file.path(), - last_select().context("Failed to get the persistent selection file path")?, - ) - .context("Failed to persist selection file")?; - - let mut watching = Vec::new(); - let reader = BufReader::new(&read_file); - for line in reader.lines() { - let line = line.context("Failed to read line")?; - - if let Some(downloadable) = - filter_line(&line).with_context(|| format!("Failed to process line: '{}'", line))? - { - watching.push(downloadable); - } - } - - if watching.is_empty() { - return Ok(()); - } - - let downloader = Downloader::new(watching).context("Failed to construct downloader")?; - downloader - .consume() - .context("Failed to consume downloader")?; - - Ok(()) -} diff --git a/sys/nixpkgs/pkgs/yt/src/bin/ytc/args.rs b/sys/nixpkgs/pkgs/yt/src/bin/ytc/args.rs deleted file mode 100644 index 8b2d6a61..00000000 --- a/sys/nixpkgs/pkgs/yt/src/bin/ytc/args.rs +++ /dev/null @@ -1,26 +0,0 @@ -use clap::{Parser, Subcommand}; -/// A helper for downloading and playing youtube videos -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -pub struct Args { - #[command(subcommand)] - /// The subcommand to execute - pub subcommand: Command, -} -#[derive(Subcommand, Debug)] -pub enum Command { - #[clap(value_parser)] - /// Work based of ytcc ids - Id { - #[clap(value_parser)] - /// A list of ids to play - ids: Vec, - }, - #[clap(value_parser)] - /// Work based of raw youtube urls - Url { - #[clap(value_parser)] - /// A list of urls to play - urls: Vec, - }, -} diff --git a/sys/nixpkgs/pkgs/yt/src/bin/ytc/main.rs b/sys/nixpkgs/pkgs/yt/src/bin/ytc/main.rs deleted file mode 100644 index b38157df..00000000 --- a/sys/nixpkgs/pkgs/yt/src/bin/ytc/main.rs +++ /dev/null @@ -1,77 +0,0 @@ -use std::{env, process::Command as StdCmd}; - -use anyhow::{bail, Context, Result}; -use clap::Parser; -use log::debug; -use url::Url; -use yt::{ - downloader::{Downloadable, Downloader}, - YtccListData, -}; - -use crate::args::{Args, Command}; - -mod args; - -fn main() -> Result<()> { - let args = Args::parse(); - cli_log::init_cli_log!(); - - let playspec: Vec = match args.subcommand { - Command::Id { ids } => { - let mut output = Vec::with_capacity(ids.len()); - for id in ids { - debug!("Adding {}", id); - let mut ytcc = StdCmd::new("ytcc"); - ytcc.args([ - "--output", - "json", - "list", - "--watched", - "--unwatched", - "--attributes", - "url", - "--ids", - id.to_string().as_str(), - ]); - let json = serde_json::from_slice::>( - &ytcc.output().context("Failed to get url from id")?.stdout, - ) - .context("Failed to deserialize json output")?; - - if json.is_empty() { - bail!("Could not find a video with id: {}", id); - } - assert_eq!(json.len(), 1); - let json = json.first().expect("Has only one element"); - - debug!("Id resolved to: '{}'", &json.url); - - output.push(Downloadable { - url: Url::parse(&json.url)?, - id: Some(json.id), - }) - } - output - } - Command::Url { urls } => { - let mut output = Vec::with_capacity(urls.len()); - for url in urls { - output.push(Downloadable { - url: Url::parse(&url).context("Failed to parse url")?, - id: None, - }) - } - output - } - }; - - debug!("Initializing downloader"); - let downloader = Downloader::new(playspec)?; - - downloader - .consume() - .context("Failed to consume downloader")?; - - Ok(()) -} diff --git a/sys/nixpkgs/pkgs/yt/src/bin/yts/args.rs b/sys/nixpkgs/pkgs/yt/src/bin/yts/args.rs deleted file mode 100644 index 56989421..00000000 --- a/sys/nixpkgs/pkgs/yt/src/bin/yts/args.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clap::{Parser, Subcommand}; -/// A helper for selecting which videos to download from ytcc to ytc -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -pub struct Args { - #[command(subcommand)] - /// subcommand to execute - pub subcommand: Option, -} - -#[derive(Subcommand, Debug)] -pub enum Command { - #[clap(value_parser)] - /// Which ordering to use - Order { - #[command(subcommand)] - command: OrderCommand, - }, -} - -#[derive(Subcommand, Debug)] -pub enum OrderCommand { - #[clap(value_parser)] - /// Order by date - #[group(required = true)] - Date { - #[arg(value_parser)] - /// Order descending - desc: bool, - #[clap(value_parser)] - /// Order ascending - asc: bool, - }, - #[clap(value_parser)] - /// Pass a raw SQL 'ORDER BY' value - Raw { - #[clap(value_parser)] - /// The raw value(s) to pass - value: Vec, - }, -} diff --git a/sys/nixpkgs/pkgs/yt/src/bin/yts/main.rs b/sys/nixpkgs/pkgs/yt/src/bin/yts/main.rs deleted file mode 100644 index 7398db61..00000000 --- a/sys/nixpkgs/pkgs/yt/src/bin/yts/main.rs +++ /dev/null @@ -1,91 +0,0 @@ -use anyhow::{bail, Context, Result}; -use clap::Parser; -use std::{ - env, - io::{BufRead, BufReader, Write}, - process::Command as StdCmd, -}; -use tempfile::NamedTempFile; -use yt::{constants::HELP_STR, filter_line, YtccListData}; - -use crate::args::{Args, Command, OrderCommand}; - -mod args; - -fn main() -> Result<()> { - let args = Args::parse(); - cli_log::init_cli_log!(); - - let ordering = match args.subcommand.unwrap_or(Command::Order { - command: OrderCommand::Date { - desc: true, - asc: false, - }, - }) { - Command::Order { command } => match command { - OrderCommand::Date { desc, asc } => { - if desc { - vec!["--order-by".into(), "publish_date".into(), "desc".into()] - } else if asc { - vec!["--order-by".into(), "publish_date".into(), "asc".into()] - } else { - vec!["--order-by".into(), "publish_date".into(), "desc".into()] - } - } - OrderCommand::Raw { value } => [vec!["--order-by".into()], value].concat(), - }, - }; - - let json_map = { - let mut ytcc = StdCmd::new("ytcc"); - ytcc.args(["--output", "json", "list"]); - ytcc.args(ordering); - - serde_json::from_slice::>( - &ytcc.output().context("Failed to json from ytcc")?.stdout, - ) - .context("Failed to deserialize json output")? - }; - - let mut edit_file = NamedTempFile::new().context("Failed to get tempfile")?; - - json_map.iter().for_each(|line| { - let line = line.to_string(); - edit_file - .write_all(line.as_bytes()) - .expect("This write should not fail"); - }); - - write!(&edit_file, "{}", HELP_STR)?; - edit_file.flush().context("Failed to flush edit file")?; - - let read_file = edit_file.reopen()?; - - let mut nvim = StdCmd::new("nvim"); - nvim.arg(edit_file.path()); - - let status = nvim.status().context("Falied to run nvim")?; - if !status.success() { - bail!("Nvim exited with error status: {}", status) - } - - let mut watching = Vec::new(); - let reader = BufReader::new(&read_file); - for line in reader.lines() { - let line = line.context("Failed to read line")?; - - if let Some(downloadable) = - filter_line(&line).with_context(|| format!("Failed to process line: '{}'", line))? - { - watching.push(downloadable); - } - } - - let watching: String = watching - .iter() - .map(|d| d.to_string()) - .collect::>() - .join("\n"); - println!("{}", &watching); - Ok(()) -} diff --git a/sys/nixpkgs/pkgs/yt/src/constants.rs b/sys/nixpkgs/pkgs/yt/src/constants.rs deleted file mode 100644 index 5e233656..00000000 --- a/sys/nixpkgs/pkgs/yt/src/constants.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::{env, fs, path::PathBuf}; - -pub const HELP_STR: &str = include_str!("./help.str"); - -pub const YT_DLP_FLAGS: [&str; 13] = [ - // Ignore errors arising of unavailable sponsor block API - "--ignore-errors", - "--format", - "bestvideo[height<=?1080]+bestaudio/best", - "--embed-chapters", - "--progress", - "--write-comments", - "--extractor-args", - "youtube:max_comments=150,all,100;comment_sort=top", - "--write-info-json", - "--sponsorblock-mark", - "default", - "--sponsorblock-remove", - "sponsor", -]; -pub const MPV_FLAGS: [&str; 4] = [ - "--speed=2.7", - "--volume=75", - "--keep-open=yes", - "--msg-level=osd/libass=fatal", -]; - -pub const CONCURRENT: u32 = 5; - -pub const DOWNLOAD_DIR: &str = "/tmp/ytcc"; - -fn get_runtime_path(component: &'static str) -> anyhow::Result { - let out: PathBuf = format!( - "{}/{}", - env::var("XDG_RUNTIME_DIR").expect("This should always exist"), - component - ) - .into(); - fs::create_dir_all(out.parent().expect("Parent should exist"))?; - Ok(out) -} - -const STATUS_PATH: &str = "ytcc/running"; -pub fn status_path() -> anyhow::Result { - get_runtime_path(STATUS_PATH) -} - -const LAST_SELECT: &str = "ytcc/selected.yts"; -pub fn last_select() -> anyhow::Result { - get_runtime_path(LAST_SELECT) -} diff --git a/sys/nixpkgs/pkgs/yt/src/downloader.rs b/sys/nixpkgs/pkgs/yt/src/downloader.rs deleted file mode 100644 index e915700d..00000000 --- a/sys/nixpkgs/pkgs/yt/src/downloader.rs +++ /dev/null @@ -1,212 +0,0 @@ -use std::{ - fs::{self, canonicalize}, - io::{stderr, stdout, Read}, - mem, - os::unix::fs::symlink, - path::PathBuf, - process::Command, - sync::mpsc::{self, Receiver, Sender}, - thread::{self, JoinHandle}, -}; - -use anyhow::{bail, Context, Result}; -use log::{debug, error, warn}; -use url::Url; - -use crate::constants::{status_path, CONCURRENT, DOWNLOAD_DIR, MPV_FLAGS, YT_DLP_FLAGS}; - -#[derive(Debug)] -pub struct Downloadable { - pub url: Url, - pub id: Option, -} - -impl std::fmt::Display for Downloadable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - write!( - f, - "{}|{}", - self.url.as_str().replace('|', ";"), - self.id.unwrap_or(0), - ) - } -} - -pub struct Downloader { - sent: usize, - download_thread: JoinHandle>, - orx: Receiver<(PathBuf, Option)>, - itx: Option>, - playspec: Vec, -} - -impl Downloader { - pub fn new(mut playspec: Vec) -> anyhow::Result { - let (itx, irx): (Sender, Receiver) = mpsc::channel(); - let (otx, orx) = mpsc::channel(); - let jh = thread::spawn(move || -> Result<()> { - while let Ok(pt) = irx.recv() { - debug!("Got '{}' to be downloaded", pt); - let path = download_url(&pt.url) - .with_context(|| format!("Failed to download url: '{}'", &pt.url))?; - otx.send((path, pt.id)).expect("Should not be dropped"); - } - debug!("Finished Downloading everything"); - Ok(()) - }); - - playspec.reverse(); - let mut output = Downloader { - sent: 0, - download_thread: jh, - orx, - itx: Some(itx), - playspec, - }; - if output.playspec.len() <= CONCURRENT as usize { - output.add(output.playspec.len() as u32)?; - } else { - output.add(CONCURRENT)?; - } - Ok(output) - } - - pub fn add(&mut self, number_to_add: u32) -> Result<()> { - debug!("Adding {} to be downloaded concurrently", number_to_add); - for _ in 0..number_to_add { - let pt = self.playspec.pop().expect("This call should be guarded"); - self.itx.as_ref().expect("Should still be valid").send(pt)?; - self.sent += 1; - } - Ok(()) - } - - /// Return the next video already downloaded, will block until the download is complete - pub fn next(&mut self) -> Option<(PathBuf, Option)> { - debug!("Requesting next output"); - match self.orx.recv() { - Ok(ok) => { - debug!("Output downloaded to: {}", ok.0.display()); - if !self.playspec.is_empty() { - self.add(1).ok()?; - } else { - debug!( - "Done sending videos to be downloaded, downoladed: {} videos", - self.sent - ); - let itx = mem::take(&mut self.itx); - drop(itx) - } - debug!("Returning: {}|{}", ok.0.display(), ok.1.unwrap_or(0)); - Some(ok) - } - Err(err) => { - debug!("Received error while listening: {}", err); - None - } - } - } - - pub fn drop(self) -> anyhow::Result<()> { - // Check that we really downloaded everything - assert_eq!(self.playspec.len(), 0); - match self.download_thread.join() { - Ok(ok) => ok, - Err(err) => panic!("Failed to join downloader thread: '{:#?}'", err), - } - } - - pub fn consume(mut self) -> anyhow::Result<()> { - while let Some((path, id)) = self.next() { - debug!("Next path to play is: '{}'", path.display()); - let mut info_json = canonicalize(&path).context("Failed to canoncialize path")?; - info_json.set_extension("info.json"); - - if status_path()?.is_symlink() { - fs::remove_file(status_path()?).context("Failed to delete old status file")?; - } else if !status_path()?.exists() { - debug!( - "The status path at '{}' does not exists", - status_path()?.display() - ); - } else { - bail!( - "The status path ('{}') is not a symlink but exists!", - status_path()?.display() - ); - } - - symlink(info_json, status_path()?).context("Failed to symlink")?; - - let mut mpv = Command::new("mpv"); - mpv.stdout(stdout()); - mpv.stderr(stderr()); - mpv.args(MPV_FLAGS); - // TODO: Set the title to the name of the video, not the path <2024-02-09> - // mpv.arg(format!("--title=")) - mpv.arg(&path); - - let status = mpv.status().context("Failed to run mpv")?; - if status.success() { - fs::remove_file(&path)?; - if let Some(id) = id { - println!("\x1b[32;1mMarking {} as watched!\x1b[0m", id); - let mut ytcc = std::process::Command::new("ytcc"); - ytcc.stdout(stdout()); - ytcc.stderr(stderr()); - ytcc.args(["mark"]); - ytcc.arg(id.to_string()); - let status = ytcc.status().context("Failed to run ytcc")?; - if let Some(code) = status.code() { - if code != 0 { - bail!("Ytcc failed with status: {}", code); - } - } - } - debug!("mpv exited with: '{}'", status); - } else { - warn!("mpv exited with: '{}'", status); - } - } - self.drop()?; - Ok(()) - } -} - -fn download_url(url: &Url) -> Result { - let output_file = tempfile::NamedTempFile::new().context("Failed to create tempfile")?; - output_file - .as_file() - .set_len(0) - .context("Failed to truncate temp-file")?; - if !Into::::into(DOWNLOAD_DIR).exists() { - fs::create_dir_all(DOWNLOAD_DIR) - .with_context(|| format!("Failed to create download dir at: {}", DOWNLOAD_DIR))? - } - let mut yt_dlp = Command::new("yt-dlp"); - yt_dlp.current_dir(DOWNLOAD_DIR); - yt_dlp.stdout(stdout()); - yt_dlp.stderr(stderr()); - yt_dlp.args(YT_DLP_FLAGS); - yt_dlp.args([ - "--output", - "%(channel)s/%(title)s.%(ext)s", - url.as_str(), - "--print-to-file", - "after_move:filepath", - ]); - yt_dlp.arg(output_file.path().as_os_str()); - - let status = yt_dlp.status().context("Failed to run yt-dlp")?; - if !status.success() { - error!("yt-dlp execution failed with error: '{}'", status); - } - - let mut path = String::new(); - output_file - .as_file() - .read_to_string(&mut path) - .context("Failed to read output file temp file")?; - let path = path.trim(); - Ok(path.into()) -} diff --git a/sys/nixpkgs/pkgs/yt/src/help.str b/sys/nixpkgs/pkgs/yt/src/help.str deleted file mode 100644 index 130fe42a..00000000 --- a/sys/nixpkgs/pkgs/yt/src/help.str +++ /dev/null @@ -1,8 +0,0 @@ -# Commands: -# w, watch = watch id -# d, drop = mark id as watched -# u, url = open the associated URL in the `timesinks.youtube` Firefox profile -# p, pick = leave id as is; This is a noop -# -# These lines can be re-ordered; they are executed from top to bottom. -# vim: filetype=yts conceallevel=2 concealcursor=nc colorcolumn= diff --git a/sys/nixpkgs/pkgs/yt/src/lib.rs b/sys/nixpkgs/pkgs/yt/src/lib.rs deleted file mode 100644 index b089c1a2..00000000 --- a/sys/nixpkgs/pkgs/yt/src/lib.rs +++ /dev/null @@ -1,185 +0,0 @@ -use anyhow::{bail, Context}; -use downloader::Downloadable; -use serde::Deserialize; -use url::Url; - -pub mod constants; -pub mod downloader; - -#[derive(Deserialize)] -pub struct YtccListData { - pub url: String, - pub title: String, - pub description: String, - pub publish_date: String, - pub watch_date: Option, - pub duration: String, - pub thumbnail_url: Option, - pub extractor_hash: String, - pub id: u32, - pub playlists: Vec, -} - -impl std::fmt::Display for YtccListData { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - write!( - f, - r#"pick {} "{}" "{}" "{}" "{}" "{}"{}"#, - self.id, - self.title.replace(['"', '„', '”'], "'"), - self.publish_date, - self.playlists - .iter() - .map(|p| p.name.replace('"', "'")) - .collect::>() - .join(", "), - Duration::from(self.duration.trim()), - self.url.replace('"', "'"), - "\n" - ) - } -} - -#[derive(Deserialize)] -pub struct YtccPlaylistData { - pub name: String, - pub url: String, - pub reverse: bool, -} - -pub enum LineCommand { - Pick, - Drop, - Watch, - Url, -} - -impl std::str::FromStr for LineCommand { - type Err = anyhow::Error; - fn from_str(v: &str) -> Result::Err> { - match v { - "pick" | "p" => Ok(Self::Pick), - "drop" | "d" => Ok(Self::Drop), - "watch" | "w" => Ok(Self::Watch), - "url" | "u" => Ok(Self::Url), - other => bail!("'{}' is not a recognized command!", other), - } - } -} - -pub struct Line { - pub cmd: LineCommand, - pub id: u32, - pub url: Url, -} - -/// We expect that each line is correctly formatted, and simply use default ones if they are not -impl From<&str> for Line { - fn from(v: &str) -> Self { - let buf: Vec<_> = v.split_whitespace().collect(); - let url: Url = Url::parse( - buf.last() - .expect("This should always exists") - .trim_matches('"'), - ) - .expect("This parsing should work,as the url is generated"); - - Line { - cmd: buf - .get(0) - .unwrap_or(&"pick") - .parse() - .unwrap_or(LineCommand::Pick), - id: buf.get(1).unwrap_or(&"0").parse().unwrap_or(0), - url, - } - } -} - -pub struct Duration { - time: u32, -} - -impl From<&str> for Duration { - fn from(v: &str) -> Self { - let buf: Vec<_> = v.split(':').take(2).collect(); - Self { - time: (buf[0].parse::().expect("Should be a number") * 60) - + buf[1].parse::().expect("Should be a number"), - } - } -} - -impl std::fmt::Display for Duration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - const SECOND: u32 = 1; - const MINUTE: u32 = 60 * SECOND; - const HOUR: u32 = 60 * MINUTE; - - let base_hour = self.time - (self.time % HOUR); - let base_min = (self.time % HOUR) - ((self.time % HOUR) % MINUTE); - let base_sec = (self.time % HOUR) % MINUTE; - - let h = base_hour / HOUR; - let m = base_min / MINUTE; - let s = base_sec / SECOND; - - if self.time == 0 { - write!(f, "[No Duration]") - } else if h > 0 { - write!(f, "[{h}h {m}m]") - } else { - write!(f, "[{m}m {s}s]") - } - } -} -#[cfg(test)] -mod test { - use crate::Duration; - - #[test] - fn test_display_duration_1h() { - let dur = Duration { time: 60 * 60 }; - assert_eq!("[1h 0m]".to_owned(), dur.to_string()); - } - #[test] - fn test_display_duration_30min() { - let dur = Duration { time: 60 * 30 }; - assert_eq!("[30m 0s]".to_owned(), dur.to_string()); - } -} - -pub fn ytcc_drop(id: u32) -> anyhow::Result<()> { - let mut ytcc = std::process::Command::new("ytcc"); - ytcc.args(["mark", &format!("{}", id)]); - if !ytcc.status().context("Failed to run ytcc")?.success() { - bail!("`ytcc mark {}` failed to execute", id) - } - Ok(()) -} - -pub fn filter_line(line: &str) -> anyhow::Result> { - // Filter out comments and empty lines - if line.starts_with('#') || line.trim().is_empty() { - return Ok(None); - } - - let line = Line::from(line); - match line.cmd { - LineCommand::Pick => Ok(None), - LineCommand::Drop => ytcc_drop(line.id) - .with_context(|| format!("Failed to drop: {}", line.id)) - .map(|_| None), - LineCommand::Watch => Ok(Some(Downloadable { - id: Some(line.id), - url: line.url, - })), - LineCommand::Url => { - let mut firefox = std::process::Command::new("firefox"); - firefox.args(["-P", "timesinks.youtube"]); - firefox.arg(line.url.as_str()); - let _handle = firefox.spawn().context("Failed to run firefox")?; - Ok(None) - } - } -} diff --git a/sys/nixpkgs/pkgs/yt/update.sh b/sys/nixpkgs/pkgs/yt/update.sh deleted file mode 100755 index e500bb23..00000000 --- a/sys/nixpkgs/pkgs/yt/update.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh - -nix flake update - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update - -# vim: ft=sh diff --git a/sys/nixpkgs/pkgs/yt/yt.nix b/sys/nixpkgs/pkgs/yt/yt.nix deleted file mode 100644 index aaa971c3..00000000 --- a/sys/nixpkgs/pkgs/yt/yt.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - lib, - rustPlatform, - ytcc, - yt-dlp, - mpv, - makeWrapper, -}: -rustPlatform.buildRustPackage { - pname = "yt"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - - buildNoDefaultFeatures = true; - buildFeatures = ["yt"]; - - nativeBuildInputs = [ - makeWrapper - ]; - - postInstall = '' - wrapProgram $out/bin/yt \ - --prefix PATH : ${lib.makeBinPath [mpv yt-dlp ytcc]} - ''; -} diff --git a/sys/nixpkgs/pkgs/yt/ytc.nix b/sys/nixpkgs/pkgs/yt/ytc.nix deleted file mode 100644 index dff5bcf8..00000000 --- a/sys/nixpkgs/pkgs/yt/ytc.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - lib, - rustPlatform, - ytcc, - yt-dlp, - mpv, - makeWrapper, -}: -rustPlatform.buildRustPackage { - pname = "ytc"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - - buildNoDefaultFeatures = true; - buildFeatures = ["ytc"]; - - nativeBuildInputs = [ - makeWrapper - ]; - - postInstall = '' - wrapProgram $out/bin/ytc \ - --set PATH ${lib.makeBinPath [mpv yt-dlp ytcc]} - ''; -} diff --git a/sys/nixpkgs/pkgs/yt/yts.nix b/sys/nixpkgs/pkgs/yt/yts.nix deleted file mode 100644 index 9a8b172e..00000000 --- a/sys/nixpkgs/pkgs/yt/yts.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - lib, - rustPlatform, - ytcc, - makeWrapper, -}: -rustPlatform.buildRustPackage { - pname = "yts"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - - buildNoDefaultFeatures = true; - buildFeatures = ["yts"]; - - nativeBuildInputs = [ - makeWrapper - ]; - - postInstall = '' - wrapProgram $out/bin/yts \ - --prefix PATH : ${lib.makeBinPath [ytcc]} - ''; -} diff --git a/sys/options/default.nix b/sys/options/default.nix deleted file mode 100644 index 72ebc4fb..00000000 --- a/sys/options/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - config, - ... -}: let - cfg = config.soispha; -in { - options.soispha = { - laptop = { - enable = lib.mkEnableOption "Laptop improvemens"; - backlight = lib.mkOption { - type = lib.types.str; - example = lib.mdDoc "intel_backlight"; - description = lib.mdDoc "Which backlight to query for the screen brightness"; - }; - }; - secrets = { - #enable = lib.mkEnableOption "Secrets through agenix"; - enable = lib.mkOption { - type = lib.types.bool; - default = true; - description = lib.mdDoc "Enable secrets through agenix"; - }; - }; - }; -} diff --git a/sys/options/secret.nix b/sys/options/secret.nix deleted file mode 100644 index 06b1bc21..00000000 Binary files a/sys/options/secret.nix and /dev/null differ diff --git a/sys/polkit/default.nix b/sys/polkit/default.nix deleted file mode 100644 index 9de68f35..00000000 --- a/sys/polkit/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{...}: { - security.polkit.enable = true; -} diff --git a/sys/power/default.nix b/sys/power/default.nix deleted file mode 100644 index d20a97f2..00000000 --- a/sys/power/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{...}: { - # see this for reference: https://github.com/NixOS/nixpkgs/issues/211345 - services = { - # conflicts with tlp - power-profiles-daemon.enable = false; - thermald.enable = true; - tlp = { - enable = true; - settings = { - CPU_BOOST_ON_AC = 1; - CPU_BOOST_ON_BAT = 0; - CPU_SCALING_GOVERNOR_ON_AC = "performance"; - CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; - SATA_LINKPWR_ON_AC = "max_performance"; - SATA_LINKPWR_ON_BAT = "min_power"; - }; - }; - }; -} diff --git a/sys/secrets/default.nix b/sys/secrets/default.nix deleted file mode 100644 index 35be53fb..00000000 --- a/sys/secrets/default.nix +++ /dev/null @@ -1,77 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (config.networking) hostName; - # mkFakeSecret = secretName: { - # name = secretName; - # value = { - # path = "/dev/null"; - # }; - # }; - # fakeSecrets = - # builtins.listToAttrs (lib.debug.traceValSeqN 2 (builtins.map mkFakeSecret - # (lib.debug.traceValSeqN 2 (builtins.attrNames secrets)))); -in { - config = - lib.mkIf config.soispha.secrets.enable - { - age = { - secrets = { - nheko = { - file = ./nheko/conf. + hostName; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - lf_cd_paths = { - file = ./lf/cd_paths; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - - # FIXME: Reactive when serverphone is merged in tree again <2024-05-11> - # - # serverphoneCa = { - # file = ./serverphone/ca.key; - # mode = "700"; - # owner = "serverphone"; - # group = "serverphone"; - # }; - # serverphoneServer = { - # file = ./serverphone/server.key; - # mode = "700"; - # owner = "serverphone"; - # group = "serverphone"; - # }; - - taskserverPrivate = { - file = ./taskserver/private.key; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - taskserverPublic = { - file = ./taskserver/public.cert; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - taskserverCA = { - file = ./taskserver/ca.cert; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - taskserverCredentials = { - file = ./taskserver/credentials; - mode = "700"; - owner = "soispha"; - group = "users"; - }; - }; - }; - }; -} diff --git a/sys/secrets/lf/cd_paths b/sys/secrets/lf/cd_paths deleted file mode 100644 index fff32c61..00000000 --- a/sys/secrets/lf/cd_paths +++ /dev/null @@ -1,4190 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrVzR4V1ZkdlNxNEwwbE9J -RkFtS1VFTFYvVi9mYTVRVTFNTWovMVRlaUNBClBoMzBYTDNrREMrZGNoSTlDNVZr -YVIxaVVFRkxVK2c3WHNidE1haHBCQkEKLT4gc3NoLWVkMjU1MTkgelpFb25nIDho -T21PTHAwRGJwRGlPNWE2YndnOC8wNVNhTi9nY0kzMzZlZ0JkdGxrUVUKVStHMzlN -bnB4VXRHSFpZY3IrUis2dEtwRUFyZnJIN0Rpc2RkcnlGTFhPcwotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgV2tKamE4T2Z3UGVVdXAzL2N2OGdsT1BqWld2cEhCTnBEQ2sr -QVR6QjFDOAp6YW5mQkVtOHdId1JJTVB2NW5YUGE1QURWS1haUVRHdmIzT1pXc1VV -aXdBCi0tLSB1VWRLVzNvbDIrSmswcUpqSGFsc3lnVFBpckZ5M0MxdVIxNEdGcmZa -U000Cofv00o3Z8wl2SaMdgZg2frL82hEazXauOvHejiYd0nEL/uWxf0+8KEKXMjm -HKCtoTMq3Ub9TF4WV8YYj2Y3EiJV5+Jv1LvefGto8qX/8YZw4nvNoziWWVLb6uWp -8cpZAQS3uKYoFb40pL0/ovdrQjHSsmJYdwLU6DtJEzXQPp1Log2L5pLN47+vT+y0 -J9ouYaYeB9GclvyTSo9/D36thjrAINy4elvQ7fI7maJ0Vnvi/BHm06jFAG5tWvsn -zgnXNNJrT5dF1pyKnT1gDOQupbI08arNA7p/WNzBw5Z52d8a09Y3plZ9P0cl7WVj -OJUkm0jIiqVSRcKH/gc/YYeSzeceVhbhiP9ZDPTS+1FRJMEOJGnz8VPit90RIFKj -dXTTEYqFnkVUcjSYLvtO/t66N1AMGrLVAj04ebFWMC6Tom1LQjNycZ4vGsoL5a0X -zBICK1Z+k1ABJgWe1L70hGyut8WFIZ5oRu24MQQtfRru4fnDS7tz3YM65bJdlMl1 -HZYocbs2ETdpDaAgcyHFvD8gjjrVJVWyZ/K/gTZPMuWXPxUEgLbP9bsrBN6i9Yiu -p7wolpsVWTaPjloBxGk7yyPXHIopyGDYl+9Jvv6w3CUTJxXn++Ym/SMF9hj+OCSt -0D67OyHK6JqZJh62HBMzcrwEN9j7tzs45CpGpr1TTHtlBpRrxPGi/imf+mjczVVt -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 -to20Jkr+r4i94inTPVNyz8ws1J8inZ/S21zYTHyCbJ5noCTkSzAgsi8OO4rwfOdY -BhY/UxdINZ0Cey0GBgKGxHduGgzIWZJ9mlhepOelzu3O9lvYZtb+R/RHnJpZq4+D -wxrc5GY0YjW8k/zlVBDY/8m+1lPNXCIJyc/ckcWLc46tHp96pvCRLvYDBv/9KZUj -D63vdaUnEnQndZgoTfk1J4ZTuyfzBWQCcWSLifKe/e0SOG+F69pIiKka7koWnQiM -UtN1xJ68IgiqTsX+dEQQxG2Z2p+6DKb2Gq1RF0Sce8zfdw3YpeKKT3E+ioDS334r -utNPm+ZYOLq/mG9EFlEFwwN2Fw6qZx5cnhJmIcMJvdXGM0F6kuoOLpx/9eIe81Wj -yi5PDkqRaKsTR2LtEtccPM8qZ5yI/GbGeUAHN/79LoHrKHqdk/MxA7Jtc0CaCA6O -tDscBTC6/IB7GAe3NXOLrVqWuZA2ntlmoGB2/qh+ADLidwTgcAAt0rUwRcH2wrwk -S4/eATCsdI7MXmZ3keCrR1bv+T4TO5/IyFl1kGTp7vKEWqm1QbqwbBp4dVRVjCph -CoVj8vXI2xf6D7dD2Th90K+FvMnf6rvsJNSjWkWm/wbNbyvo2ThYmLT/SnOHxv1p -FpTPoc3hx8VTMn7vk5v79LNERSeW0BSpAoVxLONdgT2phMn6fOf+CB57nl+p+sp0 -clC8Ru4XpfBx6TQvdETffKb6qvk8FBkq3+gAKw4Vkau3e3+HKHYxR7q5FkwEz0Zl -rgr0YXjWp50WsLSDc6P3PXbnqJDpqAFc4/R7S+ihPmttvesT8+aCTLZay3AYIXyf -E4RfgWLiBzfxhS4qQHBtrxMVTICueLpT2cvGXIi1ioVGsC/buzB1Nld+Qfk9LwnF -ZIMXQ5JpsgoFqB/ISvxH75n9Bw9zyvhEziVdQ7Xqkd+fqI72xuB21VhREBXjAqzp -UkbVG6mOiAV/WoE5xlWAx1FU5F29xkbBHB7dsvZVFJNNc7mptwYDE6wofKzhfQjw -THaX8H63JLdMpi2lsZUiVZcRYG9vP0AD1DfgvYm/kP13YXPHmLsN+lV+M8O0uuEi -HAgWHfihjx4qhZoMjVnl413PtGOF+Dp4p6+cffK6ee8AYzHXPIXoIHfAOd/hhoRW -fjgpAwUVCbkVztRBZKxFFzR7fGKf3slqieDWDs9z1jtFUAmhAoA+y3HaMaQNbQCk -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 -gQ== ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/nheko/conf.apzu b/sys/secrets/nheko/conf.apzu deleted file mode 100644 index a4f704ea..00000000 --- a/sys/secrets/nheko/conf.apzu +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYUVBnV3NkVlZuN0IrdzdZ -UmlXZUF5cmFvd1pzOGFZNlJuRzdFY3pWV25vCjVVNksrYjhPRi9ZTy9DOXA4anY2 -N3AxWXJTT0dZZU0zOEFCSUo2dUZhK0EKLT4gc3NoLWVkMjU1MTkgN0hmRlV3IC9U -UUhPY29BU2tVY2Z3YTJicjVwZjc0dVVRVHd5bzlqS3pKMDlDc1hjM3MKVmRxc3c2 -SkZvdk9nTzhSdkV2OEdrRjFqT3gyOTFZN3BRT1pZb09nQUg1SQotPiBiLWdyZWFz -ZSBsR0txeUoKanFDNm5BCi0tLSBqWCtNdWk2cWh6WDFXRTBsTjBHaXNRdDVlY2ps -dENOeVc1YmZnNEpZVWRrCpj1HsID0+Oi3IoVUCsFVPIxeKsvptv+8T+Zycu8tmfS -gZZm0XHdJHJFh81d75YyHRBhAhuq/Rg5sR5Wdu9UAAo0NqDIlKICFfKmdrbxEj8D -QL/W6TThKeR/rDZNy2E8Y1hRgQz5y1YG91kjoZpUQReNZBugaq5P0n1UiI4YYa2Y -Dp2E0S53pnLfd3f8UyVkli8fxciFCD0l3h+pueRhEalpaJlJAublyMLXO1rPFvw5 -MiqeP77+kcEtXWC3icfPwNdVhQJEIdOHNsUh6CdD37WORZmg8Kwq2vN0cO+xlZt0 -5zRe3pcBFSzqVmVC8BYRfeJPyygEo70kqbqd5JmnC4wcqvwbHyB8JNBspqkVc0Kh -+u2iYGFjtz6hN6wCxssIOxKLhgqmY5mS0qC21stDa3MrH83cAthtTWEf4IIHduHC -qDnmcpD4dJtB5fboxBrgZ4K3TxMPgRx7J+2tqY3wtxZUEonFFH1L7MyEGmJ6cFiU -RV1cbJRwOYH5nesA4nqAP7/d42vB0unbeTrkYOpTaUSa/hOXfycCtqhtHWFB5378 -2I5wvDdZeTzt+FmQO12Qj01Pqy19FbjMmUeQtKfAiBgOSdvdGOKBA7VmFlG1sow2 -vsU09JluQok/cuDEqunun4cHxLlzTJtH9eGAKceXx3trnKz/zyzbWw55G7VQqM7a -snpi0rsikr+7i0/oxAcrMoBOEX6EDShS6Vio6IIz8KNU5zUPQW5tNbbkfMQW1GM7 -rlZScSlk4N2CmR34BwtEUbAEKzPuNZU3zOX/urDd7rN6gjqwTwa8AGH8bCItMWSI -xxzPq00znHsf2hQkLOI40ENrs84/9ZiW4X3lJSPGaT/t1plzjiPUiIb37hSA6rhR -95zo5qzsjhVJqLB5V4S9wkWJ2vN5Yc4CY6hgoRnZz3n4XoxRed/rdXZ5eUQr2kg8 -h07CNpzeCUfx73kzsrFFIkBiNe0pd3ss2UXR8ilKyY2qMjqQc9Ypd0dLFU34nK+J -t8rQShs+288ni6kXu4PgBVzT891LRuwSxzv8lIZGHtUQ7XJFSJaeFBl+jIGo3iP2 -bdxlFuikGkhyvo+H/RFrAsmxHKgVs4y+ccCkMoapyUiVRvHA2X+LK935EEbGdTI/ -wNmUTPNmB3xlnIsrPxjqw4iUCf3OXZGFd1tSGc4C+5+IYryPPX4rln8fEnmYWq8f -mbHwIjri7YOuC/dVmI+fh74M0tqL7qGtTm8j//AYo1U1a0kgOPItiRzJRLX1TZ7M -JnjQbCmyPX17liRAVbeTJGLAorYIHhCXMRSf7TYwBGgOFHGcdQteFYms2eh9asDe -Zt6Zlmk5yJxz1je+ayWFzp7rms/wEkHR3kZ9dKUMtvAtLzusWcLL4A0zuBU9+GpW -thA+tcskvhX+UR8sYLT3d71JjGPqXujdHFpp4kM/RN+vdpdF+tOm0HVIn/ZuVcNV -pvGdAcKddXH9NXrc/5EDfQWfHbUrjgdHdZVo+BcD/4EZ/k7pQ4Q8EP9IXDvYmORU -5buuZsphAs8JFnuAu0FkwOuQQHX1NjVv0XGjwWMJsTDtRpZTfTL1wJmIdolqJRcZ -5EvhzViERXdZaOOXvUzy5N2BeZA/lX8Ls5P9ygOiCfF5rDajfk6CZLqrvJ+czW6m -07lkpfCo1CsxYGQPcNWlVQOnvO9lW7EtErEOcjdt1VcWJEm462O4FiILVm6Ef0Ax -/qDJUPwFd1NjmvW9e+GkHMXHDnADKxNxQU/KJJsLVdUyZVX4BzQ3W86N/kMyyWQd -1kgAzH1Aba1XyjDGyBAwC0ll0jwemqsD1F5Wzsvmm1dHMWev9y8P/jnQ3hsZ2j1c -n91KbPiZSaqK8ARRROzaVwJMGJIqnGAtqlwD/h1dE1cfHly/OxBHoo5VXPX8R9r7 -W31vHWjKrH7ZlZUa095f3X3xxUvhhnlFFhAwXluWc+FO5IlcqWMdfaeZKYORANdR -sB/moDP0n9WDQZrql15gfca+TQZMNcba8bsa9xnnkow+Gnl3LXE8SPTCE/nWK7lr -gXczbdNe7hpj4cK4lpQMlfk4iMeHYj47k8FFBEh0dbkAz9EpZQcRTjwJScybD51S -XhcOtSD1DJsNcl4RlaraDI4LRlfPqkTGbdmWfxaBmxgSupezF3wa9IC7iXmZeCt+ -doPKlB4LGmrr9ZHX0mDEJZtdrLT1x3xR80afZPlHCI4p3bKIgcmIKyxKxDpoKCou -OPpi0J2mtDZRG7M+u4dDJhiTiYPnhWxOmlL3yHGgN09xb2ZlmO6PhH5yL7eqiItS -n/iJA0bOZE/wT19+D5DofKzs2yjGTx4L+W4= ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/nheko/conf.isimud b/sys/secrets/nheko/conf.isimud deleted file mode 100644 index ef6c52b6..00000000 --- a/sys/secrets/nheko/conf.isimud +++ /dev/null @@ -1,47 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwa0Fvb0p0aU5yRGFCSm5h -d1lNSWc3aWl1NS9FcXpsalVVVGpuZGNRMnlrClVBM2R3aXpSa3pjZFpQbEV0Njcv -QUkySlJRNkV3THBjYUt3RWY3ZWRtaTgKLT4gc3NoLWVkMjU1MTkgN0hmRlV3IHda -dUU2WEwxdjNIZ0R2Wi9rbFQyb1l1TlFBZUJMWlFuMXZNSWZaZFIza2MKVGwyOExv -cW5GK0JsOFVRLzloaVUyQjhvYzR5QnNIc1RTaStISXdnT003ZwotPiBjejctZ3Jl -YXNlIFR9UFRJZyAwTjpdfCBrXlc4TXVnCmlHWTBMOUhPWU4vTzV1ZWFZVTVzTTRC -aitrNHJMQlBrMm85bWhBU29ONHpvSnkvSEFzcnZOTk5Ma1FNM20yVDUKMGF0M25C -UzR5RDdrN3cKLS0tIFNUQk1jU05lSStkQXdYMkttYjY2UVczMi9xZkhZYkdIQWw1 -RkpIOTBvWncKIACBrSaYzKJ84Kjpj57B/WC2vjIvvDAfy3TF1gVEWFOUgYkCpO52 -4sjWpd3JVpdLzsJczS7Ty0HZYBlmz3Qtejf7x6b4xftJSari5WUK6loGtmGKbgJW -lk2LZonpTsnyyALFavanlQKkv1isR9jqWxRe0KZu76zbX/QTUVfHyjV+4m6kleUI -ZJj1mLUKxYdJn2aGyTr4kwTfbLYR8/xxJYGqPUmCrFrLhsr7qy/yBXvPyIfJ+sd/ -ab2/Qz2U8wE8d0JRiwoguFaRTbrIKBzliF84CrbDznJtLQjn02zbc78lzn4n/7MV -3VArXkqw1pICkbrfLl1+own3Mw6ge73tDnSunzgJWBKSOFOrs/b/J1uMMjoiTGWi -THy8+asIFw/zZTmrUnlfmm0gE20nm/HYTJ+428nGrMwdh++LqgocxqX+CNcNTT56 -QhXwR3JuliST8jptRaFo8fzoJUImclSj+o3X2/KORm4fS8u67lcDA6KB/lw6WOie -UE09CVsrkR4X7ACe5Y7PYr0fWYNh1PrYxIabYttQq3aus5SunfkrCX+/+xtbMNsm -FX0TxMintrp3UV4eWEZzsHNz18PaXtyZTFCF4sTmnxjfP7TelZRTHNh/LbKLFrqL -kna9ChqIUiHIEYbugkZsSWUICWMbEGBWQxD4CT6DfGuve4vOgw5FWtqdvHz43f0j -9Agjvab5H+fBvDJTbJiHOFn681Wl219hR4z1plM1eVu+59JIFECVeEePoDrjGy9n -K50HUNs5Vq0p8RFus2BbjTuECmggkzd0P7mZb34bVo6K/89lCny21WeGyhwim8Hr -KKBmpm+hCh7gikBKXP0tnpmt4A5sPg30+YxePgaKCNtUjLLnN4moEGzzAsks1qsJ -GYvzSZv7AmTfyww2cjVm9ZSrlo4EHL5dMPEVBHpy6pcSV6WotkZiDklYPD4g0ZO2 -wgbLU5/YDhve9FOKoP7Y4wocP18O6ffjiPVeCg9XDUmoKq5Y/Ea1d317q973G2hf -YxUD8z9I8+fGlfqmgIjJZx8/0wTFlrCxI1oam6xPDmbSjrdVI+nr/2lfNqy/VOYN -SQMr/Po7DcAwB5SS4ItxYXKYo9FAFyoHAljYhV156l7dveqehZDKaqBzBF+pCefQ -BfiwvYg3by/R9jtMdh6MwfMeF1Z0siJdrPouIKmsuITLexuj85GkzPzSPDa69H2s -iInDepGDX2YvH2BUsUi8QPwoxRXROFwDqaIpA/aaPf224YN7D46TzU+a2HQzlpmV -xWqh/pBEwKdTpbgtdoG9GLrETDD5/2FV9FiQXxQgvV8934nlOAvdwHEJqGMlNIT2 -mlNhZyx49lOfx8BFP+NXb2adUY49Aahkdx4/uB6fN0H/RyNh39R74DCbjvIQUxRV -OUKyWZ2a2wSbZbA6tNmB5sXYtfCUOZLfE8mUwJgUSVrEccQ7UlSlEy9+gZDiHjS+ -OYnTBdRdG2AjPy3mBAdfqooTdzQwT5HNnFskg7Q3wnWRf230yZ6Qr2lBOyBgtnm1 -Hj8fI9VrACfAtYMIWUarBAnnoWHB1pHfoZOui6Zr4jtqlH7lgOAUFx/b60g4SsSF -jAJnRCFyUYbTv53GefabjkDg3WkCiyxrNhr7gS7oONa1qHai/1TQeWPCe9zj9kaR -nMRZQKI1/wmK8szhH7sA+tShtM3ktqkNlIWXuwId3OJ8ne2vcES92NRfyUI8qY39 -atndXRUg47+2MubBZhP1pnLEdxpvdOQVgDIzoNx3mu0mWkSi2K3Dy/Y4mZGVaee/ -K98cPo3S42eKEulsN/iyTWD1nJpaDNp4fWDCDMSK8dy7vSWYcT3htzzR3a4WIlLk -PV3/7l99y/HLjlJmqUwRri1hydRdC74Lk3FSV6gc6snn54WnaLUCVOpCIgHefNVr -zYmUR+4I6zioxp9540zrD8YvrK8YSSs47PtbpDYI8E9O4L7+uy7gujwJtSupZVRc -BP48+5NddK3gpQt4BagYj6CO/vENwDmUiA+kUM9WdQbnV/lmeNPdqm2VjVbxNObZ -5xHlXODOOCVg+LSpFybFT+3A2MNA/jRKGID5Kai0a9c7jY/XIrUdIaCpyVylj2dX -4JDC6AsRb1VXu7FaqhLhOabZZzW+o8m94ZjayWA2BT3IMf5Kd6eq+v9zh5RPlvtu -vcoLBTEsLPZeAyERpaTto431yRqzSKMvDQ6nwpXbdIcHLIvbp+utRoaqtel2JGO4 -PBz21qEI/ACc6sDhyUHHLz+MybEQilTSrBJ+jYSohFfm0DEpG8cThgm6mMSDUMEM -6ehgKHIYdlMa7YIBcIpJBsl8Xs6If2+FA7cbeh6xqbw= ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/nheko/conf.tiamat b/sys/secrets/nheko/conf.tiamat deleted file mode 100644 index 51cab7df..00000000 --- a/sys/secrets/nheko/conf.tiamat +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCUDQ4ZUtkcEVTVWpTQ0Zy -Yi9naWRDaDJFYm9GR0k1QVhJR3V2Rmc0a2hNClNxeTQ2YmFHRkxRWnhlc3IrKzJE -eHpWNGFSTEV2WDR0OHNwTEZiMGdxOFEKLT4gc3NoLWVkMjU1MTkgelpFb25nIDFH -M3orVXZFMndGc0hPN1hWY0xyeXJuYmFLVks4bFVqdHFQVEN5eUhNRmcKUWlZdjlH -ZWtrcGlnZ2ZGVHBwNEZrM29CT3c0MERBNm5SVjhMdWxGbEgvbwotPiBULWdyZWFz -ZSBoOGYKdzBOVGpYNVJFdXoxK1dZdU9rdG5jU21UbUp4UjJYZXRoTTJqNnJvCi0t -LSBwZTJaUS9XRVRINmpNVFhxMnkvdGxkVTJaNkZTZG1PUGVZN0F5QmpJWkxrCohN -YfE5W/OxshJPerGCFWpYkFcQhJaz/HEknz13rCqH4yXfp3M7uoHWKfEFi1uzFdZs -H9MnIKS5NN8bLW4xssBaogalqCAigEUDuLPKmep8224Y4h9i+7fWOMBhgHjU322N -7iJCjnHiKT2tM4uv95c9Fa676xHcfZwzaCFDxbasQZmZL3G3U1wDseSK7EHCZ78R -sXqqd54ApUQyAwdSLPFVvX/YlhOIL6MMUWvhmmgHcNRYa71cQcoojleJI28fu53w -6X0qez81+/D8txyCEtF07m7ckCtYTe7oKT+mF5cvT99lHqEJBJzq/PxUIQt2dA2y -AQr09/7LJ5h8RYVG8emwlqzBasvCdLFXwtCNRMQGb5kDJ5CcZKy50SIpYvDdj269 -Ap4Lq/luQIeOMXQudbc+ECToxbrRKy4gcG8oKsvIXytIOszA8x4WjR14zSBTNunx -Z4mOb0zDy1GdKWsgPcyYdiOBIKzEpTLvjCbWYWJunGSPIlsksBvAAP6MsCbV0WQo -brp48ds24jlCjtqW+AdSIvo5+YVdyCEho8Gdw7k134cIhjoC0SU1vmNNzh1swoW0 -yRKG8ql2Tj6myIDcLM/KDozsgu/gNC2ugRwTCDv+gcApZBmKUXN2w0abhI2UMksH -FEw2ITrWDhPE87bXWNua+vdaBa619lg43xoJTGeJHqF5gXEV3blZ5bTvVjT2H7Dy -uBfCk+XQ4G51Dwh5iyjrQyWxCkYS0FJGD6WUTBU0nrxc6d9UERcxVurtPr7I9Tmf -IVdl6jkrjpfVIL/Imo+YgfdG9CvhyEl/x50c4umDsLxEi67v8TE/yEBhY+o5RnKD -EU0NjdHDIgtI9+Fa0KujnkIN6DqJ0V+QHKv7K8yiR8BScIq2YD1LOOApb6pom7+4 -440vZwmo4NgPsPyM/GgGUIyTeR4tU42BPyMTPjKEuN97ZwWZqIFreUl+nyLzViK/ -bGLYcRfVjjHTJPIeZRosYUo0ZMFggXAuslx5trQcb1B4iHvL7k2jjnMRJmyYZX2d -CWohscc+7+1iFNdH++tefcED8T8HCGpM1RxSM31kfpnKnINeBdo9E9ZDmNCElZm+ -nds5fgTm/MLKsuC/t+MecVdfeHTufc/Akh343DMdIMNmZ35xLcpNLmxTJ+iCALS7 -nheIWAFUaTh6GB6IGocSSjQ0RwS0wIftka4QdW+UEtEjnvB0D/CjwDLSO3pUl0mj -44r8fH8IZVcQcnqhuEsFoih/XOlH3N95O0HxXCvUcI13/HaSpUKdJqyAIn8w/jBM -FL/boJVA1zOH5sIY0AD2IMavuS5b/ZgJtPsESrc0LUiL4nztDVdAEtpHUM0OEzb9 -tSAIN888UKTC8MFSIwA+4cXIyCEpxXP3HbSNaar5gp75oG5/BqOu1aF5sC0kKpmn -9C9+z9sLTDigzV1GKlPpUGd9lVOeH2JpAY8ZUyn2gxh7C6IHwwUbWUclEPy2siYd -HcAMneEwXpm6DfJevMi2o0wOdVakcpN+YUNzIgferM/IU5FbgtC8gNBpDCBo2yLe -X7ERSzP177QWwXLIF2WhZeG4Cvszj4tySYsRJhoZPc9jpRjiK/ccOoNo8A1UKbJC -H/836MNskBmmbNoPsS979mLv8ijpRzvjnwbWn+ZlCo3gZAKVM7PcXuTODcWfoAJ4 -2ugEHCAiOobGQtGUp5HOhXYfAK2Wene0a9RmSAT3SgPmx95u1Fy8n+m/PDK2opIe -REpj9UTcoT0+5aHIwp2gqLVpQH2953Prd0qaNfc1t6gQKwDXDDU+b+QmxAaPBwpu -0TEIEYKsx237lX314XSaq+Nt7Ko1OPABR4gkz/ELL4WOKwFbf7oAAV3UiNPwweY8 -R3cpVvQ70y+M2Nnwepxf7wSruo+FDtgsic9vtobdpwBViPC+AG2QbI1hTD3uhslE -KunFtbO08ARcTMeMgZ0BE3XXnrgxdKjXmPEybQiyObFxDGbV1EX/2i1MKArQdQzs -MxCpKOzDi5axr3Qd/W6Y/foMZWfRYgb+0xITHU7haR8QRD80uTbt9TfsqK98H1A1 -UMosMKhkzKG70qdNvTiEh+OqBAIbUL42IKNn4SCiZt7ZCQ6/QqwcCi6ND0w8+dO1 -u8vZdRF+r/3AAPpa3W7BiIiLUmmU8IUI8A/72cCrY6PyrjaomXnpVWlZjQ616i9Q -TU9IwBahMa2j/a4317pv/7ltQQCpCkRs/HweQy5CQS+yFuOcoOVikL0ZHd9XC4YX -QJ/T6R5+OngxkJgoPRtJ ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/secrets.nix b/sys/secrets/secrets.nix deleted file mode 100644 index cd6447b7..00000000 --- a/sys/secrets/secrets.nix +++ /dev/null @@ -1,22 +0,0 @@ -let - soispha = "age1mshh4ynzhhzhff25tqwkg4j054g3xwrfznh98ycchludj9wjj48qn2uffn"; - - tiamat = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMD87QQIUXdEv3TaNRrI9clD9VgpsuVLFg2CrNGa5lVB"; - apzu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBivF5b6PyxsR/t+4Qg4IEDXHVXrjmZpslTUNXpvcVbO"; -in { - "nheko/conf.tiamat".publicKeys = [soispha tiamat]; - "nheko/conf.apzu".publicKeys = [soispha apzu]; - - # only here to satisfy the nix evaluation - "nheko/conf.isimud".publicKeys = [soispha]; - - "lf/cd_paths".publicKeys = [soispha tiamat apzu]; - - "serverphone/ca.key".publicKeys = [soispha tiamat apzu]; - "serverphone/server.key".publicKeys = [soispha tiamat apzu]; - - "taskserver/private.key".publicKeys = [soispha tiamat apzu]; - "taskserver/public.cert".publicKeys = [soispha tiamat apzu]; - "taskserver/ca.cert".publicKeys = [soispha tiamat apzu]; - "taskserver/credentials".publicKeys = [soispha tiamat apzu]; -} diff --git a/sys/secrets/serverphone/ca.key b/sys/secrets/serverphone/ca.key deleted file mode 100644 index d49c5395..00000000 --- a/sys/secrets/serverphone/ca.key +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyaGJNQkRRVy9MRXZ3b2tJ -Q2R1NUcrYUNGRE5uQkNyUDdkSm5rUWYxaXpjCjduMG1FSG1VamozdnJoVFFZUDYz -T2pyK1k3ekZ4RnFMaDFKdUZPWVNuR3MKLT4gc3NoLWVkMjU1MTkgelpFb25nIEpP -d0xwS3Nia3AwNmppRjZhODdzNXhEcnRsZW5rUzBQcTN6NWhWeTNiQ0EKTkpUZ1Jk -NHE3WVRzVEhpMnJGaVFpdkFBVW5QNThCSUdFSHVQR1RrQUJsZwotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgdjJKUUtlRjE5UFEyR2tBOWhEbHNMVlNSOUMyZ1dkYkhYZWRW -by9QZ2UxTQpVSnhJcFFYay9LSStrSFFJcXJPWUxydXNGbUNXRVpLcHJibjM2TDlw -RnlVCi0+IGNHPjMiSyQtZ3JlYXNlIGcgdWZkbApmY0YzMmhDdzBWT0RKaWlUUmZP -bmRPOExuRVJ3Yk5mMFhYSnhlRENqWXJxK1VWdnBibUxzNWV1NHMyNVNXN054CmR0 -VFAzYUR0RHVaZUpOTlB3USt2TXVDcXdLOGtpZwotLS0gaTliQzBjbjdUYkVidURX -em9wcU04cDhNMHB6KzNBSVMyMmtSRERKS240SQryB70ZEgDQ4eJ/pjIWh6MBEUQr -iAx2i+J+XJu+74bC9DfB5rWpR4/HAdp8EF6wmi05TuEPUpG9brwm/mHi+FB/Drpu -00viGfM3dlCyALz1jB2W/MbruouK85o2L3RWDCgc+eT1gA+u2C7ZxO6iYA3aP4lu -ShDcSHlsKkh9lx4cRsNTua/8N+GQZLciSC7iMDroruxWj1HET9IxeeVN+VSuqcjW -ocX3LU2uU8vP9WT9zT1lbQB5Z0EM7W+ez61SjGpzrpXB2mpmi+SHOIWF3VdG1H8R -18BIyRjKIj5Op+8XD7qAe6nl9SSCnMURH+arc7yjNMgEbzFykfldfug2ibI2G/kW -OxeiEBoSFlC+V8ivS6I= ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/serverphone/server.key b/sys/secrets/serverphone/server.key deleted file mode 100644 index a2720406..00000000 --- a/sys/secrets/serverphone/server.key +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJZnBXSzF4K0ljR3B1Rkk1 -M0lSSkVmVlA2Tjcrd0JCRmhHWDY4bzNoYnhjCmsvQjJmYU5vNVh1Umw0dzhCQjNF -WVRhVHpUTUIzRVBxaXhFWHpuenZHN0kKLT4gc3NoLWVkMjU1MTkgelpFb25nIHAz -aG02dkxiNVRreVNadXJjbnc0bXBtSFRSNDhrYjljanUrNldwVFlabXcKU2c2L25r -VlNjeDFENUdQeWllenRGWlRqRW53UU5VNEdCaUZsbHpaL1ZFTQotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgZytvUUhZSXhwQ01mQmtkZmhzdHJUd2tlQS9yYkxCdTBYZ2pJ -UEd4WEF4SQp4WVh2UEJReDVES2tCWlpqQS9aanQzRGRsSTA4S0VXSWZxZ2hoKzZq -YllzCi0+IEc4eC1ncmVhc2UgaGQhIGFydERoaS4gLERUcQprczdDdHhaOXpmN1VU -MDlHNlYzVmMxY09Oa2xzTVN6M0ZyYnpRSzJEMS9nMmlqRVo4Wk1qN1lKZnp0N0RT -UStuCm51L01Rb3ZxNUhEa0c5Z3orYlp0YmlXMkhpeHVJMjNkRFZYWmR3QmV2Zwot -LS0gdWJDeHZvc0xOMU9uUjUyMlRGUnlGSW9PZzVKWWNoa3pWbVM1OE9LdFk2NAo+ -WS82jL1us5iVw+xWVI80luHMs31hxZfQgJDBuFbtpY0nKkM97U7rusl6t8P+s93c -R0IYBEUuz6n33GTeVOLipDqkZftlOOvSZkFneZ766+GpEO01dCjeSW9KViDC1jI/ -721IXq9TQNZw0Ou3Vf5E0nDypsfG0UhEoLCy6QZL9YCIyl5s//kyFFnpQjyaGT/P -pRHGhD0BxZa2ib07WDWzBpsTFtVemwcn9lqAx7DlYV2X3UwCT3qVOVjDuA/j6qUt -8bCDoXs4/dWleHNHzpwRhe+j2W4OWDKp7o0zYqxkUuPpEWXL7+A+B/+/08nAtZQk -ZvJyaZSL5wicIPAjLxrD00z2QcE/ZPyUrXsi0gOovuk= ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/taskserver/ca.cert b/sys/secrets/taskserver/ca.cert deleted file mode 100644 index 203d62a8..00000000 --- a/sys/secrets/taskserver/ca.cert +++ /dev/null @@ -1,92 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5c0xqVmk5MzZrUmhqTkUv -YUdRamtpQTdvZ2N1QUM4MWNiWWlYbmwvWURvCnhLYzJuSGM5dkhGbmZGaWNpNVhn -L3hSTU9xb0cwc1FSZHJpYUFqTE1NZlUKLT4gc3NoLWVkMjU1MTkgelpFb25nIFhv -N2dOR2xleGVRUWU1cTd5Q1RnQjVtZElJOVdaS2EzTGtVbmswNXdiRWMKa0hubkRD -bFE0NXp6R2QvcHpCUTZjblk1RVpIMmJ1TFhyajM0N1lYRy80UQotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgOFpvTm1tN21pemJFUXVYYzREcE1aZ3dnMU5TLzVxLzFjdWI2 -eENGWXR4QQpwcHFLMS9WNDRiNFZxSThRUk85RVZhS2hyQnptL2FHdHo5OCt3dHF0 -amZZCi0+IGctZ3JlYXNlIDttPFJBT3FfIDZeMT91Ois3IEx0CkFTbFYxZzloWlJZ -WndXZGx3WHI0aXh0U09la3BmblZmcDRIb3RRYjdhL3drQnhQRWNrNUZabzE4R0Q0 -bnpqZGcKVy8xbWV2TXV4blpRNFg3czZHWExOZllLR20yU3hrdlltZwotLS0gUjQv -QXQ1L2NselJ2OVJtUzc0YnIrWlpXK29WNFFVUXEzUTQ4ZG0xRm9zSQqJzYGOwU7Y -Jt/x8jJohpCDiaBjukoqL0WH7ocjgjt084M+on5vp3pBbT9eIgErCJvGc7oDmke0 -Isnb6RvWg6fY66WY4Bsm67VqGiNyV1yQmAXB+zp6gfKjAfvdZk7wUbgll6mUYU8M -IVwvPHS6C3ByIMVU6OaNPXvAMIakDoQUM+HSQpy7Cu3ZuLwZJs7kM9CWGM/GzyNU -fhBiO8L17J5ZtiC5qOZ0DqIUCefdvKINXGLFCV1a/PoZwpbM7Q36R/urEEz77tLm -qzlM1qwq+G4SWjiihYwQ+3rcA2BPzDtYF/F0O9skw2FYFyRZhENqnba3OOewMb6C -CLVtJcCw7doOjHrpxCwYg7bcP1k9V7sR5F7ez80krQ72qHWlGBL7G4v8Mx9o/GQq -cNv8000KWIORBnPl7qyUc+Y5fZBqm8ebkGh9xg5wRflqXXZvOU81av2ayT4hjfgZ -dmSZPtYmX8jaTQwp/WqzpcJq47a9xaLfo4J8UNiG9y9paoN7J5fwn6IALrWnxK9U -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 ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/taskserver/credentials b/sys/secrets/taskserver/credentials deleted file mode 100644 index f3aaf502..00000000 --- a/sys/secrets/taskserver/credentials +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdGQ3a0pWb3lvZXFWbTFQ -UG1JbGREZW9SS3ZuWXJhbTdvTTBqZUdhN0Q0CjF1cnJFM1d2ZFNyRW44Rzlvamlz -VWQycXhmWnB4L1hiSE5qbFozWFlGMU0KLT4gc3NoLWVkMjU1MTkgelpFb25nIEFk -bVQ3U3BsU1FkeWxBY0sySTV2UkxocXJpVXMyd1FrMXA3YUR0NWtTR1kKeUtHODVy -aXE3aXh4WkFmYTJtdlZyZ1A1QlhYZGZuTUYxYVVlblRUV1BqOAotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgdGR4cFMya3p6TEx5cnhYcWNXR2FlVEk3UTBEcHQ3Y3RmK0lY -YlpwRXJGcwpwZUVqODB3SUZUdTlQVW4yaWlZaTE0RE9OT1dLanZlSGV6cnlJRElQ -UjBBCi0+ICFALWdyZWFzZSB0MFU2IDZoIEJPWUZIP1sKN1l2dzdWN1JDbEhEeXBq -THV0cWJIV1RLalVsVVp3RCtwbk5NS2pnd3kxS1RhNTNaa3pqWXZFVm9FM2N2cFp5 -TQpYR2MKLS0tIEhLQWdwL0VoT1ZGNU5UUWs0SVVqK0ZQTndkTURPb0VtNEtJN3or -S0Q0K1UKRfhyrcVb0EbsKj9gL5kqaIpfrsWd2cizrVQ67y9ZOwWilWgk/gkoXadf -q7QeYjnWsHeIVtSZIaHSa8+9pvKAwiYW+B6DjRi7EXkCYz8zGeanMuoKA4by5Q9x -VMKJlWk7c0WIzSuviw== ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/taskserver/private.key b/sys/secrets/taskserver/private.key deleted file mode 100644 index 5afecdaf..00000000 --- a/sys/secrets/taskserver/private.key +++ /dev/null @@ -1,450 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNkZidXVhQ1ExVjdEQWY4 -bUtLR1VCNUl0c2tQUUxCZXFRNE43aDQybFdJCk5qN3FGY2JOV0VjS0R2a1JTR0Fz -NTl1WlV3QVZYdTBvUCt5T2tzV1dWbXcKLT4gc3NoLWVkMjU1MTkgelpFb25nIDBm -MUl6ZDNEL1BVVHNnSlpiRWhDMStBMjYrUEZZZEVnWGh3NjFBYWh0dzQKZjhXbFY4 -NllvbHdwKzFSR2FJUEdHWHdBeVRBRzh2NWU1UUlabnlHQmxkOAotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgd0MwWm1WY2R2NnhaS3dQYWZPcUtCY3BseEtkWUp1eURvKzRu -UXA2OStXMApXdjNEQ01JWlZSb1l3SmxYcDBMMUM4NEtPOVFvL2tHdlMzQ3hMN2t2 -N2w4Ci0+IFciK2Uicy1ncmVhc2UgKildWHNqZSA4QVIgNUE+T2EzdSYKODJIck9K -NzF0RW85RkJVNDBVaWNkTXlkbk03ZnBHNWFxSDN4K3A3THNVNEJLQXJ4MWxENWdq -d2oyL3lQUlVxcwp1VzJxTWpCMU9JRHc2NHZXM0ZvUm1MK1htaGFsTUVKaTZXbEtD -NTZzcy9hSFpGYmRzMzQKLS0tIFFjd25qSEdFT09LYlZCVzNNU04vVEY5RGdIdGs3 -ZkhodEM4SGZ4emlRUmMK3XxmNQwv5++wwwJ3CqpDfqKBLDcwyIfYM7VXqGlxaVR9 -TR9VjtFB6siP6Umo1oewRDt9Gc+MUI+rlc8aUN044ve5g+9im6uni2nQ6hubRZzD -Q3LQCLGGDiFL9+F7xHTLgFH8dIaLs4pnzeSzl+Od0Iybe05HOPGaZDhptqZvGWHr -uGHQz940sUU6k3kbnJ02qpj06AP3Uujl++s/4w5QKvVwx5m9Jio0ZOCaXv/6uUTn -Xq8l0uLMNBLtMhJsd4D5X5XRnvWSEWvUaQf2+nKFdCkxmDqxf8rv8qAE5ryx5SO0 -SnHVFZrSUhUDH4q2lVOPsGExwaExV/N/KB/24foJRoUafvpRb6GfNR8t2SmA82Qd -HVj2aqzuIcPBvefbq19T0WD2vJWHuF2p8NafL9x3KLdRIIm7urG+GLgZtB4am7BS -9B/bZrryjCVJybwy7POlIS1P+1OhuyNSdpv49tTL+v6o5PzGHeJFjykoEKyzTP5e -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 -Z/W/Onv5TRV/l+3dh4SPufGMw5b6CW0elZf1geeTz2fKM/M84xkOnSwk72c1fM2L -15U3MUbeW9kyKxq840CkIRWNuUp4AwtfH9oqdObFpVL4sOTYPHd7zx903tenAsmH -Q+oo/HhxrlDpnVLeHdli2Lffyei3E5TRujQ/XdEvcKylpldMXCUimhiW317SEjip -Tx9OeMUHAjEsGTp9qln4kgA9GTAs+3Zxs0CBJcWeiumd+qhfVyiqxkQ7spy6Yct2 -XuZcFzax/FvcwMZjXBjpgCqeYImG6FH3y3gtkm+ZhbK7qcw/FSR12/xew0SIIVI5 -xU4kvOmZd6nQojefy/S/THwcBbeihstfPpjH0kJ/vOfshfTYawP/Pj4ZqDKv76MJ -i45w8i4UuYCUtEnxo+3KeUMxdofi7lMpW1m4UlRUwHaSlb9blkzYe0OusL5IywP6 -yNqQ4ns1hs+NR9ylsDTMz4DdtgxxOcrdgXT4/zjMQztUe/NwBa6Dyj+zjap28lry -vLHYtpKRtB50JaC2j8RRodM/56YtENOU7HfS7T/FCC2nDCK4Th+saeG1QtQk/2uA -y/ASPmk6UToUYesV0TLCA23JftSZoaVGmfDaM5Zpko8Z9bW2MauRB9cNxm5yE3LL -5TKJJ4R2yNVHAeSNCVtZC0n2UjM/eMwqVQ/pQsWusTgoOeRBMCDc9j+3nIrg6j27 -QYMp3yKZhDgCeCEZrWD66PZeMGm4Q5MVO4g982TqWyDlDe2sragxRyeYwGSRc7VF -87VcMqGO2Kmegzhacew0jR/sbT9yUjAYHbTu81zHjDjCfeFqYbqo9YcTId+pzKzM -nVWu+DQQB9u7G/jIWLb0VR/LcD+Chs/Sd147sCy3aZiWwkgMvN1Atrw1JPjeQoyu -hMKDdiCBiRhY4VDQWtykaQGndrrxkYyS2d8MQfeBzyyJr/v9yhhRB5RnJnhVSKUp -LlN6GvqyUY38NLrNIMUxJ6CR9GvaF5/eIAopCAFN9ViAIAFR92ItHVRby8I0JY3S -wvszNDWPxwao5hQOa4mH4EpCE8x4y88Wo1uVO3OexwnK0ARWKVuv8BgNm/loojxR -GHdPUEuZiS2SsPZ33dqB5oblMRF7eiH/nj/dMhyzUWaE0VDww0Ve7VNptk7yo7DF -sJpaKMIpbpfHqsuI5P+IBcqPvg4QQi16Q4H8BwkmHV3JlQFWeElyAiWD5Kpzg61T -iKTL4Zb2q8p3MqvWe5XqYoq8lji0hNsgLWPBqPobRYlrPHGGKL6yyLA/ddy9z+L2 -3wXPmzEADKzi604M5EZlHZ51+60HSypPA2fqwn0+4EdycUwa5/a8oEEvcYMxCA+q -B7Xc68bYgpM9aO9TONOMWD15uxitj95t71/K+AxGMOr/aU9S/No39VJiCe9YTR5l -3ZamB+FocLtPEH0/MVnMjC4LyXElIB/gjwEbHTADsllErgDQ2TSrkcco6K9HeBHI -VjyXcI7sra2vNiCMfNlvh55XVDh11sFd1dJhInJHMhN2XqxqRqmQ2jHGJP5fhr2q -B6rj0DROBUssMH9umIYhp62ydZyfLQbi8vWjfe8TAPPcolfgBceD8/RmQjWtxGIs -HNg9mQc6+kaBK8QLHaFZs19ag0NWFwSCwNMjVc+uMZizO2ZNWNCEunEAq3R/qivo -fbZEDOoaYi3c1EtZnHS40fJwGoh8R75CW1YgT0zeG7+gB0TxG0XyMa+SrWUgVm0i -aMuD9kgdnqpoI2XwmGJ9vWKdSTZuSyIH1K35HQOw7rfX48pCicv63gYkwjVv4bmW -ldOXdfHOu4D6qa7Jq3g0p02SxgSzpMq1dZSMftMMR/E45YVZrarOn7/cxiFe/IE2 -kpbPi0KnvWH6/CJOiBxH4DEJuDgSCQfX48Fl2yPDYZwoFHZ7SIzdwDOwblz+TuS4 -YCX0/slWc1/Xd7YYPDNnnyQcNIdOi088HCklszmQZwrhJpzzaruXpChSJjbjs/Rj -A4bKNIa4tOepqO379cIh3JUCceLhFGI/6rY71bH0yQ59FtcFUjW0r1onzXKrUuXp -uhqoc8fEeoA8YOk/KtL89Wgq0fb0ON05viG3FVZzrMNQVvLpLhpvvksXHGShPJ/g -xm77d8SEedxEdVH7vsvcaztUvmf8mGfq1eXZPCjGXa6VebhVNB+pheurycqNx7RS -DM1WaD3cE/RtiFw+9u+pZPbIHCuk7N5EtmUZGvJ5CCLvGIwBAv/lb64G9EgKKFz6 -X3xDzXMfoU4MDQfc5bCM4zhkeIV6nuu3gTqK6KLn6DRSgKGga2HcdHu+rnZWdTxQ -oo80TjfwF8TXpmN7sNLDCDK+dnWS75lWZFpsjm/K9EHru/8wPFCjz5nsFR5rjbVm -BVbc4Z6+51pc9mRqqCApKK+ozU7zAtmAD44Hd/cQKdK5aYM4Yt3mLBgpzjw+756l -M/rUStFPt7ZxW9v5kfNDxNtqAFFfWH3X1OURRzDpBA+UfYtn5Mplwy0Gf5Me45sg -8rSnvGlQLNTotL+TX8yPQPkKJATQeZwu8ry5OTybbyPeHzOceIv3l/UjgHlCj6sT -aT2SSJFfi4ic12/zV3FykPr0ZjOqLYvlhMN6ziLAzlp1lCMPzr506k4xN1/zwRpS -YEx4+g2VbQjnVryVm13D2uSIqWFt7cSp+35h4LuAl2NfBSjZDDMy6IyF2xf0gnaf -seqm0yBHNSs0U0MDqLJ150/32sjuWSDm6BzYELXTs0v+8aKXi9cSPcuZrRXgtA/Q -EW67SBaa/dxN8kcydViHufaAbq4BFEz1uc1N+RvHZEPacH4ou01XY/6fsl3yZBeT -jDC5lMW9aSZ45P00CUm0FUtUySEoVztbPrnSi1oGY9Sre95KjQ4WUWulxiuwngqL -zkKw0KHtBE6s7PcFSLePnRO/kKXlPbD85kfRhktfzxf63j3ULrmmPhXBcfDUiOqG -GYmK7dlSFfXlKiOhhIx1zXAxYnD/Q0Jzb0svM3Pp8PfqaaJLmeu8nMUcSN9R5knP -BX3UQAdf7+nKHsRE1up9waB8IEoiR9hfeQ8Wq/3uLY0Z16GppRlIJCCXTtvSrYwO -7BpuFbQzDxPPSM993QblBqzl2SgTV0chHuoegTjXY1Lpt6J88xMnGdfJ9VX+ZZAA -rj9UIu2M8Da+1Jd6f1lud+9ZThbHQZHClgxaM/6GqiYHghGrDfNgeTtWVS8Hl4RL -Vyou/tZEy7k3/mswu9q5wdunJCmkXYIpcXmA18afhdEiRymcnLjy767LioFqIgxp -tIya0OcSFa/yc6gNRFSG2qExPnVPcbGxqbR/N7fHfN/4V+mGQZmDXBlaubWsLiCx -bHF8b2j7Do5b/TjUwct5L7OgHUwSmRlUAF8xMX1kTPkCeTMnMQT0hDHq2B8+Zg+Q -N+GuiY2fr3+i5NKa9oeiv0aZRmaE/nKgPK1UvoXQL8YagmoS3TXSVLOu2JGPyMey -gquVr+UrAOtZp9HWzR/f/jpU0HrqVzMGUOuOK2VfKGBPE+MsNDr7xTgYuw8blYx1 -WXbj8l0whIdmelsr3apmtLGPxc6LjUSnYspaf7m2iqSmioUoZUO59LjxNCe8eYEC -HcxXCJa/wRxWl5IFJzfoUxEGinfrLBFXFtiKewMB/XuNTT8smffvsM7zWz1DC6F0 -WScwAIvwWK8qauLrO2U2qN9d/8dl0G1quDDE3Y27onU67lbemlNahjVmC27WnHHA -fBc+fA3kDnU1zqLFHOonYrVPSWbwaXJwBeJmFzAE5647xgi/l7e2rD8LDoOCjj2a -KVOLPHfvSehX1RbX325lb5VvHjVp1whOQVRF8RgkYg8d/ef9sye6e9Eyz2aVcVPi -0T6jOMZGF2sfeYO2fBLZKF/vezNMUxTWvEOP38Gt6HNMBk76Vhl8v/7ZD7kDs0iB -2NFh3vN6YVCHeNbfAJMESojAlUvhmrOAhvz8uuz9VRVr+66JZkESONHbFfS9r4Z4 -iG8venQ93o2Mq0ccN7+v01eJgyDooJLEAnTNOnq5o0YQrWBgfN2JXGbT9XZKaeDx -CYA5EkLLhdLy6uZa/1UM2fnoZ+zLjQWLVntUwYa88QJbAk3QcD9c/aSEmJqxxI7k -xw2tWebQfQwpz1Ws2U1O8hPL5uJZ7ewuC44H4T7inGUIavWuBLwrkFACk9ASz0Qa -FXtELm3da2+KEVuWvAwgwLm0wpLMktENE3nMsVwFzAk0pM2oPz7paJv7EU5jrTWs -mgDL3ooui5baxSHLCspx04YhBk+VL2BukQVPXfsPN6CL8fRJoE2p9my8MeXlBI5R -7b+Hg4y4ZcH8mURkx3RCVDbH3g== ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/taskserver/public.cert b/sys/secrets/taskserver/public.cert deleted file mode 100644 index 1cf9b5f0..00000000 --- a/sys/secrets/taskserver/public.cert +++ /dev/null @@ -1,83 +0,0 @@ ------BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6RnRGSEZSNE0yWWhXODhk -N1FGNkFPSEVIaFJhWm52eEZ3Q3Bwb2I5c25nCkpCU1Zhd3ZhZ1YyOVFmTGxkVnZT -aDhxOHBrWGdhcE00THh2WnFSbUM1bHMKLT4gc3NoLWVkMjU1MTkgelpFb25nIFh2 -WmVLTTc0ZjUxaUFFNVFuNzVjNkhLRzR6VGdJOVRvZGtBT1BrTnJJQnMKOExOck0r -TW9mSVY0d0VTSk9IS0c3NHdscXVyMHhlUnkyNnFJWnFmekJJWQotPiBzc2gtZWQy -NTUxOSA3SGZGVXcgOXFTejhFNWd0TklHcytUMlJQdU1OaUlNVlBSbWZWdnhWbmVp -TlpNekwwcwoyQXpEd3JCVVcrdHR2cDN4LzdmSVhveGNiaThEOVE3TlJEUXdnejdY -R3NjCi0+IFdAQS1ncmVhc2UgWgpRei9tQTFCcjY1bGxEVlhxdWJFVnB1d3B5MWov -amVZbm1EaEovVmVnczA5RWpuSUx0eUFLc0J0aEZqVmpJMmIxCjUwWmJyYTNxT3g3 -Qjl5MGhuWEEKLS0tIHNaMnh1N1JhUkJIdFZ5TnRtR3hDM1kxRlNMU2pWL2VBdkkx -cUw1TWhWa28KwuibZXNGOy/Qqhs17FD2aTdWit9nvgRl/n+F/gKwJXoaEvRM7veM -uTEvmfIRJzLm5ox7ko48f8g+EWQDWvcXsa1KwCDI4DDoP3WxhMOUmNE6SYqDgGpP -ilQLOvX7kKrtY/oB6OQj6QFMEJe8dElNEq8rcapaqiWnRDQsqvDtFm7j0HcGNQ2U -Kg+/c6UQRf4lgZXLs2cGMCjUivEA6eojyLctIcXdswIxWI9TwxBOJ7NTKI7wF4hn -TKqZSlWhLg8xpW7s0ZRpAQaONMVo+Ve9TH3fPaPFsUZUu+x0jfk+NMUWBscYbYUN -JZT9xuMOmEcnXZ+/1DIgl0zw5kG2hQ30lX0QGRqrWaPoOv0KchORWuwsVgkFFMTk -eiYeqf5mkAfswR8iN6Ye1K6gH6WAI666yRbkMmdJTAO5iC2JhQVLgdJuKBWixTE7 -0Y6xdPIRUhDXn2fgeYFxnTwqR7oi7Aa9H6LVtxdFMVvhqJ2l0QKd8UqcwO3RrCRK -VLehYc3prKklzrkevKVr5k+62ateISjMF/NoEpZf4wTzh6wByyk32cNHT5OU1Qr7 -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 -m7vbEx2mecNNVw96F/k= ------END AGE ENCRYPTED FILE----- diff --git a/sys/secrets/update.sh b/sys/secrets/update.sh deleted file mode 100755 index edc4ae8a..00000000 --- a/sys/secrets/update.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env nix -#! nix shell nixpkgs#age nixpkgs#jq nixpkgs#dash --command dash -# shellcheck shell=dash - -cleanup() { - [ "$key_file" ] && rm "$key_file" -} -trap cleanup EXIT - -update_lf_cd_paths() { - echo "Starting to update the lf/cd_paths file.." - - cd "$(git rev-parse --show-toplevel)/sys/secrets" || { - echo "A secrets dir does not exist! (This is most likely a bug)" - exit 1 - } - - key_file="$(mktemp)" - - nix eval -f ./secrets.nix --json | jq --raw-output '.["lf/cd_paths"].publicKeys | join("\n")' >"$key_file" - - # `lf-make-map` is provided by the dev shell - { - lf-make-map --quiet --depth 4 visualize ~/media ~/repos ~/school | sed 's|\(.*\)|# \1|' - lf-make-map --quiet --depth 4 generate ~/media ~/repos ~/school - } | age --recipients-file "$key_file" --encrypt --armor --output ./lf/cd_paths - - echo "Finished updating the lf/cd_paths file.." -} - -main() { - update_lf_cd_paths -} - -main - -# vim: ft=sh diff --git a/sys/sound/default.nix b/sys/sound/default.nix deleted file mode 100644 index 49e4fa83..00000000 --- a/sys/sound/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{...}: { - # Enable sound with pipewire. - sound.enable = true; - hardware.pulseaudio.enable = false; - security.rtkit.enable = true; - - services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - }; - - # TODO: Is this even needed? <2024-03-10> - # environment.etc.pipewire-pulse-config = { - # target = "pipewire/pipewire-pulse.conf.d/pipewire-pulse-config.conf"; - # text = '' - # # Extra scripts can be started here. Setup in default.pa can be moved in - # # a script or in pulse.cmd below - # context.exec = [ - # { path = "${pkgs.pulseaudio}/bin/pactl" args = "set-sink-volume 0 13%" } - # ] - # ''; - # }; -} diff --git a/sys/svcs/adb/default.nix b/sys/svcs/adb/default.nix deleted file mode 100644 index 4055dbb1..00000000 --- a/sys/svcs/adb/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - lib, - config, - ... -}: let - cfg = config.soispha.adb; -in { - options.soispha.adb = { - enable = lib.mkEnableOption "Android adb bridge"; - user = lib.mkOption { - type = lib.types.str; - example = "soispha"; - default = "soispha"; - description = "Username to grant access to adb bridge"; - }; - }; - - config = lib.mkIf cfg.enable { - programs.adb.enable = true; - users.users."${cfg.user}".extraGroups = ["adbusers"]; - }; -} diff --git a/sys/svcs/backup/default.nix b/sys/svcs/backup/default.nix deleted file mode 100644 index 91433bf9..00000000 --- a/sys/svcs/backup/default.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - lib, - pkgs, - config, - ... -}: let - backup-script = pkgs.writeShellScriptBin "backsnap" '' - ${pkgs.util-linux}/bin/mount --mkdir "/dev/disk/by-uuid/${cfg.backupDiskUuid}" "/run/media/${cfg.backupDiskUuid}"; - ${pkgs.snap-sync-forked}/bin/snap-sync-forked --UUID "${cfg.backupDiskUuid}" --noconfirm; - ${pkgs.util-linux}/bin/umount "/run/media/${cfg.backupDiskUuid}"; - ''; - cfg = config.soispha.fs.backup; -in { - options.soispha.fs.backup = { - enable = lib.mkEnableOption (lib.mdDoc "backups with snap-sync"); - backupDiskUuid = lib.mkOption { - type = lib.types.str; - example = lib.literalExpression "d1d20ae7-3d8a-44da-86da-677dbbb10c89"; - description = lib.mdDoc "The UUID of the backup disk"; - }; - }; - config = lib.mkIf cfg.enable { - systemd = { - services.backup = { - wantedBy = lib.mkForce []; - unitConfig = { - Description = "Backup the last snapshots of the persitent-storage subvolume."; - }; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${backup-script}/bin/backsnap"; - }; - }; - timers.backup = { - wantedBy = ["timers.target"]; - unitConfig = { - Description = "Backup 15min after boot and every 8 hours"; - }; - timerConfig = { - OnBootSec = "15min"; - OnUnitActiveSec = "8h"; - }; - }; - }; - }; -} diff --git a/sys/svcs/dconf/default.nix b/sys/svcs/dconf/default.nix deleted file mode 100644 index db35208e..00000000 --- a/sys/svcs/dconf/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: { - # needed to make home-manager play nice with some apps. See: - # https://nix-community.github.io/home-manager/index.html#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal - programs.dconf.enable = true; -} diff --git a/sys/svcs/default.nix b/sys/svcs/default.nix deleted file mode 100644 index 56a16055..00000000 --- a/sys/svcs/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{...}: { - imports = [ - ./adb - ./backup - ./dconf - ./fwupd - ./getty - ./nix - ./openssh - ./postgresql - ./printing - ./scanning - #./serverphone - ./snapper - ./steam - ./swaylock - ./xdg - ]; -} diff --git a/sys/svcs/fwupd/default.nix b/sys/svcs/fwupd/default.nix deleted file mode 100644 index 999ca72b..00000000 --- a/sys/svcs/fwupd/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{...}: { - services.fwupd.enable = true; -} diff --git a/sys/svcs/getty/default.nix b/sys/svcs/getty/default.nix deleted file mode 100644 index 7e8a4e46..00000000 --- a/sys/svcs/getty/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - lib, - config, - ... -}: { - services.getty = { - greetingLine = lib.mkForce '' - [?25l[?7l  -  ▗▄▄▄ ▗▄▄▄▄ ▄▄▄▖  -  ▜███▙ ▜███▙ ▟███▛  -  ▜███▙ ▜███▙▟███▛  -  ▜███▙ ▜██████▛  -  ▟█████████████████▙ ▜████▛ ▟▙  -  ▟███████████████████▙ ▜███▙ ▟██▙  -  ▄▄▄▄▖ ▜███▙ ▟███▛  -  ▟███▛ ▜██▛ ▟███▛  -  ▟███▛ ▜▛ ▟███▛  - ▟███████████▛ ▟██████████▙ - ▜██████████▛ ▟███████████▛ -  ▟███▛ ▟▙ ▟███▛  -  ▟███▛ ▟██▙ ▟███▛  -  ▟███▛ ▜███▙ ▝▀▀▀▀  -  ▜██▛ ▜███▙ ▜██████████████████▛  -  ▜▛ ▟████▙ ▜████████████████▛  -  ▟██████▙ ▜███▙  -  ▟███▛▜███▙ ▜███▙  -  ▟███▛ ▜███▙ ▜███▙  -  ▝▀▀▀ ▀▀▀▀▘ ▀▀▀▘  -   -  NixOS ${config.system.nixos.label}  -  -------------- -  -   date: \d -   time: \t -   ipv4: \4 -   ipv6: \6 -   tty: \l -  - ''; - }; -} diff --git a/sys/svcs/nix/default.nix b/sys/svcs/nix/default.nix deleted file mode 100644 index 5766fcdd..00000000 --- a/sys/svcs/nix/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ - pkgs, - # flakes - nixpkgs_as_input, - templates, - self, - ... -}: { - nix = { - package = pkgs.nixVersions.latest; - - # Disable nix channels (this is a remnant of old days) - channel.enable = false; - - registry = { - nixpkgs.flake = nixpkgs_as_input; - n.flake = self; # Otherwise the nixpkgs config is not available - - t.flake = templates; - - my_flake.flake = self; - m.flake = self; - }; - - gc = { - automatic = true; - dates = "weekly"; - options = "--delete-older-than 7d"; - }; - - settings = { - auto-optimise-store = true; - experimental-features = [ - "nix-command" - "flakes" - #"ca-derivations" - ]; - - use-xdg-base-directories = true; - - #substituters = ["https://cache.ngi0.nixos.org/"]; - #trusted-public-keys = ["cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA="]; - - fallback = true; # Build from source, if binary can't be substituted - - keep-failed = true; # keep failed tmp build dirs - pure-eval = true; # restrict file system and network access to hash - - sandbox-fallback = false; # Don't disable the sandbox, if the kernel doesn't support it - }; - }; -} diff --git a/sys/svcs/openssh/default.nix b/sys/svcs/openssh/default.nix deleted file mode 100644 index b733dbe7..00000000 --- a/sys/svcs/openssh/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{...}: { - services.openssh = { - enable = true; - hostKeys = [ - { - path = "/srv/sshd/ssh_host_ed25519_key"; - rounds = 1000; - type = "ed25519"; - } - ]; - settings = { - PasswordAuthentication = false; - }; - }; -} diff --git a/sys/svcs/postgresql/default.nix b/sys/svcs/postgresql/default.nix deleted file mode 100644 index 09cca2ef..00000000 --- a/sys/svcs/postgresql/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{config, ...}: { - services.postgresql = { - enable = !config.soispha.laptop.enable; - }; -} diff --git a/sys/svcs/printing/default.nix b/sys/svcs/printing/default.nix deleted file mode 100644 index ea197bbf..00000000 --- a/sys/svcs/printing/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -{...}: { - services.avahi = { - enable = true; - nssmdns4 = true; - nssmdns6 = true; - openFirewall = true; - }; - services.printing = { - enable = true; - startWhenNeeded = true; - webInterface = true; - - # deletes `/var/cache/cups`, `/var/lib/cups` and `/var/spool/cups` on cups startup - stateless = true; - - drivers = []; - }; - hardware = { - printers = { - ensurePrinters = [ - { - name = "Brother"; - description = "Brother DCP-9022CDW"; - model = "everywhere"; - deviceUri = "dnssd://Brother%20DCP-9022CDW._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-30055c773bcf"; - } - ]; - ensureDefaultPrinter = "Brother"; - }; - }; -} diff --git a/sys/svcs/scanning/default.nix b/sys/svcs/scanning/default.nix deleted file mode 100644 index 6621e08f..00000000 --- a/sys/svcs/scanning/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -{pkgs, ...}: { - hardware = { - sane = { - enable = true; - extraBackends = [pkgs.sane-airscan]; - }; - }; - - users.users.soispha.extraGroups = [ - "scanner" # for permission to access the scanner. - ]; -} diff --git a/sys/svcs/serverphone/certificates/ca.crt b/sys/svcs/serverphone/certificates/ca.crt deleted file mode 100644 index 7a4ae6f9..00000000 --- a/sys/svcs/serverphone/certificates/ca.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBXDCCAQOgAwIBAgIIRQ2wXiaD5pMwCgYIKoZIzj0EAwIwGTEXMBUGA1UEAwwO -U2VydmVycGhvbmUgQ0EwHhcNMjMwNjA2MTIzNzM3WhcNMzMwNjAzMTIzNzM3WjAZ -MRcwFQYDVQQDDA5TZXJ2ZXJwaG9uZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEH -A0IABDZMtz3liWniBedisStXDO2sxFCKBH239ezH7uADu8g5peGssmNu1rXEDrg1 -sFwVUjQeJAocYYNoUeHiVpODf1ejNTAzMB0GA1UdDgQWBBST5oMmXrANRbCLIQpN -W7e5uSCL3DASBgNVHRMBAf8ECDAGAQH/AgEBMAoGCCqGSM49BAMCA0cAMEQCIFig -xA3MvRNP4uXaUEWwdP1pYL/R8N46G4NZrPEfiNV4AiA+NJSTFRCOUqEsvSb7PTFx -YuMuJF4XxWnmStz3ym7xXA== ------END CERTIFICATE----- diff --git a/sys/svcs/serverphone/certificates/server.crt b/sys/svcs/serverphone/certificates/server.crt deleted file mode 100644 index f994cdc8..00000000 --- a/sys/svcs/serverphone/certificates/server.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBTjCB9KADAgECAgkAhKrdjsoiOrkwCgYIKoZIzj0EAwIwGTEXMBUGA1UEAwwO -U2VydmVycGhvbmUgQ0EwHhcNMjMwNjA2MTIzOTIwWhcNMjQwNjA1MTIzOTIwWjAm -MSQwIgYDVQQDDBtDbGllbnQgcnVubmluZyBvbiBsb2NhbGhvc3QwWTATBgcqhkjO -PQIBBggqhkjOPQMBBwNCAAS1ILQo8ae8ydqFlt5RncUT7joQiozk6Omunb0vxVz5 -toJRDmVqc1s6KhpCTipUV5coTcaK1TBz0+fft+9VH7cwoxgwFjAUBgNVHREEDTAL -gglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDSQAwRgIhAN7ohtsBLrjlgmSe9ngovxZM -z61n0+/7w2mtX/OrLMWIAiEAu+D2S2o0s7E9pp2Rkug8cT5T4GCWgFgEHk5x2L/E -RVI= ------END CERTIFICATE----- diff --git a/sys/svcs/serverphone/default.nix b/sys/svcs/serverphone/default.nix deleted file mode 100644 index 20125a75..00000000 --- a/sys/svcs/serverphone/default.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - serverphone, - system, - lib, - ... -}: { - config = lib.mkIf config.soispha.secrets.enable { - services.serverphone = { - package = "${serverphone.packages.${system}.default}"; - enable = true; - domain = "localhost"; - configureDoas = true; - acceptedSshKeys = [ - "AAAAC3NzaC1lZDI1NTE5AAAAIGBFuTNNn71Rhfnop2cdz3r/RhWWlCePnSBOhTBbu2ME" - ]; - authorized = { - acceptedGpgKeys = [ - { - source = ./keys/key_1; - trust = "ultimate"; - } - { - source = ./keys/key_2; - trust = "ultimate"; - } - ]; - }; - caCertificate = "${./certificates/ca.crt}"; - certificate = "${./certificates/server.crt}"; - privateKey = config.age.secrets.serverphoneServer.path; - certificateRequest = { - acceptedUsers = [ - "soispha $argon2id$v=19$m=19456,t=2,p=1$EvhPENIBqL5b1RO5waNMWA$pJ8vDrCNJKDlqwB5bVDLjHVPEXm9McQhtt9OXSD8Zkc" - ]; - caPrivateKey = config.age.secrets.serverphoneCa.path; - }; - }; - - users.users.serverphone = { - group = "serverphone"; - isSystemUser = true; - home = "/run/serverphone"; - }; - users.groups.serverphone = { - members = ["serverphone"]; - }; - }; -} diff --git a/sys/svcs/serverphone/keys/key_1 b/sys/svcs/serverphone/keys/key_1 deleted file mode 120000 index 67720882..00000000 --- a/sys/svcs/serverphone/keys/key_1 +++ /dev/null @@ -1 +0,0 @@ -../../../../home-manager/soispha/config/gpg/keys/key_1 \ No newline at end of file diff --git a/sys/svcs/serverphone/keys/key_2 b/sys/svcs/serverphone/keys/key_2 deleted file mode 120000 index 24df7207..00000000 --- a/sys/svcs/serverphone/keys/key_2 +++ /dev/null @@ -1 +0,0 @@ -../../../../home-manager/soispha/config/gpg/keys/key_2 \ No newline at end of file diff --git a/sys/svcs/snapper/default.nix b/sys/svcs/snapper/default.nix deleted file mode 100644 index 41e4b381..00000000 --- a/sys/svcs/snapper/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{...}: { - services.snapper = { - configs = { - srv = { - SUBVOLUME = "/srv"; - FSTYPE = "btrfs"; - # users and groups allowed to work with config - ALLOW_GROUPS = ["wheel"]; - - # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots - # directory - SYNC_ACL = true; - - # run daily number cleanup - NUMBER_CLEANUP = false; - - # limit for number cleanup - NUMBER_MIN_AGE = 1800; - NUMBER_LIMIT = 50; - NUMBER_LIMIT_IMPORTANT = 10; - - # create hourly snapshots - TIMELINE_CREATE = true; - - # cleanup hourly snapshots after some time - TIMELINE_CLEANUP = true; - - # limits for timeline cleanup - TIMELINE_MIN_AGE = 1800; - TIMELINE_LIMIT_HOURLY = 7; - TIMELINE_LIMIT_DAILY = 3; - TIMELINE_LIMIT_WEEKLY = 2; - TIMELINE_LIMIT_MONTHLY = 0; - TIMELINE_LIMIT_YEARLY = 2; - - # cleanup empty pre-post-pairs - EMPTY_PRE_POST_CLEANUP = true; - }; - }; - }; -} diff --git a/sys/svcs/steam/default.nix b/sys/svcs/steam/default.nix deleted file mode 100644 index 54091493..00000000 --- a/sys/svcs/steam/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: let - cfg = config.soispha.services.steam; -in { - options.soispha.services.steam = { - enable = lib.mkOption { - default = false; - description = lib.mdDoc "Steam"; - }; - }; - config = lib.mkIf cfg.enable { - programs.steam = { - enable = true; - }; - environment.systemPackages = [ - pkgs.wineWowPackages.waylandFull - ]; - }; -} diff --git a/sys/svcs/swaylock/default.nix b/sys/svcs/swaylock/default.nix deleted file mode 100644 index 6cbcef28..00000000 --- a/sys/svcs/swaylock/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{...}: { - # otherwise swaylock can't access the user password. - security.pam.services.swaylock = {}; -} diff --git a/sys/svcs/xdg/default.nix b/sys/svcs/xdg/default.nix deleted file mode 100644 index 5140a832..00000000 --- a/sys/svcs/xdg/default.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - pkgs, - nixpkgs_open_prs, - sysLib, - system, - ... -}: let - pkgs_tfc = nixpkgs_open_prs.nixpkgs-tfc.legacyPackages."${system}"; -in { - services.dbus.enable = true; - xdg = { - portal = { - enable = true; - termfilechooser = { - enable = true; - logLevel = "TRACE"; - package = pkgs_tfc.xdg-desktop-portal-termfilechooser; - settings = { - filechooser = { - default_dir = "/tmp"; - cmd = "${sysLib.writeShellScript { - src = ./scripts/lf_wrapper.sh; - name = "lf_wrapper"; - keepPath = true; - dependencies = with pkgs; [ - lf - alacritty - bash - ]; - }}/bin/lf_wrapper"; - }; - }; - }; - wlr = { - enable = true; - }; - config = { - common = { - # NOTE: The next entry is supposedly needed for gtk based apps <2023-08-31> - default = ["wlr" "gtk"]; - "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"]; - }; - - # TODO: Also activate, when on another wlr-based compositor <2023-11-25> - river = { - default = ["wlr" "gtk"]; - "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"]; - }; - }; - extraPortals = [ - pkgs.xdg-desktop-portal-gtk - pkgs.xdg-desktop-portal-wlr - pkgs_tfc.xdg-desktop-portal-termfilechooser - ]; - }; - }; - # TODO: mime = {}; -} diff --git a/sys/svcs/xdg/scripts/lf_wrapper.sh b/sys/svcs/xdg/scripts/lf_wrapper.sh deleted file mode 100755 index 16603fe4..00000000 --- a/sys/svcs/xdg/scripts/lf_wrapper.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH - -# This wrapper script is invoked by xdg-desktop-portal-termfilechooser. -# -# Inputs: -# 1. "1" if multiple files can be chosen, "0" otherwise. -# 2. "1" if a directory should be chosen, "0" otherwise. -# 3. "0" if opening files was requested, "1" if writing to a file was -# requested. For example, when uploading files in Firefox, this will be "0". -# When saving a web page in Firefox, this will be "1". -# 4. If writing to a file, this is recommended path provided by the caller. For -# example, when saving a web page in Firefox, this will be the recommended -# path Firefox provided, such as "~/Downloads/webpage_title.html". -# Note that if the path already exists, we keep appending "_" to it until we -# get a path that does not exist. -# 5. The output path, to which results should be written. -# -# Output: -# The script should print the selected paths to the output path (argument #5), -# one path per line. -# If nothing is printed, then the operation is assumed to have been canceled. - -multiple="$1" -directory="$2" -save="$3" -recommended_path="$4" -out="$5" - -# echo > /tmp/stdout -# echo > /tmp/stderr -# -# exec 1>> /tmp/stdout -# exec 2>> /tmp/stderr - -cmd="$(command -v lf)" -termcmd="${TERMINAL:-$(command -v alacritty)}" - -if [ "$save" = "1" ]; then - set -- -selection-path="$out" -command='set promptfmt "Select the file to write to %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$recommended_path" - cat <"$recommended_path" -xdg-desktop-portal-termfilechooser saving files tutorial - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!! === WARNING! === !!! -!!! The contents of *whatever* file you open last in !!! -!!! lf will be *overwritten*! !!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -Instructions: -1) Move this file wherever you want. -2) Rename the file if needed. -3) Confirm your selection by opening the file, for - example by pressing . - -Notes: -1) This file is provided for your convenience. You - could delete it and choose another file to overwrite - that, for example. -2) If you quit lf without opening a file, this file - will be removed and the save operation aborted. -EOF - -elif [ "$directory" = "1" ]; then - set -- -selection-path="$out" -command='set dironly' -command='set promptfmt "Select directory (quit in dir to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' -elif [ "$multiple" = "1" ]; then - set -- -selection-path="$out" -command='set promptfmt "Select file(s) (open file to select it; to select multiple) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' -else - set -- -selection-path="$out" -command='set promptfmt "Select file (open file to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' -fi - -"$termcmd" --title 'floating please' -e "$cmd" "$@" - -if [ "$save" = "1" ] && [ ! -s "$out" ]; then - rm "$recommended_path" -fi -# vim: ft=sh diff --git a/sys/svcs/xdg/scripts/ranger_wrapper.sh b/sys/svcs/xdg/scripts/ranger_wrapper.sh deleted file mode 100755 index e148bf19..00000000 --- a/sys/svcs/xdg/scripts/ranger_wrapper.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env dash - -# shellcheck source=/dev/null -SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH -# This wrapper script is invoked by xdg-desktop-portal-termfilechooser. -# -# Inputs: -# 1. "1" if multiple files can be chosen, "0" otherwise. -# 2. "1" if a directory should be chosen, "0" otherwise. -# 3. "0" if opening files was requested, "1" if writing to a file was -# requested. For example, when uploading files in Firefox, this will be "0". -# When saving a web page in Firefox, this will be "1". -# 4. If writing to a file, this is recommended path provided by the caller. For -# example, when saving a web page in Firefox, this will be the recommended -# path Firefox provided, such as "~/Downloads/webpage_title.html". -# Note that if the path already exists, we keep appending "_" to it until we -# get a path that does not exist. -# 5. The output path, to which results should be written. -# -# Output: -# The script should print the selected paths to the output path (argument #5), -# one path per line. -# If nothing is printed, then the operation is assumed to have been canceled. - -multiple="$1" -directory="$2" -save="$3" -path="$4" -out="$5" - -cmd="$(command -v ranger)" -termcmd="${TERMCMD:-$(command -v kitty)}" - -if [ "$save" = "1" ]; then - set -- --choosefile="$out" --cmd='echo Select save path (see tutorial in preview pane; try pressing zv or zp if no preview)' "$path" - printf '%s' 'xdg-desktop-portal-termfilechooser saving files tutorial - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!! === WARNING! === !!! -!!! The contents of *whatever* file you open last in !!! -!!! ranger will be *overwritten*! !!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -Instructions: -1) Move this file wherever you want. -2) Rename the file if needed. -3) Confirm your selection by opening the file, for - example by pressing . - -Notes: -1) This file is provided for your convenience. You - could delete it and choose another file to overwrite - that, for example. -2) If you quit ranger without opening a file, this file - will be removed and the save operation aborted. -' >"$path" -elif [ "$directory" = "1" ]; then - set -- --choosedir="$out" --show-only-dirs --cmd="echo Select directory (quit in dir to select it)" -elif [ "$multiple" = "1" ]; then - set -- --choosefiles="$out" --cmd="echo Select file(s) (open file to select it; to select multiple)" -else - set -- --choosefile="$out" --cmd="echo Select file (open file to select it)" -fi - -"$termcmd" -- "$cmd" "$@" -if [ "$save" = "1" ] && [ ! -s "$out" ]; then - rm "$path" -fi diff --git a/sys/tempfiles/default.nix b/sys/tempfiles/default.nix deleted file mode 100644 index 2d48b02e..00000000 --- a/sys/tempfiles/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{config, ...}: { - systemd.tmpfiles.rules = [ - # this file is needed to trash stuff on the temp fs - "d /.Trash 1777 root root" # TODO: move this to the lf config - ]; -} diff --git a/sys/users/default.nix b/sys/users/default.nix deleted file mode 100644 index 46e489a3..00000000 --- a/sys/users/default.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - cfg = config.soispha.users; -in { - options.soispha.users = { - # enable = lib.mkEnableOption (lib.mdDoc "users"); - hashedPassword = lib.mkOption { - type = lib.types.str; - example = lib.literalExpression "$y$jFT$ONrCqZIJKB7engmfA4orD/$0GO58/wV5wrYWj0cyONhyujZPjFmbT0XKtx2AvXLG0B"; - default = "$y$jFT$ONrCqZIJKB7engmfA4orD/$0GO58/wV5wrYWj0cyONhyujZPjFmbT0XKtx2AvXLG0B"; - description = lib.mdDoc "Hashed password for the user"; - }; - }; - - config = { - # I was told, that this solves some nasty problems: - programs.zsh.enable = true; - - users = { - groups = { - plugdev.members = ["soispha"]; - }; - mutableUsers = false; - users.soispha = { - isNormalUser = true; - home = "/home/soispha"; - createHome = true; - shell = pkgs.zsh; - initialHashedPassword = cfg.hashedPassword; - extraGroups = [ - "plugdev" # although deprecated, this helps with old udev rules, that still use this group. TODO: check for an open issue - "wheel" - ]; - uid = 1000; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIME4ZVa+IoZf6T3U08JG93i6QIAJ4amm7mkBzO14JSkz" - ]; - }; - }; - }; -} diff --git a/sys/waydroid/default.nix b/sys/waydroid/default.nix deleted file mode 100644 index 09c388a6..00000000 --- a/sys/waydroid/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{...}: { - # FIXME: Running `waydroid session start` causes all fuse mounts instances to coredump <2023-09-02> - virtualisation.waydroid.enable = false; -} -- cgit 1.4.1