diff --git a/.gitignore b/.gitignore index 2ef777e..198945c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +/.upkg /results.tap diff --git a/README.md b/README.md index f147134..bfd7113 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,31 @@ you need the container image tag variant. ## Behavior -| git ref | program version | -| -------------------------------------------------------------- | --------------- | -| `refs/heads/main` | `main` | -| `refs/heads/master` | `master` | -| `refs/heads/ft-refactor` | `ft-refactor` | -| `refs/tags/v1.0.3` | `v1.0.3` | -| `refs/tags/1.0.3` | `v1.0.3` | -| `refs/tags/very-pinned` (treated just like branches) | `very-pinned` | -| `refs/tags/f1.0.3` (treated just like branches) | `f1.0.3` | -| `refs/tags/v` | `v` | -| `e02d09699ffb56440f34cb7448a0bc436e3ae212` (i.e. non-symbolic) | `e02d0969` | -| `e02d09699ffb56440f34cb7448` (not 40 hex chars) | error | -| `master` (no `refs/heads/` prefix) | error | -| `v1.0.3` (no `refs/tags/` prefix) | error | -| `refs/heads/` (empty branch name) | error | -| `refs/tags/` (empty tag name) | error | +| git ref | program version | prefix | +| -------------------------------------------------------------- | -------------------- | ---------- | +| `refs/heads/main` | `main` | `v` | +| `refs/heads/master` | `master` | `v` | +| `refs/heads/ft-refactor` | `ft-refactor` | `v` | +| `refs/tags/v1.0.3` | `v1.0.3` | `v` | +| `refs/tags/1.0.3` | `1.0.3` | `v` | +| `refs/tags/very-pinned` (treated just like branches) | `very-pinned` | `v` | +| `refs/tags/f1.0.3` (treated just like branches) | `f1.0.3` | `v` | +| `refs/tags/v` | `v` | `v` | +| `e02d09699ffb56440f34cb7448a0bc436e3ae212` (i.e. non-symbolic) | `e02d0969` | `v` | +| `e02d09699ffb56440f34cb7448` (not 40 hex chars) | error | `v` | +| `master` (no `refs/heads/` prefix) | error | `v` | +| `v1.0.3` (no `refs/tags/` prefix) | error | `v` | +| `refs/heads/` (empty branch name) | error | `v` | +| `refs/tags/` (empty tag name) | error | `v` | +| **Custom prefix** | | | +| `refs/heads/main` | `main` | `mytool-v` | +| `refs/heads/mytool-vmain` | `mytool-vmain` | `mytool-v` | +| `refs/tags/v1.0.3` | `v1.0.3` | `mytool-v` | +| `refs/tags/mytool-v1.0.3` | `v1.0.3` | `mytool-v` | +| `refs/tags/mytool-v1.0.3` (prefix=`v`) | `mytool-v1.0.3` | `v` | +| `refs/tags/1.0.3` | `1.0.3` | `mytool-v` | +| `refs/tags/mytool-very-pinned` (treated just like branches) | `mytool-very-pinned` | `mytool-v` | +| `refs/tags/mytool-v` | `mytool-v` | `mytool-v` | ## CLI @@ -48,8 +57,21 @@ version=$(program-version "$(jq -re '.version // empty' "$PKGROOT/upkg.json" 2>/ ### Parameters -- `ref`: The git ref to calculate the version from, defaults to - `${{ github.ref }}`. +- `ref`: The git ref to calculate the version from. Defaults to `${{ github.ref }}`. +- `prefix`: Operate on tag versions with the specified prefix. Defaults to `v`. + +### Inputs + +| Name | Description | Default | +| -------- | -------------------------------------------------- | ------------------------ | +| `ref` | The git ref to calculate the version from. | `${{ github.ref }} input | +| `prefix` | Operate on tag versions with the specified prefix. | `v` | + +### Outputs + +| Name | Description | +| --------- | -------------------- | +| `version` | The program version. | ### Usage diff --git a/action.yaml b/action.yaml index dc79c9a..f609cea 100644 --- a/action.yaml +++ b/action.yaml @@ -5,6 +5,10 @@ inputs: description: The git ref to use. Defaults to `github.ref`. default: ${{ github.ref }} required: false + prefix: + description: Operate on tag versions with the specified prefix. Defaults to `v``. + default: ${{ github.ref }} + required: false outputs: version: description: The program version diff --git a/bin/program-version b/bin/program-version index ae870f8..dad6663 100755 --- a/bin/program-version +++ b/bin/program-version @@ -1,20 +1,47 @@ #!/usr/bin/env bash +# shellcheck source-path=.. main() { set -eo pipefail; shopt -s inherit_errexit + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") + source "$pkgroot/.upkg/records.sh/records.sh" + DOC="program-version - Determine the program version based on a git ref. +Usage: + program-version [-p P] REF - local ref=${1:?'Usage: program-version REF'} - if [[ $ref =~ refs/tags/v?[0-9]+ ]]; then - local tag=${ref#'refs/tags/'} - printf "v%s\n" "${tag#v}" - elif [[ $ref = refs/tags/* ]]; then - printf "%s\n" "${ref#'refs/tags/'}" - elif [[ $ref = refs/heads/?* ]]; then - printf "%s\n" "${ref#'refs/heads/'}" - elif [[ $ref =~ ^[0-9a-f]{40}$ ]]; then - printf "%s\n" "${ref:0:8}" +Options: + -p --prefix P Operate on tag versions with the specified prefix [default: v] +" +# docopt parser below, refresh this parser with `docopt.sh program-version` +# shellcheck disable=2016,2086,2317,1090,1091,2034 +docopt() { local v='2.0.2'; source \ +"$pkgroot/.upkg/docopt-lib-v$v/docopt-lib.sh" "$v" || { ret=$?;printf -- "exit \ +%d\n" "$ret";exit "$ret";};set -e;trimmed_doc=${DOC:0:193};usage=${DOC:68:35} +digest=a75bc;options=('-p --prefix 1');node_0(){ value __prefix 0;};node_1(){ +value REF a;};node_2(){ optional 0;};node_3(){ sequence 2 1;};cat <<<' \ +docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:68:35}" >&2;exit 1;}';local varnames=(__prefix REF) varname;for varname \ +in "${varnames[@]}"; do unset "var_$varname";done;parse 3 "$@";local \ +p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset "$p$varname" +done;eval $p'__prefix=${var___prefix:-v};'$p'REF=${var_REF:-};';local docopt_i=1 +[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2;for ((;docopt_i>0;docopt_i--)); do +for varname in "${varnames[@]}"; do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib-v$v/docopt-lib.sh"' program-version` + eval "$(docopt "$@")" + + # shellcheck disable=2154 + local P=$__prefix + + if [[ $REF = refs/tags/${P}* && ${REF#"refs/tags/$P"} =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then + printf "v%s\n" "${REF#"refs/tags/$P"}" + elif [[ $REF = refs/tags/* ]]; then + printf "%s\n" "${REF#'refs/tags/'}" + elif [[ $REF = refs/heads/?* ]]; then + printf "%s\n" "${REF#'refs/heads/'}" + elif [[ $REF =~ ^[0-9a-f]{40}$ ]]; then + printf "%s\n" "${REF:0:8}" else - printf "program-version.sh: REF must start with refs/tags/, refs/heads/, or be a shasum. Got '%s'.\n" "$ref" >&2 + error "REF must start with refs/tags/, refs/heads/, or be a shasum. Got '%s'.\n" "$REF" >&2 return 1 fi } diff --git a/test.bats b/test.bats index 400ed3a..438496a 100755 --- a/test.bats +++ b/test.bats @@ -25,9 +25,9 @@ setup_file() { [ "$output" = "v1.0.3" ] } -@test 'refs/tags/1.0.3=v1.0.3' { +@test 'refs/tags/1.0.3=1.0.3' { run bin/program-version refs/tags/1.0.3 - [ "$output" = "v1.0.3" ] + [ "$output" = "1.0.3" ] } @test 'refs/tags/very-pinned=very-pinned' { @@ -69,3 +69,43 @@ setup_file() { @test 'refs/tags=error' { run -1 bin/program-version refs/tags } + +@test '-p=mytool-v refs/heads/main=main' { + run bin/program-version -p mytool-v refs/heads/main + [ "$output" = "main" ] +} + +@test '-p=mytool-v refs/heads/mytool-vmain=mytool-vmain' { + run bin/program-version -p mytool-v refs/heads/mytool-vmain + [ "$output" = "mytool-vmain" ] +} + +@test '-p=mytool-v refs/tags/v1.0.3=v1.0.3' { + run bin/program-version -p mytool-v refs/tags/v1.0.3 + [ "$output" = "v1.0.3" ] +} + +@test '-p=mytool-v refs/tags/mytool-v1.0.3=v1.0.3' { + run bin/program-version -p mytool-v refs/tags/mytool-v1.0.3 + [ "$output" = "v1.0.3" ] +} + +@test '-p=mytool-v refs/tags/mytool-v1.0.3=mytool-v1.0.3' { + run bin/program-version -p v refs/tags/mytool-v1.0.3 + [ "$output" = "mytool-v1.0.3" ] +} + +@test '-p=mytool-v refs/tags/1.0.3=1.0.3' { + run bin/program-version -p mytool-v refs/tags/1.0.3 + [ "$output" = "1.0.3" ] +} + +@test '-p=mytool-v refs/tags/mytool-very-pinned=mytool-very-pinned' { + run bin/program-version -p mytool-v refs/tags/mytool-very-pinned + [ "$output" = "mytool-very-pinned" ] +} + +@test '-p=mytool-v refs/tags/mytool-v=mytool-v' { + run bin/program-version -p mytool-v refs/tags/mytool-v + [ "$output" = "mytool-v" ] +} diff --git a/upkg.json b/upkg.json index 98ddb9e..45340ff 100644 --- a/upkg.json +++ b/upkg.json @@ -1,3 +1,14 @@ { - "name": "program-version" + "name": "program-version", + "dependencies": [ + { + "tar": "https://github.com/orbit-online/records.sh/releases/download/v0.9.6/records.sh.tar.gz", + "sha256": "9ef37448a3c35e64c1bcddeb6e42ba7650b3dfa4e2dc457c2f82364d4b6d343d" + }, + { + "name": "docopt-lib-v2.0.2", + "tar": "https://github.com/andsens/docopt.sh/releases/download/v2.0.2/docopt-lib.sh.tar.gz", + "sha256": "d6997858e7f2470aa602fdd1e443d89b4e2084245b485e4b7924b0f388ec401e" + } + ] }