diff --git a/install.ps1 b/install.ps1 index 9d8c67d88..f4b4b52b3 100644 --- a/install.ps1 +++ b/install.ps1 @@ -8,6 +8,8 @@ The destination path to install to. .Parameter Version The version to install. +.Parameter C1Version + The Cadence 1 version to install. .Parameter AddToPath Add the absolute destination path to the 'User' scope environment variable 'Path'. .Parameter GitHubToken @@ -23,6 +25,7 @@ #> param ( [string] $version="", + [string] $c1Version="", [string] $directory = "$env:APPDATA\Flow", [bool] $addToPath = $true, [string] $githubToken = "" @@ -36,12 +39,11 @@ Set-ItemProperty HKCU:\Console VirtualTerminalLevel -Type DWORD 1 $ErrorActionPreference = "Stop" $repo = "onflow/flow-cli" -$versionURL = "https://api.github.com/repos/$repo/releases/latest" $assetsURL = "https://github.com/$repo/releases/download" # Add the GitHub token to the web request headers if it was provided $webRequestOptions = if ($githubToken) { - @{ 'Headers' = @{ 'Authorization' = "Bearer $githubToken" } } + @{ 'Headers' = @{ 'Authorization' = "Bearer $githubToken" } } } else { @{} } @@ -49,16 +51,15 @@ $webRequestOptions = if ($githubToken) { # Function to get the latest version function Get-Version { param ( - [string]$repo, [string]$searchTerm, - [hashtable]$webRequestOptions + [bool]$prerelease ) $page = 1 $version = $null while (-not $version) { - $response = Invoke-WebRequest -Uri "https://api.github.com/repos/$repo/releases?per_page=100&page=$page" -UseBasicParsing @webRequestOptions -ErrorAction SilentlyContinue + $response = Invoke-WebRequest -Uri "https://api.github.com/repos/$repo/releases?per_page=10&page=$page" -UseBasicParsing @webRequestOptions -ErrorAction SilentlyContinue $status = $response.StatusCode if ($status -eq 403 -and $githubTokenHeader) { @@ -75,7 +76,7 @@ function Get-Version { $jsonResponse = $response.Content | ConvertFrom-Json foreach ($release in $jsonResponse) { - if ($release.tag_name -like "*$searchTerm*") { + if (($release.prerelease -eq $prerelease) -and ($release.tag_name -like "*$searchTerm*")) { $version = $release.tag_name break } @@ -87,27 +88,46 @@ function Get-Version { return $version } -if (-not $version) { - $version = Get-Version -repo $repo -searchTerm "cadence-v1.0.0" -webRequestOptions $webRequestOptions -} +function Install-FlowCLI { + param ( + [string]$version, + [string]$destinationFileName + ) + + Write-Output("Installing version {0} ..." -f $version) + + New-Item -ItemType Directory -Force -Path $directory | Out-Null + + $progressPreference = 'silentlyContinue' + + Invoke-WebRequest -Uri "$assetsURL/$version/flow-cli-$version-windows-amd64.zip" -UseBasicParsing -OutFile "$directory\flow.zip" @webRequestOptions -Write-Output("Installing version {0} ..." -f $version) + Expand-Archive -Path "$directory\flow.zip" -DestinationPath "$directory" -Force -New-Item -ItemType Directory -Force -Path $directory | Out-Null + try { + Stop-Process -Name flow -Force + Start-Sleep -Seconds 1 + } + catch {} + + Move-Item -Path "$directory\flow-cli.exe" -Destination "$directory\$destinationFileName" -Force +} + +if (-not $version) { + Write-Output "Getting version of latest stable release ..." -$progressPreference = 'silentlyContinue' + $version = Get-Version -searchTerm '' -prerelease $false +} -Invoke-WebRequest -Uri "$assetsURL/$version/flow-cli-$version-windows-amd64.zip" -UseBasicParsing -OutFile "$directory\flow.zip" @webRequestOptions +Install-FlowCLI -version $version -destinationFileName "flow.exe" -Expand-Archive -Path "$directory\flow.zip" -DestinationPath "$directory" -Force +if (-not $c1version) { + Write-Output "Getting version of latest Cadence 1.0 preview release ..." -try { - Stop-Process -Name flow -Force - Start-Sleep -Seconds 1 + $c1version = Get-Version -searchTerm "cadence-v1.0.0" -prerelease $true } -catch {} -Move-Item -Path "$directory\flow-cli.exe" -Destination "$directory\flow-c1.exe" -Force +Install-FlowCLI -version $c1Version -destinationFileName "flow-c1.exe" # Check if the directory is already in the PATH $existingPaths = [Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::User).Split(';') @@ -121,7 +141,11 @@ if ($addToPath -and $existingPaths -notcontains $directory) { } Write-Output "" -Write-Output "Successfully installed Flow CLI $version" -Write-Output "PRE-RELEASE: Use the 'flow-c1' command to interact with this Cadence 1.0 CLI pre-release." +Write-Output "Successfully installed Flow CLI $version as 'flow'." +Write-Output "Use the 'flow' command to interact with the Flow CLI compatible with versions of Cadence before 1.0 (only)." +Write-Output "" +Write-Output "Successfully installed Flow CLI $c1Version as 'flow-c1'." +Write-Output "Use the 'flow-c1' command to interact with the Flow CLI preview compatible with Cadence 1.0 (only)." +Write-Output "" -Start-Sleep -Seconds 1 \ No newline at end of file +Start-Sleep -Seconds 1 diff --git a/install.sh b/install.sh index c639eb185..5b2403894 100755 --- a/install.sh +++ b/install.sh @@ -5,12 +5,12 @@ set -e REPO="onflow/flow-cli" ASSETS_URL="https://github.com/$REPO/releases/download/" -# The version to download, set by get_version (defaults to args[1]) +# The version to install (defaults to args[1]) VERSION="$1" +# The Cadence 1.0 version to install (defaults to args[2]) +C1VERSION="$2" # The architecture string, set by get_architecture ARCH="" -# The tag search term to use if no version is specified (first match is used) -SEARCH_TERM="cadence-v1.0.0" # Optional environment variable for Github API token # If GITHUB_TOKEN is set, use it in the curl requests to avoid rate limiting @@ -61,81 +61,118 @@ get_architecture() { TARGET_PATH="${_targetpath}" } -# Get the latest version from remote if none specified in args. -page=1 get_version() { - if [ -z "$VERSION" ] - then - VERSION="" - if [ -n "$github_token_header" ] - then - response=$(curl -H "$github_token_header" -s "https://api.github.com/repos/$REPO/releases?per_page=100&page=$page" -w "%{http_code}") - else - response=$(curl -s "https://api.github.com/repos/$REPO/releases?per_page=100&page=$page" -w "%{http_code}") - fi + local search_term="$1" + local page="$2" + + local version="" + + response=$(curl -H "$github_token_header" -s "https://api.github.com/repos/$REPO/releases?per_page=10&page=$page" -w "%{http_code}") status=$(echo "$response" | tail -n 1) if [ "$status" -eq "403" ] && [ -n "$github_token_header" ] then - echo "Failed to get latest version from Github API, is your GITHUB_TOKEN valid? Trying without authentication..." + echo "Failed to get releases from Github API, is your GITHUB_TOKEN valid? Re-trying without authentication ..." github_token_header="" - get_version + get_version "$search_term" "$page" fi if [ "$status" -ne "200" ] then - echo "Failed to get latest version from Github API, please manually specify a version to install as an argument to this script." + echo "Failed to get releases from Github API, please manually specify a version to install as an argument to this script." return 1 fi - VERSION=$(echo "$response" | grep -E 'tag_name' | grep -E "$SEARCH_TERM" | head -n 1 | cut -d '"' -f 4) + version=$(echo "$response" | grep -E 'tag_name' | grep -E "$search_term" | head -n 1 | cut -d '"' -f 4) - if [ -z "$VERSION" ] + if [ -z "$version" ] then - page=$((page+1)) - get_version + get_version "$search_term" "$((page+1))" fi - fi + + echo "$version" } -# Determine the system architecure, download the appropriate binary, and -# install it in `/usr/local/bin` on macOS and `~/.local/bin` on Linux -# with executable permission. -main() { +get_latest() { + local version="" - get_architecture || exit 1 - get_version || exit 1 + response=$(curl -H "$github_token_header" -s "https://api.github.com/repos/$REPO/releases/latest" -w "%{http_code}") + + status=$(echo "$response" | tail -n 1) + if [ "$status" -eq "403" ] && [ -n "$github_token_header" ] + then + echo "Failed to get latest release from Github API, is your GITHUB_TOKEN valid? Re-trying without authentication ..." + github_token_header="" + get_latest + fi + + if [ "$status" -ne "200" ] + then + echo "Failed to get latest release from Github API, please manually specify a version to install as an argument to this script." + return 1 + fi + + echo "$response" | grep -E 'tag_name' | grep -E "$search_term" | head -n 1 | cut -d '"' -f 4 +} + +# Function to download and install a specified version +install_version() { + local version="$1" + local target_name="$2" - echo "Downloading version $VERSION ..." + echo "Installing version $version ..." tmpfile=$(mktemp 2>/dev/null || mktemp -t flow) - url="$ASSETS_URL$VERSION/flow-cli-$VERSION-$ARCH.tar.gz" - if [ -n "$github_token_header" ] - then - curl -H "$github_token_header" -L --progress-bar "$url" -o $tmpfile - else - curl -L --progress-bar "$url" -o $tmpfile - fi + url="$ASSETS_URL$version/flow-cli-$version-$ARCH.tar.gz" + curl -H "$github_token_header" -L --progress-bar "$url" -o "$tmpfile" # Ensure we don't receive a not found error as response. - if grep -q "Not Found" $tmpfile + if grep -q "Not Found" "$tmpfile" then - echo "Version $VERSION could not be found" + echo "Version $version could not be found" exit 1 fi - [ -d $TARGET_PATH ] || mkdir -p $TARGET_PATH + [ -d "$TARGET_PATH" ] || mkdir -p "$TARGET_PATH" + + tar -xf "$tmpfile" -C "$TARGET_PATH" + mv "$TARGET_PATH/flow-cli" "$TARGET_PATH/$target_name" + chmod +x "$TARGET_PATH/$target_name" +} + +# Determine the system architecture, download the appropriate binaries, and +# install them in `/usr/local/bin` on macOS and `~/.local/bin` on Linux +# with executable permissions. +main() { + get_architecture || exit 1 + + if [ -z "$VERSION" ] + then + echo "Getting version of latest stable release ..." + + VERSION=$(get_latest || exit 1) + fi + + install_version "$VERSION" "flow" - tar -xf $tmpfile -C $TARGET_PATH - mv $TARGET_PATH/flow-cli $TARGET_PATH/flow-c1 - chmod +x $TARGET_PATH/flow-c1 + if [ -z "$C1VERSION" ] + then + echo "Getting version of latest Cadence 1.0 preview release ..." + + C1VERSION=$(get_version "cadence-v1.0.0" 1 || exit 1) + fi + + install_version "$C1VERSION" "flow-c1" echo "" - echo "Successfully installed Flow CLI $VERSION to $TARGET_PATH." - echo "Make sure $TARGET_PATH is in your \$PATH environment variable." + echo "Successfully installed Flow CLI $VERSION as 'flow' in $TARGET_PATH." + echo "Use the 'flow' command to interact with the Flow CLI compatible with versions of Cadence before 1.0 (only)." echo "" - echo "PRE-RELEASE: Use the 'flow-c1' command to interact with this Cadence 1.0 CLI pre-release." + echo "Successfully installed Flow CLI $C1VERSION as 'flow-c1' in $TARGET_PATH." + echo "Use the 'flow-c1' command to interact with the Flow CLI preview compatible with Cadence 1.0 (only)." + echo "" + echo "Make sure $TARGET_PATH is in your \$PATH environment variable." echo "" } -main +main \ No newline at end of file