Created
March 27, 2026 03:21
-
-
Save holly/933f4e9594fc3ee67a8cb8eadfb3077e to your computer and use it in GitHub Desktop.
shfmt install
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -e | |
| set -u | |
| set -o pipefail | |
| set -C | |
| # 設定 | |
| REPO="mvdan/sh" | |
| API_URL="https://api.github.com/repos/${REPO}/releases/latest" | |
| INSTALL_DIR="$HOME/.local/bin" | |
| BINARY_NAME="shfmt" | |
| CURL_OPTS=(-sSfL) | |
| if [ -n "$GITHUB_TOKEN" ]; then | |
| echo "Using GITHUB_TOKEN for authentication." | |
| CURL_OPTS+=(-H "Authorization: token ${GITHUB_TOKEN}") | |
| fi | |
| # 依存コマンドのチェック | |
| if ! command -v curl &>/dev/null; then | |
| echo "Error: curl is required but not installed." >&2 | |
| exit 1 | |
| fi | |
| if ! command -v jq &>/dev/null; then | |
| echo "Error: jq is required but not installed." >&2 | |
| exit 1 | |
| fi | |
| # 1. APIから最新リリース情報を取得し、tag_nameを取得 | |
| echo "Fetching latest release information..." | |
| JSON_RESPONSE=$(curl "${CURL_OPTS[@]}" "$API_URL") | |
| TAG_NAME=$(echo "$JSON_RESPONSE" | jq -r .tag_name) | |
| if [ -z "$TAG_NAME" ] || [ "$TAG_NAME" = "null" ]; then | |
| echo "Error: Could not fetch tag_name from API." >&2 | |
| exit 1 | |
| fi | |
| echo "Latest version: $TAG_NAME" | |
| # 3. すでにshfmtがインストールされていて、同じバージョンであれば終了 | |
| if command -v "$BINARY_NAME" &>/dev/null; then | |
| CURRENT_VERSION=$("$BINARY_NAME" --version 2>/dev/null) | |
| if [ "$CURRENT_VERSION" = "$TAG_NAME" ]; then | |
| echo "shfmt $TAG_NAME is already installed. Skipping." | |
| exit 0 | |
| fi | |
| fi | |
| # 4. uname -s, uname -mの結果に合わせて適切なassetsのURLを取得 | |
| OS=$(uname -s | tr '[:upper:]' '[:lower:]') | |
| ARCH=$(uname -m) | |
| # アーキテクチャのマッピング (shfmtの命名規則に合わせる) | |
| case "$ARCH" in | |
| x86_64) ARCH="amd64" ;; | |
| aarch64) ARCH="arm64" ;; # Linux aarch64 | |
| arm64) ARCH="arm64" ;; # macOS arm64 | |
| i386 | i686) ARCH="386" ;; | |
| esac | |
| # 例: shfmt_v3.13.0_darwin_amd64 のようなパターンを検索 | |
| # APIレスポンス内で name に "_${OS}_${ARCH}" を含むものを探す | |
| DOWNLOAD_URL=$(echo "$JSON_RESPONSE" | jq -r --arg os "$OS" --arg arch "$ARCH" \ | |
| '.assets[] | select(.name | test("_\($os)_\($arch)$")) | .browser_download_url' | head -n 1) | |
| if [ -z "$DOWNLOAD_URL" ]; then | |
| echo "Error: No matching download URL found for OS=$OS, ARCH=$ARCH." >&2 | |
| exit 1 | |
| fi | |
| echo "Download URL: $DOWNLOAD_URL" | |
| # 5. ~/.local/bin にインストール | |
| mkdir -p "$INSTALL_DIR" | |
| # バイナリをダウンロード(バージョン付きで保存) | |
| BINARY_PATH="${INSTALL_DIR}/${BINARY_NAME}-${TAG_NAME}" | |
| echo "Downloading to $BINARY_PATH..." | |
| curl -sL "$DOWNLOAD_URL" -o "$BINARY_PATH" | |
| chmod +x "$BINARY_PATH" | |
| # 6. shfmtという名前にsymlinkを作成する | |
| SYMLINK_PATH="${INSTALL_DIR}/${BINARY_NAME}" | |
| # 既存のシンボリックリンクやファイルがあれば削除 | |
| if [ -L "$SYMLINK_PATH" ]; then | |
| rm "$SYMLINK_PATH" | |
| elif [ -e "$SYMLINK_PATH" ]; then | |
| echo "Warning: Removing existing file at $SYMLINK_PATH" | |
| rm "$SYMLINK_PATH" | |
| fi | |
| ln -s "$BINARY_PATH" "$SYMLINK_PATH" | |
| echo "" | |
| echo "Installation complete!" | |
| echo "Version: $TAG_NAME" | |
| echo "Binary: $BINARY_PATH" | |
| echo "Link: $SYMLINK_PATH" | |
| # パスが通っていない場合の警告 | |
| if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then | |
| echo "" | |
| echo "Warning: $INSTALL_DIR is not in your PATH." | |
| echo "Please add the following line to your .bashrc or .zshrc:" | |
| echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment