diff --git a/README.md b/README.md
index 85d4ac3..cf194cb 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,11 @@
[](https://github.com/smashedr/install-release/pkgs/container/install-release)
[](https://github.com/smashedr/install-release/blob/master/go.mod)
[](https://github.com/smashedr/install-release/deployments/docs)
-[](https://github.com/smashedr/install-release/deployments/preview)
-[](https://github.com/smashedr/install-release/actions/workflows/release.yaml)
-[](https://github.com/smashedr/install-release/actions/workflows/lint.yaml)
+[](https://github.com/smashedr/install-release/deployments/preview)
+[](https://github.com/smashedr/install-release/actions/workflows/release.yaml)
+[](https://github.com/smashedr/install-release/actions/workflows/lint.yaml)
[](https://github.com/smashedr/install-release/pulse)
-[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
+[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
[](https://github.com/smashedr/install-release/graphs/contributors)
[](https://github.com/smashedr/install-release/issues)
@@ -31,6 +31,7 @@
- [Install](#install)
+- [Features](#features)
- [Usage](#usage)
- [Development](#development)
- [Support](#Support)
@@ -38,7 +39,9 @@
CLI to Install a GitHub Release.
-Easily Install GitHub Release binaries with Windows, Linux and macOS Support.
+Easily Install GitHub Release binaries on Windows, Linux and macOS.
+
+Interactively select the release version, asset, and executable name with automatically detected presets.
[](https://smashedr.github.io/install-release/)
@@ -46,6 +49,17 @@ Easily Install GitHub Release binaries with Windows, Linux and macOS Support.
> This project is in development.
> It is functional but may have bugs.
+## Features
+
+- Supports Windows, Linux and macOS
+- Interactively Select Options
+- Set Options w/ Flags or Variables
+- Save or Set a Custom `bin` Path
+- List and Remove Installed Apps
+- Get App Information
+
+[](https://smashedr.github.io/install-release/)
+
## Install
[](https://github.com/smashedr/install-release/releases)
@@ -60,7 +74,7 @@ brew install cssnr/tap/install-release
#### Bash
```shell
-curl 'https://i.jpillora.com/smashedr/install-release!?as=ir' | bash
+curl 'https://raw.githubusercontent.com/smashedr/install-release/refs/heads/master/scripts/install.sh' | bash
```
💾 Alternatively, you can manually [download a release](https://github.com/smashedr/install-release/releases).
@@ -87,7 +101,7 @@ docker run --rm -itv ~/bin:/out ghcr.io/smashedr/ir:latest -b /out smashedr/inst
_Note: Docker requires you to mount the target bin directory._
-[](https://smashedr.github.io/install-release/)
+[](https://smashedr.github.io/install-release/)
## Usage
@@ -169,7 +183,7 @@ Edit the settings.
ir config
```
-[](https://smashedr.github.io/install-release/)
+[](https://smashedr.github.io/install-release/)
# Development
@@ -225,8 +239,8 @@ For a full list of current projects visit: [https://cssnr.github.io/](https://cs
-
-
-
+
+
+
diff --git a/Taskfile.yml b/Taskfile.yml
index 54ecb40..b606a91 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -28,6 +28,7 @@ tasks:
- task: pslint
pslint:
+ desc: Invoke-ScriptAnalyzer does NOT exit with error!
platforms: [windows]
cmd: powershell -Command "Invoke-ScriptAnalyzer -Path scripts -Recurse"
diff --git a/assets/main.tape b/assets/main.tape
index 11bc4d0..d7a500a 100644
--- a/assets/main.tape
+++ b/assets/main.tape
@@ -3,6 +3,19 @@ Type "ir smashedr/bup"
Sleep 0.5s
Enter
+# select version
+Wait / [0-9]\.[0-9]/
+Sleep 1.5s
+Down
+Sleep 0.2s
+Down
+Sleep 0.5s
+Up
+Sleep 0.2s
+Up
+Sleep 0.5s
+Enter
+# select asset
Wait / bup_/
Sleep 1.5s
Up
@@ -14,6 +27,7 @@ Sleep 0.2s
Down
Sleep 0.5s
Enter
+# set name
Wait /\> /
Sleep 1s
Backspace
diff --git a/cmd/info.go b/cmd/info.go
index 4efd042..5e5ea9c 100644
--- a/cmd/info.go
+++ b/cmd/info.go
@@ -31,10 +31,13 @@ var infoCmd = &cobra.Command{
}
log.Info("Repository", "owner", owner, "repo", repo, "tag", tag)
client := getClient()
- release, err := getRelease(client, owner, repo, tag, preRelease)
+ release, err := getRelease(client, owner, repo, tag, preRelease, true)
if err != nil {
log.Fatalf("Error getting release: %v", err)
}
+ if release == nil {
+ log.Fatalf("No release found")
+ }
if verbose >= 3 {
log.Debugf("%v", release)
}
diff --git a/cmd/install.go b/cmd/install.go
index 05cbd3a..6cd48ba 100644
--- a/cmd/install.go
+++ b/cmd/install.go
@@ -66,10 +66,13 @@ func runInstall(cmd *cobra.Command, args []string) error { // NOSONAR
client := getClient()
- release, err := getRelease(client, owner, repo, tag, preRelease)
+ release, err := getRelease(client, owner, repo, tag, preRelease, skipPrompts)
if err != nil {
return fmt.Errorf("get release error: %w", err)
}
+ if release == nil {
+ return fmt.Errorf("no release found")
+ }
if verbose >= 3 {
log.Debugf("release: %v", release)
}
@@ -392,7 +395,7 @@ func getClient() *github.Client {
return github.NewClient(httpClient)
}
-func getRelease(client *github.Client, owner, repo, tag string, pre bool) (*github.RepositoryRelease, error) {
+func getRelease(client *github.Client, owner, repo, tag string, pre, skip bool) (*github.RepositoryRelease, error) {
ctx := context.Background()
var release *github.RepositoryRelease
var err error
@@ -400,11 +403,14 @@ func getRelease(client *github.Client, owner, repo, tag string, pre bool) (*gith
log.Debugf("client.Repositories.GetReleaseByTag: %v", tag)
release, _, err = client.Repositories.GetReleaseByTag(ctx, owner, repo, tag)
} else if pre {
- log.Debugf("GetLatestRelease - Including Pre-Releases")
+ log.Debugf("GetLatestRelease")
release, err = getLatestRelease(client, owner, repo)
- } else {
+ } else if skip {
log.Debugf("client.Repositories.GetLatestRelease")
release, _, err = client.Repositories.GetLatestRelease(ctx, owner, repo)
+ } else {
+ log.Debugf("chooseRelease")
+ release, err = chooseRelease(client, owner, repo, 30)
}
if err != nil {
return nil, fmt.Errorf("get release error: %w", err)
@@ -413,16 +419,52 @@ func getRelease(client *github.Client, owner, repo, tag string, pre bool) (*gith
}
func getLatestRelease(client *github.Client, owner, repo string) (*github.RepositoryRelease, error) {
+ releases, err := getReleases(client, owner, repo, 1)
+ if err != nil {
+ return nil, err
+ }
+ if len(releases) == 0 {
+ return nil, nil
+ }
+ return releases[0], nil
+}
+
+func getReleases(client *github.Client, owner, repo string, number int) ([]*github.RepositoryRelease, error) {
ctx := context.Background()
- releases, _, err := client.Repositories.ListReleases(ctx, owner, repo, &github.ListOptions{PerPage: 1})
+ releases, _, err := client.Repositories.ListReleases(ctx, owner, repo, &github.ListOptions{PerPage: number})
if err != nil {
return nil, err
}
- if len(releases) > 0 {
- return releases[0], nil
+ return releases, nil
+}
+
+func chooseRelease(client *github.Client, owner, repo string, number int) (*github.RepositoryRelease, error) {
+ releases, err := getReleases(client, owner, repo, number)
+ if err != nil {
+ return nil, fmt.Errorf("error getting releases: %w", err)
+ }
+
+ log.Debugf("releases: %v", len(releases))
+ var result1 int
+ options := make([]huh.Option[int], len(releases))
+ for i, release := range releases {
+ options[i] = huh.NewOption(release.GetTagName(), i)
}
- // TODO: Consider returning an error here...
- return nil, nil
+ form := huh.NewSelect[int]().
+ Title("Select a version:").
+ Options(options...).
+ Value(&result1)
+
+ err = form.Run()
+ if err != nil {
+ return nil, fmt.Errorf("prompt failed: %w", err)
+ }
+ log.Debugf("result1: %v", result1)
+
+ chosen := releases[result1]
+ log.Debugf("release: %v", chosen)
+ log.Debugf("tag: %v", chosen.GetTagName())
+ return chosen, nil
}
func ensureWinExt(destName string) string {
diff --git a/docs/index.md b/docs/index.md
index 55e2683..59ed116 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -11,11 +11,11 @@ icon: lucide/rocket
[](https://github.com/smashedr/install-release/pkgs/container/install-release)
[](https://github.com/smashedr/install-release/blob/master/go.mod)
[](https://github.com/smashedr/install-release/pulse)
-[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
+[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
[](https://github.com/smashedr/install-release?tab=readme-ov-file#readme)
[](https://github.com/smashedr/install-release/graphs/contributors)
[](https://github.com/smashedr/install-release/issues)
-[](https://github.com/smashedr/install-release/discussions)
+[](https://github.com/smashedr/install-release/discussions)
[](https://github.com/smashedr/install-release/forks)
[](https://github.com/smashedr/install-release/stargazers)
[](https://cssnr.github.io/)
@@ -24,7 +24,9 @@ icon: lucide/rocket
CLI to Install a GitHub Release.
-Easily Install GitHub Release binaries with Windows, Linux and macOS Support.
+Easily Install GitHub Release binaries on Windows, Linux and macOS.
+
+Interactively select the release version, asset, and executable name with automatically detected presets.
--8<-- "docs/snippets/install.md"
@@ -38,12 +40,12 @@ If you run into any issues or have any questions, [support](support.md) is avail
## :lucide-sparkles: Features
-- Supports Windows
-- Custom `bin` Path
-- Automatic Release Detection
-- Select Asset and Name Interactively
-- Set Asset and Name Programmatically
+- Supports Windows, Linux and macOS
+- Interactively Select Options
+- Set Options w/ Flags or Variables
+- Save or Set a Custom `bin` Path
- List and Remove Installed Apps
+- Get App Information
## :lucide-plane-takeoff: Install
diff --git a/docs/snippets/install.md b/docs/snippets/install.md
index 6d4722d..70844f9 100644
--- a/docs/snippets/install.md
+++ b/docs/snippets/install.md
@@ -7,7 +7,7 @@
=== ":lucide-terminal-square: bash"
```shell
- curl 'https://i.jpillora.com/smashedr/install-release!?as=ir' | bash # (1)!
+ curl 'https://raw.githubusercontent.com/smashedr/install-release/refs/heads/master/scripts/install.sh' | bash # (1)!
```
1. Alternatively, you can manually [download a release](https://github.com/smashedr/install-release/releases).
diff --git a/docs/support.md b/docs/support.md
index bfa7319..f823146 100644
--- a/docs/support.md
+++ b/docs/support.md
@@ -48,4 +48,12 @@ From here you can contact me directly, `Shane@111150265075298304`.
More information available at: [https://cssnr.com/](https://cssnr.com/)
-[{ width="360" }](https://ko-fi.com/cssnr)
+[{ width="360" }](https://ko-fi.com/cssnr)
+
+
+
+
+
+
+
+
diff --git a/scripts/install.sh b/scripts/install.sh
index 750ebf4..1881245 100644
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -1,72 +1,33 @@
#!/usr/bin/env bash
# https://raw.githubusercontent.com/smashedr/install-release/refs/heads/master/scripts/install.sh
+set -e
+
+
OWNER="smashedr"
REPO="install-release"
EXE="ir"
-
-echo "Installing: ${OWNER}/${REPO} as ${EXE}"
-
TARGET_BIN="${HOME}/bin"
-echo "TARGET_BIN: ${TARGET_BIN}"
-set -e
-
-WORK_DIR=$(mktemp -d -t install-release-XXXXXXXXXX 2>&1)
-echo "WORK_DIR: ${WORK_DIR}"
-function _execution_trap() {
- _ST="$?"
- rm -rf "${WORK_DIR}"
- if [[ "${_ST}" != "0" ]];then
- echo "⛔ Installation Error! Exit Code: ${_ST}"
- fi
- exit "${_ST}"
-}
+echo "Installing: ${OWNER}/${REPO} as ${EXE}"
-trap _execution_trap EXIT HUP INT QUIT PIPE TERM
function fail() {
_ST="$?"
- echo "_ST: ${_ST} - Message: ${1}" 1>&2
- exit ${_ST}
+ echo "fail _ST: ${_ST}"
+ echo "⛔ ${1}" 1>&2
+ if [ "$_ST" -eq 0 ]; then
+ exit 1
+ fi
+ exit "${_ST}"
}
-# CHECKS
-[ ! "$BASH_VERSION" ] && fail "Please use bash instead"
-which find > /dev/null || fail "find not installed"
-which xargs > /dev/null || fail "xargs not installed"
-which sort > /dev/null || fail "sort not installed"
-which tail > /dev/null || fail "tail not installed"
-which cut > /dev/null || fail "cut not installed"
-which du > /dev/null || fail "du not installed"
-
-
-# PATH
-if ! echo "${PATH}" | tr ':' '\n' | grep -qx "${TARGET_BIN}"; then
- echo "⚠️ Target bin NOT in PATH: ${TARGET_BIN}"
- # TODO: Add TARGET_BIN to PATH
-fi
-
-
-# GET
-GET=""
-if which curl > /dev/null; then
- GET="curl --fail -# -L"
-elif which wget > /dev/null; then
- GET="wget -qO-"
-else
- fail "neither curl or wget are installed"
-fi
-if [[ -n "${GITHUB_TOKEN}" ]]; then
- GET="$GET -H 'Authorization: ${GITHUB_TOKEN}'"
-fi
-echo "GET: ${GET}" # TODO: Exposes GITHUB_TOKEN
-
# OS
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
-case "$OS" in
+echo "OS: ${OS}"
+case "${OS}" in
darwin)
OS="Darwin"
FTYPE="tar.gz"
@@ -75,17 +36,21 @@ linux)
OS="Linux"
FTYPE="tar.gz"
;;
+mingw* | msys* | cygwin* | windows*)
+ OS="Windows"
+ FTYPE="zip"
+ ;;
*)
fail "unknown os: $(uname -s)"
;;
esac
-# TODO: Add windows support?
echo "OS: ${OS}"
# ARCH
ARCH="$(uname -m)"
-if [[ $OS = "darwin" ]] && sysctl hw.optional.arm64 2>/dev/null | grep -q ': 1'; then
+echo "ARCH: ${ARCH}"
+if [[ ${OS} = "Darwin" ]] && sysctl hw.optional.arm64 2>/dev/null | grep -q ': 1'; then
ARCH="arm64"
elif uname -m | grep -E '(aarch64|arm64)' > /dev/null; then
ARCH="arm64"
@@ -99,47 +64,105 @@ fi
echo "ARCH: ${ARCH}"
+# FTYPE
+if [[ ${FTYPE} = "tar.gz" ]]; then
+ which tar > /dev/null || fail "tar is not installed"
+ which gzip > /dev/null || fail "gzip is not installed"
+elif [[ ${FTYPE} = "zip" ]]; then
+ which unzip > /dev/null || fail "unzip is not installed"
+else
+ fail "unknown file type: ${FTYPE}"
+fi
+echo "FTYPE: ${FTYPE}"
+
+
# URL
URL="https://github.com/${OWNER}/${REPO}/releases/latest/download/${EXE}_${OS}_${ARCH}.${FTYPE}"
echo "URL: ${URL}"
+# GET
+GET=""
+if which curl > /dev/null; then
+ GET="curl --fail -# -L"
+elif which wget > /dev/null; then
+ GET="wget -qO-"
+else
+ fail "neither curl or wget are installed"
+fi
+#if [[ -n "${GITHUB_TOKEN}" ]]; then
+# GET="${GET} -H 'Authorization: ${GITHUB_TOKEN}'"
+#fi
+echo "GET: ${GET}"
+
+
+# BIN
+echo "Target Directory: $TARGET_BIN"
+echo -n "Enter Path [press to accept]: "
+read -r input
+if [[ -n "${input}" ]]; then
+ # TODO: Sanatize TARGET_BIN
+ TARGET_BIN="${input}"
+fi
+echo "TARGET_BIN: $TARGET_BIN"
+
+
+# PATH
+if ! echo "${PATH}" | tr ':' '\n' | grep -qx "${TARGET_BIN}"; then
+ echo "⚠️ Target bin NOT in PATH: ${TARGET_BIN}"
+ # TODO: Add TARGET_BIN to PATH
+fi
+if [[ ! -d "${TARGET_BIN}" ]]; then
+ echo "⚠️ Creating bin directory: ${TARGET_BIN}"
+ mkdir -p "${TARGET_BIN}" || fail "mkdir failed on: ${TARGET_BIN}"
+fi
+
+
+# TEMP
+TEMP_DIR=$(mktemp -d -t install-release-XXXXXXXXXX 2>&1)
+echo "TEMP_DIR: ${TEMP_DIR}"
+
+function _execution_trap() {
+ _ST="$?"
+ rm -rf "${TEMP_DIR}"
+ if [[ "${_ST}" != "0" ]]; then
+ echo "⛔ Installation Error! Exit Code: ${_ST}" 1>&2
+ fi
+ exit "${_ST}"
+}
+trap _execution_trap EXIT HUP INT QUIT PIPE TERM
+
+
# DOWNLOAD
-echo "cd ${WORK_DIR}"
-cd "${WORK_DIR}"
-if [[ $FTYPE = "tar.gz" ]] || [[ $FTYPE = ".tgz" ]]; then
- which tar > /dev/null || fail "tar is not installed"
- which gzip > /dev/null || fail "gzip is not installed"
- bash -c "$GET $URL" | tar zxf - || fail "download failed"
-elif [[ $FTYPE = "zip" ]]; then
- which unzip > /dev/null || fail "unzip is not installed"
- bash -c "$GET $URL" > tmp.zip || fail "download failed"
+cd "${TEMP_DIR}"
+if [[ ${FTYPE} = "tar.gz" ]]; then
+ bash -c "${GET} ${URL}" | tar zxf - || fail "download failed"
+elif [[ ${FTYPE} = "zip" ]]; then
+ bash -c "${GET} ${URL}" > tmp.zip || fail "download failed"
unzip -o -qq tmp.zip || fail "unzip failed"
rm tmp.zip || fail "cleanup failed"
-else
- fail "unknown file type: $FTYPE"
fi
# CHMOD
-TMP_BIN="${WORK_DIR}/${EXE}"
-echo "TMP_BIN: ${TMP_BIN}"
-chmod +x "${TMP_BIN}" || fail "chmod +x failed"
+TEMP_BIN="${TEMP_DIR}/${EXE}"
+echo "TEMP_BIN: ${TEMP_BIN}"
+chmod +x "${TEMP_BIN}" || fail "chmod +x failed"
DEST="${TARGET_BIN}/${EXE}"
echo "DEST: ${DEST}"
# MOVE
-mv "${TMP_BIN}" "${DEST}"
+mv "${TEMP_BIN}" "${DEST}" || fail "move to destination failed"
-#OUT=$(mv "${TMP_BIN}" "${DEST}" 2>&1)
+#OUT=$(mv "${TEMP_BIN}" "${DEST}" 2>&1)
#STATUS=$?
#echo "OUT: ${OUT}"
#echo "STATUS: ${STATUS}"
#if [[ "${STATUS}" != "0" ]]; then
# if [[ $OUT =~ "Permission denied" ]]; then
# echo "mv with sudo..."
-# sudo mv "${TMP_BIN}" "${DEST}" || fail "sudo mv failed"
+# sudo mv "${TEMP_BIN}" "${DEST}" || fail "sudo mv failed"
# fi
#fi