diff --git a/.editorconfig b/.editorconfig
index 1923d41..16bec6a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,8 +1,12 @@
root = true
[*]
-indent_style = space
-indent_size = 2
+indent_style = tab
+end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
+
+[*.{md,yml,yaml}]
+indent_style = space
+indent_size = 2
diff --git a/.github/PULL_REQUEST/pull_request_template.md b/.github/PULL_REQUEST/pull_request_template.md
index 6d98686..a32de42 100644
--- a/.github/PULL_REQUEST/pull_request_template.md
+++ b/.github/PULL_REQUEST/pull_request_template.md
@@ -25,7 +25,7 @@
-## Checklist:
+## Checklist
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..5ace460
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 514dcbf..49c0e8d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,22 +1,22 @@
name: Build
+
on:
- pull_request:
- paths-ignore:
- - "**.md"
push:
- paths-ignore:
- - "**.md"
+ branches:
+ - main
+ pull_request:
jobs:
plugin_test:
name: asdf plugin test
strategy:
matrix:
- os: [ubuntu-latest, macos-latest]
+ os:
+ - ubuntu-latest
+ - macos-latest
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
- name: asdf_plugin_test
- uses: asdf-vm/actions/plugin-test@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3
+ uses: asdf-vm/actions/plugin-test@v2
with:
command: spruce --version
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 28203b4..5c3ffed 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,24 +1,24 @@
name: Lint
+
on:
- pull_request:
- paths-ignore:
- - "**.md"
push:
- paths-ignore:
- - "**.md"
+ branches:
+ - main
+ pull_request:
jobs:
lint:
- name: Shellcheck and Shell Format
runs-on: ubuntu-latest
steps:
- - name: Checkout code
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
- - name: asdf_install
- uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 # v3
- - name: Shellcheck
- run: shellcheck -x bin/* -P lib/
- - name: Shell Format - List files to check
- run: shfmt -f .
- - name: Shell Format - Validate
- run: shfmt -d -i 2 -ci .
+ - uses: actions/checkout@v3
+ - uses: asdf-vm/actions/install@v2
+ - run: scripts/lint.bash
+
+ actionlint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Check workflow files
+ uses: docker://rhysd/actionlint:1.6.23
+ with:
+ args: -color
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..454ce7a
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,18 @@
+name: Release
+
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ release-please:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: GoogleCloudPlatform/release-please-action@v3
+ with:
+ release-type: simple
diff --git a/.github/workflows/semantic-pr.yml b/.github/workflows/semantic-pr.yml
new file mode 100644
index 0000000..8b26fa4
--- /dev/null
+++ b/.github/workflows/semantic-pr.yml
@@ -0,0 +1,18 @@
+name: Lint
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ - edited
+ - synchronize
+
+jobs:
+ semantic-pr:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: amannn/action-semantic-pull-request@v5.2.0
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ validateSingleCommit: true
diff --git a/README.md b/README.md
index 2fd4eef..3cd98d5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-# asdf-spruce ![Build](https://github.com/woneill/asdf-spruce/workflows/Build/badge.svg) ![Lint](https://github.com/woneill/asdf-spruce/workflows/Lint/badge.svg)
+# asdf-spruce [![Build](https://github.com/woneill/asdf-spruce/actions/workflows/build.yml/badge.svg)](https://github.com/woneill/asdf-spruce/actions/workflows/build.yml) [![Lint](https://github.com/woneill/asdf-spruce/actions/workflows/lint.yml/badge.svg)](https://github.com/woneill/asdf-spruce/actions/workflows/lint.yml)
[spruce](https://github.com/geofffranks/spruce) plugin for the [asdf version manager](https://asdf-vm.com).
@@ -10,14 +10,12 @@
- [Dependencies](#dependencies)
- [Install](#install)
-- [Why?](#why)
- [Contributing](#contributing)
- [License](#license)
# Dependencies
-- `bash`, `curl`, `tar`: generic POSIX utilities.
-- `SOME_ENV_VAR`: set this environment variable in your shell config to load the correct version of tool x.
+- `bash`, `curl`, `tar`, and [POSIX utilities](https://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html).
# Install
@@ -56,4 +54,4 @@ Contributions of any kind welcome! See the [contributing guide](contributing.md)
# License
-See [LICENSE](LICENSE) © [Bill ONeill](https://github.com/woneill/)
+See [LICENSE](LICENSE) © [Bill O'Neill](https://github.com/woneill/)
diff --git a/bin/download b/bin/download
index fdc7e24..324db57 100755
--- a/bin/download
+++ b/bin/download
@@ -2,13 +2,18 @@
set -euo pipefail
-# shellcheck source=../lib/utils.bash
-source "$(dirname "$0")/../lib/utils.bash"
+current_script_path=${BASH_SOURCE[0]}
+plugin_dir=$(dirname "$(dirname "$current_script_path")")
+
+# shellcheck source=./lib/utils.bash
+source "${plugin_dir}/lib/utils.bash"
mkdir -p "$ASDF_DOWNLOAD_PATH"
-# TODO: Adapt this to proper extension and adapt extracting strategy.
+# Adapt this to proper extension and adapt extracting strategy.
release_file="$ASDF_DOWNLOAD_PATH/$TOOL_NAME"
# Download file to the download directory
download_release "$ASDF_INSTALL_VERSION" "$release_file"
+
+chmod a+x "$release_file"
diff --git a/bin/install b/bin/install
index 9737a63..6ca759a 100755
--- a/bin/install
+++ b/bin/install
@@ -5,7 +5,7 @@ set -euo pipefail
current_script_path=${BASH_SOURCE[0]}
plugin_dir=$(dirname "$(dirname "$current_script_path")")
-# shellcheck source=../lib/utils.bash
+# shellcheck source=./lib/utils.bash
source "${plugin_dir}/lib/utils.bash"
install_version "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH"
diff --git a/bin/latest-stable b/bin/latest-stable
new file mode 100755
index 0000000..818f26e
--- /dev/null
+++ b/bin/latest-stable
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+current_script_path=${BASH_SOURCE[0]}
+plugin_dir=$(dirname "$(dirname "$current_script_path")")
+
+# shellcheck source=./lib/utils.bash
+. "${plugin_dir}/lib/utils.bash"
+
+curl_opts=(-sI)
+
+if [ -n "${GITHUB_API_TOKEN:-}" ]; then
+ curl_opts=("${curl_opts[@]}" -H "Authorization: token $GITHUB_API_TOKEN")
+fi
+
+# curl of REPO/releases/latest is expected to be a 302 to another URL
+# when no releases redirect_url="REPO/releases"
+# when there are releases redirect_url="REPO/releases/tag/v"
+redirect_url=$(curl "${curl_opts[@]}" "$GH_REPO/releases/latest" | sed -n -e "s|^location: *||p" | sed -n -e "s|\r||p")
+version=
+printf "redirect url: %s\n" "$redirect_url" >&2
+if [[ "$redirect_url" == "$GH_REPO/releases" ]]; then
+ version="$(list_all_versions | sort_versions | tail -n1 | xargs echo)"
+else
+ version="$(printf "%s\n" "$redirect_url" | sed 's|.*/tag/v\{0,1\}||')"
+fi
+
+printf "%s\n" "$version"
diff --git a/bin/list-all b/bin/list-all
index 943371e..9b8b666 100755
--- a/bin/list-all
+++ b/bin/list-all
@@ -5,7 +5,7 @@ set -euo pipefail
current_script_path=${BASH_SOURCE[0]}
plugin_dir=$(dirname "$(dirname "$current_script_path")")
-# shellcheck source=../lib/utils.bash
+# shellcheck source=./lib/utils.bash
source "${plugin_dir}/lib/utils.bash"
list_all_versions | sort_versions | xargs echo
diff --git a/lib/utils.bash b/lib/utils.bash
index 22a58d5..a9c40c1 100644
--- a/lib/utils.bash
+++ b/lib/utils.bash
@@ -4,69 +4,85 @@ set -euo pipefail
GH_REPO="https://github.com/geofffranks/spruce"
TOOL_NAME="spruce"
-TOOL_TEST="--version"
+TOOL_TEST="${TOOL_NAME} --version"
fail() {
- echo -e "asdf-$TOOL_NAME: $*"
- exit 1
+ echo -e "asdf-$TOOL_NAME: $*"
+ exit 1
}
curl_opts=(-fsSL)
# NOTE: You might want to remove this if spruce is not hosted on GitHub releases.
if [ -n "${GITHUB_API_TOKEN:-}" ]; then
- curl_opts=("${curl_opts[@]}" -H "Authorization: token $GITHUB_API_TOKEN")
+ curl_opts=("${curl_opts[@]}" -H "Authorization: token $GITHUB_API_TOKEN")
fi
sort_versions() {
- sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' |
- LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
+ sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' |
+ LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
}
list_github_tags() {
- git ls-remote --tags --refs "$GH_REPO" |
- grep -o 'refs/tags/.*' | cut -d/ -f3- |
- sed 's/^v//' # NOTE: You might want to adapt this sed to remove non-version strings from tags
+ git ls-remote --tags --refs "$GH_REPO" |
+ grep -o 'refs/tags/.*' | cut -d/ -f3- |
+ sed 's/^v//' # NOTE: You might want to adapt this sed to remove non-version strings from tags
}
list_all_versions() {
- list_github_tags
+ # TODO: Adapt this. By default we simply list the tag names from GitHub releases.
+ # Change this function if spruce has other means of determining installable versions.
+ list_github_tags
}
download_release() {
- local version filename url
- version="$1"
- filename="$2"
- platform="$(uname | tr '[:upper:]' '[:lower:]')"
-
- # Adapt the release URL convention for spruce
- # https://github.com/geofffranks/spruce/releases/download/v1.27.0/spruce-darwin-amd64
- url="$GH_REPO/releases/download/v${version}/${TOOL_NAME}-${platform}-amd64"
-
- echo "* Downloading $TOOL_NAME release $version..."
- curl "${curl_opts[@]}" -o "$filename" -C - "$url" || fail "Could not download $url"
- chmod a+x "$filename"
+ local version filename url
+ version="$1"
+ filename="$2"
+
+ local platform architecture
+
+ case "$OSTYPE" in
+ darwin*) platform="darwin" ;;
+ linux*) platform="linux" ;;
+ *) fail "Unsupported platform" ;;
+ esac
+
+ case "$(uname -m)" in
+ aarch64* | arm64) architecture="arm64" ;;
+ x86_64*) architecture="amd64" ;;
+ *) fail "Unsupported architecture" ;;
+ esac
+
+ # Adapt the release URL convention for spruce
+ # https://github.com/geofffranks/spruce/releases/download/v1.27.0/spruce-darwin-amd64
+ url="$GH_REPO/releases/download/v${version}/${TOOL_NAME}-${platform}-${architecture}"
+
+ echo "* Downloading $TOOL_NAME release $version for ${platform}-${architecture}..."
+ curl "${curl_opts[@]}" -o "$filename" -C - "$url" || fail "Could not download $url"
}
install_version() {
- local install_type="$1"
- local version="$2"
- local install_path="$3"
-
- if [ "$install_type" != "version" ]; then
- fail "asdf-$TOOL_NAME supports release installs only"
- fi
-
- (
- mkdir -p "$install_path"/bin
- cp -pr "$ASDF_DOWNLOAD_PATH"/* "$install_path"/bin/
-
- test -x "$install_path/bin/$TOOL_NAME" || fail "Expected $install_path/bin/$TOOL_NAME to be executable."
- tool_version=$("$install_path"/bin/$TOOL_NAME $TOOL_TEST) && test "${tool_version##*\ }" = "v${version}" || fail "Expected $install_path/bin/$TOOL_NAME to be version v${version} but got ${tool_version##*\ }."
-
- echo "$TOOL_NAME $version installation was successful!"
- ) || (
- rm -rf "$install_path"
- fail "An error ocurred while installing $TOOL_NAME $version."
- )
+ local install_type="$1"
+ local version="$2"
+ local install_path="${3%/bin}/bin"
+
+ if [ "$install_type" != "version" ]; then
+ fail "asdf-$TOOL_NAME supports release installs only"
+ fi
+
+ (
+ mkdir -p "$install_path"
+ cp -r "$ASDF_DOWNLOAD_PATH"/* "$install_path"
+
+ # TODO: Assert spruce executable exists.
+ local tool_cmd
+ tool_cmd="$(echo "$TOOL_TEST" | cut -d' ' -f1)"
+ test -x "$install_path/$tool_cmd" || fail "Expected $install_path/$tool_cmd to be executable."
+
+ echo "$TOOL_NAME $version installation was successful!"
+ ) || (
+ rm -rf "$install_path"
+ fail "An error occurred while installing $TOOL_NAME $version."
+ )
}
diff --git a/renovate.json b/renovate.json
deleted file mode 100644
index 1b889e9..0000000
--- a/renovate.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": ["local>woneill/.github:renovate-config"]
-}
diff --git a/scripts/format.bash b/scripts/format.bash
new file mode 100755
index 0000000..1a216ea
--- /dev/null
+++ b/scripts/format.bash
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+shfmt --language-dialect bash --write \
+ ./**/*
diff --git a/scripts/lint.bash b/scripts/lint.bash
new file mode 100755
index 0000000..3451a05
--- /dev/null
+++ b/scripts/lint.bash
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+shellcheck --shell=bash --external-sources \
+ bin/* --source-path=template/lib/ \
+ lib/* \
+ scripts/*
+
+shfmt --language-dialect bash --diff \
+ ./**/*
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..e69de29