diff --git a/README.md b/README.md index 9536bca..1bb6f62 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,16 @@ access to the site, use `--ssh` to override the protocol: $ basher install --ssh juanibiapina/gg ~~~ +### Installing with a custom folder name + +You can install a package with a custom folder name by providing a second argument: + +~~~ sh +$ basher install sstephenson/bats bats-core/bats +~~~ + +This will install the package into `~/.basher/packages/bats-core/bats` instead of the default location. And it will appear in `basher list` as `bats-core/bats`. + ### Installing a local package If you develop a package locally and want to try it through basher, @@ -119,8 +129,9 @@ This will source a file `lib/file.sh` under the package `username/repo`. - `basher commands` - List commands - `basher help ` - Display help for a command +- `basher install [--ssh] [site]/[@ref] [folder]` - Install a package - `basher uninstall ` - Uninstall a package -- `basher list` - List installed packages +- `basher list [-v]` - List installed packages - `basher outdated` - List packages which are not in the latest version - `basher upgrade ` - Upgrade a package to the latest version diff --git a/libexec/basher-_clone b/libexec/basher-_clone index 6d02688..1070ff8 100755 --- a/libexec/basher-_clone +++ b/libexec/basher-_clone @@ -2,11 +2,11 @@ # # Summary: Clones a package from a site, but doesn't install it # -# Usage: basher _clone [] +# Usage: basher _clone [] [folder] set -e -if [ "$#" -ne 3 ] && [ "$#" -ne 4 ]; then +if [ "$#" -lt 3 -o "$#" -gt 5 ]; then basher-help _clone exit 1 fi @@ -15,6 +15,7 @@ use_ssh="$1" site="$2" package="$3" ref="$4" +folder="$5" if [ -z "$use_ssh" ]; then basher-help _clone @@ -49,8 +50,12 @@ if [ -z "$name" ]; then exit 1 fi -if [ -e "$BASHER_PACKAGES_PATH/$package" ]; then - echo "Package '$package' is already present" +if [ -z "$folder" ]; then + folder="$package" +fi + +if [ -e "$BASHER_PACKAGES_PATH/$folder" ]; then + echo "Folder '$folder' already exists" exit 0 fi @@ -66,5 +71,4 @@ else URI="https://${site}/$package.git" fi -# shellcheck disable=SC2086 -git clone ${DEPTH_OPTION} ${BRANCH_OPTION} --recursive "$URI" "${BASHER_PACKAGES_PATH}/$package" +git clone ${DEPTH_OPTION} ${BRANCH_OPTION} --recursive "$URI" "${BASHER_PACKAGES_PATH}/$folder" diff --git a/libexec/basher-install b/libexec/basher-install index bc0acdc..c1cd136 100755 --- a/libexec/basher-install +++ b/libexec/basher-install @@ -2,7 +2,7 @@ # # Summary: Installs a package from github (or a custom site) # -# Usage: basher install [--ssh] [site]/[@ref] +# Usage: basher install [--ssh] [site]/[@ref] [folder] set -e @@ -15,7 +15,7 @@ case $1 in ;; esac -if [ "$#" -ne 1 ]; then +if [ "$#" -lt 1 -o "$#" -gt 2 ]; then basher-help install exit 1 fi @@ -24,10 +24,24 @@ if [[ "$1" = */*/* ]]; then IFS=/ read -r site user name <<< "$1" package="${user}/${name}" else - package="$1" + IFS=/ read -r user name <<< "$1" + package="${user}/${name}" site="github.com" fi +# defaults to package's name, but allows custom folder name +folder="$package" +custom_folder=false +if [ -n "$2" ]; then + if ! [[ "$2" =~ ^[^/]+/[^/]+$ ]]; then + basher-help install + echo "Optional argunment [folder] must be in the format <...>/<...>" + exit 1 + fi + folder="$2" + custom_folder=true +fi + if [ -z "$package" ]; then basher-help install exit 1 @@ -51,10 +65,21 @@ else ref="" fi -if [ -z "$ref" ]; then - basher-_clone "$use_ssh" "$site" "$package" +# Call basher-_clone with appropriate number of parameters +if [ "$custom_folder" = "false" ]; then + # No custom folder - use original behavior + if [ -z "$ref" ]; then + basher-_clone "$use_ssh" "$site" "$package" + else + basher-_clone "$use_ssh" "$site" "$package" "$ref" + fi else - basher-_clone "$use_ssh" "$site" "$package" "$ref" + # Custom folder specified - pass all parameters + basher-_clone "$use_ssh" "$site" "$package" "$ref" "$folder" fi -basher-_deps "$package" -basher-_link "$package" + +# Use folder for subsequent operations +basher-_deps "$folder" +basher-_link-bins "$folder" +basher-_link-man "$folder" +basher-_link-completions "$folder" diff --git a/libexec/basher-list b/libexec/basher-list index d00f213..776c9cf 100755 --- a/libexec/basher-list +++ b/libexec/basher-list @@ -1,10 +1,17 @@ #!/usr/bin/env bash # # Summary: List installed packages -# Usage: basher list +# Usage: basher list [-v] set -e +case $1 in + -v) + verbose="true" + shift + ;; +esac + if [ "$#" -gt 0 ]; then basher-help list exit 1 @@ -17,5 +24,9 @@ do username="$(dirname "$package_path")" username="${username##*/}" package="${package_path##*/}" - echo "$username/$package" + if [ -z "$verbose" ]; then + echo "$username/$package" + else + printf "%-30s %-30s\n" "$username/$package" "($(git --git-dir=${BASHER_PACKAGES_PATH}/$username/$package/.git config --get remote.origin.url))" + fi done diff --git a/tests/basher-_clone.bats b/tests/basher-_clone.bats index 8eb6941..b90ec55 100644 --- a/tests/basher-_clone.bats +++ b/tests/basher-_clone.bats @@ -5,19 +5,19 @@ load test_helper @test "without arguments prints usage" { run basher-_clone assert_failure - assert_line "Usage: basher _clone []" + assert_line "Usage: basher _clone [] [folder]" } @test "invalid package prints usage" { run basher-_clone false github.com invalid_package assert_failure - assert_line "Usage: basher _clone []" + assert_line "Usage: basher _clone [] [folder]" } @test "too many arguments prints usage" { - run basher-_clone false site a/b ref fourth_arg + run basher-_clone false site a/b ref folder fifth_arg assert_failure - assert_line "Usage: basher _clone []" + assert_line "Usage: basher _clone [] [folder]" } @test "install a specific version" { @@ -34,7 +34,7 @@ load test_helper run basher-_clone false github.com username/package assert_success - assert_output "Package 'username/package' is already present" + assert_output "Folder 'username/package' already exists" } @test "using a different site" { @@ -79,3 +79,36 @@ load test_helper assert_success assert_output "git clone --depth=1 --recursive git@site:username/package.git ${BASHER_PACKAGES_PATH}/username/package" } + +@test "clones to custom folder" { + mock_command git + + run basher-_clone false github.com username/package "" custom/folder + assert_success + assert_output "git clone --depth=1 --recursive https://github.com/username/package.git ${BASHER_PACKAGES_PATH}/custom/folder" +} + +@test "clones to custom folder with version" { + mock_command git + + run basher-_clone false github.com username/package v1.2.3 custom/folder + assert_success + assert_output "git clone --depth=1 -b v1.2.3 --recursive https://github.com/username/package.git ${BASHER_PACKAGES_PATH}/custom/folder" +} + +@test "custom folder defaults to package name when not specified" { + mock_command git + + run basher-_clone false github.com username/package "" "" + assert_success + assert_output "git clone --depth=1 --recursive https://github.com/username/package.git ${BASHER_PACKAGES_PATH}/username/package" +} + +@test "does nothing if custom folder already exists" { + mkdir -p "$BASHER_PACKAGES_PATH/custom/folder" + + run basher-_clone false github.com username/package "" custom/folder + + assert_success + assert_output "Folder 'custom/folder' already exists" +} diff --git a/tests/basher-install.bats b/tests/basher-install.bats index 3d92d2e..3841dbe 100644 --- a/tests/basher-install.bats +++ b/tests/basher-install.bats @@ -5,19 +5,19 @@ load test_helper @test "without arguments prints usage" { run basher-install assert_failure - assert_line "Usage: basher install [--ssh] [site]/[@ref]" + assert_line "Usage: basher install [--ssh] [site]/[@ref] [folder]" } @test "incorrect argument prints usage" { run basher-install first_arg assert_failure - assert_line "Usage: basher install [--ssh] [site]/[@ref]" + assert_line "Usage: basher install [--ssh] [site]/[@ref] [folder]" } @test "too many arguments prints usage" { - run basher-install a/b wrong + run basher-install a/b folder wrong assert_failure - assert_line "Usage: basher install [--ssh] [site]/[@ref]" + assert_line "Usage: basher install [--ssh] [site]/[@ref] [folder]" } @test "executes install steps in right order" { @@ -102,3 +102,42 @@ basher-_link-completions username/package" run basher-install username/package assert_success } + +@test "installs package with custom folder name" { + mock_command basher-_clone + mock_command basher-_deps + mock_command basher-_link-bins + mock_command basher-_link-man + mock_command basher-_link-completions + + run basher-install username/package my/folder + + assert_line "basher-_clone false github.com username/package my/folder" + assert_line "basher-_deps my/folder" + assert_line "basher-_link-bins my/folder" + assert_line "basher-_link-man my/folder" + assert_line "basher-_link-completions my/folder" +} + +@test "installs package with custom folder name and version" { + mock_command basher-_clone + mock_command basher-_deps + mock_command basher-_link-bins + mock_command basher-_link-man + mock_command basher-_link-completions + + run basher-install username/package@v1.2.3 my/folder + + assert_line "basher-_clone false github.com username/package v1.2.3 my/folder" + assert_line "basher-_deps my/folder" + assert_line "basher-_link-bins my/folder" + assert_line "basher-_link-man my/folder" + assert_line "basher-_link-completions my/folder" +} + + +@test "rejects invalid custom folder name format" { + run basher-install username/package invalid-folder + assert_failure + assert_line "Optional argunment [folder] must be in the format <...>/<...>" +} diff --git a/tests/basher-list.bats b/tests/basher-list.bats index 49817a6..88ababe 100644 --- a/tests/basher-list.bats +++ b/tests/basher-list.bats @@ -5,7 +5,7 @@ load test_helper @test "with arguments shows usage" { run basher-list a_arg assert_failure - assert_line "Usage: basher list" + assert_line "Usage: basher list [-v]" } @test "list installed packages" { @@ -22,3 +22,36 @@ load test_helper assert_line "username2/p2" refute_line "username2/p3" } + +@test "list installed packages with verbose flag shows remote URLs" { + mock_clone + create_package username/p1 + create_package username2/p2 + basher-install username/p1 + basher-install username2/p2 + + run basher-list -v + assert_success + # Check that output contains package names in the verbose format + # The format is: package-name (remote-url) + assert_output --regexp "username/p1 +\(${BASHER_ORIGIN_DIR}/username/p1\)" + assert_output --regexp "username2/p2 +\(${BASHER_ORIGIN_DIR}/username2/p2\)" +} + +@test "verbose flag with arguments shows usage" { + run basher-list -v extra_arg + assert_failure + assert_line "Usage: basher list [-v]" +} + +@test "displays nothing if there are no packages" { + run basher-list + assert_success + assert_output "" +} + +@test "displays nothing if there are no packages with verbose flag" { + run basher-list -v + assert_success + assert_output "" +}