Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Install test dependencies
run: sudo apt-get update && sudo apt-get install -y bats shellcheck
- name: Run shellcheck tests
run: shellcheck alf setup uninstall
run: shellcheck alf setup uninstall test/test_helper.bash
- name: Run Bats tests
run: bats --recursive --print-output-on-failure test

Expand Down
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ This repository is a Bashly-based CLI. Prefer working from the source partials i
- `src/lib/*.sh`
- `settings.yml`

## Helper Commands

- `op.conf` is the repo-local source of truth for common helper commands such as
testing, ShellCheck, formatting, generation, and docs tasks.
- Prefer the `op.conf` entries when looking up or running standard project
workflows.

## Generated Artifact Policy

- Only inspect `./alf` when you need to verify generated output, trace a generation issue, or confirm the final emitted behavior.
Expand Down
17 changes: 12 additions & 5 deletions alf
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,8 @@ find_config() {

# src/lib/generate_completion.sh
generate_completions() {
ali1_regex="^([a-z0-9\-]+):"
ali2_regex="^ +([a-z0-9\-]+):"
ali1_regex="^([a-zA-Z0-9\-]+):"
ali2_regex="^ +([a-zA-Z0-9\-]+):"
find_config

echo '# Completions'
Expand Down Expand Up @@ -625,7 +625,7 @@ generate_last_cmd() {

# src/lib/has_subcommands.sh
has_subcommands() {
regex="^ +([a-z0-9\-]+):"
regex="^ +([a-zA-Z0-9\-]+):"
find_config

while IFS= read -r line || [ -n "$line" ]; do
Expand Down Expand Up @@ -763,7 +763,14 @@ upload_repo() {

pushd "$repo_path" >/dev/null
echo "Pushing $repo_path to repository"
git commit -am "automatic push"
git add -A

if git diff --cached --quiet; then
echo "No local changes to commit"
else
git commit -m "automatic push"
fi

git push
popd >/dev/null
}
Expand Down Expand Up @@ -1449,7 +1456,7 @@ alf_info_parse_requirements() {
# :command.initialize
initialize() {
declare -g version="0.6.1"
set -e
set -eo pipefail

# src/initialize.sh
aliases_file=${ALF_ALIASES_FILE:-~/.bash_aliases}
Expand Down
2 changes: 1 addition & 1 deletion op.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ watch: filewatcher --immediate "src/**/*.*" "bashly generate"
test: bats --recursive --print-output-on-failure --abort "${1:-test}"
#? Run all tests or a given test

shellcheck: shellcheck alf setup uninstall && green "PASS"
shellcheck: shellcheck alf setup uninstall test/test_helper.bash && green "PASS"
#? Run shellcheck

shfmt: shfmt -ci -i 2 -d alf setup uninstall && green "PASS"
Expand Down
1 change: 1 addition & 0 deletions settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ commands_dir: commands
enable_view_markers: always
enable_env_var_names_array: never
enable_deps_array: never
strict: set -eo pipefail

usage_colors:
caption: bold
Expand Down
2 changes: 1 addition & 1 deletion src/lib/download_repo.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
download_repo() {
find_config
find_config || return 1

if [[ ! -f $rc_file ]]; then
echo "Cannot find $rc_file"
Expand Down
4 changes: 2 additions & 2 deletions src/lib/find_config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ find_config() {
echo "You should either:"
echo "- Run this command in a folder with 'alf.conf' file, or"
echo "- Run 'alf connect' to properly connect to a remote config"
exit 1
return 1
fi
}
}
7 changes: 3 additions & 4 deletions src/lib/generate_completion.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generate_completions() {
ali1_regex="^([a-z0-9\-]+):"
ali2_regex="^ +([a-z0-9\-]+):"
find_config
ali1_regex="^([a-zA-Z0-9\-]+):"
ali2_regex="^ +([a-zA-Z0-9\-]+):"
find_config || return 1

echo '# Completions'
echo 'if command -v complete &> /dev/null ; then'
Expand All @@ -28,4 +28,3 @@ generate_completions() {

echo 'fi'
}

3 changes: 1 addition & 2 deletions src/lib/generate_config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ generate_config() {
state="simple"
lastcmd=""
case_open="false"
find_config
find_config || return 1

echo "# This file was automatically generated by alf"
echo "# https://github.com/dannyben/alf"
Expand Down Expand Up @@ -64,4 +64,3 @@ generate_config() {
generate_completions
fi
}

6 changes: 3 additions & 3 deletions src/lib/has_subcommands.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Returns true if the config has subcommands
has_subcommands() {
regex="^ +([a-z0-9\-]+):"
find_config
regex="^ +([a-zA-Z0-9\-]+):"
find_config || return 1

while IFS= read -r line || [ -n "$line" ]; do
if [[ $line =~ $regex ]]; then
Expand All @@ -10,4 +10,4 @@ has_subcommands() {
done <"$config_file"

return 1
}
}
2 changes: 1 addition & 1 deletion src/lib/save_config.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
save_config() {
find_config
find_config || return 1

tilde='~'
friendly_aliases_file="${aliases_file/#$HOME/$tilde}"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/show_alias_command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ show_alias_command() {
local subcode="${2:-}"
local regex_exact_code regex_exact_subcode cmd1 cmd2

find_config
find_config || return 1
regex_exact_code="^($code): *(.+)$"
regex_exact_subcode="^( +)($subcode): *(.+)$"
cmd1=""
Expand Down
2 changes: 1 addition & 1 deletion src/lib/show_info.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
show_info() {
find_config
find_config || return 1

if [[ -d "$repo_path/.git" ]]; then
pushd "$repo_path" >/dev/null
Expand Down
11 changes: 9 additions & 2 deletions src/lib/upload_repo.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
upload_repo() {
find_config
find_config || return 1

if [[ ! -f $rc_file ]]; then
echo "Cannot find $rc_file"
Expand All @@ -9,7 +9,14 @@ upload_repo() {

pushd "$repo_path" >/dev/null
echo "Pushing $repo_path to repository"
git commit -am "automatic push"
git add -A

if git diff --cached --quiet; then
echo "No local changes to commit"
else
git commit -m "automatic push"
fi

git push
popd >/dev/null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
G: git
S: status
L: log
dir: ls
DC: docker-compose
DEPLOY: stack deploy
UPD: up -d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Completions
if command -v complete &> /dev/null ; then
complete -W "S L" G
complete -W "DEPLOY UPD" DC
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
G: git
S: status
DEPLOY: !docker stack deploy
DNS: dig +short
CHECK: !host -t ns
Original file line number Diff line number Diff line change
@@ -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 "$@"
;;
*)
dig +short "$@"
;;
esac
}

# Completions
if command -v complete &> /dev/null ; then
complete -W "S DEPLOY" G
complete -W "CHECK" DNS
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
G: git
S: status
L: log
dc: docker-compose
DEPLOY: stack deploy
12 changes: 12 additions & 0 deletions test/lib/generate_completion.bats
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ teardown() {
[ "$output" = "$(cat "$(fixture_path generate_completion/with-subcommands/expected.txt)")" ]
}

@test "generate_completions preserves uppercase aliases and subcommands" {
export ALF_RC_FILE
ALF_RC_FILE="$(fixture_path generate_completion/with-uppercase-subcommands/alfrc)"
cd "$(fixture_path generate_completion/with-uppercase-subcommands)" || exit 1
source_libs find_config generate_completion

run generate_completions

[ "$status" -eq 0 ]
[ "$output" = "$(cat "$(fixture_path generate_completion/with-uppercase-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)"
Expand Down
12 changes: 12 additions & 0 deletions test/lib/generate_config.bats
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ teardown() {
[ "$output" = "$(cat "$(fixture_path generate_config/with-subcommands/expected.sh)")" ]
}

@test "generate_config emits uppercase nested alias functions and completions" {
export ALF_RC_FILE
ALF_RC_FILE="$(fixture_path generate_config/with-uppercase-subcommands/alfrc)"
cd "$(fixture_path generate_config/with-uppercase-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-uppercase-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)"
Expand Down
11 changes: 11 additions & 0 deletions test/lib/has_subcommands.bats
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ teardown() {
[ "$?" -eq 0 ]
}

@test "has_subcommands returns success when nested aliases use uppercase codes" {
export ALF_RC_FILE
ALF_RC_FILE="$(fixture_path has_subcommands/with-uppercase-subcommands/alfrc)"
cd "$(fixture_path has_subcommands/with-uppercase-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)"
Expand Down
2 changes: 1 addition & 1 deletion test/lib/save_config.bats
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ teardown() {

find_config() {
echo "ERROR: Cannot find config file"
exit 1
return 1
}

generate_config() {
Expand Down
36 changes: 34 additions & 2 deletions test/lib/upload_repo.bats
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,44 @@ teardown() {

git() {
printf '%s\n' "$1" >>"$TEST_ROOT/git.log"

if [ "$1" = "diff" ]; then
return 1
fi
}

upload_repo

[ "$(sed -n '1p' "$TEST_ROOT/git.log")" = "commit" ]
[ "$(sed -n '2p' "$TEST_ROOT/git.log")" = "push" ]
[ "$(sed -n '1p' "$TEST_ROOT/git.log")" = "add" ]
[ "$(sed -n '2p' "$TEST_ROOT/git.log")" = "diff" ]
[ "$(sed -n '3p' "$TEST_ROOT/git.log")" = "commit" ]
[ "$(sed -n '4p' "$TEST_ROOT/git.log")" = "push" ]
}

@test "upload_repo pushes even when there is nothing to commit" {
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"
}

run upload_repo

[ "$status" -eq 0 ]
assert_output_contains "No local changes to commit"
[ "$(sed -n '1p' "$TEST_ROOT/git.log")" = "add" ]
[ "$(sed -n '2p' "$TEST_ROOT/git.log")" = "diff" ]
[ "$(sed -n '3p' "$TEST_ROOT/git.log")" = "push" ]
[ -z "$(sed -n '4p' "$TEST_ROOT/git.log")" ]
}

@test "upload_repo fails when no rc file exists" {
Expand Down
5 changes: 4 additions & 1 deletion test/test_helper.bash
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ teardown_test_environment() {

assert_output_contains() {
local expected="$1"
[[ "$output" == *"$expected"* ]]
[[ "${output-}" == *"$expected"* ]]
}

fixture_path() {
Expand All @@ -47,13 +47,16 @@ unset_functions() {
source_libs() {
local lib

# shellcheck disable=SC1091
source "$ALF_REPO_ROOT/src/initialize.sh"

for lib in "$@"; do
# shellcheck disable=SC1090
source "$ALF_REPO_ROOT/src/lib/${lib}.sh"
done
}

source_command() {
# shellcheck disable=SC1090
source "$ALF_REPO_ROOT/src/commands/${1}.sh"
}
Loading