From 4cf779b3fe0ba2f7d821efe401fe88b0323c4a35 Mon Sep 17 00:00:00 2001 From: Rawleenc Date: Thu, 1 May 2025 20:35:29 +0200 Subject: [PATCH] feat: add command-line interface and package management functionality - Implemented a new CLI using Clap for managing Fedora configurations and packages. - Added commands for configuring dnf, adding repositories, installing RPM Fusion, adding users to groups, and managing packages. - Created data files for various package lists (AMD, Intel, common, firmware, gnome extra) and user groups. - Introduced Zsh completion script for improved command-line usability. - Removed the old CLI implementation and integrated the new structure into the main application logic. --- Cargo.lock | 223 ++++++++++++ Cargo.toml | 2 + Makefile | 36 ++ completions.bash | 793 ++++++++++++++++++++++++++++++++++++++++++ completions.fish | 93 +++++ completions.zsh | 603 ++++++++++++++++++++++++++++++++ data/amd_list | 16 + data/common_list | 42 +++ data/firmware_list | 1 + data/gnome_extra_list | 7 + data/intel_list | 13 + data/user_groups | 15 + src/cli.rs | 60 ---- src/lib.rs | 152 ++++++++ src/main.rs | 323 +++++++++++++---- 15 files changed, 2245 insertions(+), 134 deletions(-) create mode 100644 Makefile create mode 100644 completions.bash create mode 100644 completions.fish create mode 100644 completions.zsh create mode 100644 data/amd_list create mode 100644 data/common_list create mode 100644 data/firmware_list create mode 100644 data/gnome_extra_list create mode 100644 data/intel_list create mode 100644 data/user_groups delete mode 100644 src/cli.rs create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cc87f0a..a1add42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,24 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "4.5.37" @@ -116,6 +134,41 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -147,8 +200,27 @@ dependencies = [ "clap_complete", "env_logger", "log", + "rust-ini", + "whoami", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "heck" version = "0.5.0" @@ -185,6 +257,22 @@ dependencies = [ "syn", ] +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + [[package]] name = "log" version = "0.4.27" @@ -203,6 +291,16 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown", +] + [[package]] name = "portable-atomic" version = "1.11.0" @@ -236,6 +334,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.11.1" @@ -265,6 +372,17 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rust-ini" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +dependencies = [ + "cfg-if", + "ordered-multimap", + "trim-in-place", +] + [[package]] name = "serde" version = "1.0.219" @@ -302,6 +420,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "trim-in-place" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -314,6 +447,96 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" +dependencies = [ + "redox_syscall", + "wasite", + "web-sys", +] + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index fab3c52..3fd81ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,5 @@ clap = { version = "4.5", features = ["derive", "env", "cargo"] } clap_complete = "4.5" log = "0.4" env_logger = "0.11" +rust-ini = "0.21" +whoami = "1.6" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a3f0491 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +ifeq ($(CARGO_PKG_VERSION),) + CARGO_PKG_VERSION := 0.0.0 +endif + +ifeq ($(APP_NAME),) + APP_NAME := feddy +endif + +build: clean + cargo build --release + ./target/release/$(APP_NAME) --generate=bash > completions.bash + ./target/release/$(APP_NAME) --generate=zsh > completions.zsh + ./target/release/$(APP_NAME) --generate=fish > completions.fish + +clean: + rm -f completions.bash + rm -f completions.zsh + rm -f completions.fish + +format: + cargo fmt --all + +# PREFIX is environment variable, but if it is not set, then set default value +ifeq ($(PREFIX),) + PREFIX := /usr/local +endif + +install: + install -d $(PREFIX)/bin/ + install -m 755 target/release/$(APP_NAME) $(PREFIX)/bin/ + install -d /usr/share/bash-completion/completions/ + install -m 644 completions.bash /usr/share/bash-completion/completions/$(APP_NAME) + install -d /usr/share/zsh/site-functions/ + install -m 644 completions.zsh /usr/share/zsh/site-functions/_$(APP_NAME) + install -d /usr/share/fish/vendor_completions.d/ + install -m 644 completions.fish /usr/share/fish/vendor_completions.d/$(APP_NAME).fish \ No newline at end of file diff --git a/completions.bash b/completions.bash new file mode 100644 index 0000000..b6b55e6 --- /dev/null +++ b/completions.bash @@ -0,0 +1,793 @@ +_feddy() { + local i cur prev opts cmd + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]} + do + case "${cmd},${i}" in + ",$1") + cmd="feddy" + ;; + feddy,add-repo) + cmd="feddy__add__repo" + ;; + feddy,add-user-to-groups) + cmd="feddy__add__user__to__groups" + ;; + feddy,configure-dnf) + cmd="feddy__configure__dnf" + ;; + feddy,help) + cmd="feddy__help" + ;; + feddy,install-rpm-fusion) + cmd="feddy__install__rpm__fusion" + ;; + feddy,package) + cmd="feddy__package" + ;; + feddy__add__repo,help) + cmd="feddy__add__repo__help" + ;; + feddy__add__repo,mullvad) + cmd="feddy__add__repo__mullvad" + ;; + feddy__add__repo,vivaldi) + cmd="feddy__add__repo__vivaldi" + ;; + feddy__add__repo,vscode) + cmd="feddy__add__repo__vscode" + ;; + feddy__add__repo__help,help) + cmd="feddy__add__repo__help__help" + ;; + feddy__add__repo__help,mullvad) + cmd="feddy__add__repo__help__mullvad" + ;; + feddy__add__repo__help,vivaldi) + cmd="feddy__add__repo__help__vivaldi" + ;; + feddy__add__repo__help,vscode) + cmd="feddy__add__repo__help__vscode" + ;; + feddy__help,add-repo) + cmd="feddy__help__add__repo" + ;; + feddy__help,add-user-to-groups) + cmd="feddy__help__add__user__to__groups" + ;; + feddy__help,configure-dnf) + cmd="feddy__help__configure__dnf" + ;; + feddy__help,help) + cmd="feddy__help__help" + ;; + feddy__help,install-rpm-fusion) + cmd="feddy__help__install__rpm__fusion" + ;; + feddy__help,package) + cmd="feddy__help__package" + ;; + feddy__help__add__repo,mullvad) + cmd="feddy__help__add__repo__mullvad" + ;; + feddy__help__add__repo,vivaldi) + cmd="feddy__help__add__repo__vivaldi" + ;; + feddy__help__add__repo,vscode) + cmd="feddy__help__add__repo__vscode" + ;; + feddy__help__package,amd-list) + cmd="feddy__help__package__amd__list" + ;; + feddy__help__package,common-list) + cmd="feddy__help__package__common__list" + ;; + feddy__help__package,custom-list) + cmd="feddy__help__package__custom__list" + ;; + feddy__help__package,firmware-list) + cmd="feddy__help__package__firmware__list" + ;; + feddy__help__package,gnome-extra-list) + cmd="feddy__help__package__gnome__extra__list" + ;; + feddy__help__package,intel-list) + cmd="feddy__help__package__intel__list" + ;; + feddy__package,amd-list) + cmd="feddy__package__amd__list" + ;; + feddy__package,common-list) + cmd="feddy__package__common__list" + ;; + feddy__package,custom-list) + cmd="feddy__package__custom__list" + ;; + feddy__package,firmware-list) + cmd="feddy__package__firmware__list" + ;; + feddy__package,gnome-extra-list) + cmd="feddy__package__gnome__extra__list" + ;; + feddy__package,help) + cmd="feddy__package__help" + ;; + feddy__package,intel-list) + cmd="feddy__package__intel__list" + ;; + feddy__package__help,amd-list) + cmd="feddy__package__help__amd__list" + ;; + feddy__package__help,common-list) + cmd="feddy__package__help__common__list" + ;; + feddy__package__help,custom-list) + cmd="feddy__package__help__custom__list" + ;; + feddy__package__help,firmware-list) + cmd="feddy__package__help__firmware__list" + ;; + feddy__package__help,gnome-extra-list) + cmd="feddy__package__help__gnome__extra__list" + ;; + feddy__package__help,help) + cmd="feddy__package__help__help" + ;; + feddy__package__help,intel-list) + cmd="feddy__package__help__intel__list" + ;; + *) + ;; + esac + done + + case "${cmd}" in + feddy) + opts="-h -V --generate --help --version configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --generate) + COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo) + opts="-h --help vscode mullvad vivaldi help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__help) + opts="vscode mullvad vivaldi help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__help__mullvad) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__help__vivaldi) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__help__vscode) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__mullvad) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__vivaldi) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__repo__vscode) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__add__user__to__groups) + opts="-u -h --user --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --user) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -u) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__configure__dnf) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help) + opts="configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__add__repo) + opts="vscode mullvad vivaldi" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__add__repo__mullvad) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__add__repo__vivaldi) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__add__repo__vscode) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__add__user__to__groups) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__configure__dnf) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__install__rpm__fusion) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package) + opts="common-list amd-list intel-list gnome-extra-list firmware-list custom-list" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__amd__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__common__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__custom__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__firmware__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__gnome__extra__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__help__package__intel__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__install__rpm__fusion) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package) + opts="-r -h --remove --help common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__amd__list) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__common__list) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__custom__list) + opts="-f -h --file --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__firmware__list) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__gnome__extra__list) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help) + opts="common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__amd__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__common__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__custom__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__firmware__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__gnome__extra__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__help__intel__list) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + feddy__package__intel__list) + opts="-h --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + esac +} + +if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then + complete -F _feddy -o nosort -o bashdefault -o default feddy +else + complete -F _feddy -o bashdefault -o default feddy +fi diff --git a/completions.fish b/completions.fish new file mode 100644 index 0000000..684e5ab --- /dev/null +++ b/completions.fish @@ -0,0 +1,93 @@ +# Print an optspec for argparse to handle cmd's options that are independent of any subcommand. +function __fish_feddy_global_optspecs + string join \n generate= h/help V/version +end + +function __fish_feddy_needs_command + # Figure out if the current invocation already has a command. + set -l cmd (commandline -opc) + set -e cmd[1] + argparse -s (__fish_feddy_global_optspecs) -- $cmd 2>/dev/null + or return + if set -q argv[1] + # Also print the command, so this can be used to figure out what it is. + echo $argv[1] + return 1 + end + return 0 +end + +function __fish_feddy_using_subcommand + set -l cmd (__fish_feddy_needs_command) + test -z "$cmd" + and return 1 + contains -- $cmd[1] $argv +end + +complete -c feddy -n "__fish_feddy_needs_command" -l generate -r -f -a "bash\t'' +elvish\t'' +fish\t'' +powershell\t'' +zsh\t''" +complete -c feddy -n "__fish_feddy_needs_command" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_needs_command" -s V -l version -d 'Print version' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "configure-dnf" -d 'Configure dnf' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "add-repo" -d 'Add a repository' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "install-rpm-fusion" -d 'Install RPM fusion' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "add-user-to-groups" -d 'Add user to groups' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "package" -d 'Manage packages' +complete -c feddy -n "__fish_feddy_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand configure-dnf" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and not __fish_seen_subcommand_from vscode mullvad vivaldi help" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and not __fish_seen_subcommand_from vscode mullvad vivaldi help" -f -a "vscode" -d 'Add VSCode repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and not __fish_seen_subcommand_from vscode mullvad vivaldi help" -f -a "mullvad" -d 'Add Mullvad repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and not __fish_seen_subcommand_from vscode mullvad vivaldi help" -f -a "vivaldi" -d 'Add Vivaldi repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and not __fish_seen_subcommand_from vscode mullvad vivaldi help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from vscode" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from mullvad" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from vivaldi" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from help" -f -a "vscode" -d 'Add VSCode repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from help" -f -a "mullvad" -d 'Add Mullvad repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from help" -f -a "vivaldi" -d 'Add Vivaldi repository' +complete -c feddy -n "__fish_feddy_using_subcommand add-repo; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand install-rpm-fusion" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand add-user-to-groups" -s u -l user -r +complete -c feddy -n "__fish_feddy_using_subcommand add-user-to-groups" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -s r -l remove +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "common-list" -d 'Install/Remove the common list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "amd-list" -d 'Install/Remove the AMD list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "intel-list" -d 'Install/Remove the Intel list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "gnome-extra-list" -d 'Install/Remove the Gnome extra list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "firmware-list" -d 'Install/Remove the firmware list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "custom-list" -d 'Install/Remove a custom list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and not __fish_seen_subcommand_from common-list amd-list intel-list gnome-extra-list firmware-list custom-list help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from common-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from amd-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from intel-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from gnome-extra-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from firmware-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from custom-list" -s f -l file -r +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from custom-list" -s h -l help -d 'Print help' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "common-list" -d 'Install/Remove the common list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "amd-list" -d 'Install/Remove the AMD list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "intel-list" -d 'Install/Remove the Intel list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "gnome-extra-list" -d 'Install/Remove the Gnome extra list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "firmware-list" -d 'Install/Remove the firmware list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "custom-list" -d 'Install/Remove a custom list' +complete -c feddy -n "__fish_feddy_using_subcommand package; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "configure-dnf" -d 'Configure dnf' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "add-repo" -d 'Add a repository' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "install-rpm-fusion" -d 'Install RPM fusion' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "add-user-to-groups" -d 'Add user to groups' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "package" -d 'Manage packages' +complete -c feddy -n "__fish_feddy_using_subcommand help; and not __fish_seen_subcommand_from configure-dnf add-repo install-rpm-fusion add-user-to-groups package help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from add-repo" -f -a "vscode" -d 'Add VSCode repository' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from add-repo" -f -a "mullvad" -d 'Add Mullvad repository' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from add-repo" -f -a "vivaldi" -d 'Add Vivaldi repository' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "common-list" -d 'Install/Remove the common list' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "amd-list" -d 'Install/Remove the AMD list' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "intel-list" -d 'Install/Remove the Intel list' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "gnome-extra-list" -d 'Install/Remove the Gnome extra list' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "firmware-list" -d 'Install/Remove the firmware list' +complete -c feddy -n "__fish_feddy_using_subcommand help; and __fish_seen_subcommand_from package" -f -a "custom-list" -d 'Install/Remove a custom list' diff --git a/completions.zsh b/completions.zsh new file mode 100644 index 0000000..b4c1776 --- /dev/null +++ b/completions.zsh @@ -0,0 +1,603 @@ +#compdef feddy + +autoload -U is-at-least + +_feddy() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1 + + if is-at-least 5.2; then + _arguments_options=(-s -S -C) + else + _arguments_options=(-s -C) + fi + + local context curcontext="$curcontext" state line + _arguments "${_arguments_options[@]}" : \ +'--generate=[]:GENERATOR:(bash elvish fish powershell zsh)' \ +'-h[Print help]' \ +'--help[Print help]' \ +'-V[Print version]' \ +'--version[Print version]' \ +":: :_feddy_commands" \ +"*::: :->feddy" \ +&& ret=0 + case $state in + (feddy) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-command-$line[1]:" + case $line[1] in + (configure-dnf) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(add-repo) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_feddy__add-repo_commands" \ +"*::: :->add-repo" \ +&& ret=0 + + case $state in + (add-repo) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-add-repo-command-$line[1]:" + case $line[1] in + (vscode) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(mullvad) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(vivaldi) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_feddy__add-repo__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-add-repo-help-command-$line[1]:" + case $line[1] in + (vscode) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(mullvad) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(vivaldi) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(install-rpm-fusion) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(add-user-to-groups) +_arguments "${_arguments_options[@]}" : \ +'-u+[]:USER:_default' \ +'--user=[]:USER:_default' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(package) +_arguments "${_arguments_options[@]}" : \ +'-r[]' \ +'--remove[]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_feddy__package_commands" \ +"*::: :->package" \ +&& ret=0 + + case $state in + (package) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-package-command-$line[1]:" + case $line[1] in + (common-list) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(amd-list) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(intel-list) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(gnome-extra-list) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(firmware-list) +_arguments "${_arguments_options[@]}" : \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(custom-list) +_arguments "${_arguments_options[@]}" : \ +'-f+[]:FILE:_default' \ +'--file=[]:FILE:_default' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_feddy__package__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-package-help-command-$line[1]:" + case $line[1] in + (common-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(amd-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(intel-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(gnome-extra-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(firmware-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(custom-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_feddy__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-help-command-$line[1]:" + case $line[1] in + (configure-dnf) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(add-repo) +_arguments "${_arguments_options[@]}" : \ +":: :_feddy__help__add-repo_commands" \ +"*::: :->add-repo" \ +&& ret=0 + + case $state in + (add-repo) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-help-add-repo-command-$line[1]:" + case $line[1] in + (vscode) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(mullvad) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(vivaldi) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(install-rpm-fusion) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(add-user-to-groups) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(package) +_arguments "${_arguments_options[@]}" : \ +":: :_feddy__help__package_commands" \ +"*::: :->package" \ +&& ret=0 + + case $state in + (package) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:feddy-help-package-command-$line[1]:" + case $line[1] in + (common-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(amd-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(intel-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(gnome-extra-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(firmware-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(custom-list) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +} + +(( $+functions[_feddy_commands] )) || +_feddy_commands() { + local commands; commands=( +'configure-dnf:Configure dnf' \ +'add-repo:Add a repository' \ +'install-rpm-fusion:Install RPM fusion' \ +'add-user-to-groups:Add user to groups' \ +'package:Manage packages' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy commands' commands "$@" +} +(( $+functions[_feddy__add-repo_commands] )) || +_feddy__add-repo_commands() { + local commands; commands=( +'vscode:Add VSCode repository' \ +'mullvad:Add Mullvad repository' \ +'vivaldi:Add Vivaldi repository' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy add-repo commands' commands "$@" +} +(( $+functions[_feddy__add-repo__help_commands] )) || +_feddy__add-repo__help_commands() { + local commands; commands=( +'vscode:Add VSCode repository' \ +'mullvad:Add Mullvad repository' \ +'vivaldi:Add Vivaldi repository' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy add-repo help commands' commands "$@" +} +(( $+functions[_feddy__add-repo__help__help_commands] )) || +_feddy__add-repo__help__help_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo help help commands' commands "$@" +} +(( $+functions[_feddy__add-repo__help__mullvad_commands] )) || +_feddy__add-repo__help__mullvad_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo help mullvad commands' commands "$@" +} +(( $+functions[_feddy__add-repo__help__vivaldi_commands] )) || +_feddy__add-repo__help__vivaldi_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo help vivaldi commands' commands "$@" +} +(( $+functions[_feddy__add-repo__help__vscode_commands] )) || +_feddy__add-repo__help__vscode_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo help vscode commands' commands "$@" +} +(( $+functions[_feddy__add-repo__mullvad_commands] )) || +_feddy__add-repo__mullvad_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo mullvad commands' commands "$@" +} +(( $+functions[_feddy__add-repo__vivaldi_commands] )) || +_feddy__add-repo__vivaldi_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo vivaldi commands' commands "$@" +} +(( $+functions[_feddy__add-repo__vscode_commands] )) || +_feddy__add-repo__vscode_commands() { + local commands; commands=() + _describe -t commands 'feddy add-repo vscode commands' commands "$@" +} +(( $+functions[_feddy__add-user-to-groups_commands] )) || +_feddy__add-user-to-groups_commands() { + local commands; commands=() + _describe -t commands 'feddy add-user-to-groups commands' commands "$@" +} +(( $+functions[_feddy__configure-dnf_commands] )) || +_feddy__configure-dnf_commands() { + local commands; commands=() + _describe -t commands 'feddy configure-dnf commands' commands "$@" +} +(( $+functions[_feddy__help_commands] )) || +_feddy__help_commands() { + local commands; commands=( +'configure-dnf:Configure dnf' \ +'add-repo:Add a repository' \ +'install-rpm-fusion:Install RPM fusion' \ +'add-user-to-groups:Add user to groups' \ +'package:Manage packages' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy help commands' commands "$@" +} +(( $+functions[_feddy__help__add-repo_commands] )) || +_feddy__help__add-repo_commands() { + local commands; commands=( +'vscode:Add VSCode repository' \ +'mullvad:Add Mullvad repository' \ +'vivaldi:Add Vivaldi repository' \ + ) + _describe -t commands 'feddy help add-repo commands' commands "$@" +} +(( $+functions[_feddy__help__add-repo__mullvad_commands] )) || +_feddy__help__add-repo__mullvad_commands() { + local commands; commands=() + _describe -t commands 'feddy help add-repo mullvad commands' commands "$@" +} +(( $+functions[_feddy__help__add-repo__vivaldi_commands] )) || +_feddy__help__add-repo__vivaldi_commands() { + local commands; commands=() + _describe -t commands 'feddy help add-repo vivaldi commands' commands "$@" +} +(( $+functions[_feddy__help__add-repo__vscode_commands] )) || +_feddy__help__add-repo__vscode_commands() { + local commands; commands=() + _describe -t commands 'feddy help add-repo vscode commands' commands "$@" +} +(( $+functions[_feddy__help__add-user-to-groups_commands] )) || +_feddy__help__add-user-to-groups_commands() { + local commands; commands=() + _describe -t commands 'feddy help add-user-to-groups commands' commands "$@" +} +(( $+functions[_feddy__help__configure-dnf_commands] )) || +_feddy__help__configure-dnf_commands() { + local commands; commands=() + _describe -t commands 'feddy help configure-dnf commands' commands "$@" +} +(( $+functions[_feddy__help__help_commands] )) || +_feddy__help__help_commands() { + local commands; commands=() + _describe -t commands 'feddy help help commands' commands "$@" +} +(( $+functions[_feddy__help__install-rpm-fusion_commands] )) || +_feddy__help__install-rpm-fusion_commands() { + local commands; commands=() + _describe -t commands 'feddy help install-rpm-fusion commands' commands "$@" +} +(( $+functions[_feddy__help__package_commands] )) || +_feddy__help__package_commands() { + local commands; commands=( +'common-list:Install/Remove the common list' \ +'amd-list:Install/Remove the AMD list' \ +'intel-list:Install/Remove the Intel list' \ +'gnome-extra-list:Install/Remove the Gnome extra list' \ +'firmware-list:Install/Remove the firmware list' \ +'custom-list:Install/Remove a custom list' \ + ) + _describe -t commands 'feddy help package commands' commands "$@" +} +(( $+functions[_feddy__help__package__amd-list_commands] )) || +_feddy__help__package__amd-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package amd-list commands' commands "$@" +} +(( $+functions[_feddy__help__package__common-list_commands] )) || +_feddy__help__package__common-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package common-list commands' commands "$@" +} +(( $+functions[_feddy__help__package__custom-list_commands] )) || +_feddy__help__package__custom-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package custom-list commands' commands "$@" +} +(( $+functions[_feddy__help__package__firmware-list_commands] )) || +_feddy__help__package__firmware-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package firmware-list commands' commands "$@" +} +(( $+functions[_feddy__help__package__gnome-extra-list_commands] )) || +_feddy__help__package__gnome-extra-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package gnome-extra-list commands' commands "$@" +} +(( $+functions[_feddy__help__package__intel-list_commands] )) || +_feddy__help__package__intel-list_commands() { + local commands; commands=() + _describe -t commands 'feddy help package intel-list commands' commands "$@" +} +(( $+functions[_feddy__install-rpm-fusion_commands] )) || +_feddy__install-rpm-fusion_commands() { + local commands; commands=() + _describe -t commands 'feddy install-rpm-fusion commands' commands "$@" +} +(( $+functions[_feddy__package_commands] )) || +_feddy__package_commands() { + local commands; commands=( +'common-list:Install/Remove the common list' \ +'amd-list:Install/Remove the AMD list' \ +'intel-list:Install/Remove the Intel list' \ +'gnome-extra-list:Install/Remove the Gnome extra list' \ +'firmware-list:Install/Remove the firmware list' \ +'custom-list:Install/Remove a custom list' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy package commands' commands "$@" +} +(( $+functions[_feddy__package__amd-list_commands] )) || +_feddy__package__amd-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package amd-list commands' commands "$@" +} +(( $+functions[_feddy__package__common-list_commands] )) || +_feddy__package__common-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package common-list commands' commands "$@" +} +(( $+functions[_feddy__package__custom-list_commands] )) || +_feddy__package__custom-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package custom-list commands' commands "$@" +} +(( $+functions[_feddy__package__firmware-list_commands] )) || +_feddy__package__firmware-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package firmware-list commands' commands "$@" +} +(( $+functions[_feddy__package__gnome-extra-list_commands] )) || +_feddy__package__gnome-extra-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package gnome-extra-list commands' commands "$@" +} +(( $+functions[_feddy__package__help_commands] )) || +_feddy__package__help_commands() { + local commands; commands=( +'common-list:Install/Remove the common list' \ +'amd-list:Install/Remove the AMD list' \ +'intel-list:Install/Remove the Intel list' \ +'gnome-extra-list:Install/Remove the Gnome extra list' \ +'firmware-list:Install/Remove the firmware list' \ +'custom-list:Install/Remove a custom list' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'feddy package help commands' commands "$@" +} +(( $+functions[_feddy__package__help__amd-list_commands] )) || +_feddy__package__help__amd-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help amd-list commands' commands "$@" +} +(( $+functions[_feddy__package__help__common-list_commands] )) || +_feddy__package__help__common-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help common-list commands' commands "$@" +} +(( $+functions[_feddy__package__help__custom-list_commands] )) || +_feddy__package__help__custom-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help custom-list commands' commands "$@" +} +(( $+functions[_feddy__package__help__firmware-list_commands] )) || +_feddy__package__help__firmware-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help firmware-list commands' commands "$@" +} +(( $+functions[_feddy__package__help__gnome-extra-list_commands] )) || +_feddy__package__help__gnome-extra-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help gnome-extra-list commands' commands "$@" +} +(( $+functions[_feddy__package__help__help_commands] )) || +_feddy__package__help__help_commands() { + local commands; commands=() + _describe -t commands 'feddy package help help commands' commands "$@" +} +(( $+functions[_feddy__package__help__intel-list_commands] )) || +_feddy__package__help__intel-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package help intel-list commands' commands "$@" +} +(( $+functions[_feddy__package__intel-list_commands] )) || +_feddy__package__intel-list_commands() { + local commands; commands=() + _describe -t commands 'feddy package intel-list commands' commands "$@" +} + +if [ "$funcstack[1]" = "_feddy" ]; then + _feddy "$@" +else + compdef _feddy feddy +fi diff --git a/data/amd_list b/data/amd_list new file mode 100644 index 0000000..908e6ec --- /dev/null +++ b/data/amd_list @@ -0,0 +1,16 @@ +libva +libva-utils +gstreamer1-vaapi +ffmpeg +mesa-dri-drivers +mesa-va-drivers-freeworld +mesa-vdpau-drivers-freeworld +mesa-va-drivers-freeworld.i686 +mesa-vdpau-drivers-freeworld.i686 +rocm-opencl +rocminfo +rocm-clinfo +rocm-hip +rocm-runtime +rocm-smi +rocm-hip-devel \ No newline at end of file diff --git a/data/common_list b/data/common_list new file mode 100644 index 0000000..13f58f1 --- /dev/null +++ b/data/common_list @@ -0,0 +1,42 @@ +@development-tools +@virtualization +@multimedia +@sound-and-video +vim +papirus-icon-theme +jetbrains-mono-fonts-all +rsms-inter-fonts +rsms-inter-vf-fonts +fish +rustup +git +htop +btop +fastfetch +inxi +dejavu-fonts-all +liberation-fonts +liberation-narrow-fonts +google-noto-emoji-fonts +google-noto-color-emoji-fonts +google-noto-sans-fonts +google-roboto* +mozilla-fira* +adobe-source-code* +adobe-source-sans-pro-fonts +fontawesome-fonts-all +google-droid-fonts-all +bitstream-vera-fonts-all +fira-code-fonts +cascadia-fonts-all +intel-one-mono-fonts +curl +gstreamer1-plugins-base +gstreamer1-plugins-good +gstreamer1-plugins-bad-free +gstreamer1-plugins-good-extras +gstreamer1-plugins-bad-free-extras +gstreamer1-plugins-ugly-free +gstreamer1-plugin-libav +gstreamer1-plugin-openh264 +https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm \ No newline at end of file diff --git a/data/firmware_list b/data/firmware_list new file mode 100644 index 0000000..34392ec --- /dev/null +++ b/data/firmware_list @@ -0,0 +1 @@ +*-firmware \ No newline at end of file diff --git a/data/gnome_extra_list b/data/gnome_extra_list new file mode 100644 index 0000000..eed01a2 --- /dev/null +++ b/data/gnome_extra_list @@ -0,0 +1,7 @@ +gnome-tweaks +gnome-extensions-app +gnome-shell-extension-appindicator +gnome-shell-extension-dash-to-dock +gnome-shell-extension-caffeine +gnome-shell-extension-gsconnect +gnome-shell-extension-system-monitor \ No newline at end of file diff --git a/data/intel_list b/data/intel_list new file mode 100644 index 0000000..bfa7066 --- /dev/null +++ b/data/intel_list @@ -0,0 +1,13 @@ +intel-media-driver +libva-intel-driver +libva-intel-media-driver +libva +libva-utils +gstreamer1-vaapi +ffmpeg +intel-gpu-tools +mesa-dri-drivers +mesa-va-drivers-freeworld +mesa-vdpau-drivers-freeworld +mesa-va-drivers-freeworld.i686 +mesa-vdpau-drivers-freeworld.i686 \ No newline at end of file diff --git a/data/user_groups b/data/user_groups new file mode 100644 index 0000000..45e2b6d --- /dev/null +++ b/data/user_groups @@ -0,0 +1,15 @@ +libvirt +video +audio +bin +colord +daemon +dbus +flatpak +games +input +kvm +pipewire +polkitd +qemu +render \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs deleted file mode 100644 index 728c0fe..0000000 --- a/src/cli.rs +++ /dev/null @@ -1,60 +0,0 @@ -use clap::{Parser, Args, Subcommand, crate_authors, crate_description, crate_name, crate_version}; -use clap_complete::Shell; - -#[derive(Parser, Debug, PartialEq)] -#[command(name = crate_name!(), author = crate_authors!(), version = crate_version!(), about = crate_description!())] -pub struct Cli { - #[arg(long = "generate", hide = true, value_enum)] - pub generator: Option, - - #[command(subcommand)] - pub command: Commands, -} - -#[derive(Subcommand, Debug, PartialEq)] -pub enum Commands { - #[command(about = "A set of commands to configure Fedora")] - Config(ConfigCommand), - - #[command(about = "A set of commands to manage packages")] - Package(PackageCommand), -} - -#[derive(Args, Debug, PartialEq)] -pub struct ConfigCommand { - #[arg(long, value_name = "CONFIG_FILE", default_value = "config.toml")] - pub config_file: String, - - #[command(subcommand)] - pub subcommand: ConfigSubcommand, -} - -#[derive(Args, Debug, PartialEq)] -pub struct PackageCommand { - #[arg(long, value_name = "PACKAGE_FILE", default_value = "packages.toml")] - pub package_file: String, - - #[command(subcommand)] - pub subcommand: PackageSubcommand, -} - -#[derive(Subcommand, Debug, PartialEq)] -pub enum ConfigSubcommand { - #[command(about = "Generate a configuration file")] - Generate, - - #[command(about = "Validate a configuration file")] - Validate, -} - -#[derive(Subcommand, Debug, PartialEq)] -pub enum PackageSubcommand { - #[command(about = "Install packages")] - Install, - - #[command(about = "Remove packages")] - Remove, - - #[command(about = "List installed packages")] - List, -} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d381965 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,152 @@ +use clap::{ + Args, Command, Parser, Subcommand, crate_authors, crate_description, crate_name, crate_version, +}; +use clap_complete::{Generator, Shell, generate}; +use core::str; +use env_logger::fmt::style; +use std::{error::Error, io::Write}; + +pub type Result = core::result::Result>; + +#[derive(Parser, Debug, PartialEq)] +#[command(name = crate_name!(), author = crate_authors!(), version = crate_version!(), about = crate_description!())] +pub struct Cli { + #[arg(long = "generate", hide = true, value_enum)] + pub generator: Option, + + #[command(subcommand)] + pub command: Option, +} + +#[derive(Subcommand, Debug, PartialEq)] +pub enum Commands { + #[command(about = "Configure dnf")] + ConfigureDnf, + + #[command(about = "Add a repository")] + AddRepo(AddRepoCommand), + + #[command(about = "Install RPM fusion")] + InstallRpmFusion, + + #[command(about = "Add user to groups")] + AddUserToGroups(AddUserToGroupsCommand), + + #[command(about = "Manage packages")] + Package(PackageCommand), +} + +#[derive(Args, Debug, PartialEq)] +pub struct AddUserToGroupsCommand { + #[arg(short, long)] + pub user: Option, +} + +#[derive(Args, Debug, PartialEq)] +pub struct AddRepoCommand { + #[command(subcommand)] + pub command: AddRepoSubCommand, +} + +#[derive(Subcommand, Debug, PartialEq)] +pub enum AddRepoSubCommand { + #[command(about = "Add VSCode repository")] + Vscode, + + #[command(about = "Add Mullvad repository")] + Mullvad, + + #[command(about = "Add Vivaldi repository")] + Vivaldi, +} + +#[derive(Args, Debug, PartialEq, Clone)] +pub struct PackageCommand { + #[arg(short, long)] + pub remove: bool, + + #[command(subcommand)] + pub command: PackageSubCommand, +} + +#[derive(Subcommand, Debug, PartialEq, Clone)] +pub enum PackageSubCommand { + #[command(about = "Install/Remove the common list")] + CommonList, + + #[command(about = "Install/Remove the AMD list")] + AmdList, + + #[command(about = "Install/Remove the Intel list")] + IntelList, + + #[command(about = "Install/Remove the Gnome extra list")] + GnomeExtraList, + + #[command(about = "Install/Remove the firmware list")] + FirmwareList, + + #[command(about = "Install/Remove a custom list")] + CustomList(CustomListCommand), +} + +#[derive(Args, Debug, PartialEq, Clone)] +pub struct CustomListCommand { + #[arg(short, long)] + pub file: String, +} + +#[macro_export] +macro_rules! success { + () => { + log::info!(); + }; + ($($arg:tt)*) => {{ + let style = env_logger::fmt::style::AnsiColor::Green.on_default().bold(); + log::info!("{style}{}{style:#}", format!($($arg)*) + ); + }}; +} + +#[macro_export] +macro_rules! read_file { + ($file:expr) => { + std::fs::read_to_string($file).map_err(|e| { + log::error!("Error reading file {}: {}", $file, e); + e + }) + }; +} + +pub fn configure_logger() { + let log_level = std::env::var("RUST_LOG").unwrap_or("info".to_string()); + env_logger::Builder::new() + .format(|buf, record| { + let level = record.level(); + let style = buf.default_level_style(level); + let dimmed = style::AnsiColor::White.on_default().dimmed(); + let message_style = match level { + log::Level::Error => style::AnsiColor::Red.on_default().bold(), + log::Level::Warn => style::AnsiColor::Yellow.on_default().bold(), + log::Level::Info => style::AnsiColor::White.on_default(), + log::Level::Debug => dimmed, + log::Level::Trace => dimmed, + }; + writeln!( + buf, + "{style}{level:<5}{style:#} {dimmed}>{dimmed:#} {message_style}{}{message_style:#}", + record.args() + ) + }) + .parse_filters(log_level.as_str()) + .init(); +} + +pub fn print_completions(generator: G, cmd: &mut Command) { + generate( + generator, + cmd, + cmd.get_name().to_string(), + &mut std::io::stdout(), + ); +} diff --git a/src/main.rs b/src/main.rs index 654de08..4f2a201 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,95 +1,270 @@ -mod cli; +use std::thread::available_parallelism; -use clap::Parser; -use cli::Cli; -use env_logger::fmt::style; - -use std::io::Write; +use clap::{CommandFactory, Parser}; +use feddy::*; +use ini::Ini; fn main() { - let log_level = std::env::var("RUST_LOG").unwrap_or("info".to_string()); - env_logger::Builder::new() - .format(|buf, record| { - let level = record.level(); - let style = buf.default_level_style(level); - let dimmed = style::AnsiColor::White.on_default().dimmed(); - let message_style = match level { - log::Level::Error => style::AnsiColor::Red.on_default().bold(), - log::Level::Warn => style::AnsiColor::Yellow.on_default().bold(), - log::Level::Info => style::AnsiColor::White.on_default(), - log::Level::Debug => dimmed, - log::Level::Trace => dimmed, - }; - writeln!( - buf, - "{style}{level:<5}{style:#} {dimmed}>{dimmed:#} {message_style}{}{message_style:#}", - record.args() - ) - }) - .parse_filters(log_level.as_str()) - .init(); + configure_logger(); let cli = Cli::parse(); - log::debug!("Parsed CLI arguments: {:?}", cli); - match cli.command { - cli::Commands::Config(config) => { - log::info!("Config command selected with config file: {}", config.config_file); - handle_config_command(config); - } - cli::Commands::Package(package) => { - log::info!("Package command selected with package file: {}", package.package_file); - handle_package_command(package); - } + let mut cmd = Cli::command(); + + if let Some(generator) = cli.generator { + log::info!("Generating completion file for {generator:?}..."); + print_completions(generator, &mut cmd); + return; } + + if let Some(command) = cli.command { + match command { + Commands::ConfigureDnf => { + if let Err(e) = configure_dnf() { + log::error!("Error configuring dnf: {}", e); + } + } + Commands::AddRepo(repo_command) => { + if let Err(e) = add_repo(repo_command) { + log::error!("Error adding repository: {}", e); + } + } + Commands::InstallRpmFusion => { + if let Err(e) = install_rpm_fusion() { + log::error!("Error installing RPM Fusion: {}", e); + } + } + Commands::AddUserToGroups(add_user_command) => { + if let Err(e) = add_user_to_groups(add_user_command) { + log::error!("Error adding user to groups: {}", e); + } + } + Commands::Package(package_command) => { + if let Err(e) = manage_package(package_command) { + log::error!("Error executing package command: {}", e); + } + } + } + } else { + cmd.print_help().unwrap(); + } + + success!("Bye :)"); } -fn handle_config_command(config: cli::ConfigCommand) { - match config.subcommand { - cli::ConfigSubcommand::Generate => { - log::info!("Generating configuration file: {}", config.config_file); - handle_generate_config(&config.config_file); - } - cli::ConfigSubcommand::Validate => { - log::info!("Validating configuration file: {}", config.config_file); - handle_validate_config(&config.config_file); - } +fn add_user_to_groups(add_user_command: AddUserToGroupsCommand) -> Result<()> { + let user = add_user_command.user.unwrap_or_else(|| { + log::info!("No user specified, using current user"); + whoami::username() + }); + log::info!("Adding user {} to groups...", user); + let groups = include_str!("../data/user_groups").to_string(); + + let groups = groups + .lines() + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .filter(|group| { + let group_exists = std::process::Command::new("getent") + .arg("group") + .arg(group) + .output() + .map(|output| output.status.success()) + .unwrap_or(false); + if !group_exists { + log::warn!("Group {} does not exist.", group); + } + group_exists + }) + .collect::>(); + + if groups.is_empty() { + log::warn!("No valid groups found to add user to."); + return Ok(()); } + + let groups = groups.join(","); + + log::info!("Adding user {} to groups: {}", user, groups); + + let mut cmd = std::process::Command::new("usermod"); + cmd.arg("-aG"); + cmd.arg(groups); + cmd.arg(&user); + + log::debug!("Executing command: {:?}", cmd); + + cmd.status()?; + + Ok(()) } -fn handle_package_command(package: cli::PackageCommand) { - match package.subcommand { - cli::PackageSubcommand::Install => { - log::info!("Installing packages from file: {}", package.package_file); - handle_install_packages(&package.package_file); +fn add_repo(repo_command: AddRepoCommand) -> Result<()> { + match repo_command.command { + AddRepoSubCommand::Vscode => { + add_repo_common( + "vscode", + "Visual Studio Code", + "https://packages.microsoft.com/keys/microsoft.asc", + "https://packages.microsoft.com/yumrepos/vscode", + "/etc/yum.repos.d/vscode.repo", + )?; } - cli::PackageSubcommand::Remove => { - log::info!("Removing packages from file: {}", package.package_file); - handle_remove_packages(&package.package_file); + AddRepoSubCommand::Mullvad => { + add_repo_common( + "mullvad-stable", + "Mullvad VPN", + "https://repository.mullvad.net/rpm/mullvad-keyring.asc", + "https://repository.mullvad.net/rpm/stable/$basearch", + "/etc/yum.repos.d/mullvad.repo", + )?; } - cli::PackageSubcommand::List => { - log::info!("Listing installed packages from file: {}", package.package_file); - handle_list_packages(&package.package_file); + AddRepoSubCommand::Vivaldi => { + add_repo_common( + "vivaldi", + "Vivaldi", + "https://repo.vivaldi.com/archive/linux_signing_key.pub", + "https://repo.vivaldi.com/archive/rpm/x86_64", + "/etc/yum.repos.d/vivaldi.repo", + )?; } } + + Ok(()) } -fn handle_generate_config(config_file: &str) { - log::info!("Generating configuration file: {}", config_file); - // Implement the logic to generate a configuration file +fn add_repo_common( + name: &str, + display_name: &str, + gpg_key_url: &str, + baseurl: &str, + repo_file_path: &str, +) -> Result<()> { + log::info!("Importing {} GPG key...", display_name); + std::process::Command::new("rpm") + .arg("--import") + .arg(gpg_key_url) + .status()?; + + let mut conf = Ini::new(); + conf.with_section(Some(name)) + .set("name", display_name) + .set("enabled", "1") + .set("gpgcheck", "1") + .set("autorefresh", "1") + .set("baseurl", baseurl) + .set("gpgkey", gpg_key_url); + + log::info!("Adding {} repository...", display_name); + conf.write_to_file(repo_file_path)?; + + Ok(()) } -fn handle_validate_config(config_file: &str) { - log::info!("Validating configuration file: {}", config_file); - // Implement the logic to validate a configuration file + +fn install_rpm_fusion() -> Result<()> { + let fedora_version_vec = std::process::Command::new("rpm") + .arg("-E") + .arg("%fedora") + .output()? + .stdout; + let fedora_version = String::from_utf8_lossy(&fedora_version_vec); + let fedora_version = fedora_version.trim(); + log::info!("Installing RPM Fusion for Fedora {}", fedora_version); + + log::info!("Enabling the openh264 library..."); + std::process::Command::new("dnf") + .arg("config-manager") + .arg("setopt") + .arg("fedora-cisco-openh264.enabled=1") + .status()?; + + log::info!("Installing RPM Fusion free and non-free repositories..."); + std::process::Command::new("dnf") + .arg("install") + .arg(format!( + "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{}.noarch.rpm", + fedora_version + )) + .arg(format!( + "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{}.noarch.rpm", + fedora_version + )) + .status()?; + + log::info!("Installing RPM Fusion additional packages..."); + std::process::Command::new("dnf") + .arg("install") + .arg("rpmfusion-free-appstream-data") + .arg("rpmfusion-nonfree-appstream-data") + .arg("rpmfusion-free-release-tainted") + .arg("rpmfusion-nonfree-release-tainted") + .status()?; + + Ok(()) } -fn handle_install_packages(package_file: &str) { - log::info!("Installing packages from file: {}", package_file); - // Implement the logic to install packages + +fn manage_package(package_command: PackageCommand) -> Result<()> { + let list = match &package_command.command { + PackageSubCommand::CommonList => include_str!("../data/common_list").to_string(), + PackageSubCommand::AmdList => include_str!("../data/amd_list").to_string(), + PackageSubCommand::IntelList => include_str!("../data/intel_list").to_string(), + PackageSubCommand::GnomeExtraList => include_str!("../data/gnome_extra_list").to_string(), + PackageSubCommand::FirmwareList => include_str!("../data/firmware_list").to_string(), + PackageSubCommand::CustomList(custom_list_command) => { + log::info!("Using custom list from {}", custom_list_command.file); + read_file!(&custom_list_command.file)? + } + }; + + manage_list(list, package_command.remove)?; + + Ok(()) } -fn handle_remove_packages(package_file: &str) { - log::info!("Removing packages from file: {}", package_file); - // Implement the logic to remove packages + +fn manage_list(list: String, remove: bool) -> Result<()> { + let packages = list + .lines() + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .collect::>(); + + let mut dnf_cmd = std::process::Command::new("dnf"); + if remove { + log::info!("Removing common list..."); + dnf_cmd.arg("remove"); + } else { + log::info!("Installing common list..."); + dnf_cmd.arg("install").arg("--allowerasing"); + } + + packages.iter().for_each(|package| { + dnf_cmd.arg(package); + }); + + dnf_cmd.status()?; + + Ok(()) +} + +fn configure_dnf() -> Result<()> { + log::info!("Tweaking dnf configuration..."); + let mut conf = Ini::load_from_file("/etc/dnf/dnf.conf")?; + + let max_parallel_downloads = + std::cmp::min(20, std::cmp::max(available_parallelism()?.get() / 2, 3)); + + log::info!( + "Setting max_parallel_downloads to {}", + max_parallel_downloads + ); + log::info!("Setting defaultyes to True"); + + conf.with_section(Some("main")) + .set("defaultyes", "True") + .set("max_parallel_downloads", max_parallel_downloads.to_string()); + + // Write the changes back to the file + log::info!("Writing changes to /etc/dnf/dnf.conf"); + conf.write_to_file("/etc/dnf/dnf.conf")?; + + Ok(()) } -fn handle_list_packages(package_file: &str) { - log::info!("Listing installed packages from file: {}", package_file); - // Implement the logic to list installed packages -} \ No newline at end of file