diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..16bec6a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+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/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..a32de42
--- /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..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
new file mode 100644
index 0000000..476fe90
--- /dev/null
+++ b/.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: fluttergen -v
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/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/.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..02bc034
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+
+MIT License
+
+Copyright (c) [year] [fullname]
+
+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..99e50d8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,60 @@
+
+
+# asdf-fluttergen [![Build](https://github.com/FlutterGen/asdf-fluttergen/actions/workflows/build.yml/badge.svg)](https://github.com/FlutterGen/asdf-fluttergen/actions/workflows/build.yml) [![Lint](https://github.com/FlutterGen/asdf-fluttergen/actions/workflows/lint.yml/badge.svg)](https://github.com/FlutterGen/asdf-fluttergen/actions/workflows/lint.yml)
+
+[fluttergen](https://github.com/FlutterGen/flutter_gen) 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`, and [POSIX utilities](https://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html).
+- `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 fluttergen
+# or
+asdf plugin add fluttergen https://github.com/FlutterGen/asdf-fluttergen.git
+```
+
+fluttergen:
+
+```shell
+# Show all installable versions
+asdf list-all fluttergen
+
+# Install specific version
+asdf install fluttergen latest
+
+# Set a version globally (on your ~/.tool-versions file)
+asdf global fluttergen latest
+
+# Now fluttergen commands are available
+fluttergen -v
+```
+
+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/FlutterGen/asdf-fluttergen/graphs/contributors)!
+
+# License
+
+See [LICENSE](LICENSE) © [FlutterGen](https://github.com/FlutterGen/)
diff --git a/bin/download b/bin/download
new file mode 100755
index 0000000..c11ee53
--- /dev/null
+++ b/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/bin/install b/bin/install
new file mode 100755
index 0000000..6ca759a
--- /dev/null
+++ b/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/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
new file mode 100755
index 0000000..9b8b666
--- /dev/null
+++ b/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/contributing.md b/contributing.md
new file mode 100644
index 0000000..7f1cd2d
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,12 @@
+# Contributing
+
+Testing Locally:
+
+```shell
+asdf plugin test [--asdf-tool-version ] [--asdf-plugin-gitref ] [test-command*]
+
+# TODO: adapt this
+asdf plugin test fluttergen https://github.com/FlutterGen/asdf-fluttergen.git "fluttergen -v"
+```
+
+Tests are automatically run in GitHub Actions on push and PR.
diff --git a/lib/utils.bash b/lib/utils.bash
new file mode 100644
index 0000000..08751fc
--- /dev/null
+++ b/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 fluttergen.
+GH_REPO="https://github.com/FlutterGen/flutter_gen"
+TOOL_NAME="fluttergen"
+TOOL_TEST="fluttergen -v"
+
+fail() {
+ echo -e "asdf-$TOOL_NAME: $*"
+ exit 1
+}
+
+curl_opts=(-fsSL)
+
+# NOTE: You might want to remove this if fluttergen 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 fluttergen 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 fluttergen
+ 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 fluttergen 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/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