From 8696c3310062497563acf8831a8f800902e14e28 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 18:34:07 +0200 Subject: [PATCH 1/8] - Add unit tests --- .github/workflows/test.yml | 2 + AGENTS.md | 60 +++++++++++++++ docker-compose.yml | 5 +- op.conf | 3 +- {test => test-legacy}/approvals.bash | 0 .../approvals/alf_download_help | 0 .../approvals/alf_generate_help | 0 {test => test-legacy}/approvals/alf_info_help | 0 {test => test-legacy}/approvals/alf_save_help | 0 .../approvals/alf_upload_help | 0 {test => test-legacy}/approve | 2 +- {test => test-legacy}/approve_zsh | 6 +- {test => test-legacy}/connect_spec.sh | 0 {test => test-legacy}/download_spec.sh | 0 {test => test-legacy}/edit_spec.sh | 0 .../fixtures/connect/.gitignore | 0 .../fixtures/connect/approvals/alf_connect | 0 .../approvals/alf_connect_DannyBen_https | 0 .../approvals/alf_connect_DannyBen_yes | 0 .../connect/approvals/alf_connect_help | 0 ...https_github_com_DannyBen_alf_conf_git_yes | 0 .../fixtures/connect/approvals/alf_download | 2 +- .../fixtures/connect/approvals/alf_upload | 2 +- .../fixtures/connect/approvals/cat_alfrc | 1 + .../approvals/echo_a_alf_connect_JohnSnow | 2 +- .../echo_a_alf_connect_JohnSnow_winterfell | 2 +- ...ct_https_bitbucket_com_JohnSnow_winterfell | 2 +- .../fixtures/empty-dir/approvals/alf | 0 .../fixtures/empty-dir/approvals/alf_download | 0 .../fixtures/empty-dir/approvals/alf_generate | 0 .../fixtures/empty-dir/approvals/alf_help | 0 .../fixtures/empty-dir/approvals/alf_save | 0 .../fixtures/empty-dir/approvals/alf_upgrade | 15 ++++ .../empty-dir/approvals/alf_upgrade_help | 0 .../fixtures/empty-dir/approvals/alf_upload | 0 .../fixtures/empty-dir/approvals/alf_version | 0 .../fixtures/generate/alf.conf | 0 .../fixtures/generate/aliases.txt | 0 .../fixtures/generate/approvals/alf_generate | 0 .../fixtures/generate/approvals/alf_save | 0 .../fixtures/generate/approvals/alf_which | 0 .../generate/approvals/alf_which_dc_deploy | 0 .../generate/approvals/alf_which_dc_upd | 0 .../fixtures/generate/approvals/alf_which_g | 0 .../fixtures/generate/approvals/alf_which_g_l | 0 .../generate/approvals/alf_which_g_no | 0 .../generate/approvals/alf_which_help | 0 .../fixtures/generate/approvals/alf_which_no | 0 .../generate/approvals/say_again_zsh_works | 0 {test => test-legacy}/fixtures/info/alf.conf | 0 test-legacy/fixtures/info/alfrc | 1 + .../fixtures/info/aliases.txt | 0 .../fixtures/info/approvals/alf_info | 6 +- .../fixtures/no-subcommands/alf.conf | 0 .../no-subcommands/approvals/alf_generate | 0 .../fixtures/sample/alf.conf | 0 .../fixtures/sample/approvals/alf_edit | 0 .../fixtures/sample/approvals/alf_edit_help | 0 .../fixtures/sample/approvals/alf_info | 2 +- {test => test-legacy}/generate_spec.sh | 0 {test => test-legacy}/info_spec.sh | 0 {test => test-legacy}/save_spec.sh | 0 {test => test-legacy}/upgrade_spec.sh | 0 {test => test-legacy}/upload_spec.sh | 0 {test => test-legacy}/usage_spec.sh | 0 {test => test-legacy}/which_spec.sh | 0 test/commands/info.bats | 53 +++++++++++++ test/fixtures/connect/approvals/cat_alfrc | 1 - test/fixtures/empty-dir/approvals/alf_upgrade | 25 ------ .../fixtures/find_config/remote-repo/alf.conf | 1 + test/fixtures/find_config/with-alfrc/alfrc | 1 + .../find_config/with-local-config/alf.conf | 1 + .../find_config/without-config/.gitkeep | 1 + .../with-subcommands/alf.conf | 7 ++ .../with-subcommands/expected.txt | 5 ++ .../without-config/.gitkeep | 1 + .../without-subcommands/alf.conf | 2 + .../without-subcommands/expected.txt | 3 + test/fixtures/generate_config/flat/alf.conf | 2 + .../fixtures/generate_config/flat/expected.sh | 12 +++ .../generate_config/with-subcommands/alf.conf | 5 ++ .../with-subcommands/expected.sh | 38 +++++++++ .../generate_config/without-config/.gitkeep | 1 + .../has_subcommands/with-subcommands/alf.conf | 3 + .../has_subcommands/without-config/.gitkeep | 1 + .../without-subcommands/alf.conf | 2 + test/fixtures/info/alfrc | 1 - test/lib/find_config.bats | 48 ++++++++++++ test/lib/generate_completion.bats | 47 +++++++++++ test/lib/generate_config.bats | 47 +++++++++++ test/lib/has_subcommands.bats | 46 +++++++++++ test/lib/save_config.bats | 77 +++++++++++++++++++ test/test_helper.bash | 47 +++++++++++ 93 files changed, 547 insertions(+), 44 deletions(-) create mode 100644 AGENTS.md rename {test => test-legacy}/approvals.bash (100%) rename {test => test-legacy}/approvals/alf_download_help (100%) rename {test => test-legacy}/approvals/alf_generate_help (100%) rename {test => test-legacy}/approvals/alf_info_help (100%) rename {test => test-legacy}/approvals/alf_save_help (100%) rename {test => test-legacy}/approvals/alf_upload_help (100%) rename {test => test-legacy}/approve (93%) mode change 100755 => 100644 rename {test => test-legacy}/approve_zsh (70%) rename {test => test-legacy}/connect_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/download_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/edit_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/fixtures/connect/.gitignore (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_connect (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_connect_DannyBen_https (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_connect_DannyBen_yes (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_connect_help (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes (100%) rename {test => test-legacy}/fixtures/connect/approvals/alf_download (64%) rename {test => test-legacy}/fixtures/connect/approvals/alf_upload (61%) create mode 100644 test-legacy/fixtures/connect/approvals/cat_alfrc rename {test => test-legacy}/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow (78%) rename {test => test-legacy}/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell (78%) rename {test => test-legacy}/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell (72%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_download (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_generate (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_help (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_save (100%) create mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_upgrade rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_upgrade_help (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_upload (100%) rename {test => test-legacy}/fixtures/empty-dir/approvals/alf_version (100%) rename {test => test-legacy}/fixtures/generate/alf.conf (100%) rename {test => test-legacy}/fixtures/generate/aliases.txt (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_generate (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_save (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_dc_deploy (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_dc_upd (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_g (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_g_l (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_g_no (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_help (100%) rename {test => test-legacy}/fixtures/generate/approvals/alf_which_no (100%) rename {test => test-legacy}/fixtures/generate/approvals/say_again_zsh_works (100%) rename {test => test-legacy}/fixtures/info/alf.conf (100%) create mode 100644 test-legacy/fixtures/info/alfrc rename {test => test-legacy}/fixtures/info/aliases.txt (100%) rename {test => test-legacy}/fixtures/info/approvals/alf_info (58%) rename {test => test-legacy}/fixtures/no-subcommands/alf.conf (100%) rename {test => test-legacy}/fixtures/no-subcommands/approvals/alf_generate (100%) rename {test => test-legacy}/fixtures/sample/alf.conf (100%) rename {test => test-legacy}/fixtures/sample/approvals/alf_edit (100%) rename {test => test-legacy}/fixtures/sample/approvals/alf_edit_help (100%) rename {test => test-legacy}/fixtures/sample/approvals/alf_info (84%) rename {test => test-legacy}/generate_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/info_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/save_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/upgrade_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/upload_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/usage_spec.sh (100%) mode change 100755 => 100644 rename {test => test-legacy}/which_spec.sh (100%) mode change 100755 => 100644 create mode 100644 test/commands/info.bats delete mode 100644 test/fixtures/connect/approvals/cat_alfrc delete mode 100644 test/fixtures/empty-dir/approvals/alf_upgrade create mode 100644 test/fixtures/find_config/remote-repo/alf.conf create mode 100644 test/fixtures/find_config/with-alfrc/alfrc create mode 100644 test/fixtures/find_config/with-local-config/alf.conf create mode 100644 test/fixtures/find_config/without-config/.gitkeep create mode 100644 test/fixtures/generate_completion/with-subcommands/alf.conf create mode 100644 test/fixtures/generate_completion/with-subcommands/expected.txt create mode 100644 test/fixtures/generate_completion/without-config/.gitkeep create mode 100644 test/fixtures/generate_completion/without-subcommands/alf.conf create mode 100644 test/fixtures/generate_completion/without-subcommands/expected.txt create mode 100644 test/fixtures/generate_config/flat/alf.conf create mode 100644 test/fixtures/generate_config/flat/expected.sh create mode 100644 test/fixtures/generate_config/with-subcommands/alf.conf create mode 100644 test/fixtures/generate_config/with-subcommands/expected.sh create mode 100644 test/fixtures/generate_config/without-config/.gitkeep create mode 100644 test/fixtures/has_subcommands/with-subcommands/alf.conf create mode 100644 test/fixtures/has_subcommands/without-config/.gitkeep create mode 100644 test/fixtures/has_subcommands/without-subcommands/alf.conf delete mode 100644 test/fixtures/info/alfrc create mode 100644 test/lib/find_config.bats create mode 100644 test/lib/generate_completion.bats create mode 100644 test/lib/generate_config.bats create mode 100644 test/lib/has_subcommands.bats create mode 100644 test/lib/save_config.bats create mode 100644 test/test_helper.bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2bde82..c675801 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,6 +18,8 @@ jobs: run: docker compose run ci - name: Run sanity test in zsh run: docker compose run test_zsh + - name: Run Bats tests + run: bats test/commands test/lib ubuntu_setup: name: Setup on Ubuntu diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e9d4b27 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,60 @@ +# AGENTS.md + +## Purpose + +This repository is a Bashly-based CLI. Prefer working from the source partials in `src/` and regenerate artifacts as needed. + +## Source Of Truth + +- Do not use the generated `./alf` executable as the primary code-reading target. +- Treat `./alf` as a generated artifact for verification only. +- Read and edit: + - `src/bashly.yml` + - `src/initialize.sh` + - `src/*_command.sh` + - `src/lib/*.sh` + - `settings.yml` + +## Generated Artifact Policy + +- Only inspect `./alf` when you need to verify generated output, trace a generation issue, or confirm the final emitted behavior. +- Do not base architectural conclusions or refactoring plans on `./alf` when the equivalent source exists under `src/`. + +## Test Strategy + +The repository currently uses approval tests. Keep this distinction clear in future work: + +- Approval tests should cover stable user-facing output: + - help text + - generated alias output + - other intentional CLI snapshots +- Behavioral tests should move toward Bats: + - config discovery + - `which` + - `generate` + - `save` + - `upload` + - failure modes + - local fixture repo scenarios + +## Approval Testing Rules + +- Never edit approval files manually. +- Never refresh approval files as a blind mechanical step. +- Approval updates should happen only through the approval workflow itself. +- Approval changes should be user-approved, because the approval step is the control point that distinguishes intended output changes from regressions. +- Do not "bake in" new snapshots unless the changed output has been intentionally reviewed and accepted. + +## Migration Guidance + +- Do not remove or loosen existing approval coverage until replacement behavioral coverage exists and the current approvals pass cleanly. +- Reduce approvals only after: + - deterministic Bats coverage is in place + - network-dependent tests are removed or isolated + - the current approval suite is green + +## Review Notes + +- This project is being prepared for a `1.0.0` release and semver commitment. +- Prefer deterministic, local, hermetic tests over live network access. +- Treat installer and upgrade flows as release/integration verification, not unit coverage. diff --git a/docker-compose.yml b/docker-compose.yml index d530fc0..537b0a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,16 +20,15 @@ services: volumes: - .:/app environment: { TEST } - command: test/approve + command: test-legacy/approve test_zsh: &test_zsh <<: *zsh environment: { CI, GITHUB_ACTIONS } - command: test/approve_zsh + command: test-legacy/approve_zsh ci: <<: *test environment: CI: 1 volumes: [] - diff --git a/op.conf b/op.conf index a8ee50e..b879910 100644 --- a/op.conf +++ b/op.conf @@ -13,6 +13,7 @@ test: docker compose build bash docker compose run --rm test [[ -z "$TEST" ]] && docker compose run --rm test_zsh + bats --recursive --print-output-on-failure --abort "${1:-test}" ; echo "Exit code: $?" #? Run test suite inside a docker container #? If a specific TEST is requested, zsh tests will not be executed #? Usage: op test @@ -41,7 +42,7 @@ changelog: git changelog --save version: [[ -n "$1" ]] || abort "Usage: op version NEW_VERSION" - sed -i "s/$(alf --version)/$1/g" README.md src/bashly.yml test/fixtures/empty-dir/approvals/alf_version test/fixtures/empty-dir/approvals/alf_upgrade + sed -i "s/$(alf --version)/$1/g" README.md src/bashly.yml test-legacy/fixtures/empty-dir/approvals/alf_version test-legacy/fixtures/empty-dir/approvals/alf_upgrade op generate git commit -am "version bump $1" git tag v$1 diff --git a/test/approvals.bash b/test-legacy/approvals.bash similarity index 100% rename from test/approvals.bash rename to test-legacy/approvals.bash diff --git a/test/approvals/alf_download_help b/test-legacy/approvals/alf_download_help similarity index 100% rename from test/approvals/alf_download_help rename to test-legacy/approvals/alf_download_help diff --git a/test/approvals/alf_generate_help b/test-legacy/approvals/alf_generate_help similarity index 100% rename from test/approvals/alf_generate_help rename to test-legacy/approvals/alf_generate_help diff --git a/test/approvals/alf_info_help b/test-legacy/approvals/alf_info_help similarity index 100% rename from test/approvals/alf_info_help rename to test-legacy/approvals/alf_info_help diff --git a/test/approvals/alf_save_help b/test-legacy/approvals/alf_save_help similarity index 100% rename from test/approvals/alf_save_help rename to test-legacy/approvals/alf_save_help diff --git a/test/approvals/alf_upload_help b/test-legacy/approvals/alf_upload_help similarity index 100% rename from test/approvals/alf_upload_help rename to test-legacy/approvals/alf_upload_help diff --git a/test/approve b/test-legacy/approve old mode 100755 new mode 100644 similarity index 93% rename from test/approve rename to test-legacy/approve index 6e453cb..b0d4275 --- a/test/approve +++ b/test-legacy/approve @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Run this from the main repo directory -cd ./test +cd ./test-legacy source "approvals.bash" if [[ $TEST ]]; then diff --git a/test/approve_zsh b/test-legacy/approve_zsh similarity index 70% rename from test/approve_zsh rename to test-legacy/approve_zsh index ed53794..c44f84d 100644 --- a/test/approve_zsh +++ b/test-legacy/approve_zsh @@ -1,18 +1,18 @@ #!/usr/bin/env zsh # Run this from the main repo directory -source 'test/approvals.bash' +source 'test-legacy/approvals.bash' unset ALF_RC_FILE export ALF_ALIASES_FILE="aliases.txt" context "in zsh" describe "generated aliases in zsh" - pushd test/fixtures/generate > /dev/null + pushd test-legacy/fixtures/generate > /dev/null rm -f "aliases.txt" approve "alf save" source 'aliases.txt' || return 0 approve "say again zsh-works" popd -green "\nsanity test on ZSH passed!" \ No newline at end of file +green "\nsanity test on ZSH passed!" diff --git a/test/connect_spec.sh b/test-legacy/connect_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/connect_spec.sh rename to test-legacy/connect_spec.sh diff --git a/test/download_spec.sh b/test-legacy/download_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/download_spec.sh rename to test-legacy/download_spec.sh diff --git a/test/edit_spec.sh b/test-legacy/edit_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/edit_spec.sh rename to test-legacy/edit_spec.sh diff --git a/test/fixtures/connect/.gitignore b/test-legacy/fixtures/connect/.gitignore similarity index 100% rename from test/fixtures/connect/.gitignore rename to test-legacy/fixtures/connect/.gitignore diff --git a/test/fixtures/connect/approvals/alf_connect b/test-legacy/fixtures/connect/approvals/alf_connect similarity index 100% rename from test/fixtures/connect/approvals/alf_connect rename to test-legacy/fixtures/connect/approvals/alf_connect diff --git a/test/fixtures/connect/approvals/alf_connect_DannyBen_https b/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https similarity index 100% rename from test/fixtures/connect/approvals/alf_connect_DannyBen_https rename to test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https diff --git a/test/fixtures/connect/approvals/alf_connect_DannyBen_yes b/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes similarity index 100% rename from test/fixtures/connect/approvals/alf_connect_DannyBen_yes rename to test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes diff --git a/test/fixtures/connect/approvals/alf_connect_help b/test-legacy/fixtures/connect/approvals/alf_connect_help similarity index 100% rename from test/fixtures/connect/approvals/alf_connect_help rename to test-legacy/fixtures/connect/approvals/alf_connect_help diff --git a/test/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes b/test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes similarity index 100% rename from test/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes rename to test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes diff --git a/test/fixtures/connect/approvals/alf_download b/test-legacy/fixtures/connect/approvals/alf_download similarity index 64% rename from test/fixtures/connect/approvals/alf_download rename to test-legacy/fixtures/connect/approvals/alf_download index 619c1ed..70f5846 100644 --- a/test/fixtures/connect/approvals/alf_download +++ b/test-legacy/fixtures/connect/approvals/alf_download @@ -1,4 +1,4 @@ -Pulling from repository to /app/test/fixtures/connect/alf-conf +Pulling from repository to /app/test-legacy/fixtures/connect/alf-conf Already up to date. Saving to /root/.bash_aliases To apply the new aliases to the current session, run: diff --git a/test/fixtures/connect/approvals/alf_upload b/test-legacy/fixtures/connect/approvals/alf_upload similarity index 61% rename from test/fixtures/connect/approvals/alf_upload rename to test-legacy/fixtures/connect/approvals/alf_upload index 937de80..9654fd4 100644 --- a/test/fixtures/connect/approvals/alf_upload +++ b/test-legacy/fixtures/connect/approvals/alf_upload @@ -1,4 +1,4 @@ -Pushing /app/test/fixtures/connect/alf-conf to repository +Pushing /app/test-legacy/fixtures/connect/alf-conf to repository On branch master Your branch is up to date with 'origin/master'. diff --git a/test-legacy/fixtures/connect/approvals/cat_alfrc b/test-legacy/fixtures/connect/approvals/cat_alfrc new file mode 100644 index 0000000..ad8dc3a --- /dev/null +++ b/test-legacy/fixtures/connect/approvals/cat_alfrc @@ -0,0 +1 @@ +/app/test-legacy/fixtures/connect/alf-conf diff --git a/test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow similarity index 78% rename from test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow rename to test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow index 0a0fa5e..2fefc91 100644 --- a/test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow +++ b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow @@ -3,7 +3,7 @@ This operation will: clone JohnSnow/alf-conf.git to ./alf-conf - write /app/test/fixtures/connect/alf-conf + write /app/test-legacy/fixtures/connect/alf-conf to ./alfrc Would you like to connect to GitHub via SSH or HTTPS? diff --git a/test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell similarity index 78% rename from test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell rename to test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell index 4f0aa65..b3ee2f4 100644 --- a/test/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell +++ b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell @@ -3,7 +3,7 @@ This operation will: clone JohnSnow/winterfell.git to ./alf-conf - write /app/test/fixtures/connect/alf-conf + write /app/test-legacy/fixtures/connect/alf-conf to ./alfrc Would you like to connect to GitHub via SSH or HTTPS? diff --git a/test/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell similarity index 72% rename from test/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell rename to test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell index 71bf53b..bd1c30f 100644 --- a/test/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell +++ b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell @@ -3,7 +3,7 @@ This operation will: clone https://bitbucket.com/JohnSnow/winterfell to ./alf-conf - write /app/test/fixtures/connect/alf-conf + write /app/test-legacy/fixtures/connect/alf-conf to ./alfrc Continue? [yN] Aborting diff --git a/test/fixtures/empty-dir/approvals/alf b/test-legacy/fixtures/empty-dir/approvals/alf similarity index 100% rename from test/fixtures/empty-dir/approvals/alf rename to test-legacy/fixtures/empty-dir/approvals/alf diff --git a/test/fixtures/empty-dir/approvals/alf_download b/test-legacy/fixtures/empty-dir/approvals/alf_download similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_download rename to test-legacy/fixtures/empty-dir/approvals/alf_download diff --git a/test/fixtures/empty-dir/approvals/alf_generate b/test-legacy/fixtures/empty-dir/approvals/alf_generate similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_generate rename to test-legacy/fixtures/empty-dir/approvals/alf_generate diff --git a/test/fixtures/empty-dir/approvals/alf_help b/test-legacy/fixtures/empty-dir/approvals/alf_help similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_help rename to test-legacy/fixtures/empty-dir/approvals/alf_help diff --git a/test/fixtures/empty-dir/approvals/alf_save b/test-legacy/fixtures/empty-dir/approvals/alf_save similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_save rename to test-legacy/fixtures/empty-dir/approvals/alf_save diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade new file mode 100644 index 0000000..80a7e05 --- /dev/null +++ b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade @@ -0,0 +1,15 @@ +Initializing installer... +• info  → Installing alf +• info  → Installed: /usr/local/bin/alf +• info  → Installed: /usr/local/share/man/man1/alf-connect.1 +• info  → Installed: /usr/local/share/man/man1/alf-download.1 +• info  → Installed: /usr/local/share/man/man1/alf-edit.1 +• info  → Installed: /usr/local/share/man/man1/alf-generate.1 +• info  → Installed: /usr/local/share/man/man1/alf-info.1 +• info  → Installed: /usr/local/share/man/man1/alf-save.1 +• info  → Installed: /usr/local/share/man/man1/alf-upgrade.1 +• info  → Installed: /usr/local/share/man/man1/alf-upload.1 +• info  → Installed: /usr/local/share/man/man1/alf-which.1 +• info  → Installed: /usr/local/share/man/man1/alf.1 +• info  → Installed: /usr/local/share/man/man5/alf.conf.5 +• info  → alf --version : 0.6.1 diff --git a/test/fixtures/empty-dir/approvals/alf_upgrade_help b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_upgrade_help rename to test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help diff --git a/test/fixtures/empty-dir/approvals/alf_upload b/test-legacy/fixtures/empty-dir/approvals/alf_upload similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_upload rename to test-legacy/fixtures/empty-dir/approvals/alf_upload diff --git a/test/fixtures/empty-dir/approvals/alf_version b/test-legacy/fixtures/empty-dir/approvals/alf_version similarity index 100% rename from test/fixtures/empty-dir/approvals/alf_version rename to test-legacy/fixtures/empty-dir/approvals/alf_version diff --git a/test/fixtures/generate/alf.conf b/test-legacy/fixtures/generate/alf.conf similarity index 100% rename from test/fixtures/generate/alf.conf rename to test-legacy/fixtures/generate/alf.conf diff --git a/test/fixtures/generate/aliases.txt b/test-legacy/fixtures/generate/aliases.txt similarity index 100% rename from test/fixtures/generate/aliases.txt rename to test-legacy/fixtures/generate/aliases.txt diff --git a/test/fixtures/generate/approvals/alf_generate b/test-legacy/fixtures/generate/approvals/alf_generate similarity index 100% rename from test/fixtures/generate/approvals/alf_generate rename to test-legacy/fixtures/generate/approvals/alf_generate diff --git a/test/fixtures/generate/approvals/alf_save b/test-legacy/fixtures/generate/approvals/alf_save similarity index 100% rename from test/fixtures/generate/approvals/alf_save rename to test-legacy/fixtures/generate/approvals/alf_save diff --git a/test/fixtures/generate/approvals/alf_which b/test-legacy/fixtures/generate/approvals/alf_which similarity index 100% rename from test/fixtures/generate/approvals/alf_which rename to test-legacy/fixtures/generate/approvals/alf_which diff --git a/test/fixtures/generate/approvals/alf_which_dc_deploy b/test-legacy/fixtures/generate/approvals/alf_which_dc_deploy similarity index 100% rename from test/fixtures/generate/approvals/alf_which_dc_deploy rename to test-legacy/fixtures/generate/approvals/alf_which_dc_deploy diff --git a/test/fixtures/generate/approvals/alf_which_dc_upd b/test-legacy/fixtures/generate/approvals/alf_which_dc_upd similarity index 100% rename from test/fixtures/generate/approvals/alf_which_dc_upd rename to test-legacy/fixtures/generate/approvals/alf_which_dc_upd diff --git a/test/fixtures/generate/approvals/alf_which_g b/test-legacy/fixtures/generate/approvals/alf_which_g similarity index 100% rename from test/fixtures/generate/approvals/alf_which_g rename to test-legacy/fixtures/generate/approvals/alf_which_g diff --git a/test/fixtures/generate/approvals/alf_which_g_l b/test-legacy/fixtures/generate/approvals/alf_which_g_l similarity index 100% rename from test/fixtures/generate/approvals/alf_which_g_l rename to test-legacy/fixtures/generate/approvals/alf_which_g_l diff --git a/test/fixtures/generate/approvals/alf_which_g_no b/test-legacy/fixtures/generate/approvals/alf_which_g_no similarity index 100% rename from test/fixtures/generate/approvals/alf_which_g_no rename to test-legacy/fixtures/generate/approvals/alf_which_g_no diff --git a/test/fixtures/generate/approvals/alf_which_help b/test-legacy/fixtures/generate/approvals/alf_which_help similarity index 100% rename from test/fixtures/generate/approvals/alf_which_help rename to test-legacy/fixtures/generate/approvals/alf_which_help diff --git a/test/fixtures/generate/approvals/alf_which_no b/test-legacy/fixtures/generate/approvals/alf_which_no similarity index 100% rename from test/fixtures/generate/approvals/alf_which_no rename to test-legacy/fixtures/generate/approvals/alf_which_no diff --git a/test/fixtures/generate/approvals/say_again_zsh_works b/test-legacy/fixtures/generate/approvals/say_again_zsh_works similarity index 100% rename from test/fixtures/generate/approvals/say_again_zsh_works rename to test-legacy/fixtures/generate/approvals/say_again_zsh_works diff --git a/test/fixtures/info/alf.conf b/test-legacy/fixtures/info/alf.conf similarity index 100% rename from test/fixtures/info/alf.conf rename to test-legacy/fixtures/info/alf.conf diff --git a/test-legacy/fixtures/info/alfrc b/test-legacy/fixtures/info/alfrc new file mode 100644 index 0000000..ad8dc3a --- /dev/null +++ b/test-legacy/fixtures/info/alfrc @@ -0,0 +1 @@ +/app/test-legacy/fixtures/connect/alf-conf diff --git a/test/fixtures/info/aliases.txt b/test-legacy/fixtures/info/aliases.txt similarity index 100% rename from test/fixtures/info/aliases.txt rename to test-legacy/fixtures/info/aliases.txt diff --git a/test/fixtures/info/approvals/alf_info b/test-legacy/fixtures/info/approvals/alf_info similarity index 58% rename from test/fixtures/info/approvals/alf_info rename to test-legacy/fixtures/info/approvals/alf_info index d2659b2..4ae786e 100644 --- a/test/fixtures/info/approvals/alf_info +++ b/test-legacy/fixtures/info/approvals/alf_info @@ -8,11 +8,11 @@ Environment: Paths: alfrc path: ./alfrc aliases path: ./aliases.txt - repo path: /app/test/fixtures/connect/alf-conf - config path: /app/test/fixtures/connect/alf-conf/alf.conf + repo path: /app/test-legacy/fixtures/connect/alf-conf + config path: /app/test-legacy/fixtures/connect/alf-conf/alf.conf Files: - alfrc: exists with '/app/test/fixtures/connect/alf-conf' + alfrc: exists with '/app/test-legacy/fixtures/connect/alf-conf' aliases: exists GitHub: diff --git a/test/fixtures/no-subcommands/alf.conf b/test-legacy/fixtures/no-subcommands/alf.conf similarity index 100% rename from test/fixtures/no-subcommands/alf.conf rename to test-legacy/fixtures/no-subcommands/alf.conf diff --git a/test/fixtures/no-subcommands/approvals/alf_generate b/test-legacy/fixtures/no-subcommands/approvals/alf_generate similarity index 100% rename from test/fixtures/no-subcommands/approvals/alf_generate rename to test-legacy/fixtures/no-subcommands/approvals/alf_generate diff --git a/test/fixtures/sample/alf.conf b/test-legacy/fixtures/sample/alf.conf similarity index 100% rename from test/fixtures/sample/alf.conf rename to test-legacy/fixtures/sample/alf.conf diff --git a/test/fixtures/sample/approvals/alf_edit b/test-legacy/fixtures/sample/approvals/alf_edit similarity index 100% rename from test/fixtures/sample/approvals/alf_edit rename to test-legacy/fixtures/sample/approvals/alf_edit diff --git a/test/fixtures/sample/approvals/alf_edit_help b/test-legacy/fixtures/sample/approvals/alf_edit_help similarity index 100% rename from test/fixtures/sample/approvals/alf_edit_help rename to test-legacy/fixtures/sample/approvals/alf_edit_help diff --git a/test/fixtures/sample/approvals/alf_info b/test-legacy/fixtures/sample/approvals/alf_info similarity index 84% rename from test/fixtures/sample/approvals/alf_info rename to test-legacy/fixtures/sample/approvals/alf_info index e540bce..a255420 100644 --- a/test/fixtures/sample/approvals/alf_info +++ b/test-legacy/fixtures/sample/approvals/alf_info @@ -8,7 +8,7 @@ Environment: Paths: alfrc path: /root/.alfrc aliases path: /root/.bash_aliases - repo path: /app/test/fixtures/sample/alf-conf + repo path: /app/test-legacy/fixtures/sample/alf-conf config path: alf.conf Files: diff --git a/test/generate_spec.sh b/test-legacy/generate_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/generate_spec.sh rename to test-legacy/generate_spec.sh diff --git a/test/info_spec.sh b/test-legacy/info_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/info_spec.sh rename to test-legacy/info_spec.sh diff --git a/test/save_spec.sh b/test-legacy/save_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/save_spec.sh rename to test-legacy/save_spec.sh diff --git a/test/upgrade_spec.sh b/test-legacy/upgrade_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/upgrade_spec.sh rename to test-legacy/upgrade_spec.sh diff --git a/test/upload_spec.sh b/test-legacy/upload_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/upload_spec.sh rename to test-legacy/upload_spec.sh diff --git a/test/usage_spec.sh b/test-legacy/usage_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/usage_spec.sh rename to test-legacy/usage_spec.sh diff --git a/test/which_spec.sh b/test-legacy/which_spec.sh old mode 100755 new mode 100644 similarity index 100% rename from test/which_spec.sh rename to test-legacy/which_spec.sh diff --git a/test/commands/info.bats b/test/commands/info.bats new file mode 100644 index 0000000..4c6be0c --- /dev/null +++ b/test/commands/info.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "info reports local config details when no git repo is connected" { + fixture_dir="$TEST_ROOT/with-config" + mkdir -p "$fixture_dir" + write_file "$fixture_dir/alf.conf" "g: git" + export ALF_RC_FILE="$TEST_ROOT/missing-alfrc" + export ALF_ALIASES_FILE="$TEST_ROOT/aliases.txt" + + run env ALF_RC_FILE="$ALF_RC_FILE" ALF_ALIASES_FILE="$ALF_ALIASES_FILE" ALF_REPO_ROOT="$ALF_REPO_ROOT" PATH="$PATH" bash -lc "source '$ALF_REPO_ROOT/src/initialize.sh'; source '$ALF_REPO_ROOT/src/lib/find_config.sh'; cd '$fixture_dir' || exit 1; source '$ALF_REPO_ROOT/src/info_command.sh'" + + [ "$status" -eq 0 ] + assert_output_contains "path: $TEST_ROOT/bin/alf" + assert_output_contains "alfrc path: $TEST_ROOT/missing-alfrc" + assert_output_contains "aliases path: $TEST_ROOT/aliases.txt" + assert_output_contains "config path: alf.conf" + assert_output_contains "alfrc: does not exist" + assert_output_contains "aliases: does not exist" + assert_output_contains "remote: unset" +} + +@test "info reports connected repo details from ALF_RC_FILE" { + repo_path="$TEST_ROOT/connected-alf" + mkdir -p "$repo_path" + write_file "$repo_path/alf.conf" "g: git" + git -C "$repo_path" init -q + write_file "$TEST_ROOT/alfrc" "$repo_path" + export ALF_RC_FILE="$TEST_ROOT/alfrc" + export ALF_ALIASES_FILE="$TEST_ROOT/aliases.txt" + touch "$TEST_ROOT/aliases.txt" + git -C "$repo_path" remote add origin https://example.com/acme/alf-conf.git + + run env ALF_RC_FILE="$ALF_RC_FILE" ALF_ALIASES_FILE="$ALF_ALIASES_FILE" ALF_REPO_ROOT="$ALF_REPO_ROOT" PATH="$PATH" HOME="$HOME" bash -lc "source '$ALF_REPO_ROOT/src/initialize.sh'; source '$ALF_REPO_ROOT/src/lib/find_config.sh'; cd '$HOME' || exit 1; source '$ALF_REPO_ROOT/src/info_command.sh'" + + [ "$status" -eq 0 ] + assert_output_contains "ALF_RC_FILE: $TEST_ROOT/alfrc" + assert_output_contains "ALF_ALIASES_FILE: $TEST_ROOT/aliases.txt" + assert_output_contains "repo path: $repo_path" + assert_output_contains "config path: $repo_path/alf.conf" + assert_output_contains "alfrc: exists with '$repo_path'" + assert_output_contains "aliases: exists" + assert_output_contains "remote: https://example.com/acme/alf-conf.git" +} diff --git a/test/fixtures/connect/approvals/cat_alfrc b/test/fixtures/connect/approvals/cat_alfrc deleted file mode 100644 index fe78cd4..0000000 --- a/test/fixtures/connect/approvals/cat_alfrc +++ /dev/null @@ -1 +0,0 @@ -/app/test/fixtures/connect/alf-conf diff --git a/test/fixtures/empty-dir/approvals/alf_upgrade b/test/fixtures/empty-dir/approvals/alf_upgrade deleted file mode 100644 index f939d28..0000000 --- a/test/fixtures/empty-dir/approvals/alf_upgrade +++ /dev/null @@ -1,25 +0,0 @@ - -=== Initializing - -=== Checking for pre-requisites - git found - -=== Cloning DannyBen/alf -Cloning into '.'... - -=== Copying files -alf  => /usr/local/bin/ -doc/alf-connect.1  => /usr/local/share/man/man1/ -doc/alf-download.1  => /usr/local/share/man/man1/ -doc/alf-edit.1  => /usr/local/share/man/man1/ -doc/alf-generate.1  => /usr/local/share/man/man1/ -doc/alf-info.1  => /usr/local/share/man/man1/ -doc/alf-save.1  => /usr/local/share/man/man1/ -doc/alf-upgrade.1  => /usr/local/share/man/man1/ -doc/alf-upload.1  => /usr/local/share/man/man1/ -doc/alf-which.1  => /usr/local/share/man/man1/ -doc/alf.1  => /usr/local/share/man/man1/ -doc/alf.conf.5  => /usr/local/share/man/man5/ - -=== Done -0.6.1 diff --git a/test/fixtures/find_config/remote-repo/alf.conf b/test/fixtures/find_config/remote-repo/alf.conf new file mode 100644 index 0000000..f1227ef --- /dev/null +++ b/test/fixtures/find_config/remote-repo/alf.conf @@ -0,0 +1 @@ +g: git diff --git a/test/fixtures/find_config/with-alfrc/alfrc b/test/fixtures/find_config/with-alfrc/alfrc new file mode 100644 index 0000000..3790ff0 --- /dev/null +++ b/test/fixtures/find_config/with-alfrc/alfrc @@ -0,0 +1 @@ +../remote-repo diff --git a/test/fixtures/find_config/with-local-config/alf.conf b/test/fixtures/find_config/with-local-config/alf.conf new file mode 100644 index 0000000..f1227ef --- /dev/null +++ b/test/fixtures/find_config/with-local-config/alf.conf @@ -0,0 +1 @@ +g: git diff --git a/test/fixtures/find_config/without-config/.gitkeep b/test/fixtures/find_config/without-config/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/find_config/without-config/.gitkeep @@ -0,0 +1 @@ + diff --git a/test/fixtures/generate_completion/with-subcommands/alf.conf b/test/fixtures/generate_completion/with-subcommands/alf.conf new file mode 100644 index 0000000..cd4279a --- /dev/null +++ b/test/fixtures/generate_completion/with-subcommands/alf.conf @@ -0,0 +1,7 @@ +g: git + s: status + l: log +dir: ls +dc: docker-compose + deploy: stack deploy + upd: up -d diff --git a/test/fixtures/generate_completion/with-subcommands/expected.txt b/test/fixtures/generate_completion/with-subcommands/expected.txt new file mode 100644 index 0000000..3321e6d --- /dev/null +++ b/test/fixtures/generate_completion/with-subcommands/expected.txt @@ -0,0 +1,5 @@ +# Completions +if command -v complete &> /dev/null ; then + complete -W "s l" g + complete -W "deploy upd" dc +fi diff --git a/test/fixtures/generate_completion/without-config/.gitkeep b/test/fixtures/generate_completion/without-config/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/generate_completion/without-config/.gitkeep @@ -0,0 +1 @@ + diff --git a/test/fixtures/generate_completion/without-subcommands/alf.conf b/test/fixtures/generate_completion/without-subcommands/alf.conf new file mode 100644 index 0000000..b442087 --- /dev/null +++ b/test/fixtures/generate_completion/without-subcommands/alf.conf @@ -0,0 +1,2 @@ +greet: echo hello +yell: echo HELLO diff --git a/test/fixtures/generate_completion/without-subcommands/expected.txt b/test/fixtures/generate_completion/without-subcommands/expected.txt new file mode 100644 index 0000000..d9d492a --- /dev/null +++ b/test/fixtures/generate_completion/without-subcommands/expected.txt @@ -0,0 +1,3 @@ +# Completions +if command -v complete &> /dev/null ; then +fi diff --git a/test/fixtures/generate_config/flat/alf.conf b/test/fixtures/generate_config/flat/alf.conf new file mode 100644 index 0000000..7131216 --- /dev/null +++ b/test/fixtures/generate_config/flat/alf.conf @@ -0,0 +1,2 @@ +git: git +reverse: echo $2 $1 diff --git a/test/fixtures/generate_config/flat/expected.sh b/test/fixtures/generate_config/flat/expected.sh new file mode 100644 index 0000000..e491b6d --- /dev/null +++ b/test/fixtures/generate_config/flat/expected.sh @@ -0,0 +1,12 @@ +# This file was automatically generated by alf +# https://github.com/dannyben/alf + +unalias git 1>/dev/null 2>&1 +git() { + command git "$@" +} + +unalias reverse 1>/dev/null 2>&1 +reverse() { + echo $2 $1 +} diff --git a/test/fixtures/generate_config/with-subcommands/alf.conf b/test/fixtures/generate_config/with-subcommands/alf.conf new file mode 100644 index 0000000..ae7bfd9 --- /dev/null +++ b/test/fixtures/generate_config/with-subcommands/alf.conf @@ -0,0 +1,5 @@ +g: git + s: status + deploy: !docker stack deploy +dns: ! + check: host -t ns diff --git a/test/fixtures/generate_config/with-subcommands/expected.sh b/test/fixtures/generate_config/with-subcommands/expected.sh new file mode 100644 index 0000000..e25f48e --- /dev/null +++ b/test/fixtures/generate_config/with-subcommands/expected.sh @@ -0,0 +1,38 @@ +# This file was automatically generated by alf +# https://github.com/dannyben/alf + +unalias g 1>/dev/null 2>&1 +g() { + case "$1" in + s) + shift + git status "$@" + ;; + deploy) + shift + docker stack deploy "$@" + ;; + *) + git "$@" + ;; + esac +} + +unalias dns 1>/dev/null 2>&1 +dns() { + case "$1" in + check) + shift + host -t ns "$@" + ;; + *) + echo this alias requires a subcommand + ;; + esac +} + +# Completions +if command -v complete &> /dev/null ; then + complete -W "s deploy" g + complete -W "check" dns +fi diff --git a/test/fixtures/generate_config/without-config/.gitkeep b/test/fixtures/generate_config/without-config/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/generate_config/without-config/.gitkeep @@ -0,0 +1 @@ + diff --git a/test/fixtures/has_subcommands/with-subcommands/alf.conf b/test/fixtures/has_subcommands/with-subcommands/alf.conf new file mode 100644 index 0000000..3f7cc9f --- /dev/null +++ b/test/fixtures/has_subcommands/with-subcommands/alf.conf @@ -0,0 +1,3 @@ +g: git + s: status + l: log diff --git a/test/fixtures/has_subcommands/without-config/.gitkeep b/test/fixtures/has_subcommands/without-config/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/has_subcommands/without-config/.gitkeep @@ -0,0 +1 @@ + diff --git a/test/fixtures/has_subcommands/without-subcommands/alf.conf b/test/fixtures/has_subcommands/without-subcommands/alf.conf new file mode 100644 index 0000000..6d57f95 --- /dev/null +++ b/test/fixtures/has_subcommands/without-subcommands/alf.conf @@ -0,0 +1,2 @@ +g: git +h: history diff --git a/test/fixtures/info/alfrc b/test/fixtures/info/alfrc deleted file mode 100644 index fe78cd4..0000000 --- a/test/fixtures/info/alfrc +++ /dev/null @@ -1 +0,0 @@ -/app/test/fixtures/connect/alf-conf diff --git a/test/lib/find_config.bats b/test/lib/find_config.bats new file mode 100644 index 0000000..d298f3f --- /dev/null +++ b/test/lib/find_config.bats @@ -0,0 +1,48 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "find_config uses alf.conf in the current directory" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path find_config/with-local-config/alfrc)" + cd "$(fixture_path find_config/with-local-config)" || exit 1 + source_libs find_config + + find_config + + [ "$repo_path" = "$PWD/alf-conf" ] + [ "$config_file" = "alf.conf" ] +} + +@test "find_config uses the repository referenced by ALF_RC_FILE" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path find_config/with-alfrc/alfrc)" + cd "$(fixture_path find_config/with-alfrc)" || exit 1 + source_libs find_config + + find_config + + [ "$repo_path" = "../remote-repo" ] + [ "$config_file" = "../remote-repo/alf.conf" ] +} + +@test "find_config fails with a clear message when no config is available" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path find_config/without-config/alfrc)" + cd "$(fixture_path find_config/without-config)" || exit 1 + source_libs find_config + + run find_config + + [ "$status" -eq 1 ] + assert_output_contains "ERROR: Cannot find config file" + assert_output_contains "properly connect to a remote config" +} diff --git a/test/lib/generate_completion.bats b/test/lib/generate_completion.bats new file mode 100644 index 0000000..348f0be --- /dev/null +++ b/test/lib/generate_completion.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "generate_completions emits completion lines for aliases with subcommands" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_completion/with-subcommands/alfrc)" + cd "$(fixture_path generate_completion/with-subcommands)" || exit 1 + source_libs find_config generate_completion + + run generate_completions + + [ "$status" -eq 0 ] + [ "$output" = "$(cat "$(fixture_path generate_completion/with-subcommands/expected.txt)")" ] +} + +@test "generate_completions emits only the wrapper when there are no subcommands" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_completion/without-subcommands/alfrc)" + cd "$(fixture_path generate_completion/without-subcommands)" || exit 1 + source_libs find_config generate_completion + + run generate_completions + + [ "$status" -eq 0 ] + [ "$output" = "$(cat "$(fixture_path generate_completion/without-subcommands/expected.txt)")" ] +} + +@test "generate_completions fails when no config can be found" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_completion/without-config/alfrc)" + cd "$(fixture_path generate_completion/without-config)" || exit 1 + source_libs find_config generate_completion + + run generate_completions + + [ "$status" -eq 1 ] + assert_output_contains "ERROR: Cannot find config file" +} diff --git a/test/lib/generate_config.bats b/test/lib/generate_config.bats new file mode 100644 index 0000000..72fda1d --- /dev/null +++ b/test/lib/generate_config.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "generate_config emits functions for flat aliases without completions" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_config/flat/alfrc)" + cd "$(fixture_path generate_config/flat)" || exit 1 + source_libs find_config generate_last_cmd has_subcommands generate_completion generate_config + + run generate_config + + [ "$status" -eq 0 ] + [ "$output" = "$(cat "$(fixture_path generate_config/flat/expected.sh)")" ] +} + +@test "generate_config emits nested alias functions and completions" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_config/with-subcommands/alfrc)" + cd "$(fixture_path generate_config/with-subcommands)" || exit 1 + source_libs find_config generate_last_cmd has_subcommands generate_completion generate_config + + run generate_config + + [ "$status" -eq 0 ] + [ "$output" = "$(cat "$(fixture_path generate_config/with-subcommands/expected.sh)")" ] +} + +@test "generate_config fails when no config can be found" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path generate_config/without-config/alfrc)" + cd "$(fixture_path generate_config/without-config)" || exit 1 + source_libs find_config generate_last_cmd has_subcommands generate_completion generate_config + + run generate_config + + [ "$status" -eq 1 ] + assert_output_contains "ERROR: Cannot find config file" +} diff --git a/test/lib/has_subcommands.bats b/test/lib/has_subcommands.bats new file mode 100644 index 0000000..eb06af3 --- /dev/null +++ b/test/lib/has_subcommands.bats @@ -0,0 +1,46 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "has_subcommands returns success when nested aliases exist" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path has_subcommands/with-subcommands/alfrc)" + cd "$(fixture_path has_subcommands/with-subcommands)" || exit 1 + source_libs find_config has_subcommands + + has_subcommands + + [ "$?" -eq 0 ] +} + +@test "has_subcommands returns failure when aliases are flat" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path has_subcommands/without-subcommands/alfrc)" + cd "$(fixture_path has_subcommands/without-subcommands)" || exit 1 + source_libs find_config has_subcommands + + run has_subcommands + + [ "$status" -eq 1 ] + [ -z "$output" ] +} + +@test "has_subcommands fails with the config error when no config is available" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path has_subcommands/without-config/alfrc)" + cd "$(fixture_path has_subcommands/without-config)" || exit 1 + source_libs find_config has_subcommands + + run has_subcommands + + [ "$status" -eq 1 ] + assert_output_contains "ERROR: Cannot find config file" +} diff --git a/test/lib/save_config.bats b/test/lib/save_config.bats new file mode 100644 index 0000000..3c9d490 --- /dev/null +++ b/test/lib/save_config.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "save_config writes generated aliases and prints a home-relative source path" { + export ALF_ALIASES_FILE + ALF_ALIASES_FILE="$HOME/aliases.sh" + source_libs save_config + + find_config() { + config_file="alf.conf" + } + + generate_config() { + printf '%s\n' '# generated aliases' + printf '%s\n' 'g() { git "$@"; }' + } + + run save_config + + [ "$status" -eq 0 ] + [ -f "$ALF_ALIASES_FILE" ] + assert_output_contains "Saving to $ALF_ALIASES_FILE" + assert_output_contains "source ~/aliases.sh" + grep -Fq '# generated aliases' "$ALF_ALIASES_FILE" + grep -Fq 'g() { git "$@"; }' "$ALF_ALIASES_FILE" +} + +@test "save_config keeps the full path when aliases_file is outside HOME" { + export ALF_ALIASES_FILE + ALF_ALIASES_FILE="$TEST_ROOT/aliases.sh" + source_libs save_config + + find_config() { + config_file="alf.conf" + } + + generate_config() { + printf '%s\n' 'echo outside-home' + } + + run save_config + + [ "$status" -eq 0 ] + assert_output_contains "Saving to $TEST_ROOT/aliases.sh" + assert_output_contains "source $TEST_ROOT/aliases.sh" + grep -Fq 'echo outside-home' "$ALF_ALIASES_FILE" +} + +@test "save_config stops when find_config fails" { + export ALF_ALIASES_FILE + ALF_ALIASES_FILE="$HOME/aliases.sh" + source_libs save_config + + find_config() { + echo "ERROR: Cannot find config file" + exit 1 + } + + generate_config() { + echo "should not run" + } + + run save_config + + [ "$status" -eq 1 ] + [ ! -e "$ALF_ALIASES_FILE" ] + assert_output_contains "ERROR: Cannot find config file" +} diff --git a/test/test_helper.bash b/test/test_helper.bash new file mode 100644 index 0000000..554c7ef --- /dev/null +++ b/test/test_helper.bash @@ -0,0 +1,47 @@ +setup_test_environment() { + export ALF_REPO_ROOT + ALF_REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)" + + export TEST_ROOT + TEST_ROOT="$(mktemp -d)" + + export HOME="$TEST_ROOT/home" + mkdir -p "$HOME" "$TEST_ROOT/bin" + + export PATH="$TEST_ROOT/bin:$PATH" + + cat >"$TEST_ROOT/bin/alf" <<'EOF' +#!/usr/bin/env bash +echo stub-alf +EOF + chmod +x "$TEST_ROOT/bin/alf" +} + +teardown_test_environment() { + rm -rf "$TEST_ROOT" +} + +assert_output_contains() { + local expected="$1" + [[ "$output" == *"$expected"* ]] +} + +fixture_path() { + printf '%s/test/fixtures/%s\n' "$ALF_REPO_ROOT" "$1" +} + +write_file() { + local path="$1" + shift + printf '%s\n' "$@" >"$path" +} + +source_libs() { + local lib + + source "$ALF_REPO_ROOT/src/initialize.sh" + + for lib in "$@"; do + source "$ALF_REPO_ROOT/src/lib/${lib}.sh" + done +} From 4d3df58f069a6acaef5544a32e0e764f4da1175e Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 18:41:05 +0200 Subject: [PATCH 2/8] move commands to subfolder --- alf | 110 ++++++++++++------ settings.yml | 7 +- .../connect.sh} | 0 .../download.sh} | 0 src/{edit_command.sh => commands/edit.sh} | 0 .../generate.sh} | 0 src/{info_command.sh => commands/info.sh} | 0 src/{save_command.sh => commands/save.sh} | 0 .../upgrade.sh} | 0 src/{upload_command.sh => commands/upload.sh} | 0 src/{which_command.sh => commands/which.sh} | 0 test-legacy/approvals/alf_download_help | 2 +- test-legacy/approvals/alf_generate_help | 2 +- test-legacy/approvals/alf_info_help | 2 +- test-legacy/approvals/alf_save_help | 4 +- test-legacy/approvals/alf_upload_help | 2 +- .../connect/approvals/alf_connect_help | 10 +- .../fixtures/empty-dir/approvals/alf_help | 6 +- .../empty-dir/approvals/alf_upgrade_help | 2 +- .../generate/approvals/alf_which_help | 6 +- .../fixtures/sample/approvals/alf_edit_help | 2 +- 21 files changed, 95 insertions(+), 60 deletions(-) rename src/{connect_command.sh => commands/connect.sh} (100%) rename src/{download_command.sh => commands/download.sh} (100%) rename src/{edit_command.sh => commands/edit.sh} (100%) rename src/{generate_command.sh => commands/generate.sh} (100%) rename src/{info_command.sh => commands/info.sh} (100%) rename src/{save_command.sh => commands/save.sh} (100%) rename src/{upgrade_command.sh => commands/upgrade.sh} (100%) rename src/{upload_command.sh => commands/upload.sh} (100%) rename src/{which_command.sh => commands/which.sh} (100%) diff --git a/alf b/alf index f9eb830..897234d 100755 --- a/alf +++ b/alf @@ -1,10 +1,10 @@ #!/usr/bin/env bash -# This script was generated by bashly 1.2.7 (https://bashly.dannyb.co) +# This script was generated by bashly 1.3.6 (https://bashly.dev) # Modifying it manually is not recommended # :wrapper.bash3_bouncer -if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then - printf "bash version 4 or higher is required\n" >&2 +if ((BASH_VERSINFO[0] < 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] < 2))); then + printf "bash version 4.2 or higher is required\n" >&2 exit 1 fi @@ -39,13 +39,14 @@ alf_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo - printf " %s\n" "--version, -v" + printf " %s\n" "$(bold "--version, -v")" printf " Show version number\n" echo @@ -53,7 +54,7 @@ alf_usage() { printf "%s\n" "$(bold "Environment Variables:")" # :environment_variable.usage - printf " %s\n" "ALF_RC_FILE" + printf " %s\n" "$(bold "ALF_RC_FILE")" printf " Path to alfrc file.\n \n This file holds the path to the alf-conf repository.\n \n Default: \`~/.alfrc\`\n" echo @@ -73,26 +74,27 @@ alf_connect_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage - printf " %s\n" "--ssh" + printf " %s\n" "$(bold "--ssh")" printf " Connect to GitHub non-interactively using SSH (implies \`--yes\`).\n" echo # :flag.usage - printf " %s\n" "--https" + printf " %s\n" "$(bold "--https")" printf " Connect to GitHub non-interactively using HTTPS (implies \`--yes\`).\n" echo # :flag.usage - printf " %s\n" "--yes, -y" + printf " %s\n" "$(bold "--yes, -y")" printf " Connect to any remote repository non-interactively.\n" echo # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -100,7 +102,7 @@ alf_connect_usage() { printf "%s\n" "$(bold "Arguments:")" # :argument.usage - printf " %s\n" "REPO" + printf " %s\n" "$(bold "REPO")" printf " Remote GitHub repository to connect to.\n \n Can be one of:\n \n - Your username on GitHub.\n In this case, the repository is expected to be named \`alf-conf\`.\n - Your username/repo on GitHub.\n - Any other full URL to a repository.\n" echo @@ -127,10 +129,11 @@ alf_download_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -150,10 +153,11 @@ alf_upload_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -173,10 +177,11 @@ alf_generate_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -196,10 +201,11 @@ alf_save_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -207,7 +213,7 @@ alf_save_usage() { printf "%s\n" "$(bold "Environment Variables:")" # :environment_variable.usage - printf " %s\n" "ALF_ALIASES_FILE" + printf " %s\n" "$(bold "ALF_ALIASES_FILE")" printf " Path to bash_aliases file.\n \n Aliases will be saved to this file.\n \n Default: \`~/.bash_aliases\`\n" echo @@ -227,10 +233,11 @@ alf_edit_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -250,10 +257,11 @@ alf_which_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -261,12 +269,12 @@ alf_which_usage() { printf "%s\n" "$(bold "Arguments:")" # :argument.usage - printf " %s\n" "CODE" + printf " %s\n" "$(bold "CODE")" printf " Show the command for this alias code.\n" echo # :argument.usage - printf " %s\n" "SUBCODE" + printf " %s\n" "$(bold "SUBCODE")" printf " Show the command for this alias sub-code.\n" echo @@ -284,10 +292,11 @@ alf_upgrade_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -305,10 +314,11 @@ alf_info_usage() { # :command.long_usage if [[ -n "$long_usage" ]]; then + # :command.usage_options printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags - printf " %s\n" "--help, -h" + printf " %s\n" "$(bold "--help, -h")" printf " Show this help\n" echo @@ -349,6 +359,8 @@ normalize_input() { # :command.inspect_args inspect_args() { + local k + if ((${#args[@]})); then readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort) echo args: @@ -579,7 +591,7 @@ save_config() { # :command.function alf_connect_command() { - # src/connect_command.sh + # src/commands/connect.sh repo=${args[repo]} force=${args[--yes]} force_ssh=${args[--ssh]} @@ -670,7 +682,7 @@ alf_connect_command() { # :command.function alf_download_command() { - # src/download_command.sh + # src/commands/download.sh find_config if [[ ! -f $rc_file ]]; then @@ -690,7 +702,7 @@ alf_download_command() { # :command.function alf_upload_command() { - # src/upload_command.sh + # src/commands/upload.sh find_config if [[ ! -f $rc_file ]]; then @@ -709,7 +721,7 @@ alf_upload_command() { # :command.function alf_generate_command() { - # src/generate_command.sh + # src/commands/generate.sh generate_config } @@ -717,7 +729,7 @@ alf_generate_command() { # :command.function alf_save_command() { - # src/save_command.sh + # src/commands/save.sh save_config } @@ -725,7 +737,7 @@ alf_save_command() { # :command.function alf_edit_command() { - # src/edit_command.sh + # src/commands/edit.sh find_config ${EDITOR:-vi} "$config_file" } @@ -733,7 +745,7 @@ alf_edit_command() { # :command.function alf_which_command() { - # src/which_command.sh + # src/commands/which.sh code=${args[code]} subcode=${args[subcode]} @@ -770,7 +782,7 @@ alf_which_command() { # :command.function alf_upgrade_command() { - # src/upgrade_command.sh + # src/commands/upgrade.sh exec bash <(curl -s https://raw.githubusercontent.com/DannyBen/alf/master/setup) } @@ -778,7 +790,7 @@ alf_upgrade_command() { # :command.function alf_info_command() { - # src/info_command.sh + # src/commands/info.sh find_config if [[ -d "$repo_path/.git" ]]; then @@ -830,6 +842,8 @@ alf_info_command() { # :command.parse_requirements parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -961,6 +975,8 @@ parse_requirements() { # :command.parse_requirements alf_connect_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1054,6 +1070,8 @@ alf_connect_parse_requirements() { # :command.parse_requirements alf_download_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1111,6 +1129,8 @@ alf_download_parse_requirements() { # :command.parse_requirements alf_upload_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1168,6 +1188,8 @@ alf_upload_parse_requirements() { # :command.parse_requirements alf_generate_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1213,6 +1235,8 @@ alf_generate_parse_requirements() { # :command.parse_requirements alf_save_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1260,6 +1284,8 @@ alf_save_parse_requirements() { # :command.parse_requirements alf_edit_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1305,6 +1331,8 @@ alf_edit_parse_requirements() { # :command.parse_requirements alf_which_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1367,6 +1395,8 @@ alf_which_parse_requirements() { # :command.parse_requirements alf_upgrade_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1424,6 +1454,8 @@ alf_upgrade_parse_requirements() { # :command.parse_requirements alf_info_parse_requirements() { + local key + # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do key="$1" @@ -1481,14 +1513,9 @@ alf_info_parse_requirements() { # :command.initialize initialize() { - version="0.6.1" - long_usage='' + declare -g version="0.6.1" set -e - # :command.globals - declare -g -A args=() - declare -g -a input=() - # src/initialize.sh aliases_file=${ALF_ALIASES_FILE:-~/.bash_aliases} rc_file=${ALF_RC_FILE:-~/.alfrc} @@ -1498,6 +1525,11 @@ initialize() { # :command.run run() { + # :command.globals + declare -g long_usage='' + declare -g -A args=() + declare -g -a input=() + normalize_input "$@" parse_requirements "${input[@]}" @@ -1515,6 +1547,8 @@ run() { } if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + # :command.start + command_line_args=("$@") initialize - run "$@" + run "${command_line_args[@]}" fi diff --git a/settings.yml b/settings.yml index 1bf2f57..47f1dd4 100644 --- a/settings.yml +++ b/settings.yml @@ -1,3 +1,4 @@ +commands_dir: commands enable_view_markers: always enable_env_var_names_array: never enable_deps_array: never @@ -5,6 +6,6 @@ enable_deps_array: never usage_colors: caption: bold command: green - # arg: bold - # flag: bold - # environment_variable: bold + arg: bold + flag: bold + environment_variable: bold diff --git a/src/connect_command.sh b/src/commands/connect.sh similarity index 100% rename from src/connect_command.sh rename to src/commands/connect.sh diff --git a/src/download_command.sh b/src/commands/download.sh similarity index 100% rename from src/download_command.sh rename to src/commands/download.sh diff --git a/src/edit_command.sh b/src/commands/edit.sh similarity index 100% rename from src/edit_command.sh rename to src/commands/edit.sh diff --git a/src/generate_command.sh b/src/commands/generate.sh similarity index 100% rename from src/generate_command.sh rename to src/commands/generate.sh diff --git a/src/info_command.sh b/src/commands/info.sh similarity index 100% rename from src/info_command.sh rename to src/commands/info.sh diff --git a/src/save_command.sh b/src/commands/save.sh similarity index 100% rename from src/save_command.sh rename to src/commands/save.sh diff --git a/src/upgrade_command.sh b/src/commands/upgrade.sh similarity index 100% rename from src/upgrade_command.sh rename to src/commands/upgrade.sh diff --git a/src/upload_command.sh b/src/commands/upload.sh similarity index 100% rename from src/upload_command.sh rename to src/commands/upload.sh diff --git a/src/which_command.sh b/src/commands/which.sh similarity index 100% rename from src/which_command.sh rename to src/commands/which.sh diff --git a/test-legacy/approvals/alf_download_help b/test-legacy/approvals/alf_download_help index 5eae583..06fefb4 100644 --- a/test-legacy/approvals/alf_download_help +++ b/test-legacy/approvals/alf_download_help @@ -7,5 +7,5 @@ Alias: d, pull alf download --help | -h Options: - --help, -h + --help, -h Show this help diff --git a/test-legacy/approvals/alf_generate_help b/test-legacy/approvals/alf_generate_help index fa5de64..be8b1d9 100644 --- a/test-legacy/approvals/alf_generate_help +++ b/test-legacy/approvals/alf_generate_help @@ -7,5 +7,5 @@ Alias: g alf generate --help | -h Options: - --help, -h + --help, -h Show this help diff --git a/test-legacy/approvals/alf_info_help b/test-legacy/approvals/alf_info_help index bf43e86..2fdb910 100644 --- a/test-legacy/approvals/alf_info_help +++ b/test-legacy/approvals/alf_info_help @@ -5,5 +5,5 @@ alf info - Show all alf related system facts. alf info --help | -h Options: - --help, -h + --help, -h Show this help diff --git a/test-legacy/approvals/alf_save_help b/test-legacy/approvals/alf_save_help index f31b8b4..99257fd 100644 --- a/test-legacy/approvals/alf_save_help +++ b/test-legacy/approvals/alf_save_help @@ -7,11 +7,11 @@ Alias: s alf save --help | -h Options: - --help, -h + --help, -h Show this help Environment Variables: - ALF_ALIASES_FILE + ALF_ALIASES_FILE Path to bash_aliases file. Aliases will be saved to this file. diff --git a/test-legacy/approvals/alf_upload_help b/test-legacy/approvals/alf_upload_help index 119a722..2b9c85f 100644 --- a/test-legacy/approvals/alf_upload_help +++ b/test-legacy/approvals/alf_upload_help @@ -7,5 +7,5 @@ Alias: u, push alf upload --help | -h Options: - --help, -h + --help, -h Show this help diff --git a/test-legacy/fixtures/connect/approvals/alf_connect_help b/test-legacy/fixtures/connect/approvals/alf_connect_help index 97bab76..916282a 100644 --- a/test-legacy/fixtures/connect/approvals/alf_connect_help +++ b/test-legacy/fixtures/connect/approvals/alf_connect_help @@ -7,20 +7,20 @@ Alias: c alf connect --help | -h Options: - --ssh + --ssh Connect to GitHub non-interactively using SSH (implies `--yes`). - --https + --https Connect to GitHub non-interactively using HTTPS (implies `--yes`). - --yes, -y + --yes, -y Connect to any remote repository non-interactively. - --help, -h + --help, -h Show this help Arguments: - REPO + REPO Remote GitHub repository to connect to. Can be one of: diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_help b/test-legacy/fixtures/empty-dir/approvals/alf_help index d6040be..dc0372c 100644 --- a/test-legacy/fixtures/empty-dir/approvals/alf_help +++ b/test-legacy/fixtures/empty-dir/approvals/alf_help @@ -17,14 +17,14 @@ alf - Your Little Bash Alias Friend info Show all alf related system facts. Options: - --help, -h + --help, -h Show this help - --version, -v + --version, -v Show version number Environment Variables: - ALF_RC_FILE + ALF_RC_FILE Path to alfrc file. This file holds the path to the alf-conf repository. diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help index b9e44a7..cbae2f2 100644 --- a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help +++ b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help @@ -5,5 +5,5 @@ alf upgrade - Upgrade alf to the latest version. alf upgrade --help | -h Options: - --help, -h + --help, -h Show this help diff --git a/test-legacy/fixtures/generate/approvals/alf_which_help b/test-legacy/fixtures/generate/approvals/alf_which_help index 0557ad1..e27e381 100644 --- a/test-legacy/fixtures/generate/approvals/alf_which_help +++ b/test-legacy/fixtures/generate/approvals/alf_which_help @@ -7,12 +7,12 @@ Alias: w alf which --help | -h Options: - --help, -h + --help, -h Show this help Arguments: - CODE + CODE Show the command for this alias code. - SUBCODE + SUBCODE Show the command for this alias sub-code. diff --git a/test-legacy/fixtures/sample/approvals/alf_edit_help b/test-legacy/fixtures/sample/approvals/alf_edit_help index a772d7c..f226418 100644 --- a/test-legacy/fixtures/sample/approvals/alf_edit_help +++ b/test-legacy/fixtures/sample/approvals/alf_edit_help @@ -7,5 +7,5 @@ Alias: e alf edit --help | -h Options: - --help, -h + --help, -h Show this help From c79fe19506a6e06ccbcac7330f215c70dfdbe62c Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 19:29:25 +0200 Subject: [PATCH 3/8] - Refactor commands to function units --- AGENTS.md | 6 + src/commands/connect.sh | 80 +----------- src/commands/download.sh | 15 +-- src/commands/info.sh | 43 +----- src/commands/upload.sh | 14 +- src/commands/which.sh | 28 +--- src/lib/connect_repo.sh | 83 ++++++++++++ src/lib/download_repo.sh | 16 +++ src/lib/prompt.sh | 17 +++ src/lib/show_alias_command.sh | 33 +++++ src/lib/show_info.sh | 44 +++++++ src/lib/upload_repo.sh | 15 +++ .../show_alias_command/with-config/alf.conf | 8 ++ test/lib/connect_repo.bats | 123 ++++++++++++++++++ test/lib/download_repo.bats | 55 ++++++++ test/lib/prompt.bats | 39 ++++++ test/lib/show_alias_command.bats | 71 ++++++++++ .../info.bats => lib/show_info.bats} | 12 +- test/lib/upload_repo.bats | 50 +++++++ test/test_helper.bash | 8 ++ 20 files changed, 581 insertions(+), 179 deletions(-) create mode 100644 src/lib/connect_repo.sh create mode 100644 src/lib/download_repo.sh create mode 100644 src/lib/prompt.sh create mode 100644 src/lib/show_alias_command.sh create mode 100644 src/lib/show_info.sh create mode 100644 src/lib/upload_repo.sh create mode 100644 test/fixtures/show_alias_command/with-config/alf.conf create mode 100644 test/lib/connect_repo.bats create mode 100644 test/lib/download_repo.bats create mode 100644 test/lib/prompt.bats create mode 100644 test/lib/show_alias_command.bats rename test/{commands/info.bats => lib/show_info.bats} (69%) create mode 100644 test/lib/upload_repo.bats diff --git a/AGENTS.md b/AGENTS.md index e9d4b27..0bc87d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,6 +37,12 @@ The repository currently uses approval tests. Keep this distinction clear in fut - failure modes - local fixture repo scenarios +For Bats tests, prefer this split: + +- Use checked-in fixtures when the unit's job is to interpret files, parse config, or derive behavior from prepared filesystem state. +- Use stubs when the unit's job is orchestration. +- In stub-driven unit tests, it is acceptable to create the smallest transient prerequisite inline when it is only a mechanical precondition (for example, an empty file required to satisfy an existence check). + ## Approval Testing Rules - Never edit approval files manually. diff --git a/src/commands/connect.sh b/src/commands/connect.sh index 632f594..2b449c8 100644 --- a/src/commands/connect.sh +++ b/src/commands/connect.sh @@ -3,82 +3,4 @@ force=${args[--yes]} force_ssh=${args[--ssh]} force_https=${args[--https]} -if [[ $repo =~ ':' ]]; then - repo_url=$repo -elif [[ $repo =~ '/' ]]; then - partial_github_url=1 - repo_url="$repo.git" -else - partial_github_url=1 - repo_url="$repo/alf-conf.git" -fi - -if [[ $force_ssh ]]; then - answer=y - [[ $partial_github_url ]] && repo_url="git@github.com:$repo_url" - echo "Connecting to $repo_url" - -elif [[ $force_https ]]; then - answer=y - [[ $partial_github_url ]] && repo_url="https://github.com/$repo_url" - echo "Connecting to $repo_url" - -elif [[ $force ]]; then - if [[ $partial_github_url ]]; then - echo "Error: Cannot determine the full URL for the repository" - echo "To connect to GitHub use --ssh or --https" - echo "To connect to another repository, provide the full URL" - exit 1 - fi - answer=y - echo "Connecting to $repo_url" - -else - echo "This operation will:" - echo "" - if [[ ! -d ./alf-conf ]]; then - echo " clone $repo_url" - echo " to ./alf-conf" - echo "" - fi - echo " write $PWD/alf-conf" - echo " to $rc_file" - echo "" - - if [[ -n "$partial_github_url" ]]; then - echo "Would you like to connect to GitHub via SSH or HTTPS?" - echo "" - printf "[S]SH, [H]TTPS or [A]bort (default): " - read -r answer - - if [[ $answer =~ [Ss] ]]; then - repo_url="git@github.com:$repo_url" - answer=y - echo "" - echo "Using $repo_url" - elif [[ $answer =~ [Hh] ]]; then - repo_url="https://github.com/$repo_url" - answer=y - echo "" - echo "Using $repo_url" - fi - else - printf "Continue? [yN] " - read -r answer - fi -fi - -if [[ $answer =~ [Yy] ]]; then - if [[ -d ./alf-conf ]]; then - echo "Skipping clone, directory already exists" - else - git clone "$repo_url" ./alf-conf - fi - echo "$PWD/alf-conf" >"$rc_file" - echo "Storing location in $rc_file" -else - echo "Aborting" - exit -fi - -save_config +connect_repo "$repo" "$force" "$force_ssh" "$force_https" diff --git a/src/commands/download.sh b/src/commands/download.sh index ed78d47..5451ca4 100644 --- a/src/commands/download.sh +++ b/src/commands/download.sh @@ -1,14 +1 @@ -find_config - -if [[ ! -f $rc_file ]]; then - echo "Cannot find $rc_file" - echo "Please connect alf to a repository first" - exit 1 -fi - -pushd "$repo_path" >/dev/null -echo "Pulling from repository to $repo_path" -git pull -popd >/dev/null - -save_config \ No newline at end of file +download_repo diff --git a/src/commands/info.sh b/src/commands/info.sh index 1676c43..3fd36fc 100644 --- a/src/commands/info.sh +++ b/src/commands/info.sh @@ -1,42 +1 @@ -find_config - -if [[ -d "$repo_path/.git" ]]; then - pushd "$repo_path" >/dev/null - remote="$(git config --get remote.origin.url)" - popd >/dev/null -else - remote="unset" -fi - -if [[ -f "$rc_file" ]]; then - alfrc_content="exists with '$(<"$rc_file")'" -else - alfrc_content="does not exist" -fi - -if [[ -f "$aliases_file" ]]; then - bash_aliases_status="exists" -else - bash_aliases_status="does not exist" -fi - -echo "Executable:" -echo " path: $(command -v alf)" -echo -echo "Environment:" -echo " ALF_RC_FILE: ${ALF_RC_FILE:-unset}" -echo " ALF_ALIASES_FILE: ${ALF_ALIASES_FILE:-unset}" -echo -echo "Paths:" -echo " alfrc path: $rc_file" -echo " aliases path: $aliases_file" -echo " repo path: $repo_path" -echo " config path: $config_file" -echo -echo "Files:" -echo " alfrc: $alfrc_content" -echo " aliases: $bash_aliases_status" -echo -echo "GitHub:" -echo " remote: $remote" -echo \ No newline at end of file +show_info diff --git a/src/commands/upload.sh b/src/commands/upload.sh index ba7541a..af4ec78 100644 --- a/src/commands/upload.sh +++ b/src/commands/upload.sh @@ -1,13 +1 @@ -find_config - -if [[ ! -f $rc_file ]]; then - echo "Cannot find $rc_file" - echo "Please connect alf to a repository first" - exit 1 -fi - -pushd "$repo_path" >/dev/null -echo "Pushing $repo_path to repository" -git commit -am "automatic push" -git push -popd >/dev/null \ No newline at end of file +upload_repo diff --git a/src/commands/which.sh b/src/commands/which.sh index 0b29ef0..e47b664 100644 --- a/src/commands/which.sh +++ b/src/commands/which.sh @@ -1,30 +1,4 @@ code=${args[code]} subcode=${args[subcode]} -find_config -regex_exact_code="^($code): *(.+)$" -regex_exact_subcode="^( +)($subcode): *(.+)$" -cmd1="" - -while IFS= read -r line || [ -n "$line" ]; do - if [[ $line =~ $regex_exact_code ]]; then - cmd1="${BASH_REMATCH[2]}" - if [[ -z $subcode ]]; then - echo "$cmd1" - exit 0 - fi - elif [[ -n $cmd1 ]]; then - if [[ $line =~ $regex_exact_subcode ]]; then - cmd2="${BASH_REMATCH[3]}" - if [[ $cmd2 =~ ^! ]]; then - echo "${cmd2:1}" - else - echo "$cmd1 $cmd2" - fi - exit 0 - fi - fi -done <"$config_file" - -echo "Error: No such alias: $code $subcode" -exit 1 +show_alias_command "$code" "$subcode" diff --git a/src/lib/connect_repo.sh b/src/lib/connect_repo.sh new file mode 100644 index 0000000..05aa42d --- /dev/null +++ b/src/lib/connect_repo.sh @@ -0,0 +1,83 @@ +connect_repo() { + local repo="$1" + local force="$2" + local force_ssh="$3" + local force_https="$4" + local repo_url partial_github_url answer + + if [[ $repo =~ ':' ]]; then + repo_url=$repo + elif [[ $repo =~ '/' ]]; then + partial_github_url=1 + repo_url="$repo.git" + else + partial_github_url=1 + repo_url="$repo/alf-conf.git" + fi + + if [[ $force_ssh ]]; then + answer=y + [[ $partial_github_url ]] && repo_url="git@github.com:$repo_url" + echo "Connecting to $repo_url" + + elif [[ $force_https ]]; then + answer=y + [[ $partial_github_url ]] && repo_url="https://github.com/$repo_url" + echo "Connecting to $repo_url" + + elif [[ $force ]]; then + if [[ $partial_github_url ]]; then + echo "Error: Cannot determine the full URL for the repository" + echo "To connect to GitHub use --ssh or --https" + echo "To connect to another repository, provide the full URL" + return 1 + fi + answer=y + echo "Connecting to $repo_url" + + else + echo "This operation will:" + echo "" + if [[ ! -d ./alf-conf ]]; then + echo " clone $repo_url" + echo " to ./alf-conf" + echo "" + fi + echo " write $PWD/alf-conf" + echo " to $rc_file" + echo "" + + if [[ -n "$partial_github_url" ]]; then + answer="$(prompt_for_github_protocol)" + + if [[ $answer =~ [Ss] ]]; then + repo_url="git@github.com:$repo_url" + answer=y + echo "" + echo "Using $repo_url" + elif [[ $answer =~ [Hh] ]]; then + repo_url="https://github.com/$repo_url" + answer=y + echo "" + echo "Using $repo_url" + fi + else + answer="$(prompt_to_continue)" + fi + fi + + if [[ $answer =~ [Yy] ]]; then + if [[ -d ./alf-conf ]]; then + echo "Skipping clone, directory already exists" + else + git clone "$repo_url" ./alf-conf + fi + echo "$PWD/alf-conf" >"$rc_file" + echo "Storing location in $rc_file" + else + echo "Aborting" + return 0 + fi + + save_config +} diff --git a/src/lib/download_repo.sh b/src/lib/download_repo.sh new file mode 100644 index 0000000..3bdec80 --- /dev/null +++ b/src/lib/download_repo.sh @@ -0,0 +1,16 @@ +download_repo() { + find_config + + if [[ ! -f $rc_file ]]; then + echo "Cannot find $rc_file" + echo "Please connect alf to a repository first" + return 1 + fi + + pushd "$repo_path" >/dev/null + echo "Pulling from repository to $repo_path" + git pull + popd >/dev/null + + save_config +} diff --git a/src/lib/prompt.sh b/src/lib/prompt.sh new file mode 100644 index 0000000..3b7f898 --- /dev/null +++ b/src/lib/prompt.sh @@ -0,0 +1,17 @@ +prompt_for_github_protocol() { + local answer + + echo "Would you like to connect to GitHub via SSH or HTTPS?" + echo "" + printf "[S]SH, [H]TTPS or [A]bort (default): " + read -r answer + printf '%s\n' "$answer" +} + +prompt_to_continue() { + local answer + + printf "Continue? [yN] " + read -r answer + printf '%s\n' "$answer" +} diff --git a/src/lib/show_alias_command.sh b/src/lib/show_alias_command.sh new file mode 100644 index 0000000..a47c582 --- /dev/null +++ b/src/lib/show_alias_command.sh @@ -0,0 +1,33 @@ +show_alias_command() { + local code="$1" + local subcode="${2:-}" + local regex_exact_code regex_exact_subcode cmd1 cmd2 + + find_config + regex_exact_code="^($code): *(.+)$" + regex_exact_subcode="^( +)($subcode): *(.+)$" + cmd1="" + + while IFS= read -r line || [ -n "$line" ]; do + if [[ $line =~ $regex_exact_code ]]; then + cmd1="${BASH_REMATCH[2]}" + if [[ -z $subcode ]]; then + echo "$cmd1" + return 0 + fi + elif [[ -n $cmd1 ]]; then + if [[ $line =~ $regex_exact_subcode ]]; then + cmd2="${BASH_REMATCH[3]}" + if [[ $cmd2 =~ ^! ]]; then + echo "${cmd2:1}" + else + echo "$cmd1 $cmd2" + fi + return 0 + fi + fi + done <"$config_file" + + echo "Error: No such alias: $code $subcode" + return 1 +} diff --git a/src/lib/show_info.sh b/src/lib/show_info.sh new file mode 100644 index 0000000..c063329 --- /dev/null +++ b/src/lib/show_info.sh @@ -0,0 +1,44 @@ +show_info() { + find_config + + if [[ -d "$repo_path/.git" ]]; then + pushd "$repo_path" >/dev/null + remote="$(git config --get remote.origin.url)" + popd >/dev/null + else + remote="unset" + fi + + if [[ -f "$rc_file" ]]; then + alfrc_content="exists with '$(<"$rc_file")'" + else + alfrc_content="does not exist" + fi + + if [[ -f "$aliases_file" ]]; then + bash_aliases_status="exists" + else + bash_aliases_status="does not exist" + fi + + echo "Executable:" + echo " path: $(command -v alf)" + echo + echo "Environment:" + echo " ALF_RC_FILE: ${ALF_RC_FILE:-unset}" + echo " ALF_ALIASES_FILE: ${ALF_ALIASES_FILE:-unset}" + echo + echo "Paths:" + echo " alfrc path: $rc_file" + echo " aliases path: $aliases_file" + echo " repo path: $repo_path" + echo " config path: $config_file" + echo + echo "Files:" + echo " alfrc: $alfrc_content" + echo " aliases: $bash_aliases_status" + echo + echo "GitHub:" + echo " remote: $remote" + echo +} diff --git a/src/lib/upload_repo.sh b/src/lib/upload_repo.sh new file mode 100644 index 0000000..9def189 --- /dev/null +++ b/src/lib/upload_repo.sh @@ -0,0 +1,15 @@ +upload_repo() { + find_config + + if [[ ! -f $rc_file ]]; then + echo "Cannot find $rc_file" + echo "Please connect alf to a repository first" + return 1 + fi + + pushd "$repo_path" >/dev/null + echo "Pushing $repo_path to repository" + git commit -am "automatic push" + git push + popd >/dev/null +} diff --git a/test/fixtures/show_alias_command/with-config/alf.conf b/test/fixtures/show_alias_command/with-config/alf.conf new file mode 100644 index 0000000..c1d3f3b --- /dev/null +++ b/test/fixtures/show_alias_command/with-config/alf.conf @@ -0,0 +1,8 @@ +dir: ls -l +g: git + s: status + l: log --all --graph --date=relative + p: push +dc: docker-compose + deploy: !docker stack deploy -c docker-compose.yml + upd: up -d diff --git a/test/lib/connect_repo.bats b/test/lib/connect_repo.bats new file mode 100644 index 0000000..c4ed06b --- /dev/null +++ b/test/lib/connect_repo.bats @@ -0,0 +1,123 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + unset_functions git save_config prompt_for_github_protocol prompt_to_continue + teardown_test_environment +} + +@test "connect_repo rejects --yes for shorthand GitHub repos" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + source_libs prompt connect_repo + + run connect_repo "DannyBen" "1" "" "" + + [ "$status" -eq 1 ] + assert_output_contains "Error: Cannot determine the full URL for the repository" +} + +@test "connect_repo clones a full URL non-interactively and saves config" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + mkdir -p "$TEST_ROOT/work" + cd "$TEST_ROOT/work" || exit 1 + source_libs prompt connect_repo + + git() { + [ "$1" = "clone" ] || return 1 + printf 'git %s %s %s\n' "$1" "$2" "$3" >>"$TEST_ROOT/git.log" + mkdir -p "$3" + } + + save_config() { + echo "save_config called" >>"$TEST_ROOT/save.log" + } + + run connect_repo "https://example.com/acme/alf-conf.git" "1" "" "" + + [ "$status" -eq 0 ] + assert_output_contains "Connecting to https://example.com/acme/alf-conf.git" + assert_output_contains "Storing location in $TEST_ROOT/alfrc" + [ "$(cat "$TEST_ROOT/alfrc")" = "$TEST_ROOT/work/alf-conf" ] + grep -Fq 'git clone https://example.com/acme/alf-conf.git ./alf-conf' "$TEST_ROOT/git.log" + grep -Fq 'save_config called' "$TEST_ROOT/save.log" +} + +@test "connect_repo chooses https interactively for shorthand GitHub repos" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + mkdir -p "$TEST_ROOT/work" + cd "$TEST_ROOT/work" || exit 1 + source_libs prompt connect_repo + + prompt_for_github_protocol() { + echo "h" + } + + git() { + [ "$1" = "clone" ] || return 1 + printf '%s\n' "$2" >"$TEST_ROOT/cloned-url" + mkdir -p "$3" + } + + save_config() { + : + } + + run connect_repo "DannyBen" "" "" "" + + [ "$status" -eq 0 ] + assert_output_contains "Using https://github.com/DannyBen/alf-conf.git" + [ "$(cat "$TEST_ROOT/cloned-url")" = "https://github.com/DannyBen/alf-conf.git" ] +} + +@test "connect_repo aborts when the interactive GitHub prompt declines the operation" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + source_libs prompt connect_repo + + prompt_for_github_protocol() { + echo "a" + } + + git() { + echo "git should not be called" + return 1 + } + + save_config() { + echo "save_config should not be called" + return 1 + } + + run connect_repo "DannyBen" "" "" "" + + [ "$status" -eq 0 ] + assert_output_contains "Aborting" + [ ! -e "$TEST_ROOT/alfrc" ] +} + +@test "connect_repo skips clone when alf-conf already exists" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + mkdir -p "$TEST_ROOT/work/alf-conf" + cd "$TEST_ROOT/work" || exit 1 + source_libs prompt connect_repo + + git() { + echo "git should not be called" + return 1 + } + + save_config() { + echo called >"$TEST_ROOT/save.log" + } + + run connect_repo "https://example.com/acme/alf-conf.git" "1" "" "" + + [ "$status" -eq 0 ] + assert_output_contains "Skipping clone, directory already exists" + [ "$(cat "$TEST_ROOT/alfrc")" = "$TEST_ROOT/work/alf-conf" ] + [ "$(cat "$TEST_ROOT/save.log")" = "called" ] +} diff --git a/test/lib/download_repo.bats b/test/lib/download_repo.bats new file mode 100644 index 0000000..e72147c --- /dev/null +++ b/test/lib/download_repo.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + unset_functions find_config git save_config + teardown_test_environment +} + +@test "download_repo pulls the repo and saves aliases" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + repo_path="$TEST_ROOT/repo" + mkdir -p "$repo_path" + : >"$ALF_RC_FILE" + cd "$TEST_ROOT" || exit 1 + source_libs download_repo + + find_config() { + : + } + + git() { + [ "$1" = "pull" ] || return 1 + echo pull >>"$TEST_ROOT/git.log" + } + + save_config() { + echo save >>"$TEST_ROOT/save.log" + } + + download_repo + + [ "$(cat "$TEST_ROOT/git.log")" = "pull" ] + [ "$(cat "$TEST_ROOT/save.log")" = "save" ] +} + +@test "download_repo fails when no rc file exists" { + export ALF_RC_FILE="$TEST_ROOT/missing-alfrc" + repo_path="$TEST_ROOT/repo" + source_libs download_repo + + find_config() { + : + } + + run download_repo + + [ "$status" -eq 1 ] + assert_output_contains "Cannot find $TEST_ROOT/missing-alfrc" + assert_output_contains "Please connect alf to a repository first" +} diff --git a/test/lib/prompt.bats b/test/lib/prompt.bats new file mode 100644 index 0000000..d3d470e --- /dev/null +++ b/test/lib/prompt.bats @@ -0,0 +1,39 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + unset_functions read + teardown_test_environment +} + +@test "prompt_for_github_protocol prints the prompt and returns the typed answer" { + source_libs prompt + + read() { + printf -v "$2" '%s' "h" + } + + run prompt_for_github_protocol + + [ "$status" -eq 0 ] + assert_output_contains "Would you like to connect to GitHub via SSH or HTTPS?" + assert_output_contains "[S]SH, [H]TTPS or [A]bort (default): h" +} + +@test "prompt_to_continue prints the prompt and returns the typed answer" { + source_libs prompt + + read() { + printf -v "$2" '%s' "y" + } + + run prompt_to_continue + + [ "$status" -eq 0 ] + assert_output_contains "Continue? [yN] y" +} diff --git a/test/lib/show_alias_command.bats b/test/lib/show_alias_command.bats new file mode 100644 index 0000000..2262d31 --- /dev/null +++ b/test/lib/show_alias_command.bats @@ -0,0 +1,71 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "show_alias_command prints the base command for a simple alias" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path show_alias_command/with-config/alfrc)" + cd "$(fixture_path show_alias_command/with-config)" || exit 1 + source_libs find_config show_alias_command + + run show_alias_command g + + [ "$status" -eq 0 ] + [ "$output" = "git" ] +} + +@test "show_alias_command prints the full nested command" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path show_alias_command/with-config/alfrc)" + cd "$(fixture_path show_alias_command/with-config)" || exit 1 + source_libs find_config show_alias_command + + run show_alias_command g l + + [ "$status" -eq 0 ] + [ "$output" = "git log --all --graph --date=relative" ] +} + +@test "show_alias_command respects escaped nested commands" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path show_alias_command/with-config/alfrc)" + cd "$(fixture_path show_alias_command/with-config)" || exit 1 + source_libs find_config show_alias_command + + run show_alias_command dc deploy + + [ "$status" -eq 0 ] + [ "$output" = "docker stack deploy -c docker-compose.yml" ] +} + +@test "show_alias_command returns an error for an unknown alias" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path show_alias_command/with-config/alfrc)" + cd "$(fixture_path show_alias_command/with-config)" || exit 1 + source_libs find_config show_alias_command + + run show_alias_command no + + [ "$status" -eq 1 ] + [ "$output" = "Error: No such alias: no " ] +} + +@test "show_alias_command returns an error for an unknown sub-alias" { + export ALF_RC_FILE + ALF_RC_FILE="$(fixture_path show_alias_command/with-config/alfrc)" + cd "$(fixture_path show_alias_command/with-config)" || exit 1 + source_libs find_config show_alias_command + + run show_alias_command g no + + [ "$status" -eq 1 ] + [ "$output" = "Error: No such alias: g no" ] +} diff --git a/test/commands/info.bats b/test/lib/show_info.bats similarity index 69% rename from test/commands/info.bats rename to test/lib/show_info.bats index 4c6be0c..262552d 100644 --- a/test/commands/info.bats +++ b/test/lib/show_info.bats @@ -10,14 +10,16 @@ teardown() { teardown_test_environment } -@test "info reports local config details when no git repo is connected" { +@test "show_info reports local config details when no git repo is connected" { fixture_dir="$TEST_ROOT/with-config" mkdir -p "$fixture_dir" write_file "$fixture_dir/alf.conf" "g: git" export ALF_RC_FILE="$TEST_ROOT/missing-alfrc" export ALF_ALIASES_FILE="$TEST_ROOT/aliases.txt" + cd "$fixture_dir" || exit 1 + source_libs find_config show_info - run env ALF_RC_FILE="$ALF_RC_FILE" ALF_ALIASES_FILE="$ALF_ALIASES_FILE" ALF_REPO_ROOT="$ALF_REPO_ROOT" PATH="$PATH" bash -lc "source '$ALF_REPO_ROOT/src/initialize.sh'; source '$ALF_REPO_ROOT/src/lib/find_config.sh'; cd '$fixture_dir' || exit 1; source '$ALF_REPO_ROOT/src/info_command.sh'" + run show_info [ "$status" -eq 0 ] assert_output_contains "path: $TEST_ROOT/bin/alf" @@ -29,7 +31,7 @@ teardown() { assert_output_contains "remote: unset" } -@test "info reports connected repo details from ALF_RC_FILE" { +@test "show_info reports connected repo details from ALF_RC_FILE" { repo_path="$TEST_ROOT/connected-alf" mkdir -p "$repo_path" write_file "$repo_path/alf.conf" "g: git" @@ -39,8 +41,10 @@ teardown() { export ALF_ALIASES_FILE="$TEST_ROOT/aliases.txt" touch "$TEST_ROOT/aliases.txt" git -C "$repo_path" remote add origin https://example.com/acme/alf-conf.git + cd "$HOME" || exit 1 + source_libs find_config show_info - run env ALF_RC_FILE="$ALF_RC_FILE" ALF_ALIASES_FILE="$ALF_ALIASES_FILE" ALF_REPO_ROOT="$ALF_REPO_ROOT" PATH="$PATH" HOME="$HOME" bash -lc "source '$ALF_REPO_ROOT/src/initialize.sh'; source '$ALF_REPO_ROOT/src/lib/find_config.sh'; cd '$HOME' || exit 1; source '$ALF_REPO_ROOT/src/info_command.sh'" + run show_info [ "$status" -eq 0 ] assert_output_contains "ALF_RC_FILE: $TEST_ROOT/alfrc" diff --git a/test/lib/upload_repo.bats b/test/lib/upload_repo.bats new file mode 100644 index 0000000..9f2f41c --- /dev/null +++ b/test/lib/upload_repo.bats @@ -0,0 +1,50 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + unset_functions find_config git + teardown_test_environment +} + +@test "upload_repo commits and pushes the repo" { + export ALF_RC_FILE="$TEST_ROOT/alfrc" + repo_path="$TEST_ROOT/repo" + mkdir -p "$repo_path" + : >"$ALF_RC_FILE" + cd "$TEST_ROOT" || exit 1 + source_libs upload_repo + + find_config() { + : + } + + git() { + printf '%s\n' "$1" >>"$TEST_ROOT/git.log" + } + + upload_repo + + [ "$(sed -n '1p' "$TEST_ROOT/git.log")" = "commit" ] + [ "$(sed -n '2p' "$TEST_ROOT/git.log")" = "push" ] +} + +@test "upload_repo fails when no rc file exists" { + export ALF_RC_FILE="$TEST_ROOT/missing-alfrc" + repo_path="$TEST_ROOT/repo" + source_libs upload_repo + + find_config() { + : + } + + run upload_repo + + [ "$status" -eq 1 ] + assert_output_contains "Cannot find $TEST_ROOT/missing-alfrc" + assert_output_contains "Please connect alf to a repository first" +} diff --git a/test/test_helper.bash b/test/test_helper.bash index 554c7ef..4a658da 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -36,6 +36,14 @@ write_file() { printf '%s\n' "$@" >"$path" } +unset_functions() { + local fn + + for fn in "$@"; do + unset -f "$fn" 2>/dev/null || true + done +} + source_libs() { local lib From 096cb1dc039258a482785b54740c21b9b60af74c Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 19:41:52 +0200 Subject: [PATCH 4/8] - Remove approval tests in favor of bats --- .github/workflows/test.yml | 24 +-- docker-compose.yml | 19 -- op.conf | 13 +- test-legacy/approvals.bash | 172 ------------------ test-legacy/approvals/alf_download_help | 11 -- test-legacy/approvals/alf_generate_help | 11 -- test-legacy/approvals/alf_info_help | 9 - test-legacy/approvals/alf_save_help | 19 -- test-legacy/approvals/alf_upload_help | 11 -- test-legacy/approve | 14 -- test-legacy/approve_zsh | 18 -- test-legacy/connect_spec.sh | 42 ----- test-legacy/download_spec.sh | 22 --- test-legacy/edit_spec.sh | 11 -- test-legacy/fixtures/connect/.gitignore | 3 - .../fixtures/connect/approvals/alf_connect | 2 - .../approvals/alf_connect_DannyBen_https | 6 - .../approvals/alf_connect_DannyBen_yes | 3 - .../connect/approvals/alf_connect_help | 36 ---- ...https_github_com_DannyBen_alf_conf_git_yes | 6 - .../fixtures/connect/approvals/alf_download | 5 - .../fixtures/connect/approvals/alf_upload | 5 - .../fixtures/connect/approvals/cat_alfrc | 1 - .../approvals/echo_a_alf_connect_JohnSnow | 11 -- .../echo_a_alf_connect_JohnSnow_winterfell | 11 -- ...ct_https_bitbucket_com_JohnSnow_winterfell | 9 - test-legacy/fixtures/empty-dir/approvals/alf | 17 -- .../fixtures/empty-dir/approvals/alf_download | 5 - .../fixtures/empty-dir/approvals/alf_generate | 5 - .../fixtures/empty-dir/approvals/alf_help | 32 ---- .../fixtures/empty-dir/approvals/alf_save | 5 - .../fixtures/empty-dir/approvals/alf_upgrade | 15 -- .../empty-dir/approvals/alf_upgrade_help | 9 - .../fixtures/empty-dir/approvals/alf_upload | 5 - .../fixtures/empty-dir/approvals/alf_version | 1 - test-legacy/fixtures/generate/alf.conf | 41 ----- test-legacy/fixtures/generate/aliases.txt | 116 ------------ .../fixtures/generate/approvals/alf_generate | 116 ------------ .../fixtures/generate/approvals/alf_save | 3 - .../fixtures/generate/approvals/alf_which | 2 - .../generate/approvals/alf_which_dc_deploy | 1 - .../generate/approvals/alf_which_dc_upd | 1 - .../fixtures/generate/approvals/alf_which_g | 1 - .../fixtures/generate/approvals/alf_which_g_l | 1 - .../generate/approvals/alf_which_g_no | 1 - .../generate/approvals/alf_which_help | 18 -- .../fixtures/generate/approvals/alf_which_no | 1 - .../generate/approvals/say_again_zsh_works | 1 - test-legacy/fixtures/info/alf.conf | 30 --- test-legacy/fixtures/info/alfrc | 1 - test-legacy/fixtures/info/aliases.txt | 1 - test-legacy/fixtures/info/approvals/alf_info | 19 -- test-legacy/fixtures/no-subcommands/alf.conf | 2 - .../no-subcommands/approvals/alf_generate | 12 -- test-legacy/fixtures/sample/alf.conf | 30 --- .../fixtures/sample/approvals/alf_edit | 1 - .../fixtures/sample/approvals/alf_edit_help | 11 -- .../fixtures/sample/approvals/alf_info | 19 -- test-legacy/generate_spec.sh | 23 --- test-legacy/info_spec.sh | 22 --- test-legacy/save_spec.sh | 24 --- test-legacy/upgrade_spec.sh | 12 -- test-legacy/upload_spec.sh | 20 -- test-legacy/usage_spec.sh | 10 - test-legacy/which_spec.sh | 36 ---- 65 files changed, 16 insertions(+), 1148 deletions(-) delete mode 100644 test-legacy/approvals.bash delete mode 100644 test-legacy/approvals/alf_download_help delete mode 100644 test-legacy/approvals/alf_generate_help delete mode 100644 test-legacy/approvals/alf_info_help delete mode 100644 test-legacy/approvals/alf_save_help delete mode 100644 test-legacy/approvals/alf_upload_help delete mode 100644 test-legacy/approve delete mode 100644 test-legacy/approve_zsh delete mode 100644 test-legacy/connect_spec.sh delete mode 100644 test-legacy/download_spec.sh delete mode 100644 test-legacy/edit_spec.sh delete mode 100644 test-legacy/fixtures/connect/.gitignore delete mode 100644 test-legacy/fixtures/connect/approvals/alf_connect delete mode 100644 test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https delete mode 100644 test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes delete mode 100644 test-legacy/fixtures/connect/approvals/alf_connect_help delete mode 100644 test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes delete mode 100644 test-legacy/fixtures/connect/approvals/alf_download delete mode 100644 test-legacy/fixtures/connect/approvals/alf_upload delete mode 100644 test-legacy/fixtures/connect/approvals/cat_alfrc delete mode 100644 test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow delete mode 100644 test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell delete mode 100644 test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_download delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_generate delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_help delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_save delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_upgrade delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_upload delete mode 100644 test-legacy/fixtures/empty-dir/approvals/alf_version delete mode 100644 test-legacy/fixtures/generate/alf.conf delete mode 100644 test-legacy/fixtures/generate/aliases.txt delete mode 100644 test-legacy/fixtures/generate/approvals/alf_generate delete mode 100644 test-legacy/fixtures/generate/approvals/alf_save delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_dc_deploy delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_dc_upd delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_g delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_g_l delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_g_no delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_help delete mode 100644 test-legacy/fixtures/generate/approvals/alf_which_no delete mode 100644 test-legacy/fixtures/generate/approvals/say_again_zsh_works delete mode 100644 test-legacy/fixtures/info/alf.conf delete mode 100644 test-legacy/fixtures/info/alfrc delete mode 100644 test-legacy/fixtures/info/aliases.txt delete mode 100644 test-legacy/fixtures/info/approvals/alf_info delete mode 100644 test-legacy/fixtures/no-subcommands/alf.conf delete mode 100644 test-legacy/fixtures/no-subcommands/approvals/alf_generate delete mode 100644 test-legacy/fixtures/sample/alf.conf delete mode 100644 test-legacy/fixtures/sample/approvals/alf_edit delete mode 100644 test-legacy/fixtures/sample/approvals/alf_edit_help delete mode 100644 test-legacy/fixtures/sample/approvals/alf_info delete mode 100644 test-legacy/generate_spec.sh delete mode 100644 test-legacy/info_spec.sh delete mode 100644 test-legacy/save_spec.sh delete mode 100644 test-legacy/upgrade_spec.sh delete mode 100644 test-legacy/upload_spec.sh delete mode 100644 test-legacy/usage_spec.sh delete mode 100644 test-legacy/which_spec.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c675801..cf0fd36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,14 +12,8 @@ jobs: uses: actions/checkout@v4 - name: Run shellcheck tests run: shellcheck alf setup - - name: Build container for approval tests - run: docker compose build - - name: Run approval tests - run: docker compose run ci - - name: Run sanity test in zsh - run: docker compose run test_zsh - name: Run Bats tests - run: bats test/commands test/lib + run: bats --recursive --print-output-on-failure --abort test ubuntu_setup: name: Setup on Ubuntu @@ -28,9 +22,13 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Run setup - run: ./setup + run: + ./setup + command -v alf - name: Run uninstall - run: ./uninstall + run: + ./uninstall + ! command -v alf macos_setup: name: Setup on macOS @@ -41,9 +39,13 @@ jobs: - name: Upgrade the outdated bash run: brew install bash - name: Run setup - run: ./setup + run: + ./setup + command -v alf - name: Run uninstall - run: ./uninstall + run: + ./uninstall + ! command -v alf static_analysis: name: Static analysis diff --git a/docker-compose.yml b/docker-compose.yml index 537b0a1..e30e94d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,22 +13,3 @@ services: environment: PS1: "zsh %/ $$ " entrypoint: zsh - - # TEST=connect docker compose run test - test: &test - <<: *default - volumes: - - .:/app - environment: { TEST } - command: test-legacy/approve - - test_zsh: &test_zsh - <<: *zsh - environment: { CI, GITHUB_ACTIONS } - command: test-legacy/approve_zsh - - ci: - <<: *test - environment: - CI: 1 - volumes: [] diff --git a/op.conf b/op.conf index b879910..e97b8fe 100644 --- a/op.conf +++ b/op.conf @@ -9,15 +9,8 @@ watch: filewatcher --immediate "src/**/*.*" "bashly generate" ## Testing and Linting -test: - docker compose build bash - docker compose run --rm test - [[ -z "$TEST" ]] && docker compose run --rm test_zsh - bats --recursive --print-output-on-failure --abort "${1:-test}" ; echo "Exit code: $?" -#? Run test suite inside a docker container -#? If a specific TEST is requested, zsh tests will not be executed -#? Usage: op test -#? TEST=info op test +test: bats --recursive --print-output-on-failure --abort "${1:-test}" +#? Run all tests or a given test shellcheck: shellcheck alf setup uninstall && green "PASS" #? Run shellcheck @@ -42,7 +35,7 @@ changelog: git changelog --save version: [[ -n "$1" ]] || abort "Usage: op version NEW_VERSION" - sed -i "s/$(alf --version)/$1/g" README.md src/bashly.yml test-legacy/fixtures/empty-dir/approvals/alf_version test-legacy/fixtures/empty-dir/approvals/alf_upgrade + sed -i "s/$(alf --version)/$1/g" README.md src/bashly.yml op generate git commit -am "version bump $1" git tag v$1 diff --git a/test-legacy/approvals.bash b/test-legacy/approvals.bash deleted file mode 100644 index 9ee20d7..0000000 --- a/test-legacy/approvals.bash +++ /dev/null @@ -1,172 +0,0 @@ -# approvals.bash v0.5.1 -# -# Interactive approval testing for Bash. -# https://github.com/DannyBen/approvals.bash -# -# shellcheck disable=SC2059 -# Disabling SC2059 (quoted format string) because we use dynamic format strings -approve() { - local expected approval approval_file actual cmd - approvals_dir=${APPROVALS_DIR:=approvals} - - cmd=$1 - last_exit_code=0 - actual=$(eval "$cmd" 2>&1) || last_exit_code=$? - if [[ -v allow_diff_regex && "$allow_diff_regex" ]]; then - actual=$(echo "$actual" | sed -E "s/$allow_diff_regex/*/g") - unset allow_diff_regex - fi - approval=$(printf "%b" "$cmd" | tr -s -c "[:alnum:]" _) - approval_file="$approvals_dir/${2:-"$approval"}" - - [[ -d "$approvals_dir" ]] || mkdir "$approvals_dir" - - if [[ -f "$approval_file" ]]; then - expected=$(cat "$approval_file") - else - printf -- "$new_diff_string\n" "$cmd" - printf "%b\n" "$actual" - printf -- "$new_diff_string\n" "$cmd" - expected="$actual" - user_approval "$cmd" "$actual" "$approval_file" - return - fi - - if [[ "$(printf "%b" "$actual")" = "$(printf "%b" "$expected")" ]]; then - pass "$cmd" - else - printf -- "$changed_diff_string\n" "$cmd" - $diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n") | tail -n +4 - printf -- "$changed_diff_string\n" "$cmd" - user_approval "$cmd" "$actual" "$approval_file" - fi -} - -allow_diff() { - allow_diff_regex="$1" -} - -describe() { - printf "$describe_string\n" "$*" -} - -context() { - printf "$context_string\n" "$*" -} - -it() { - printf "$it_string\n" "$*" -} - -fail() { - printf "$fail_string\n" "$*" - exit 1 -} - -pass() { - printf "$pass_string\n" "$*" - return 0 -} - -expect_exit_code() { - if [[ $last_exit_code == "$1" ]]; then - pass "exit $last_exit_code" - else - fail "expected exit code $1, got $last_exit_code" - fi -} - -# Private - -print_in_color() { - local color="$1" - shift - if [[ -z ${NO_COLOR+x} ]]; then - printf "$color%b\e[0m\n" "$*" - else - printf "%b\n" "$*" - fi -} - -red() { print_in_color "\e[31m" "$*"; } -green() { print_in_color "\e[32m" "$*"; } -yellow() { print_in_color "\e[33m" "$*"; } -blue() { print_in_color "\e[34m" "$*"; } -magenta() { print_in_color "\e[35m" "$*"; } -cyan() { print_in_color "\e[36m" "$*"; } -bold() { print_in_color "\e[1m" "$*"; } -underlined() { print_in_color "\e[4m" "$*"; } -red_bold() { print_in_color "\e[1;31m" "$*"; } -green_bold() { print_in_color "\e[1;32m" "$*"; } -yellow_bold() { print_in_color "\e[1;33m" "$*"; } -blue_bold() { print_in_color "\e[1;34m" "$*"; } -magenta_bold() { print_in_color "\e[1;35m" "$*"; } -cyan_bold() { print_in_color "\e[1;36m" "$*"; } -red_underlined() { print_in_color "\e[4;31m" "$*"; } -green_underlined() { print_in_color "\e[4;32m" "$*"; } -yellow_underlined() { print_in_color "\e[4;33m" "$*"; } -blue_underlined() { print_in_color "\e[4;34m" "$*"; } -magenta_underlined() { print_in_color "\e[4;35m" "$*"; } -cyan_underlined() { print_in_color "\e[4;36m" "$*"; } - -user_approval() { - local cmd="$1" - local actual="$2" - local approval_file="$3" - - if [[ -v CI || -v GITHUB_ACTIONS ]] && [[ -z "${AUTO_APPROVE+x}" ]]; then - fail "$cmd" - fi - - if [[ -v AUTO_APPROVE ]]; then - response=a - else - echo - printf "$approval_string" - response=$(bash -c "read -n 1 key; echo \$key") - printf "\b%.s" $(seq 1 $((${#approval_string} + 1))) - fi - - if [[ $response =~ [Aa] ]]; then - printf "%b\n" "$actual" >"$approval_file" - pass "$cmd" - else - fail "$cmd" - fi -} - -onexit() { - exitcode=$? - if [[ "$exitcode" == 0 ]]; then - printf "$exit_success_string\n" "$0" - else - printf "$exit_failed_string\n" "$0" - fi - echo - exit $exitcode -} - -onerror() { - fail "caller: $(caller)" -} - -set -e -trap 'onexit' EXIT -trap 'onerror' ERR - -describe_string="$(bold ▌ describe) %s" -context_string="$(bold ▌ context) %s" -it_string="$(bold ▌ it) %s" -fail_string=" $(red_bold failed) %s" -pass_string=" $(green approved) %s" -exit_success_string="$(green ▌ exit) $(bold %s finished successfully)" -exit_failed_string="$(red_bold ▌ exit) $(bold %s finished with errors)" -new_diff_string="────┤ $(yellow new): $(bold %s) ├────" -changed_diff_string="────┤ $(blue changed): $(bold %s) ├────" -approval_string="[A]pprove? " - -if diff --help | grep -- --color >/dev/null 2>&1; then - diff_cmd="diff --unified --color=always" -else - diff_cmd="diff --unified" -fi diff --git a/test-legacy/approvals/alf_download_help b/test-legacy/approvals/alf_download_help deleted file mode 100644 index 06fefb4..0000000 --- a/test-legacy/approvals/alf_download_help +++ /dev/null @@ -1,11 +0,0 @@ -alf download - Perform git pull on the connected repo. - -Alias: d, pull - -Usage: - alf download - alf download --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/approvals/alf_generate_help b/test-legacy/approvals/alf_generate_help deleted file mode 100644 index be8b1d9..0000000 --- a/test-legacy/approvals/alf_generate_help +++ /dev/null @@ -1,11 +0,0 @@ -alf generate - Generate aliases to stdout. - -Alias: g - -Usage: - alf generate - alf generate --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/approvals/alf_info_help b/test-legacy/approvals/alf_info_help deleted file mode 100644 index 2fdb910..0000000 --- a/test-legacy/approvals/alf_info_help +++ /dev/null @@ -1,9 +0,0 @@ -alf info - Show all alf related system facts. - -Usage: - alf info - alf info --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/approvals/alf_save_help b/test-legacy/approvals/alf_save_help deleted file mode 100644 index 99257fd..0000000 --- a/test-legacy/approvals/alf_save_help +++ /dev/null @@ -1,19 +0,0 @@ -alf save - Generate aliases to `~/.bash_aliases`. - -Alias: s - -Usage: - alf save - alf save --help | -h - -Options: - --help, -h - Show this help - -Environment Variables: - ALF_ALIASES_FILE - Path to bash_aliases file. - - Aliases will be saved to this file. - - Default: `~/.bash_aliases` diff --git a/test-legacy/approvals/alf_upload_help b/test-legacy/approvals/alf_upload_help deleted file mode 100644 index 2b9c85f..0000000 --- a/test-legacy/approvals/alf_upload_help +++ /dev/null @@ -1,11 +0,0 @@ -alf upload - Perform git commit and push on the connected repo. - -Alias: u, push - -Usage: - alf upload - alf upload --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/approve b/test-legacy/approve deleted file mode 100644 index b0d4275..0000000 --- a/test-legacy/approve +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Run this from the main repo directory - -cd ./test-legacy -source "approvals.bash" - -if [[ $TEST ]]; then - "./${TEST}_spec.sh" -else - for file in *_spec.sh ; do - context "$file" - "./$file" || fail "aborted test loop" - done -fi diff --git a/test-legacy/approve_zsh b/test-legacy/approve_zsh deleted file mode 100644 index c44f84d..0000000 --- a/test-legacy/approve_zsh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env zsh -# Run this from the main repo directory - -source 'test-legacy/approvals.bash' - -unset ALF_RC_FILE -export ALF_ALIASES_FILE="aliases.txt" - -context "in zsh" - describe "generated aliases in zsh" - pushd test-legacy/fixtures/generate > /dev/null - rm -f "aliases.txt" - approve "alf save" - source 'aliases.txt' || return 0 - approve "say again zsh-works" - popd - -green "\nsanity test on ZSH passed!" diff --git a/test-legacy/connect_spec.sh b/test-legacy/connect_spec.sh deleted file mode 100644 index 9b0a05a..0000000 --- a/test-legacy/connect_spec.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -cd ./fixtures/connect -export ALF_RC_FILE="./alfrc" -rm -rf alf-conf - -describe "alf connect --help" - approve "alf connect --help" - -describe "alf connect (no repo)" - approve "alf connect" || return 0 - expect_exit_code 1 - -describe "alf connect " - approve "echo a | alf connect JohnSnow" - -describe "alf connect /" - approve "echo a | alf connect JohnSnow/winterfell" - -describe "alf connect " - approve "echo a | alf connect https://bitbucket.com/JohnSnow/winterfell" - -describe "alf connect --yes (disallowed)" - rm -f ./alfrc - approve "alf connect DannyBen --yes" || return 0 - expect_exit_code 1 - -describe "alf connect --yes (non interactive)" - rm -f ./alfrc - approve "alf connect https://github.com/DannyBen/alf-conf.git --yes" - [[ -d alf-conf ]] || fail "Expected to have alf-conf directory" - [[ -f alf-conf/alf.conf ]] || fail "Expected to have alf-conf/alf.conf file" - approve "cat alfrc" - -describe "alf connect --https (non interactive)" - rm -f ./alfrc - approve "alf connect DannyBen --https" - [[ -d alf-conf ]] || fail "Expected to have alf-conf directory" - [[ -f alf-conf/alf.conf ]] || fail "Expected to have alf-conf/alf.conf file" - approve "cat alfrc" - diff --git a/test-legacy/download_spec.sh b/test-legacy/download_spec.sh deleted file mode 100644 index 8e1f4cc..0000000 --- a/test-legacy/download_spec.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -export ALF_RC_FILE="./alfrc" - -describe "alf download --help" - approve "alf download --help" - -describe "alf download" - pushd ./fixtures/connect > /dev/null - [[ -d alf-conf ]] || alf connect DannyBen -y - [[ -d alf-conf ]] || fail "Expected alf-conf directory to exist" - approve "alf download" - popd > /dev/null - -describe "alf download (without repo connection)" - pushd ./fixtures/empty-dir > /dev/null - rm -rf ./alf-conf - approve "alf download" || return 0 - expect_exit_code 1 - popd > /dev/null - diff --git a/test-legacy/edit_spec.sh b/test-legacy/edit_spec.sh deleted file mode 100644 index 689ca8d..0000000 --- a/test-legacy/edit_spec.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' -cd ./fixtures/sample - -describe "alf edit --help" - approve "alf edit --help" - -describe "alf edit" - export EDITOR="echo stubbed editor with: " - approve "alf edit" - diff --git a/test-legacy/fixtures/connect/.gitignore b/test-legacy/fixtures/connect/.gitignore deleted file mode 100644 index 2eeeaa1..0000000 --- a/test-legacy/fixtures/connect/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -alfrc -alf-conf -aliases.txt \ No newline at end of file diff --git a/test-legacy/fixtures/connect/approvals/alf_connect b/test-legacy/fixtures/connect/approvals/alf_connect deleted file mode 100644 index ed98523..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_connect +++ /dev/null @@ -1,2 +0,0 @@ -missing required argument: REPO -usage: alf connect REPO [OPTIONS] diff --git a/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https b/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https deleted file mode 100644 index 34b52c6..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_https +++ /dev/null @@ -1,6 +0,0 @@ -Connecting to https://github.com/DannyBen/alf-conf.git -Skipping clone, directory already exists -Storing location in ./alfrc -Saving to /root/.bash_aliases -To apply the new aliases to the current session, run: -$ source ~/.bash_aliases diff --git a/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes b/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes deleted file mode 100644 index 0623c0c..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_connect_DannyBen_yes +++ /dev/null @@ -1,3 +0,0 @@ -Error: Cannot determine the full URL for the repository -To connect to GitHub use --ssh or --https -To connect to another repository, provide the full URL diff --git a/test-legacy/fixtures/connect/approvals/alf_connect_help b/test-legacy/fixtures/connect/approvals/alf_connect_help deleted file mode 100644 index 916282a..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_connect_help +++ /dev/null @@ -1,36 +0,0 @@ -alf connect - Connect to a remote git repository. - -Alias: c - -Usage: - alf connect REPO [OPTIONS] - alf connect --help | -h - -Options: - --ssh - Connect to GitHub non-interactively using SSH (implies `--yes`). - - --https - Connect to GitHub non-interactively using HTTPS (implies `--yes`). - - --yes, -y - Connect to any remote repository non-interactively. - - --help, -h - Show this help - -Arguments: - REPO - Remote GitHub repository to connect to. - - Can be one of: - - - Your username on GitHub. - In this case, the repository is expected to be named `alf-conf`. - - Your username/repo on GitHub. - - Any other full URL to a repository. - -Examples: - alf connect you --ssh - alf connect you/alf-config - alf connect https://You@bitbucket.org/YourUser/rush-repo.git --yes diff --git a/test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes b/test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes deleted file mode 100644 index 83c395b..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_connect_https_github_com_DannyBen_alf_conf_git_yes +++ /dev/null @@ -1,6 +0,0 @@ -Connecting to https://github.com/DannyBen/alf-conf.git -Cloning into './alf-conf'... -Storing location in ./alfrc -Saving to /root/.bash_aliases -To apply the new aliases to the current session, run: -$ source ~/.bash_aliases diff --git a/test-legacy/fixtures/connect/approvals/alf_download b/test-legacy/fixtures/connect/approvals/alf_download deleted file mode 100644 index 70f5846..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_download +++ /dev/null @@ -1,5 +0,0 @@ -Pulling from repository to /app/test-legacy/fixtures/connect/alf-conf -Already up to date. -Saving to /root/.bash_aliases -To apply the new aliases to the current session, run: -$ source ~/.bash_aliases diff --git a/test-legacy/fixtures/connect/approvals/alf_upload b/test-legacy/fixtures/connect/approvals/alf_upload deleted file mode 100644 index 9654fd4..0000000 --- a/test-legacy/fixtures/connect/approvals/alf_upload +++ /dev/null @@ -1,5 +0,0 @@ -Pushing /app/test-legacy/fixtures/connect/alf-conf to repository -On branch master -Your branch is up to date with 'origin/master'. - -nothing to commit, working tree clean diff --git a/test-legacy/fixtures/connect/approvals/cat_alfrc b/test-legacy/fixtures/connect/approvals/cat_alfrc deleted file mode 100644 index ad8dc3a..0000000 --- a/test-legacy/fixtures/connect/approvals/cat_alfrc +++ /dev/null @@ -1 +0,0 @@ -/app/test-legacy/fixtures/connect/alf-conf diff --git a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow deleted file mode 100644 index 2fefc91..0000000 --- a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow +++ /dev/null @@ -1,11 +0,0 @@ -This operation will: - - clone JohnSnow/alf-conf.git - to ./alf-conf - - write /app/test-legacy/fixtures/connect/alf-conf - to ./alfrc - -Would you like to connect to GitHub via SSH or HTTPS? - -[S]SH, [H]TTPS or [A]bort (default): Aborting diff --git a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell deleted file mode 100644 index b3ee2f4..0000000 --- a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_JohnSnow_winterfell +++ /dev/null @@ -1,11 +0,0 @@ -This operation will: - - clone JohnSnow/winterfell.git - to ./alf-conf - - write /app/test-legacy/fixtures/connect/alf-conf - to ./alfrc - -Would you like to connect to GitHub via SSH or HTTPS? - -[S]SH, [H]TTPS or [A]bort (default): Aborting diff --git a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell b/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell deleted file mode 100644 index bd1c30f..0000000 --- a/test-legacy/fixtures/connect/approvals/echo_a_alf_connect_https_bitbucket_com_JohnSnow_winterfell +++ /dev/null @@ -1,9 +0,0 @@ -This operation will: - - clone https://bitbucket.com/JohnSnow/winterfell - to ./alf-conf - - write /app/test-legacy/fixtures/connect/alf-conf - to ./alfrc - -Continue? [yN] Aborting diff --git a/test-legacy/fixtures/empty-dir/approvals/alf b/test-legacy/fixtures/empty-dir/approvals/alf deleted file mode 100644 index a9d8b66..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf +++ /dev/null @@ -1,17 +0,0 @@ -alf - Your Little Bash Alias Friend - -Usage: - alf COMMAND - alf [COMMAND] --help | -h - alf --version | -v - -Commands: - connect Connect to a remote git repository. - download Perform git pull on the connected repo. - upload Perform git commit and push on the connected repo. - generate Generate aliases to stdout. - save Generate aliases to `~/.bash_aliases`. - edit Open your `alf.conf` for editing. - which Show the alias command. - upgrade Upgrade alf to the latest version. - info Show all alf related system facts. diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_download b/test-legacy/fixtures/empty-dir/approvals/alf_download deleted file mode 100644 index e810e2b..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_download +++ /dev/null @@ -1,5 +0,0 @@ -ERROR: Cannot find config file - -You should either: -- Run this command in a folder with 'alf.conf' file, or -- Run 'alf connect' to properly connect to a remote config diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_generate b/test-legacy/fixtures/empty-dir/approvals/alf_generate deleted file mode 100644 index e810e2b..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_generate +++ /dev/null @@ -1,5 +0,0 @@ -ERROR: Cannot find config file - -You should either: -- Run this command in a folder with 'alf.conf' file, or -- Run 'alf connect' to properly connect to a remote config diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_help b/test-legacy/fixtures/empty-dir/approvals/alf_help deleted file mode 100644 index dc0372c..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_help +++ /dev/null @@ -1,32 +0,0 @@ -alf - Your Little Bash Alias Friend - -Usage: - alf COMMAND - alf [COMMAND] --help | -h - alf --version | -v - -Commands: - connect Connect to a remote git repository. - download Perform git pull on the connected repo. - upload Perform git commit and push on the connected repo. - generate Generate aliases to stdout. - save Generate aliases to `~/.bash_aliases`. - edit Open your `alf.conf` for editing. - which Show the alias command. - upgrade Upgrade alf to the latest version. - info Show all alf related system facts. - -Options: - --help, -h - Show this help - - --version, -v - Show version number - -Environment Variables: - ALF_RC_FILE - Path to alfrc file. - - This file holds the path to the alf-conf repository. - - Default: `~/.alfrc` diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_save b/test-legacy/fixtures/empty-dir/approvals/alf_save deleted file mode 100644 index e810e2b..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_save +++ /dev/null @@ -1,5 +0,0 @@ -ERROR: Cannot find config file - -You should either: -- Run this command in a folder with 'alf.conf' file, or -- Run 'alf connect' to properly connect to a remote config diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade deleted file mode 100644 index 80a7e05..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade +++ /dev/null @@ -1,15 +0,0 @@ -Initializing installer... -• info  → Installing alf -• info  → Installed: /usr/local/bin/alf -• info  → Installed: /usr/local/share/man/man1/alf-connect.1 -• info  → Installed: /usr/local/share/man/man1/alf-download.1 -• info  → Installed: /usr/local/share/man/man1/alf-edit.1 -• info  → Installed: /usr/local/share/man/man1/alf-generate.1 -• info  → Installed: /usr/local/share/man/man1/alf-info.1 -• info  → Installed: /usr/local/share/man/man1/alf-save.1 -• info  → Installed: /usr/local/share/man/man1/alf-upgrade.1 -• info  → Installed: /usr/local/share/man/man1/alf-upload.1 -• info  → Installed: /usr/local/share/man/man1/alf-which.1 -• info  → Installed: /usr/local/share/man/man1/alf.1 -• info  → Installed: /usr/local/share/man/man5/alf.conf.5 -• info  → alf --version : 0.6.1 diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help b/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help deleted file mode 100644 index cbae2f2..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_upgrade_help +++ /dev/null @@ -1,9 +0,0 @@ -alf upgrade - Upgrade alf to the latest version. - -Usage: - alf upgrade - alf upgrade --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_upload b/test-legacy/fixtures/empty-dir/approvals/alf_upload deleted file mode 100644 index e810e2b..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_upload +++ /dev/null @@ -1,5 +0,0 @@ -ERROR: Cannot find config file - -You should either: -- Run this command in a folder with 'alf.conf' file, or -- Run 'alf connect' to properly connect to a remote config diff --git a/test-legacy/fixtures/empty-dir/approvals/alf_version b/test-legacy/fixtures/empty-dir/approvals/alf_version deleted file mode 100644 index ee6cdce..0000000 --- a/test-legacy/fixtures/empty-dir/approvals/alf_version +++ /dev/null @@ -1 +0,0 @@ -0.6.1 diff --git a/test-legacy/fixtures/generate/alf.conf b/test-legacy/fixtures/generate/alf.conf deleted file mode 100644 index bc4f943..0000000 --- a/test-legacy/fixtures/generate/alf.conf +++ /dev/null @@ -1,41 +0,0 @@ -# Base Alias: -# Any line that does not start with a whitespace is considered a base -# alias. -dir: ls -l - -# Sub Aliases: -# Any line that starts with one or more whitespaces will be nested as -# a subcommand of the previous base alias. -g: git - s: status - l: log --all --graph --date=relative - p: push - -# Reuse: -# You can call an alias from another alias -gg: g p - -ag: ag --color - -abc: abc - help: --help - -# Test positionals -reverse: echo $2 $1 - -say: echo - again: $1 $1 - -# Test escape operator (!) -dc: docker-compose - ls: config --services - deploy: !docker stack deploy -c docker-compose.yml - - # Separate this command from the others to verify that `which` works - # properly - upd: up -d - -# Test virtual command -dns: ! - check: host -t ns - flush: sudo systemd-resolve --flush-caches diff --git a/test-legacy/fixtures/generate/aliases.txt b/test-legacy/fixtures/generate/aliases.txt deleted file mode 100644 index 536fec5..0000000 --- a/test-legacy/fixtures/generate/aliases.txt +++ /dev/null @@ -1,116 +0,0 @@ -# This file was automatically generated by alf -# https://github.com/dannyben/alf - -unalias dir 1>/dev/null 2>&1 -dir() { - ls -l "$@" -} - -unalias g 1>/dev/null 2>&1 -g() { - case "$1" in - s) - shift - git status "$@" - ;; - l) - shift - git log --all --graph --date=relative "$@" - ;; - p) - shift - git push "$@" - ;; - *) - git "$@" - ;; - esac -} - -unalias gg 1>/dev/null 2>&1 -gg() { - g p "$@" -} - -unalias ag 1>/dev/null 2>&1 -ag() { - command ag --color "$@" -} - -unalias abc 1>/dev/null 2>&1 -abc() { - case "$1" in - help) - shift - command abc --help "$@" - ;; - *) - command abc "$@" - ;; - esac -} - -unalias reverse 1>/dev/null 2>&1 -reverse() { - echo $2 $1 -} - -unalias say 1>/dev/null 2>&1 -say() { - case "$1" in - again) - shift - echo $1 $1 - ;; - *) - echo "$@" - ;; - esac -} - -unalias dc 1>/dev/null 2>&1 -dc() { - case "$1" in - ls) - shift - docker-compose config --services "$@" - ;; - deploy) - shift - docker stack deploy -c docker-compose.yml "$@" - ;; - upd) - shift - docker-compose up -d "$@" - ;; - *) - docker-compose "$@" - ;; - esac -} - -unalias dns 1>/dev/null 2>&1 -dns() { - case "$1" in - check) - shift - host -t ns "$@" - ;; - flush) - shift - sudo systemd-resolve --flush-caches "$@" - ;; - *) - echo this alias requires a subcommand - ;; - esac -} - -# Completions -if command -v complete &> /dev/null ; then - complete -W "s l p" g - complete -W "help" abc - complete -W "again" say - complete -W "ls deploy upd" dc - complete -W "check flush" dns -fi diff --git a/test-legacy/fixtures/generate/approvals/alf_generate b/test-legacy/fixtures/generate/approvals/alf_generate deleted file mode 100644 index 536fec5..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_generate +++ /dev/null @@ -1,116 +0,0 @@ -# This file was automatically generated by alf -# https://github.com/dannyben/alf - -unalias dir 1>/dev/null 2>&1 -dir() { - ls -l "$@" -} - -unalias g 1>/dev/null 2>&1 -g() { - case "$1" in - s) - shift - git status "$@" - ;; - l) - shift - git log --all --graph --date=relative "$@" - ;; - p) - shift - git push "$@" - ;; - *) - git "$@" - ;; - esac -} - -unalias gg 1>/dev/null 2>&1 -gg() { - g p "$@" -} - -unalias ag 1>/dev/null 2>&1 -ag() { - command ag --color "$@" -} - -unalias abc 1>/dev/null 2>&1 -abc() { - case "$1" in - help) - shift - command abc --help "$@" - ;; - *) - command abc "$@" - ;; - esac -} - -unalias reverse 1>/dev/null 2>&1 -reverse() { - echo $2 $1 -} - -unalias say 1>/dev/null 2>&1 -say() { - case "$1" in - again) - shift - echo $1 $1 - ;; - *) - echo "$@" - ;; - esac -} - -unalias dc 1>/dev/null 2>&1 -dc() { - case "$1" in - ls) - shift - docker-compose config --services "$@" - ;; - deploy) - shift - docker stack deploy -c docker-compose.yml "$@" - ;; - upd) - shift - docker-compose up -d "$@" - ;; - *) - docker-compose "$@" - ;; - esac -} - -unalias dns 1>/dev/null 2>&1 -dns() { - case "$1" in - check) - shift - host -t ns "$@" - ;; - flush) - shift - sudo systemd-resolve --flush-caches "$@" - ;; - *) - echo this alias requires a subcommand - ;; - esac -} - -# Completions -if command -v complete &> /dev/null ; then - complete -W "s l p" g - complete -W "help" abc - complete -W "again" say - complete -W "ls deploy upd" dc - complete -W "check flush" dns -fi diff --git a/test-legacy/fixtures/generate/approvals/alf_save b/test-legacy/fixtures/generate/approvals/alf_save deleted file mode 100644 index e24e3ef..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_save +++ /dev/null @@ -1,3 +0,0 @@ -Saving to aliases.txt -To apply the new aliases to the current session, run: -$ source aliases.txt diff --git a/test-legacy/fixtures/generate/approvals/alf_which b/test-legacy/fixtures/generate/approvals/alf_which deleted file mode 100644 index 4f23afa..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which +++ /dev/null @@ -1,2 +0,0 @@ -missing required argument: CODE -usage: alf which CODE [SUBCODE] diff --git a/test-legacy/fixtures/generate/approvals/alf_which_dc_deploy b/test-legacy/fixtures/generate/approvals/alf_which_dc_deploy deleted file mode 100644 index f90ffb8..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_dc_deploy +++ /dev/null @@ -1 +0,0 @@ -docker stack deploy -c docker-compose.yml diff --git a/test-legacy/fixtures/generate/approvals/alf_which_dc_upd b/test-legacy/fixtures/generate/approvals/alf_which_dc_upd deleted file mode 100644 index a8341a6..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_dc_upd +++ /dev/null @@ -1 +0,0 @@ -docker-compose up -d diff --git a/test-legacy/fixtures/generate/approvals/alf_which_g b/test-legacy/fixtures/generate/approvals/alf_which_g deleted file mode 100644 index 5664e30..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_g +++ /dev/null @@ -1 +0,0 @@ -git diff --git a/test-legacy/fixtures/generate/approvals/alf_which_g_l b/test-legacy/fixtures/generate/approvals/alf_which_g_l deleted file mode 100644 index b69728a..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_g_l +++ /dev/null @@ -1 +0,0 @@ -git log --all --graph --date=relative diff --git a/test-legacy/fixtures/generate/approvals/alf_which_g_no b/test-legacy/fixtures/generate/approvals/alf_which_g_no deleted file mode 100644 index c9eeeb7..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_g_no +++ /dev/null @@ -1 +0,0 @@ -Error: No such alias: g no diff --git a/test-legacy/fixtures/generate/approvals/alf_which_help b/test-legacy/fixtures/generate/approvals/alf_which_help deleted file mode 100644 index e27e381..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_help +++ /dev/null @@ -1,18 +0,0 @@ -alf which - Show the alias command. - -Alias: w - -Usage: - alf which CODE [SUBCODE] - alf which --help | -h - -Options: - --help, -h - Show this help - -Arguments: - CODE - Show the command for this alias code. - - SUBCODE - Show the command for this alias sub-code. diff --git a/test-legacy/fixtures/generate/approvals/alf_which_no b/test-legacy/fixtures/generate/approvals/alf_which_no deleted file mode 100644 index 499dbca..0000000 --- a/test-legacy/fixtures/generate/approvals/alf_which_no +++ /dev/null @@ -1 +0,0 @@ -Error: No such alias: no diff --git a/test-legacy/fixtures/generate/approvals/say_again_zsh_works b/test-legacy/fixtures/generate/approvals/say_again_zsh_works deleted file mode 100644 index fe252f7..0000000 --- a/test-legacy/fixtures/generate/approvals/say_again_zsh_works +++ /dev/null @@ -1 +0,0 @@ -zsh-works zsh-works diff --git a/test-legacy/fixtures/info/alf.conf b/test-legacy/fixtures/info/alf.conf deleted file mode 100644 index aa86f99..0000000 --- a/test-legacy/fixtures/info/alf.conf +++ /dev/null @@ -1,30 +0,0 @@ -# Base Alias: -# Any line that does not start with a whitespace is considered a base -# alias. -dir: ls -l - -# Sub Aliases: -# Any line that starts with one or more whitespaces will be nested as -# a subcommand of the previous base alias. -g: git - s: status - l: log --all --graph --date=relative - p: push - -# Reuse: -# You can call an alias from another alias -gg: g p - -# Escape code: -# Sub commands that start with an exclamation mark will not be prefixed -# by their parent command -dc: docker-compose - deploy: !docker stack deploy -c docker-compose.yml - upd: up -d - -# Virtual command: -# When you do not need to prepend your sub aliases with the primary command, -# specify an exclamation mark in the primary command -dns: ! - check: host -t ns - flush: sudo systemd-resolve --flush-caches diff --git a/test-legacy/fixtures/info/alfrc b/test-legacy/fixtures/info/alfrc deleted file mode 100644 index ad8dc3a..0000000 --- a/test-legacy/fixtures/info/alfrc +++ /dev/null @@ -1 +0,0 @@ -/app/test-legacy/fixtures/connect/alf-conf diff --git a/test-legacy/fixtures/info/aliases.txt b/test-legacy/fixtures/info/aliases.txt deleted file mode 100644 index fab091a..0000000 --- a/test-legacy/fixtures/info/aliases.txt +++ /dev/null @@ -1 +0,0 @@ -# dummy file, just needs to exist diff --git a/test-legacy/fixtures/info/approvals/alf_info b/test-legacy/fixtures/info/approvals/alf_info deleted file mode 100644 index 4ae786e..0000000 --- a/test-legacy/fixtures/info/approvals/alf_info +++ /dev/null @@ -1,19 +0,0 @@ -Executable: - path: /usr/local/bin/alf - -Environment: - ALF_RC_FILE: ./alfrc - ALF_ALIASES_FILE: ./aliases.txt - -Paths: - alfrc path: ./alfrc - aliases path: ./aliases.txt - repo path: /app/test-legacy/fixtures/connect/alf-conf - config path: /app/test-legacy/fixtures/connect/alf-conf/alf.conf - -Files: - alfrc: exists with '/app/test-legacy/fixtures/connect/alf-conf' - aliases: exists - -GitHub: - remote: https://github.com/DannyBen/alf-conf.git diff --git a/test-legacy/fixtures/no-subcommands/alf.conf b/test-legacy/fixtures/no-subcommands/alf.conf deleted file mode 100644 index b442087..0000000 --- a/test-legacy/fixtures/no-subcommands/alf.conf +++ /dev/null @@ -1,2 +0,0 @@ -greet: echo hello -yell: echo HELLO diff --git a/test-legacy/fixtures/no-subcommands/approvals/alf_generate b/test-legacy/fixtures/no-subcommands/approvals/alf_generate deleted file mode 100644 index 85ca3be..0000000 --- a/test-legacy/fixtures/no-subcommands/approvals/alf_generate +++ /dev/null @@ -1,12 +0,0 @@ -# This file was automatically generated by alf -# https://github.com/dannyben/alf - -unalias greet 1>/dev/null 2>&1 -greet() { - echo hello "$@" -} - -unalias yell 1>/dev/null 2>&1 -yell() { - echo HELLO "$@" -} diff --git a/test-legacy/fixtures/sample/alf.conf b/test-legacy/fixtures/sample/alf.conf deleted file mode 100644 index aa86f99..0000000 --- a/test-legacy/fixtures/sample/alf.conf +++ /dev/null @@ -1,30 +0,0 @@ -# Base Alias: -# Any line that does not start with a whitespace is considered a base -# alias. -dir: ls -l - -# Sub Aliases: -# Any line that starts with one or more whitespaces will be nested as -# a subcommand of the previous base alias. -g: git - s: status - l: log --all --graph --date=relative - p: push - -# Reuse: -# You can call an alias from another alias -gg: g p - -# Escape code: -# Sub commands that start with an exclamation mark will not be prefixed -# by their parent command -dc: docker-compose - deploy: !docker stack deploy -c docker-compose.yml - upd: up -d - -# Virtual command: -# When you do not need to prepend your sub aliases with the primary command, -# specify an exclamation mark in the primary command -dns: ! - check: host -t ns - flush: sudo systemd-resolve --flush-caches diff --git a/test-legacy/fixtures/sample/approvals/alf_edit b/test-legacy/fixtures/sample/approvals/alf_edit deleted file mode 100644 index 2435dc5..0000000 --- a/test-legacy/fixtures/sample/approvals/alf_edit +++ /dev/null @@ -1 +0,0 @@ -stubbed editor with: alf.conf diff --git a/test-legacy/fixtures/sample/approvals/alf_edit_help b/test-legacy/fixtures/sample/approvals/alf_edit_help deleted file mode 100644 index f226418..0000000 --- a/test-legacy/fixtures/sample/approvals/alf_edit_help +++ /dev/null @@ -1,11 +0,0 @@ -alf edit - Open your `alf.conf` for editing. - -Alias: e - -Usage: - alf edit - alf edit --help | -h - -Options: - --help, -h - Show this help diff --git a/test-legacy/fixtures/sample/approvals/alf_info b/test-legacy/fixtures/sample/approvals/alf_info deleted file mode 100644 index a255420..0000000 --- a/test-legacy/fixtures/sample/approvals/alf_info +++ /dev/null @@ -1,19 +0,0 @@ -Executable: - path: /usr/local/bin/alf - -Environment: - ALF_RC_FILE: unset - ALF_ALIASES_FILE: unset - -Paths: - alfrc path: /root/.alfrc - aliases path: /root/.bash_aliases - repo path: /app/test-legacy/fixtures/sample/alf-conf - config path: alf.conf - -Files: - alfrc: does not exist - aliases: does not exist - -GitHub: - remote: unset diff --git a/test-legacy/generate_spec.sh b/test-legacy/generate_spec.sh deleted file mode 100644 index fec449b..0000000 --- a/test-legacy/generate_spec.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -unset ALF_RC_FILE - -describe "alf generate --help" - approve "alf generate --help" - -describe "alf generate (when alf.conf is present)" - pushd ./fixtures/generate > /dev/nll - approve "alf generate" - popd > /dev/null - -describe "alf generate (when alf.conf is not present)" - pushd ./fixtures/empty-dir > /dev/null - approve "alf generate" || return 0 - expect_exit_code 1 - popd > /dev/null - -describe "alf generate (when alf.conf does not include subcommands)" - pushd ./fixtures/no-subcommands > /dev/null - approve "alf generate" - popd > /dev/null diff --git a/test-legacy/info_spec.sh b/test-legacy/info_spec.sh deleted file mode 100644 index 1542579..0000000 --- a/test-legacy/info_spec.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -unset ALF_RC_FILE -unset ALF_ALIASES_FILE -rm -f /root/.bash_aliases - -describe "alf info --help" - approve "alf info --help" - -describe "alf info (when files do not exist)" - pushd ./fixtures/sample > /dev/null - approve "alf info" - popd > /dev/null - -describe "alf info (when files exist)" - pushd ./fixtures/info > /dev/null - export ALF_RC_FILE="./alfrc" - export ALF_ALIASES_FILE="./aliases.txt" - approve "alf info" - popd > /dev/null - diff --git a/test-legacy/save_spec.sh b/test-legacy/save_spec.sh deleted file mode 100644 index edc2421..0000000 --- a/test-legacy/save_spec.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -unset ALF_RC_FILE -export ALF_ALIASES_FILE="aliases.txt" - -describe "alf save --help" - approve "alf save --help" - -describe "alf save (when alf.conf is present)" - pushd ./fixtures/generate > /dev/null - rm -f "aliases.txt" - approve "alf save" - popd > /dev/null - -describe "alf save (when alf.conf is not present)" - pushd ./fixtures/empty-dir > /dev/null - rm -f "aliases.txt" - approve "alf save" || return 0 - expect_exit_code 1 - if [[ -f aliases.txt ]] ; then - fail "Expected file aliases.txt not to exist" - fi - popd > /dev/null diff --git a/test-legacy/upgrade_spec.sh b/test-legacy/upgrade_spec.sh deleted file mode 100644 index 13f7524..0000000 --- a/test-legacy/upgrade_spec.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' -cd ./fixtures/empty-dir - -describe "alf upgrade --help" - approve "alf upgrade --help" - -describe "alf upgrade" - cp /usr/local/bin/alf /usr/local/bin/alf-before-upgrade - # allow_diff 'tmp\..*' - approve "alf upgrade" - mv /usr/local/bin/alf-before-upgrade /usr/local/bin/alf diff --git a/test-legacy/upload_spec.sh b/test-legacy/upload_spec.sh deleted file mode 100644 index d6eefb7..0000000 --- a/test-legacy/upload_spec.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -export ALF_RC_FILE="./alfrc" - -describe "alf upload --help" - approve "alf upload --help" - -describe "alf upload" - pushd ./fixtures/connect > /dev/null - [[ -d alf-conf ]] || alf connect DannyBen -y - [[ -d alf-conf ]] || fail "Expected alf-conf directory to exist" - approve "alf upload" || return 0 - popd > /dev/null - -describe "alf upload (without repo connection)" - pushd ./fixtures/empty-dir > /dev/null - rm -rf ./alf-conf - approve "alf upload" || return 0 - popd > /dev/null diff --git a/test-legacy/usage_spec.sh b/test-legacy/usage_spec.sh deleted file mode 100644 index 26dab17..0000000 --- a/test-legacy/usage_spec.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' -cd ./fixtures/empty-dir - -describe "alf (usage)" - approve "alf" || return 0 - expect_exit_code 1 - -describe "alf --help" - approve "alf --help" diff --git a/test-legacy/which_spec.sh b/test-legacy/which_spec.sh deleted file mode 100644 index 8aca739..0000000 --- a/test-legacy/which_spec.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -source 'approvals.bash' - -unset ALF_RC_FILE -cd ./fixtures/generate - -describe "alf which --help" - approve "alf which --help" - -describe "Run alf which without parameters" - approve "alf which" || return 0 - expect_exit_code 1 - -describe "Run alf which CODE" - approve "alf which g" - expect_exit_code 0 - -describe "Run alf which CODE SUBCODE" - approve "alf which g l" || return 0 - expect_exit_code 0 - -describe "Run alf which CODE with invalid code" - approve "alf which no" || return 0 - expect_exit_code 1 - -describe "Run alf which CODE SUBCODE with invalid code" - approve "alf which g no" || return 0 - expect_exit_code 1 - -describe "Run alf which CODE SUBCODE with escaped code" - approve "alf which dc deploy" - expect_exit_code 0 - -describe "Run alf which CODE SUBCODE on a separated code" - approve "alf which dc upd" - expect_exit_code 0 From c76055e28f38504a3f11b64cb6366c95379ac3cc Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 19:54:20 +0200 Subject: [PATCH 5/8] - Remove `alf upgrade` command --- README.md | 1 - alf | 514 +++++++++++++++++----------------------- doc/alf-connect.1 | 16 +- doc/alf-connect.md | 2 +- doc/alf-download.1 | 6 +- doc/alf-download.md | 2 +- doc/alf-edit.1 | 6 +- doc/alf-edit.md | 2 +- doc/alf-generate.1 | 6 +- doc/alf-generate.md | 2 +- doc/alf-info.1 | 4 +- doc/alf-info.md | 2 +- doc/alf-save.1 | 13 +- doc/alf-save.md | 2 +- doc/alf-upgrade.1 | 13 - doc/alf-upgrade.md | 33 --- doc/alf-upload.1 | 6 +- doc/alf-upload.md | 2 +- doc/alf-which.1 | 8 +- doc/alf-which.md | 2 +- doc/alf.1 | 12 +- doc/alf.conf.5 | 6 +- doc/alf.md | 9 +- src/bashly.yml | 4 - src/commands/upgrade.sh | 1 - 25 files changed, 273 insertions(+), 401 deletions(-) delete mode 100644 doc/alf-upgrade.1 delete mode 100644 doc/alf-upgrade.md delete mode 100644 src/commands/upgrade.sh diff --git a/README.md b/README.md index cebe6ea..d53c88d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,6 @@ Commands: save Generate aliases to ~/.bash_aliases edit Open your alf.conf for editing which Show the alias command - upgrade Upgrade alf to the latest version info Show all alf related system facts Options: diff --git a/alf b/alf index 897234d..cd47bf7 100755 --- a/alf +++ b/alf @@ -33,7 +33,6 @@ alf_usage() { printf " %s Generate aliases to \`~/.bash_aliases\`.\n" "$(green "save") " printf " %s Open your \`alf.conf\` for editing.\n" "$(green "edit") " printf " %s Show the alias command.\n" "$(green "which") " - printf " %s Upgrade alf to the latest version.\n" "$(green "upgrade") " printf " %s Show all alf related system facts.\n" "$(green "info") " echo @@ -281,28 +280,6 @@ alf_which_usage() { fi } -# :command.usage -alf_upgrade_usage() { - printf "alf upgrade - Upgrade alf to the latest version.\n\n" - - printf "%s\n" "$(bold "Usage:")" - printf " alf upgrade\n" - printf " alf upgrade --help | -h\n" - echo - - # :command.long_usage - if [[ -n "$long_usage" ]]; then - # :command.usage_options - printf "%s\n" "$(bold "Options:")" - - # :command.usage_fixed_flags - printf " %s\n" "$(bold "--help, -h")" - printf " Show this help\n" - echo - - fi -} - # :command.usage alf_info_usage() { printf "alf info - Show all alf related system facts.\n\n" @@ -357,22 +334,6 @@ normalize_input() { done } -# :command.inspect_args -inspect_args() { - local k - - if ((${#args[@]})); then - readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort) - echo args: - for k in "${sorted_keys[@]}"; do - echo "- \${args[$k]} = ${args[$k]}" - done - else - echo args: none - fi - -} - # :command.user_lib # src/lib/colors.sh print_in_color() { @@ -415,6 +376,109 @@ cyan_underlined() { print_in_color "\e[4;36m" "$*"; } black_underlined() { print_in_color "\e[4;30m" "$*"; } white_underlined() { print_in_color "\e[4;37m" "$*"; } +# src/lib/connect_repo.sh +connect_repo() { + local repo="$1" + local force="$2" + local force_ssh="$3" + local force_https="$4" + local repo_url partial_github_url answer + + if [[ $repo =~ ':' ]]; then + repo_url=$repo + elif [[ $repo =~ '/' ]]; then + partial_github_url=1 + repo_url="$repo.git" + else + partial_github_url=1 + repo_url="$repo/alf-conf.git" + fi + + if [[ $force_ssh ]]; then + answer=y + [[ $partial_github_url ]] && repo_url="git@github.com:$repo_url" + echo "Connecting to $repo_url" + + elif [[ $force_https ]]; then + answer=y + [[ $partial_github_url ]] && repo_url="https://github.com/$repo_url" + echo "Connecting to $repo_url" + + elif [[ $force ]]; then + if [[ $partial_github_url ]]; then + echo "Error: Cannot determine the full URL for the repository" + echo "To connect to GitHub use --ssh or --https" + echo "To connect to another repository, provide the full URL" + return 1 + fi + answer=y + echo "Connecting to $repo_url" + + else + echo "This operation will:" + echo "" + if [[ ! -d ./alf-conf ]]; then + echo " clone $repo_url" + echo " to ./alf-conf" + echo "" + fi + echo " write $PWD/alf-conf" + echo " to $rc_file" + echo "" + + if [[ -n "$partial_github_url" ]]; then + answer="$(prompt_for_github_protocol)" + + if [[ $answer =~ [Ss] ]]; then + repo_url="git@github.com:$repo_url" + answer=y + echo "" + echo "Using $repo_url" + elif [[ $answer =~ [Hh] ]]; then + repo_url="https://github.com/$repo_url" + answer=y + echo "" + echo "Using $repo_url" + fi + else + answer="$(prompt_to_continue)" + fi + fi + + if [[ $answer =~ [Yy] ]]; then + if [[ -d ./alf-conf ]]; then + echo "Skipping clone, directory already exists" + else + git clone "$repo_url" ./alf-conf + fi + echo "$PWD/alf-conf" >"$rc_file" + echo "Storing location in $rc_file" + else + echo "Aborting" + return 0 + fi + + save_config +} + +# src/lib/download_repo.sh +download_repo() { + find_config + + if [[ ! -f $rc_file ]]; then + echo "Cannot find $rc_file" + echo "Please connect alf to a repository first" + return 1 + fi + + pushd "$repo_path" >/dev/null + echo "Pulling from repository to $repo_path" + git pull + popd >/dev/null + + save_config +} + # src/lib/find_config.sh find_config() { repo_path="$PWD/alf-conf" @@ -573,6 +637,25 @@ has_subcommands() { return 1 } +# src/lib/prompt.sh +prompt_for_github_protocol() { + local answer + + echo "Would you like to connect to GitHub via SSH or HTTPS?" + echo "" + printf "[S]SH, [H]TTPS or [A]bort (default): " + read -r answer + printf '%s\n' "$answer" +} + +prompt_to_continue() { + local answer + + printf "Continue? [yN] " + read -r answer + printf '%s\n' "$answer" +} + # src/lib/save_config.sh save_config() { find_config @@ -587,135 +670,132 @@ save_config() { echo "$ source $friendly_aliases_file" } -# :command.command_functions -# :command.function -alf_connect_command() { - - # src/commands/connect.sh - repo=${args[repo]} - force=${args[--yes]} - force_ssh=${args[--ssh]} - force_https=${args[--https]} - - if [[ $repo =~ ':' ]]; then - repo_url=$repo - elif [[ $repo =~ '/' ]]; then - partial_github_url=1 - repo_url="$repo.git" - else - partial_github_url=1 - repo_url="$repo/alf-conf.git" - fi - - if [[ $force_ssh ]]; then - answer=y - [[ $partial_github_url ]] && repo_url="git@github.com:$repo_url" - echo "Connecting to $repo_url" +# src/lib/show_alias_command.sh +show_alias_command() { + local code="$1" + local subcode="${2:-}" + local regex_exact_code regex_exact_subcode cmd1 cmd2 - elif [[ $force_https ]]; then - answer=y - [[ $partial_github_url ]] && repo_url="https://github.com/$repo_url" - echo "Connecting to $repo_url" + find_config + regex_exact_code="^($code): *(.+)$" + regex_exact_subcode="^( +)($subcode): *(.+)$" + cmd1="" - elif [[ $force ]]; then - if [[ $partial_github_url ]]; then - echo "Error: Cannot determine the full URL for the repository" - echo "To connect to GitHub use --ssh or --https" - echo "To connect to another repository, provide the full URL" - exit 1 + while IFS= read -r line || [ -n "$line" ]; do + if [[ $line =~ $regex_exact_code ]]; then + cmd1="${BASH_REMATCH[2]}" + if [[ -z $subcode ]]; then + echo "$cmd1" + return 0 + fi + elif [[ -n $cmd1 ]]; then + if [[ $line =~ $regex_exact_subcode ]]; then + cmd2="${BASH_REMATCH[3]}" + if [[ $cmd2 =~ ^! ]]; then + echo "${cmd2:1}" + else + echo "$cmd1 $cmd2" + fi + return 0 + fi fi - answer=y - echo "Connecting to $repo_url" + done <"$config_file" - else - echo "This operation will:" - echo "" - if [[ ! -d ./alf-conf ]]; then - echo " clone $repo_url" - echo " to ./alf-conf" - echo "" - fi - echo " write $PWD/alf-conf" - echo " to $rc_file" - echo "" + echo "Error: No such alias: $code $subcode" + return 1 +} - if [[ -n "$partial_github_url" ]]; then - echo "Would you like to connect to GitHub via SSH or HTTPS?" - echo "" - printf "[S]SH, [H]TTPS or [A]bort (default): " - read -r answer +# src/lib/show_info.sh +show_info() { + find_config - if [[ $answer =~ [Ss] ]]; then - repo_url="git@github.com:$repo_url" - answer=y - echo "" - echo "Using $repo_url" - elif [[ $answer =~ [Hh] ]]; then - repo_url="https://github.com/$repo_url" - answer=y - echo "" - echo "Using $repo_url" - fi - else - printf "Continue? [yN] " - read -r answer - fi + if [[ -d "$repo_path/.git" ]]; then + pushd "$repo_path" >/dev/null + remote="$(git config --get remote.origin.url)" + popd >/dev/null + else + remote="unset" fi - if [[ $answer =~ [Yy] ]]; then - if [[ -d ./alf-conf ]]; then - echo "Skipping clone, directory already exists" - else - git clone "$repo_url" ./alf-conf - fi - echo "$PWD/alf-conf" >"$rc_file" - echo "Storing location in $rc_file" + if [[ -f "$rc_file" ]]; then + alfrc_content="exists with '$(<"$rc_file")'" else - echo "Aborting" - exit + alfrc_content="does not exist" fi - save_config + if [[ -f "$aliases_file" ]]; then + bash_aliases_status="exists" + else + bash_aliases_status="does not exist" + fi + echo "Executable:" + echo " path: $(command -v alf)" + echo + echo "Environment:" + echo " ALF_RC_FILE: ${ALF_RC_FILE:-unset}" + echo " ALF_ALIASES_FILE: ${ALF_ALIASES_FILE:-unset}" + echo + echo "Paths:" + echo " alfrc path: $rc_file" + echo " aliases path: $aliases_file" + echo " repo path: $repo_path" + echo " config path: $config_file" + echo + echo "Files:" + echo " alfrc: $alfrc_content" + echo " aliases: $bash_aliases_status" + echo + echo "GitHub:" + echo " remote: $remote" + echo } -# :command.function -alf_download_command() { - - # src/commands/download.sh +# src/lib/upload_repo.sh +upload_repo() { find_config if [[ ! -f $rc_file ]]; then echo "Cannot find $rc_file" echo "Please connect alf to a repository first" - exit 1 + return 1 fi pushd "$repo_path" >/dev/null - echo "Pulling from repository to $repo_path" - git pull + echo "Pushing $repo_path to repository" + git commit -am "automatic push" + git push popd >/dev/null +} + +# :command.command_functions +# :command.function +alf_connect_command() { + + # src/commands/connect.sh + repo=${args[repo]} + force=${args[--yes]} + force_ssh=${args[--ssh]} + force_https=${args[--https]} + + connect_repo "$repo" "$force" "$force_ssh" "$force_https" + +} + +# :command.function +alf_download_command() { + + # src/commands/download.sh + download_repo - save_config } # :command.function alf_upload_command() { # src/commands/upload.sh - find_config + upload_repo - if [[ ! -f $rc_file ]]; then - echo "Cannot find $rc_file" - echo "Please connect alf to a repository first" - exit 1 - fi - - pushd "$repo_path" >/dev/null - echo "Pushing $repo_path to repository" - git commit -am "automatic push" - git push - popd >/dev/null } # :command.function @@ -749,41 +829,7 @@ alf_which_command() { code=${args[code]} subcode=${args[subcode]} - find_config - regex_exact_code="^($code): *(.+)$" - regex_exact_subcode="^( +)($subcode): *(.+)$" - cmd1="" - - while IFS= read -r line || [ -n "$line" ]; do - if [[ $line =~ $regex_exact_code ]]; then - cmd1="${BASH_REMATCH[2]}" - if [[ -z $subcode ]]; then - echo "$cmd1" - exit 0 - fi - elif [[ -n $cmd1 ]]; then - if [[ $line =~ $regex_exact_subcode ]]; then - cmd2="${BASH_REMATCH[3]}" - if [[ $cmd2 =~ ^! ]]; then - echo "${cmd2:1}" - else - echo "$cmd1 $cmd2" - fi - exit 0 - fi - fi - done <"$config_file" - - echo "Error: No such alias: $code $subcode" - exit 1 - -} - -# :command.function -alf_upgrade_command() { - - # src/commands/upgrade.sh - exec bash <(curl -s https://raw.githubusercontent.com/DannyBen/alf/master/setup) + show_alias_command "$code" "$subcode" } @@ -791,52 +837,7 @@ alf_upgrade_command() { alf_info_command() { # src/commands/info.sh - find_config - - if [[ -d "$repo_path/.git" ]]; then - pushd "$repo_path" >/dev/null - remote="$(git config --get remote.origin.url)" - popd >/dev/null - else - remote="unset" - fi - - if [[ -f "$rc_file" ]]; then - alfrc_content="exists with '$(<"$rc_file")'" - else - alfrc_content="does not exist" - fi - - if [[ -f "$aliases_file" ]]; then - bash_aliases_status="exists" - else - bash_aliases_status="does not exist" - fi - - echo "Executable:" - echo " path: $(command -v alf)" - echo - - echo "Environment:" - echo " ALF_RC_FILE: ${ALF_RC_FILE:-unset}" - echo " ALF_ALIASES_FILE: ${ALF_ALIASES_FILE:-unset}" - echo - - echo "Paths:" - echo " alfrc path: $rc_file" - echo " aliases path: $aliases_file" - echo " repo path: $repo_path" - echo " config path: $config_file" - echo - - echo "Files:" - echo " alfrc: $alfrc_content" - echo " aliases: $bash_aliases_status" - echo - - echo "GitHub:" - echo " remote: $remote" - echo + show_info } @@ -923,13 +924,6 @@ parse_requirements() { shift $# ;; - upgrade) - action="upgrade" - shift - alf_upgrade_parse_requirements "$@" - shift $# - ;; - info) action="info" shift @@ -1393,65 +1387,6 @@ alf_which_parse_requirements() { } -# :command.parse_requirements -alf_upgrade_parse_requirements() { - local key - - # :command.fixed_flags_filter - while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - --help | -h) - long_usage=yes - alf_upgrade_usage - exit - ;; - - *) - break - ;; - - esac - done - - # :command.dependencies_filter - missing_deps= - # :dependency.filter - if ! command -v curl >/dev/null 2>&1; then - printf "missing dependency: curl\n" >&2 - missing_deps=1 - fi - - if [[ -n $missing_deps ]]; then - exit 1 - fi - - # :command.command_filter - action="upgrade" - - # :command.parse_requirements_while - while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - - -?*) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - *) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 - - ;; - - esac - done - -} - # :command.parse_requirements alf_info_parse_requirements() { local key @@ -1541,14 +1476,11 @@ run() { "save") alf_save_command ;; "edit") alf_edit_command ;; "which") alf_which_command ;; - "upgrade") alf_upgrade_command ;; "info") alf_info_command ;; esac } -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - # :command.start - command_line_args=("$@") - initialize - run "${command_line_args[@]}" -fi +# :command.start +command_line_args=("$@") +initialize +run "${command_line_args[@]}" diff --git a/doc/alf-connect.1 b/doc/alf-connect.1 index ee86eae..d88991c 100644 --- a/doc/alf-connect.1 +++ b/doc/alf-connect.1 @@ -1,28 +1,28 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-connect" "1" "December 2024" "" "Connect to a remote git repository." +.TH "alf\-connect" "1" "March 2026" "" "Connect to a remote git repository." .SH NAME \f[B]alf connect\f[R] \- Connect to a remote git repository. .SH SYNOPSIS \f[B]alf connect\f[R] REPO OPTIONS .SH DESCRIPTION Connect to a remote git repository. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]c\f[R] .SH ARGUMENTS .SS REPO Remote GitHub repository to connect to. .PP Can be one of: -.IP \[bu] 2 +.IP \(bu 2 Your username on GitHub. In this case, the repository is expected to be named \f[B]alf\-conf\f[R]. -.IP \[bu] 2 +.IP \(bu 2 Your username/repo on GitHub. -.IP \[bu] 2 +.IP \(bu 2 Any other full URL to a repository. -.IP \[bu] 2 +.IP \(bu 2 \f[I]Required\f[R] .SH OPTIONS .SS \-\-ssh @@ -42,7 +42,7 @@ alf connect you \-\-ssh alf connect you/alf\-config -alf connect https://You\[at]bitbucket.org/YourUser/rush\-repo.git \-\-yes +alf connect https://You\(atbitbucket.org/YourUser/rush\-repo.git \-\-yes .EE .SH SEE ALSO \f[B]alf\f[R](1) diff --git a/doc/alf-connect.md b/doc/alf-connect.md index 23018c3..3f7e6dd 100644 --- a/doc/alf-connect.md +++ b/doc/alf-connect.md @@ -1,6 +1,6 @@ % alf-connect(1) | Connect to a remote git repository. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-download.1 b/doc/alf-download.1 index bfc524f..fa4fd6d 100644 --- a/doc/alf-download.1 +++ b/doc/alf-download.1 @@ -1,13 +1,13 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-download" "1" "December 2024" "" "Perform git pull on the connected repo." +.TH "alf\-download" "1" "March 2026" "" "Perform git pull on the connected repo." .SH NAME \f[B]alf download\f[R] \- Perform git pull on the connected repo. .SH SYNOPSIS \f[B]alf download\f[R] .SH DESCRIPTION Perform git pull on the connected repo. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]d, pull\f[R] .SH DEPENDENCIES .SS git diff --git a/doc/alf-download.md b/doc/alf-download.md index 65d470a..390780f 100644 --- a/doc/alf-download.md +++ b/doc/alf-download.md @@ -1,6 +1,6 @@ % alf-download(1) | Perform git pull on the connected repo. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-edit.1 b/doc/alf-edit.1 index 5c4adf3..2f5eeef 100644 --- a/doc/alf-edit.1 +++ b/doc/alf-edit.1 @@ -1,13 +1,13 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-edit" "1" "December 2024" "" "Open your \f[CR]alf.conf\f[R] for editing." +.TH "alf\-edit" "1" "March 2026" "" "Open your \f[CR]alf.conf\f[R] for editing." .SH NAME \f[B]alf edit\f[R] \- Open your \f[CR]alf.conf\f[R] for editing. .SH SYNOPSIS \f[B]alf edit\f[R] .SH DESCRIPTION Open your \f[B]alf.conf\f[R] for editing. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]e\f[R] .SH SEE ALSO \f[B]alf\f[R](1), \f[B]alf.conf\f[R](5) diff --git a/doc/alf-edit.md b/doc/alf-edit.md index e97473f..039e049 100644 --- a/doc/alf-edit.md +++ b/doc/alf-edit.md @@ -1,6 +1,6 @@ % alf-edit(1) | Open your `alf.conf` for editing. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-generate.1 b/doc/alf-generate.1 index cad9ca2..5d2db32 100644 --- a/doc/alf-generate.1 +++ b/doc/alf-generate.1 @@ -1,13 +1,13 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-generate" "1" "December 2024" "" "Generate aliases to stdout." +.TH "alf\-generate" "1" "March 2026" "" "Generate aliases to stdout." .SH NAME \f[B]alf generate\f[R] \- Generate aliases to stdout. .SH SYNOPSIS \f[B]alf generate\f[R] .SH DESCRIPTION Generate aliases to stdout. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]g\f[R] .SH SEE ALSO \f[B]alf\f[R](1) diff --git a/doc/alf-generate.md b/doc/alf-generate.md index 9d9ae61..c2911fa 100644 --- a/doc/alf-generate.md +++ b/doc/alf-generate.md @@ -1,6 +1,6 @@ % alf-generate(1) | Generate aliases to stdout. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-info.1 b/doc/alf-info.1 index 2bdec8a..ed676ba 100644 --- a/doc/alf-info.1 +++ b/doc/alf-info.1 @@ -1,6 +1,6 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-info" "1" "December 2024" "" "Show all alf related system facts." +.TH "alf\-info" "1" "March 2026" "" "Show all alf related system facts." .SH NAME \f[B]alf info\f[R] \- Show all alf related system facts. .SH SYNOPSIS diff --git a/doc/alf-info.md b/doc/alf-info.md index 6d5839e..fc0aa13 100644 --- a/doc/alf-info.md +++ b/doc/alf-info.md @@ -1,6 +1,6 @@ % alf-info(1) | Show all alf related system facts. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-save.1 b/doc/alf-save.1 index 0bb0fcf..f1637f9 100644 --- a/doc/alf-save.1 +++ b/doc/alf-save.1 @@ -1,14 +1,13 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-save" "1" "December 2024" "" "Generate aliases to \f[CR]\[ti]/.bash_aliases\f[R]." +.TH "alf\-save" "1" "March 2026" "" "Generate aliases to \f[CR]\(ti/.bash_aliases\f[R]." .SH NAME -\f[B]alf save\f[R] \- Generate aliases to -\f[CR]\[ti]/.bash_aliases\f[R]. +\f[B]alf save\f[R] \- Generate aliases to \f[CR]\(ti/.bash_aliases\f[R]. .SH SYNOPSIS \f[B]alf save\f[R] .SH DESCRIPTION -Generate aliases to \f[B]\[ti]/.bash_aliases\f[R]. -.IP \[bu] 2 +Generate aliases to \f[B]\(ti/.bash_aliases\f[R]. +.IP \(bu 2 Alias: \f[B]s\f[R] .SH ENVIRONMENT VARIABLES .SS ALF_ALIASES_FILE @@ -16,6 +15,6 @@ Path to bash_aliases file. .PP Aliases will be saved to this file. .PP -Default: \f[B]\[ti]/.bash_aliases\f[R] +Default: \f[B]\(ti/.bash_aliases\f[R] .SH SEE ALSO \f[B]alf\f[R](1) diff --git a/doc/alf-save.md b/doc/alf-save.md index 5b60097..89cb492 100644 --- a/doc/alf-save.md +++ b/doc/alf-save.md @@ -1,6 +1,6 @@ % alf-save(1) | Generate aliases to `~/.bash_aliases`. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-upgrade.1 b/doc/alf-upgrade.1 deleted file mode 100644 index 8e83015..0000000 --- a/doc/alf-upgrade.1 +++ /dev/null @@ -1,13 +0,0 @@ -.\" Automatically generated by Pandoc 3.2 -.\" -.TH "alf\-upgrade" "1" "December 2024" "" "Upgrade alf to the latest version." -.SH NAME -\f[B]alf upgrade\f[R] \- Upgrade alf to the latest version. -.SH SYNOPSIS -\f[B]alf upgrade\f[R] -.SH DESCRIPTION -Upgrade alf to the latest version. -.SH DEPENDENCIES -.SS curl -.SH SEE ALSO -\f[B]alf\f[R](1) diff --git a/doc/alf-upgrade.md b/doc/alf-upgrade.md deleted file mode 100644 index 14f9f63..0000000 --- a/doc/alf-upgrade.md +++ /dev/null @@ -1,33 +0,0 @@ -% alf-upgrade(1) | Upgrade alf to the latest version. -% -% December 2024 - -NAME -================================================== - -**alf upgrade** - Upgrade alf to the latest version. - -SYNOPSIS -================================================== - -**alf upgrade** - -DESCRIPTION -================================================== - -Upgrade alf to the latest version. - - -DEPENDENCIES -================================================== - -curl --------------------------------------------------- - - -SEE ALSO -================================================== - -**alf**(1) - - diff --git a/doc/alf-upload.1 b/doc/alf-upload.1 index add21bf..fddc7b0 100644 --- a/doc/alf-upload.1 +++ b/doc/alf-upload.1 @@ -1,6 +1,6 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-upload" "1" "December 2024" "" "Perform git commit and push on the connected repo." +.TH "alf\-upload" "1" "March 2026" "" "Perform git commit and push on the connected repo." .SH NAME \f[B]alf upload\f[R] \- Perform git commit and push on the connected repo. @@ -8,7 +8,7 @@ repo. \f[B]alf upload\f[R] .SH DESCRIPTION Perform git commit and push on the connected repo. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]u, push\f[R] .SH DEPENDENCIES .SS git diff --git a/doc/alf-upload.md b/doc/alf-upload.md index 8481b4f..374fd57 100644 --- a/doc/alf-upload.md +++ b/doc/alf-upload.md @@ -1,6 +1,6 @@ % alf-upload(1) | Perform git commit and push on the connected repo. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf-which.1 b/doc/alf-which.1 index 7a85789..352d807 100644 --- a/doc/alf-which.1 +++ b/doc/alf-which.1 @@ -1,18 +1,18 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf\-which" "1" "December 2024" "" "Show the alias command." +.TH "alf\-which" "1" "March 2026" "" "Show the alias command." .SH NAME \f[B]alf which\f[R] \- Show the alias command. .SH SYNOPSIS \f[B]alf which\f[R] CODE SUBCODE .SH DESCRIPTION Show the alias command. -.IP \[bu] 2 +.IP \(bu 2 Alias: \f[B]w\f[R] .SH ARGUMENTS .SS CODE Show the command for this alias code. -.IP \[bu] 2 +.IP \(bu 2 \f[I]Required\f[R] .SS SUBCODE Show the command for this alias sub\-code. diff --git a/doc/alf-which.md b/doc/alf-which.md index 6432e01..cb07a1f 100644 --- a/doc/alf-which.md +++ b/doc/alf-which.md @@ -1,6 +1,6 @@ % alf-which(1) | Show the alias command. % -% December 2024 +% March 2026 NAME ================================================== diff --git a/doc/alf.1 b/doc/alf.1 index e150cf1..26c5b20 100644 --- a/doc/alf.1 +++ b/doc/alf.1 @@ -1,6 +1,6 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" -.TH "alf" "1" "December 2024" "Version 0.6.1" "Your Little Bash Alias Friend" +.TH "alf" "1" "March 2026" "Version 0.6.1" "Your Little Bash Alias Friend" .SH NAME \f[B]alf\f[R] \- Your Little Bash Alias Friend .SH SYNOPSIS @@ -17,13 +17,11 @@ Perform git commit and push on the connected repo. .SS alf generate Generate aliases to stdout. .SS alf save -Generate aliases to \f[B]\[ti]/.bash_aliases\f[R]. +Generate aliases to \f[B]\(ti/.bash_aliases\f[R]. .SS alf edit Open your \f[B]alf.conf\f[R] for editing. .SS alf which Show the alias command. -.SS alf upgrade -Upgrade alf to the latest version. .SS alf info Show all alf related system facts. .SH ENVIRONMENT VARIABLES @@ -32,12 +30,12 @@ Path to alfrc file. .PP This file holds the path to the alf\-conf repository. .PP -Default: \f[B]\[ti]/.alfrc\f[R] +Default: \f[B]\(ti/.alfrc\f[R] .SH SEE ALSO \f[B]alf\-connect\f[R](1), \f[B]alf\-download\f[R](1), \f[B]alf\-upload\f[R](1), \f[B]alf\-generate\f[R](1), \f[B]alf\-save\f[R](1), \f[B]alf\-edit\f[R](1), \f[B]alf\-which\f[R](1), -\f[B]alf\-upgrade\f[R](1), \f[B]alf\-info\f[R](1), \f[B]alf.conf\f[R](5) +\f[B]alf\-info\f[R](1), \f[B]alf.conf\f[R](5) .SH SOURCE CODE https://github.com/dannyben/alf .SH ISSUE TRACKER diff --git a/doc/alf.conf.5 b/doc/alf.conf.5 index 2345ce5..2b4f063 100644 --- a/doc/alf.conf.5 +++ b/doc/alf.conf.5 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 3.2 +.\" Automatically generated by Pandoc 3.9 .\" .TH "alf.conf" "5" "September 2023" "alf.conf(5)" "File Formats Manual" .SH NAME @@ -63,7 +63,7 @@ This example provides two completely different aliases: \f[B]dns check\f[R] and \f[B]dns flush\f[R]. .SS Arguments By default, all arguments that are provided in the input are passed on -to the alias, using \f[B]\[dq]$\[at]\[dq]\f[R]. +to the alias, using \f[B]\(dq$\(at\(dq\f[R]. If your command contains the \f[B]$\f[R] symbol, then the array of arguments will NOT be appended to the command. .PP @@ -72,7 +72,7 @@ bash syntax, and use any bash construct, like inline functions. .IP .EX count: find ${1:\-.} \-type f | wc \-l -binlink: sudo ln \-fs \[dq]$(realpath $1)\[dq] \[dq]/usr/local/bin/$1\[dq] +binlink: sudo ln \-fs \(dq$(realpath $1)\(dq \(dq/usr/local/bin/$1\(dq .EE .SS Comments Any line starting with \f[B]#\f[R] will be considered a comment. diff --git a/doc/alf.md b/doc/alf.md index 22d06af..97cc880 100644 --- a/doc/alf.md +++ b/doc/alf.md @@ -1,6 +1,6 @@ % alf(1) Version 0.6.1 | Your Little Bash Alias Friend % Danny Ben Shitrit \ -% December 2024 +% March 2026 NAME ================================================== @@ -56,11 +56,6 @@ alf which Show the alias command. -alf upgrade --------------------------------------------------- - -Upgrade alf to the latest version. - alf info -------------------------------------------------- @@ -84,7 +79,7 @@ Default: **~/.alfrc** SEE ALSO ================================================== -**alf-connect**(1), **alf-download**(1), **alf-upload**(1), **alf-generate**(1), **alf-save**(1), **alf-edit**(1), **alf-which**(1), **alf-upgrade**(1), **alf-info**(1), **alf.conf**(5) +**alf-connect**(1), **alf-download**(1), **alf-upload**(1), **alf-generate**(1), **alf-save**(1), **alf-edit**(1), **alf-which**(1), **alf-info**(1), **alf.conf**(5) # SOURCE CODE diff --git a/src/bashly.yml b/src/bashly.yml index 88779f4..c4dda38 100644 --- a/src/bashly.yml +++ b/src/bashly.yml @@ -101,10 +101,6 @@ commands: - name: subcode help: Show the command for this alias sub-code. -- name: upgrade - help: Upgrade alf to the latest version. - dependencies: [curl] - - name: info help: Show all alf related system facts. dependencies: [git] diff --git a/src/commands/upgrade.sh b/src/commands/upgrade.sh deleted file mode 100644 index 1c16f4e..0000000 --- a/src/commands/upgrade.sh +++ /dev/null @@ -1 +0,0 @@ -exec bash <(curl -s https://raw.githubusercontent.com/DannyBen/alf/master/setup) From a8649429974b9449cac7287ebc3882985c0a6205 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 20:11:05 +0200 Subject: [PATCH 6/8] complete test migration --- AGENTS.md | 37 +++------------- alf | 12 ++--- src/commands/connect.sh | 8 ++-- src/commands/which.sh | 4 +- test/commands/all_.bats | 92 +++++++++++++++++++++++++++++++++++++++ test/integration/cli.bats | 30 +++++++++++++ test/test_helper.bash | 4 ++ 7 files changed, 143 insertions(+), 44 deletions(-) create mode 100644 test/commands/all_.bats create mode 100644 test/integration/cli.bats diff --git a/AGENTS.md b/AGENTS.md index 0bc87d3..81559b2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,7 @@ This repository is a Bashly-based CLI. Prefer working from the source partials i - Read and edit: - `src/bashly.yml` - `src/initialize.sh` - - `src/*_command.sh` + - `src/commands/*.sh` - `src/lib/*.sh` - `settings.yml` @@ -22,45 +22,18 @@ This repository is a Bashly-based CLI. Prefer working from the source partials i ## Test Strategy -The repository currently uses approval tests. Keep this distinction clear in future work: - -- Approval tests should cover stable user-facing output: - - help text - - generated alias output - - other intentional CLI snapshots -- Behavioral tests should move toward Bats: - - config discovery - - `which` - - `generate` - - `save` - - `upload` - - failure modes - - local fixture repo scenarios +The repository uses Bats as the primary test framework. For Bats tests, prefer this split: - Use checked-in fixtures when the unit's job is to interpret files, parse config, or derive behavior from prepared filesystem state. - Use stubs when the unit's job is orchestration. - In stub-driven unit tests, it is acceptable to create the smallest transient prerequisite inline when it is only a mechanical precondition (for example, an empty file required to satisfy an existence check). - -## Approval Testing Rules - -- Never edit approval files manually. -- Never refresh approval files as a blind mechanical step. -- Approval updates should happen only through the approval workflow itself. -- Approval changes should be user-approved, because the approval step is the control point that distinguishes intended output changes from regressions. -- Do not "bake in" new snapshots unless the changed output has been intentionally reviewed and accepted. - -## Migration Guidance - -- Do not remove or loosen existing approval coverage until replacement behavioral coverage exists and the current approvals pass cleanly. -- Reduce approvals only after: - - deterministic Bats coverage is in place - - network-dependent tests are removed or isolated - - the current approval suite is green +- Keep command adapter tests tiny and structural. +- Keep integration tests sparse and focused on top-level CLI wiring, not behavior that is already covered at the unit level. ## Review Notes - This project is being prepared for a `1.0.0` release and semver commitment. - Prefer deterministic, local, hermetic tests over live network access. -- Treat installer and upgrade flows as release/integration verification, not unit coverage. +- Treat installer flows as release/integration verification, not unit coverage. diff --git a/alf b/alf index cd47bf7..2a0680c 100755 --- a/alf +++ b/alf @@ -773,10 +773,10 @@ upload_repo() { alf_connect_command() { # src/commands/connect.sh - repo=${args[repo]} - force=${args[--yes]} - force_ssh=${args[--ssh]} - force_https=${args[--https]} + repo=${args["repo"]} + force=${args["--yes"]} + force_ssh=${args["--ssh"]} + force_https=${args["--https"]} connect_repo "$repo" "$force" "$force_ssh" "$force_https" @@ -826,8 +826,8 @@ alf_edit_command() { alf_which_command() { # src/commands/which.sh - code=${args[code]} - subcode=${args[subcode]} + code=${args["code"]} + subcode=${args["subcode"]} show_alias_command "$code" "$subcode" diff --git a/src/commands/connect.sh b/src/commands/connect.sh index 2b449c8..1ffb181 100644 --- a/src/commands/connect.sh +++ b/src/commands/connect.sh @@ -1,6 +1,6 @@ -repo=${args[repo]} -force=${args[--yes]} -force_ssh=${args[--ssh]} -force_https=${args[--https]} +repo=${args["repo"]} +force=${args["--yes"]} +force_ssh=${args["--ssh"]} +force_https=${args["--https"]} connect_repo "$repo" "$force" "$force_ssh" "$force_https" diff --git a/src/commands/which.sh b/src/commands/which.sh index e47b664..737a3e2 100644 --- a/src/commands/which.sh +++ b/src/commands/which.sh @@ -1,4 +1,4 @@ -code=${args[code]} -subcode=${args[subcode]} +code=${args["code"]} +subcode=${args["subcode"]} show_alias_command "$code" "$subcode" diff --git a/test/commands/all_.bats b/test/commands/all_.bats new file mode 100644 index 0000000..07026ff --- /dev/null +++ b/test/commands/all_.bats @@ -0,0 +1,92 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment + source "$ALF_REPO_ROOT/src/initialize.sh" + declare -g -A args=() +} + +teardown() { + unset_functions connect_repo download_repo generate_config save_config show_info upload_repo show_alias_command + teardown_test_environment +} + +@test "connect command calls connect_repo with parsed args" { + args[repo]="DannyBen" + args["--yes"]="1" + args["--ssh"]="" + args["--https"]="1" + + connect_repo() { + printf '%s|%s|%s|%s\n' "$1" "$2" "$3" "$4" >"$TEST_ROOT/call" + } + + source_command connect + + [ "$(cat "$TEST_ROOT/call")" = "DannyBen|1||1" ] +} + +@test "download command calls download_repo" { + download_repo() { + echo called >"$TEST_ROOT/call" + } + + source_command download + + [ "$(cat "$TEST_ROOT/call")" = "called" ] +} + +@test "generate command calls generate_config" { + generate_config() { + echo called >"$TEST_ROOT/call" + } + + source_command generate + + [ "$(cat "$TEST_ROOT/call")" = "called" ] +} + +@test "info command calls show_info" { + show_info() { + echo called >"$TEST_ROOT/call" + } + + source_command info + + [ "$(cat "$TEST_ROOT/call")" = "called" ] +} + +@test "save command calls save_config" { + save_config() { + echo called >"$TEST_ROOT/call" + } + + source_command save + + [ "$(cat "$TEST_ROOT/call")" = "called" ] +} + +@test "upload command calls upload_repo" { + upload_repo() { + echo called >"$TEST_ROOT/call" + } + + source_command upload + + [ "$(cat "$TEST_ROOT/call")" = "called" ] +} + +@test "which command calls show_alias_command with code and subcode" { + args[code]="g" + args[subcode]="l" + + show_alias_command() { + printf '%s|%s\n' "$1" "$2" >"$TEST_ROOT/call" + } + + source_command which + + [ "$(cat "$TEST_ROOT/call")" = "g|l" ] +} diff --git a/test/integration/cli.bats b/test/integration/cli.bats new file mode 100644 index 0000000..a47adc8 --- /dev/null +++ b/test/integration/cli.bats @@ -0,0 +1,30 @@ +#!/usr/bin/env bats + +load ../test_helper.bash + +setup() { + setup_test_environment +} + +teardown() { + teardown_test_environment +} + +@test "alf --help renders properly" { + run "$ALF_REPO_ROOT/alf" --help + + [ "$status" -eq 0 ] + assert_output_contains "Commands:" + assert_output_contains "connect" + assert_output_contains "which" + [[ "$output" != *"upgrade"* ]] +} + +@test "alf which --help renders properly" { + run "$ALF_REPO_ROOT/alf" which --help + + [ "$status" -eq 0 ] + assert_output_contains "alf which - Show the alias command." + assert_output_contains "Usage:" + assert_output_contains "alf which CODE [SUBCODE]" +} diff --git a/test/test_helper.bash b/test/test_helper.bash index 4a658da..08648f3 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -53,3 +53,7 @@ source_libs() { source "$ALF_REPO_ROOT/src/lib/${lib}.sh" done } + +source_command() { + source "$ALF_REPO_ROOT/src/commands/${1}.sh" +} From f36304a591bd8f5799352e13df2a1ace7d9db058 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 20:15:22 +0200 Subject: [PATCH 7/8] fix ci --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf0fd36..a07baa1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,8 +10,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Install test dependencies + run: sudo apt-get update && sudo apt-get install -y bats shellcheck - name: Run shellcheck tests - run: shellcheck alf setup + run: shellcheck alf setup uninstall - name: Run Bats tests run: bats --recursive --print-output-on-failure --abort test From 7ef4d364b9b7f5b8fe05c9934ffda09e45f00c51 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 11 Mar 2026 20:17:22 +0200 Subject: [PATCH 8/8] fix ci --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a07baa1..12624ac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Run shellcheck tests run: shellcheck alf setup uninstall - name: Run Bats tests - run: bats --recursive --print-output-on-failure --abort test + run: bats --recursive --print-output-on-failure test ubuntu_setup: name: Setup on Ubuntu