Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
283 additions
and
112 deletions.
There are no files selected for viewing
This file contains 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
139 changes: 139 additions & 0 deletions
139
extension/src/dependency-installer/installers/c1-flow-cli-installer.ts
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* Installer for Flow CLI */ | ||
import { window } from 'vscode' | ||
import { execVscodeTerminal, tryExecPowerShell, tryExecUnixDefault } from '../../utils/shell/exec' | ||
import { promptUserInfoMessage, promptUserErrorMessage } from '../../ui/prompts' | ||
import { Installer, InstallerContext } from '../installer' | ||
import * as semver from 'semver' | ||
import fetch from 'node-fetch' | ||
import { isCadenceV1Cli } from '../../flow-cli/cli-provider' | ||
|
||
// Command to check flow-cli | ||
const COMPATIBLE_FLOW_CLI_VERSIONS = '*' | ||
|
||
// Shell install commands | ||
const POWERSHELL_INSTALL_CMD = (githubToken?: string): string => | ||
`iex "& { $(irm 'https://raw.githubusercontent.com/onflow/flow-cli/feature/stable-cadence/install.ps1') } ${ | ||
githubToken != null ? `-GitHubToken ${githubToken} ` : '' | ||
}"` | ||
const BASH_INSTALL_FLOW_CLI = (githubToken?: string): string => | ||
`${ | ||
githubToken != null ? `GITHUB_TOKEN=${githubToken} ` : '' | ||
}sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/feature/stable-cadence/install.sh)"` | ||
|
||
const RELEASES_URL = (page: number) => `https://api.github.com/repos/onflow/flow-cli/releases?per_page=100&page=${page}` | ||
|
||
export class InstallC1FlowCLI extends Installer { | ||
#githubToken: string | undefined | ||
#context: InstallerContext | ||
|
||
constructor (context: InstallerContext) { | ||
super('Cadence 1.0 Flow CLI', []) | ||
this.#githubToken = process.env.GITHUB_TOKEN | ||
this.#context = context | ||
} | ||
|
||
async install (): Promise<void> { | ||
const isActive = this.#context.languageServerApi.isActive ?? false | ||
if (isActive) await this.#context.languageServerApi.deactivate() | ||
const OS_TYPE = process.platform | ||
|
||
try { | ||
switch (OS_TYPE) { | ||
case 'win32': | ||
await this.#install_windows() | ||
break | ||
default: | ||
await this.#install_bash_cmd() | ||
break | ||
} | ||
} catch { | ||
void window.showErrorMessage('Failed to install Cadence 1.0 Flow CLI') | ||
} | ||
if (isActive) await this.#context.languageServerApi.activate() | ||
} | ||
|
||
async #install_windows (): Promise<void> { | ||
// Retry if bad GH token | ||
if (this.#githubToken != null && await tryExecPowerShell(POWERSHELL_INSTALL_CMD(this.#githubToken))) { return } | ||
await execVscodeTerminal('Install Cadence 1.0 Flow CLI', POWERSHELL_INSTALL_CMD(this.#githubToken)) | ||
} | ||
|
||
async #install_bash_cmd (): Promise<void> { | ||
// Retry if bad GH token | ||
if (this.#githubToken != null && await tryExecUnixDefault(BASH_INSTALL_FLOW_CLI(this.#githubToken))) { return } | ||
await execVscodeTerminal('Install Cadence 1.0 Flow CLI', BASH_INSTALL_FLOW_CLI()) | ||
} | ||
|
||
async findLatestVersion (currentVersion: semver.SemVer): Promise<void> { | ||
// Recursive function to find cadence v1 release | ||
async function findLatestRelease (page: number): Promise<semver.SemVer> { | ||
return fetch(RELEASES_URL(page)).then(async (response: Response) => { | ||
if (!response.ok) { | ||
throw new Error(`Failed to fetch releases from flow-cli repo: ${response.statusText}`) | ||
} | ||
return await response.json() | ||
}).then((releases: any[]) => { | ||
if (releases.length === 0) { | ||
throw new Error('No releases found') | ||
} | ||
const version = semver.parse(releases[0].tag_name) | ||
if (version != null && isCadenceV1Cli(version)) return version | ||
return findLatestRelease(page + 1) | ||
}) | ||
} | ||
|
||
const latest = await findLatestRelease(1) | ||
|
||
// Check if latest version > current version | ||
if (semver.compare(latest, currentVersion) === 1) { | ||
promptUserInfoMessage( | ||
'There is a new Cadence 1.0 Flow CLI version available: ' + latest.format(), | ||
[{ | ||
label: 'Install latest Cadence 1.0 Flow CLI', | ||
callback: async () => { | ||
await this.runInstall() | ||
await this.#context.refreshDependencies() | ||
} | ||
}] | ||
) | ||
} | ||
} | ||
|
||
async checkVersion (vsn?: semver.SemVer): Promise<boolean> { | ||
// Get user's version informaton | ||
this.#context.cliProvider.refresh() | ||
const version = vsn ?? await this.#context.cliProvider.getAvailableBinaries().then(x => x.find(y => y.name === 'flow-c1')?.version) | ||
if (version == null) return false | ||
|
||
if (!semver.satisfies(version, COMPATIBLE_FLOW_CLI_VERSIONS, { | ||
includePrerelease: true | ||
})) { | ||
promptUserErrorMessage( | ||
'Incompatible Cadence 1.0 Flow CLI version: ' + version.format(), | ||
[{ | ||
label: 'Install latest Cadence 1.0 Flow CLI', | ||
callback: async () => { | ||
await this.runInstall() | ||
await this.#context.refreshDependencies() | ||
} | ||
}] | ||
) | ||
return false | ||
} | ||
|
||
// Check for newer version | ||
await this.findLatestVersion(version) | ||
|
||
return true | ||
} | ||
|
||
async verifyInstall (): Promise<boolean> { | ||
// Check if flow version is valid to verify install | ||
this.#context.cliProvider.refresh() | ||
const version = await this.#context.cliProvider.getAvailableBinaries().then(x => x.find(y => y.name === 'flow-c1')?.version) | ||
if (version == null) return false | ||
|
||
// Check flow-cli version number | ||
return await this.checkVersion(version) | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.