diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9f48fab --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..83f93ac --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: bug +assignees: "" +--- + +**Describe the bug** + + + +**Steps to reproduce** + + + +**Expected behavior** + + + +**Screenshots** + + + +**Additional context** + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..f52b3b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: enhancement +assignees: "" +--- + +**Is your feature request related to a problem? Please describe.** + + + +**Describe the solution you'd like** + + + +**Describe alternatives you've considered** + + + +**Additional context** + + diff --git a/.github/PULL_REQUEST/pull_request_template.md b/.github/PULL_REQUEST/pull_request_template.md new file mode 100644 index 0000000..6d98686 --- /dev/null +++ b/.github/PULL_REQUEST/pull_request_template.md @@ -0,0 +1,34 @@ + + +## Description + + + +## Motivation and Context + + + + +## Types of changes + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Usage examples + + + +## How Has This Been Tested? + + + +## Checklist: + + + + +- [ ] I have updated the documentation accordingly. +- [ ] I have added tests to cover my changes. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1489633 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + # dependabot for GitHub Actions for this repo + - package-ecosystem: "github-actions" + directory: "./github" + schedule: + interval: "weekly" + # dependabot for GitHub Actions for the template + - package-ecosystem: "github-actions" + directory: "template/.github/" + schedule: + interval: "weekly" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..cd79368 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,47 @@ +name: Build + +on: + push: + branches: + - main + pull_request: + +jobs: + test: + name: template setup test + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Run Template Setup + run: | + git config user.name "Foo Bearer" + ./setup.bash \ + "asdf-foo" \ + "foo --help" \ + "asdf-community" \ + "ASDF Community" \ + "https://github.com/asdf-vm/asdf" \ + "https://asdf-vm.com" \ + "Apache-2.0" \ + "yes" + + - name: Check setup result + run: | + set -xe + ls -la . + git log + test ! -d template/ + grep "Apache" LICENSE + test "main" = "$(git rev-parse --abbrev-ref HEAD)" + ! git grep -F -e "" \ + --or -e "" \ + --or -e "" \ + --or -e "" \ + --or -e "" \ + --or -e"" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..5c3ffed --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,24 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - 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/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/.tool-versions b/.tool-versions new file mode 100644 index 0000000..3d11f88 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +shellcheck 0.9.0 +shfmt 3.6.0 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0d6f2e1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 The asdf-vm core AUTHORS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3904d04 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# asdf-plugin-template [![Build](https://github.com/asdf-vm/asdf-plugin-template/actions/workflows/build.yml/badge.svg)](https://github.com/asdf-vm/asdf-plugin-template/actions/workflows/build.yml) [![Lint](https://github.com/asdf-vm/asdf-plugin-template/actions/workflows/lint.yml/badge.svg)](https://github.com/asdf-vm/asdf-plugin-template/actions/workflows/lint.yml) + +This is an [asdf-vm plugin](https://asdf-vm.com/#/plugins-create) template with CI to run [Shellcheck](https://github.com/koalaman/shellcheck) and testing with the [asdf test GitHub Action](https://github.com/asdf-vm/actions). +## Usage + +1. [Generate](https://github.com/asdf-vm/asdf-plugin-template/generate) a new repository based on this template. +1. Clone it and run `bash setup.bash`. +1. Force push to your repo: `git push --force-with-lease`. +1. Adapt your code at the TODO markers. To find the markers: `git grep TODO`. +1. To develop your plugin further, please read [the plugins create section of the docs](https://asdf-vm.com/plugins/create.html). + +>A feature of this plugin-template when hosted on GitHub is the use of [release-please](https://github.com/googleapis/release-please), an automated release tool. It leverages [Conventional Commit messages](https://www.conventionalcommits.org/) to determine semver release type, see the [documentation](https://github.com/googleapis/release-please). + +## Contributing + +Contributions welcome! + +1. Install `asdf` tools + ```shell + asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git + asdf plugin add shfmt https://github.com/luizm/asdf-shfmt.git + asdf install + ``` +1. Develop! +1. Lint & Format + ```shell + ./scripts/format.bash + ./scripts/lint.bash + ``` +1. PR changes diff --git a/scripts/format.bash b/scripts/format.bash new file mode 100755 index 0000000..bbeed6c --- /dev/null +++ b/scripts/format.bash @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# format this repo +shfmt --language-dialect bash --write \ + setup.bash \ + scripts/*.bash + +# format the template/ +shfmt --language-dialect bash --write \ + template/**/* diff --git a/scripts/lint.bash b/scripts/lint.bash new file mode 100755 index 0000000..fbd0c5c --- /dev/null +++ b/scripts/lint.bash @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# lint this repo +shellcheck --shell=bash --external-sources \ + setup.bash \ + scripts/* + +shfmt --language-dialect bash --diff \ + setup.bash \ + scripts/* + +# lint the template/ +shellcheck --shell=bash --external-sources \ + template/bin/* --source-path=template/lib/ \ + template/lib/* \ + template/scripts/* + +shfmt --language-dialect bash --diff \ + template/**/* diff --git a/setup.bash b/setup.bash new file mode 100755 index 0000000..7d5ab70 --- /dev/null +++ b/setup.bash @@ -0,0 +1,314 @@ +#!/usr/bin/env bash + +set -euo pipefail + +HELP=" +Usage: + +bash [--github | --gitlab] $0 PLUGIN_NAME TOOL_TEST GH_USER AUTHOR_NAME TOOL_GH TOOL_PAGE LICENSE + +All arguments are optional and will be interactively prompted when not given. + +PLUGIN_NAME. + A name for your new plugin always starting with \`asdf-\` prefix. + +TOOL_TEST. + A shell command used to test correct installation. + Normally this command is something taking \`--version\` or \`--help\`. + +GH_USER. + Your GitHub/GitLab username. + +AUTHOR_NAME. + Your name, used for licensing. + +TOOL_GH. + The tool's GitHub homepage. Default installation process will try to use + this to access GitHub releases. + +TOOL_PAGE. + Documentation site for tool usage, mostly informative for users. + +LICENSE. + A license keyword. + https://help.github.com/en/github/creating-cloning-and-archiving-repositories/licensing-a-repository#searching-github-by-license-type +" +HELP_PLUGIN_NAME="Name for your plugin, starting with \`asdf-\`, eg. \`asdf-foo\`" +HELP_TOOL_CHECK="Shell command for testing correct tool installation. eg. \`foo --version\` or \`foo --help\`" +HELP_TOOL_REPO="The tool's GitHub homepage." +HELP_TOOL_HOMEPAGE="The tool's documentation homepage if necessary." + +ask_for() { + local prompt="$1" + local default_value="${2:-}" + local alternatives="${3:-"[$default_value]"}" + local value="" + + while [ -z "$value" ]; do + echo "$prompt" >&2 + if [ "[]" != "$alternatives" ]; then + echo -n "$alternatives " >&2 + fi + echo -n "> " >&2 + read -r value + echo >&2 + if [ -z "$value" ] && [ -n "$default_value" ]; then + value="$default_value" + fi + done + + printf "%s\n" "$value" +} + +download_license() { + local keyword file + keyword="$1" + file="$2" + + curl -qsL "https://raw.githubusercontent.com/github/choosealicense.com/gh-pages/_licenses/${keyword}.txt" | + extract_license >"$file" +} + +extract_license() { + awk '/^---/{f=1+f} f==2 && /^$/ {f=3} f==3' +} + +test_url() { + curl -fqsL -I "$1" | head -n 1 | grep 200 >/dev/null +} + +ask_license() { + local license keyword + + printf "%s\n" "Please choose a LICENSE keyword." >&2 + printf "%s\n" "See available license keywords at" >&2 + printf "%s\n" "https://help.github.com/en/github/creating-cloning-and-archiving-repositories/licensing-a-repository#searching-github-by-license-type" >&2 + + while true; do + license="$(ask_for "License keyword:" "apache-2.0" "mit/[apache-2.0]/agpl-3.0/unlicense")" + keyword=$(echo "$license" | tr '[:upper:]' '[:lower:]') + + url="https://choosealicense.com/licenses/$keyword/" + if test_url "$url"; then + break + else + printf "Invalid license keyword: %s\n" "$license" + fi + done + + printf "%s\n" "$keyword" +} + +set_placeholder() { + local name value out file tmpfile + name="$1" + value="$2" + out="$3" + + git grep -P -l -F --untracked "$name" -- "$out" | + while IFS=$'\n' read -r file; do + tmpfile="$file.sed" + sed "s#$name#$value#g" "$file" >"$tmpfile" && mv "$tmpfile" "$file" + done +} + +setup_github() { + local cwd out tool_name tool_repo check_command author_name github_username tool_homepage ok primary_branch + + cwd="$PWD" + out="$cwd/out" + + # ask for arguments not given via CLI + tool_name="${1:-$(ask_for "$HELP_PLUGIN_NAME")}" + tool_name="${tool_name/asdf-/}" + check_command="${2:-$(ask_for "$HELP_TOOL_CHECK" "$tool_name --help")}" + + github_username="${3:-$(ask_for "Your GitHub username")}" + author_name="${4:-$(ask_for "Your name" "$(git config user.name 2>/dev/null)")}" + + tool_repo="${5:-$(ask_for "$HELP_TOOL_REPO" "https://github.com/$github_username/$tool_name")}" + tool_homepage="${6:-$(ask_for "$HELP_TOOL_HOMEPAGE" "$tool_repo")}" + license_keyword="${7:-$(ask_license)}" + license_keyword="$(echo "$license_keyword" | tr '[:upper:]' '[:lower:]')" + + primary_branch="main" + + cat <<-EOF + Setting up plugin: asdf-$tool_name + + author: $author_name + plugin repo: https://github.com/$github_username/asdf-$tool_name + license: https://choosealicense.com/licenses/$license_keyword/ + + + $tool_name github: $tool_repo + $tool_name docs: $tool_homepage + $tool_name test: \`$check_command\` + + After confirmation, the \`$primary_branch\` will be replaced with the generated + template using the above information. Please ensure all seems correct. + EOF + + ok="${8:-$(ask_for "Type \`yes\` if you want to continue.")}" + if [ "yes" != "$ok" ]; then + printf "Nothing done.\n" + else + ( + set -e + # previous cleanup to ensure we can run this program many times + git branch template 2>/dev/null || true + git checkout -f template + git worktree remove -f out 2>/dev/null || true + git branch -D out 2>/dev/null || true + + # checkout a new worktree and replace placeholders there + git worktree add --detach out + + cd "$out" + git checkout --orphan out + git rm -rf "$out" >/dev/null + git read-tree --prefix="" -u template:template/ + + download_license "$license_keyword" "$out/LICENSE" + sed -i '1s;^;TODO: INSERT YOUR NAME & COPYRIGHT YEAR\n;g' "$out/LICENSE" + + set_placeholder "" "$tool_name" "$out" + set_placeholder "" "$tool_homepage" "$out" + set_placeholder "" "$tool_repo" "$out" + set_placeholder "" "$check_command" "$out" + set_placeholder "" "$author_name" "$out" + set_placeholder "" "$github_username" "$out" + set_placeholder "" "$primary_branch" "$out" + + git add "$out" + # remove GitLab specific files + git rm -rf "$out/.gitlab" "$out/.gitlab-ci.yml" "$out/README-gitlab.md" "$out/contributing-gitlab.md" + # rename GitHub specific files to final filenames + git mv "$out/README-github.md" "$out/README.md" + git mv "$out/contributing-github.md" "$out/contributing.md" + git commit -m "Generate asdf-$tool_name plugin from template." + + cd "$cwd" + git branch -M out "$primary_branch" + git worktree remove -f out + git checkout -f "$primary_branch" + + printf "All done.\n" + printf "Your %s branch has been reset to an initial commit.\n" "$primary_branch" + printf "Push to origin/%s with \`git push --force-with-lease\`\n" "$primary_branch" + + printf "Review these TODO items:\n" + git grep -P -n -C 3 "TODO" + ) || cd "$cwd" + fi +} + +setup_gitlab() { + local cwd out tool_name tool_repo check_command author_name github_username gitlab_username tool_homepage ok primary_branch + + cwd="$PWD" + out="$cwd/out" + + # ask for arguments not given via CLI + tool_name="${1:-$(ask_for "$HELP_PLUGIN_NAME")}" + tool_name="${tool_name/asdf-/}" + check_command="${2:-$(ask_for "$HELP_TOOL_CHECK" "$tool_name --help")}" + + gitlab_username="$(ask_for "Your GitLab username")" + author_name="${4:-$(ask_for "Your name" "$(git config user.name 2>/dev/null)")}" + + github_username="${3:-$(ask_for "Tool GitHub username")}" + tool_repo="${5:-$(ask_for "$HELP_TOOL_REPO" "https://github.com/$github_username/$tool_name")}" + tool_homepage="${6:-$(ask_for "$HELP_TOOL_HOMEPAGE" "$tool_repo")}" + license_keyword="${7:-$(ask_license)}" + license_keyword="$(echo "$license_keyword" | tr '[:upper:]' '[:lower:]')" + + primary_branch="main" + + cat <<-EOF + Setting up plugin: asdf-$tool_name + + author: $author_name + plugin repo: https://gitlab.com/$gitlab_username/asdf-$tool_name + license: https://choosealicense.com/licenses/$license_keyword/ + + + $tool_name github: $tool_repo + $tool_name docs: $tool_homepage + $tool_name test: \`$check_command\` + + After confirmation, the \`$primary_branch\` will be replaced with the generated + template using the above information. Please ensure all seems correct. + EOF + + ok="${8:-$(ask_for "Type \`yes\` if you want to continue.")}" + if [ "yes" != "$ok" ]; then + printf "Nothing done.\n" + else + ( + set -e + # previous cleanup to ensure we can run this program many times + git branch template 2>/dev/null || true + git checkout -f template + git worktree remove -f out 2>/dev/null || true + git branch -D out 2>/dev/null || true + + # checkout a new worktree and replace placeholders there + git worktree add --detach out + + cd "$out" + git checkout --orphan out + git rm -rf "$out" >/dev/null + git read-tree --prefix=/ -u template:template/ + + download_license "$license_keyword" "$out/LICENSE" + + set_placeholder "" "$tool_name" "$out" + set_placeholder "" "$tool_homepage" "$out" + set_placeholder "" "$tool_repo" "$out" + set_placeholder "" "$check_command" "$out" + set_placeholder "" "$author_name" "$out" + set_placeholder "" "$github_username" "$out" + set_placeholder "" "$gitlab_username" "$out" + set_placeholder "" "$primary_branch" "$out" + + git add "$out" + # remove GitHub specific files + git rm -rf "$out/.github" "$out/README-github.md" "$out/contributing-github.md" + # rename GitLab specific files to final filenames + git mv "$out/README-gitlab.md" "$out/README.md" + git mv "$out/contributing-gitlab.md" "$out/contributing.md" + git commit -m "Generate asdf-$tool_name plugin from template." + + cd "$cwd" + git branch -M out "$primary_branch" + git worktree remove -f out + git checkout -f "$primary_branch" + + printf "All done.\n" + printf "Your %s branch has been reset to an initial commit.\n" "$primary_branch" + printf "You might want to push using \`--force-with-lease\` to origin/%s\n" "$primary_branch" + + printf "Showing pending TODO tags that you might want to review\n" + git grep -P -n -C 3 "TODO" + ) || cd "$cwd" + fi +} + +case "${1:-}" in +"-h" | "--help" | "help") + printf "%s\n" "$HELP" + exit 0 + ;; +"--gitlab") + shift + setup_gitlab "$@" + ;; +"--github") + shift + setup_github "$@" + ;; +*) + setup_github "$@" + ;; +esac diff --git a/template/.editorconfig b/template/.editorconfig new file mode 100644 index 0000000..9f48fab --- /dev/null +++ b/template/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/template/.github/ISSUE_TEMPLATE/bug_report.md b/template/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..83f93ac --- /dev/null +++ b/template/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: bug +assignees: "" +--- + +**Describe the bug** + + + +**Steps to reproduce** + + + +**Expected behavior** + + + +**Screenshots** + + + +**Additional context** + + diff --git a/template/.github/ISSUE_TEMPLATE/feature_request.md b/template/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..f52b3b9 --- /dev/null +++ b/template/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: enhancement +assignees: "" +--- + +**Is your feature request related to a problem? Please describe.** + + + +**Describe the solution you'd like** + + + +**Describe alternatives you've considered** + + + +**Additional context** + + diff --git a/template/.github/PULL_REQUEST/pull_request_template.md b/template/.github/PULL_REQUEST/pull_request_template.md new file mode 100644 index 0000000..6d98686 --- /dev/null +++ b/template/.github/PULL_REQUEST/pull_request_template.md @@ -0,0 +1,34 @@ + + +## Description + + + +## Motivation and Context + + + + +## Types of changes + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Usage examples + + + +## How Has This Been Tested? + + + +## Checklist: + + + + +- [ ] I have updated the documentation accordingly. +- [ ] I have added tests to cover my changes. diff --git a/template/.github/dependabot.yml b/template/.github/dependabot.yml new file mode 100644 index 0000000..9227877 --- /dev/null +++ b/template/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "./github" + schedule: + interval: "weekly" diff --git a/template/.github/workflows/build.yml b/template/.github/workflows/build.yml new file mode 100644 index 0000000..d58fe52 --- /dev/null +++ b/template/.github/workflows/build.yml @@ -0,0 +1,22 @@ +name: Build + +on: + push: + branches: + - main + pull_request: + +jobs: + plugin_test: + name: asdf plugin test + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + runs-on: ${{ matrix.os }} + steps: + - name: asdf_plugin_test + uses: asdf-vm/actions/plugin-test@v2 + with: + command: diff --git a/template/.github/workflows/lint.yml b/template/.github/workflows/lint.yml new file mode 100644 index 0000000..5c3ffed --- /dev/null +++ b/template/.github/workflows/lint.yml @@ -0,0 +1,24 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - 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/template/.github/workflows/release.yml b/template/.github/workflows/release.yml new file mode 100644 index 0000000..454ce7a --- /dev/null +++ b/template/.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/template/.github/workflows/semantic-pr.yml b/template/.github/workflows/semantic-pr.yml new file mode 100644 index 0000000..8b26fa4 --- /dev/null +++ b/template/.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/template/.gitlab-ci.yml b/template/.gitlab-ci.yml new file mode 100644 index 0000000..dc3617c --- /dev/null +++ b/template/.gitlab-ci.yml @@ -0,0 +1,30 @@ +image: debian:10 + +stages: + - lint + - test + +variables: + PLUGIN_NAME: asdf- + TOOL_CHECK: + SHELLCHECK_VERSION: stable + +asdf-plugin-lint: + stage: lint + before_script: + - apt update && apt install -y xz-utils wget + - wget -qO- https://github.com/koalaman/shellcheck/releases/download/$SHELLCHECK_VERSION/shellcheck-$SHELLCHECK_VERSION.linux.x86_64.tar.xz | tar xJv + - cp shellcheck-$SHELLCHECK_VERSION/shellcheck /usr/bin + script: + - shellcheck -x bin/* -P lib/ + +asdf-plugin-test: + stage: test + before_script: + - apt update && apt install -y git curl bsdmainutils file + - git clone https://github.com/asdf-vm/asdf.git + - . asdf/asdf.sh + script: + - asdf plugin-add $PLUGIN_NAME $CI_REPOSITORY_URL + - asdf list-all $PLUGIN_NAME + - asdf plugin test $PLUGIN_NAME $CI_REPOSITORY_URL --asdf-plugin-gitref $CI_COMMIT_REF_NAME "$TOOL_CHECK" || exit 1 diff --git a/template/.gitlab/issue_templates/Bug_Report.md b/template/.gitlab/issue_templates/Bug_Report.md new file mode 100644 index 0000000..c42f6c9 --- /dev/null +++ b/template/.gitlab/issue_templates/Bug_Report.md @@ -0,0 +1,21 @@ +## Describe the bug + + + +## Steps to reproduce + + + +## Expected behavior + + + +## Screenshots + + + +## Additional context + + + +/label ~bug diff --git a/template/.gitlab/issue_templates/Feature_Request.md b/template/.gitlab/issue_templates/Feature_Request.md new file mode 100644 index 0000000..759f534 --- /dev/null +++ b/template/.gitlab/issue_templates/Feature_Request.md @@ -0,0 +1,18 @@ +## Feature description + +- [ ] Is this feature the result of a problem? + + +## Desired solution + + + +## Alternatives considered + + + +## Additional context + + + +/label ~"feature request" diff --git a/template/.gitlab/merge_request_templates/Merge_Request.md b/template/.gitlab/merge_request_templates/Merge_Request.md new file mode 100644 index 0000000..6d98686 --- /dev/null +++ b/template/.gitlab/merge_request_templates/Merge_Request.md @@ -0,0 +1,34 @@ + + +## Description + + + +## Motivation and Context + + + + +## Types of changes + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Usage examples + + + +## How Has This Been Tested? + + + +## Checklist: + + + + +- [ ] I have updated the documentation accordingly. +- [ ] I have added tests to cover my changes. diff --git a/template/.tool-versions b/template/.tool-versions new file mode 100644 index 0000000..3d11f88 --- /dev/null +++ b/template/.tool-versions @@ -0,0 +1,2 @@ +shellcheck 0.9.0 +shfmt 3.6.0 diff --git a/template/README-github.md b/template/README-github.md new file mode 100644 index 0000000..16c03e3 --- /dev/null +++ b/template/README-github.md @@ -0,0 +1,61 @@ +
+ +# asdf- [![Build](https://github.com//asdf-/actions/workflows/build.yml/badge.svg)](https://github.com//asdf-/actions/workflows/build.yml) [![Lint](https://github.com//asdf-/actions/workflows/lint.yml/badge.svg)](https://github.com//asdf-/actions/workflows/lint.yml) + + +[]() plugin for the [asdf version manager](https://asdf-vm.com). + +
+ +# Contents + +- [Dependencies](#dependencies) +- [Install](#install) +- [Contributing](#contributing) +- [License](#license) + +# Dependencies + +**TODO: adapt this section** + +- `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. + +# Install + +Plugin: + +```shell +asdf plugin add +# or +asdf plugin add https://github.com//asdf-.git +``` + +: + +```shell +# Show all installable versions +asdf list-all + +# Install specific version +asdf install latest + +# Set a version globally (on your ~/.tool-versions file) +asdf global latest + +# Now commands are available + +``` + +Check [asdf](https://github.com/asdf-vm/asdf) readme for more instructions on how to +install & manage versions. + +# Contributing + +Contributions of any kind welcome! See the [contributing guide](contributing.md). + +[Thanks goes to these contributors](https://github.com//asdf-/graphs/contributors)! + +# License + +See [LICENSE](LICENSE) © [](https://github.com//) diff --git a/template/README-gitlab.md b/template/README-gitlab.md new file mode 100644 index 0000000..cccacc6 --- /dev/null +++ b/template/README-gitlab.md @@ -0,0 +1,60 @@ +
+ +# asdf- ![Build Status](https://gitlab.com//asdf-/badges//pipeline.svg) + +[]() plugin for the [asdf version manager](https://asdf-vm.com). + +
+ +# Contents + +- [Dependencies](#dependencies) +- [Install](#install) +- [Contributing](#contributing) +- [License](#license) + +# Dependencies + +**TODO: adapt this section** + +- `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. + +# Install + +Plugin: + +```shell +asdf plugin add +# or +asdf plugin add https://gitlab.com//asdf-.git +``` + +: + +```shell +# Show all installable versions +asdf list-all + +# Install specific version +asdf install latest + +# Set a version globally (on your ~/.tool-versions file) +asdf global latest + +# Now commands are available + +``` + +Check [asdf](https://github.com/asdf-vm/asdf) readme for more instructions on how to +install & manage versions. + +# Contributing + +Contributions of any kind welcome! See the [contributing guide](contributing.md). + +[Thanks goes to these contributors](https://gitlab.com//asdf-/-/graphs/)! + +# License + +See [LICENSE](LICENSE) © [](https://gitlab.com//) diff --git a/template/bin/download b/template/bin/download new file mode 100755 index 0000000..b104db2 --- /dev/null +++ b/template/bin/download @@ -0,0 +1,23 @@ +#!/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 +source "${plugin_dir}/lib/utils.bash" + +mkdir -p "$ASDF_DOWNLOAD_PATH" + +# TODO: Adapt this to proper extension and adapt extracting strategy. +release_file="$ASDF_DOWNLOAD_PATH/$TOOL_NAME-$ASDF_INSTALL_VERSION.tar.gz" + +# Download tar.gz file to the download directory +download_release "$ASDF_INSTALL_VERSION" "$release_file" + +# Extract contents of tar.gz file into the download directory +tar -xzf "$release_file" -C "$ASDF_DOWNLOAD_PATH" --strip-components=1 || fail "Could not extract $release_file" + +# Remove the tar.gz file since we don't need to keep it +rm "$release_file" diff --git a/template/bin/install b/template/bin/install new file mode 100755 index 0000000..9737a63 --- /dev/null +++ b/template/bin/install @@ -0,0 +1,11 @@ +#!/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 +source "${plugin_dir}/lib/utils.bash" + +install_version "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH" diff --git a/template/bin/latest-stable b/template/bin/latest-stable new file mode 100755 index 0000000..dd01f31 --- /dev/null +++ b/template/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 | xargs echo | tail -n1)" +else + version="$(printf "%s\n" "$redirect_url" | sed 's|.*/tag/v\{0,1\}||')" +fi + +printf "%s\n" "$version" diff --git a/template/bin/list-all b/template/bin/list-all new file mode 100755 index 0000000..943371e --- /dev/null +++ b/template/bin/list-all @@ -0,0 +1,11 @@ +#!/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 +source "${plugin_dir}/lib/utils.bash" + +list_all_versions | sort_versions | xargs echo diff --git a/template/contributing-github.md b/template/contributing-github.md new file mode 100644 index 0000000..3f70c86 --- /dev/null +++ b/template/contributing-github.md @@ -0,0 +1,12 @@ +# Contributing + +Testing Locally: + +```shell +asdf plugin test [--asdf-tool-version ] [--asdf-plugin-gitref ] [test-command*] + +# +asdf plugin test https://github.com//asdf-.git "" +``` + +Tests are automatically run in GitHub Actions on push and PR. diff --git a/template/contributing-gitlab.md b/template/contributing-gitlab.md new file mode 100644 index 0000000..08a7999 --- /dev/null +++ b/template/contributing-gitlab.md @@ -0,0 +1,12 @@ +# Contributing + +Testing Locally: + +```shell +asdf plugin test [--asdf-tool-version ] [--asdf-plugin-gitref ] [test-command*] + +# +asdf plugin test https://gitlab.com//asdf-.git "" +``` + +Tests are automatically run in GitLab CI on push and merge request. diff --git a/template/lib/utils.bash b/template/lib/utils.bash new file mode 100755 index 0000000..887708c --- /dev/null +++ b/template/lib/utils.bash @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# TODO: Ensure this is the correct GitHub homepage where releases can be downloaded for . +GH_REPO="" +TOOL_NAME="" +TOOL_TEST="" + +fail() { + echo -e "asdf-$TOOL_NAME: $*" + exit 1 +} + +curl_opts=(-fsSL) + +# NOTE: You might want to remove this if is not hosted on GitHub releases. +if [ -n "${GITHUB_API_TOKEN:-}" ]; then + 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}' +} + +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 +} + +list_all_versions() { + # TODO: Adapt this. By default we simply list the tag names from GitHub releases. + # Change this function if has other means of determining installable versions. + list_github_tags +} + +download_release() { + local version filename url + version="$1" + filename="$2" + + # TODO: Adapt the release URL convention for + url="$GH_REPO/archive/v${version}.tar.gz" + + echo "* Downloading $TOOL_NAME release $version..." + 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%/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 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/template/scripts/format.bash b/template/scripts/format.bash new file mode 100755 index 0000000..1a216ea --- /dev/null +++ b/template/scripts/format.bash @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +shfmt --language-dialect bash --write \ + ./**/* diff --git a/template/scripts/lint.bash b/template/scripts/lint.bash new file mode 100755 index 0000000..3451a05 --- /dev/null +++ b/template/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/template/version.txt b/template/version.txt new file mode 100644 index 0000000..e69de29