diff options
Diffstat (limited to 'editors/code/src/installation')
-rw-r--r-- | editors/code/src/installation/download_artifact.ts | 21 | ||||
-rw-r--r-- | editors/code/src/installation/fetch_artifact_release_info.ts | 58 | ||||
-rw-r--r-- | editors/code/src/installation/server.ts | 9 |
3 files changed, 53 insertions, 35 deletions
diff --git a/editors/code/src/installation/download_artifact.ts b/editors/code/src/installation/download_artifact.ts index 356723aba..8ed99bf0a 100644 --- a/editors/code/src/installation/download_artifact.ts +++ b/editors/code/src/installation/download_artifact.ts | |||
@@ -5,7 +5,6 @@ import { strict as assert } from "assert"; | |||
5 | 5 | ||
6 | import { ArtifactReleaseInfo } from "./interfaces"; | 6 | import { ArtifactReleaseInfo } from "./interfaces"; |
7 | import { downloadFile } from "./download_file"; | 7 | import { downloadFile } from "./download_file"; |
8 | import { throttle } from "throttle-debounce"; | ||
9 | 8 | ||
10 | /** | 9 | /** |
11 | * Downloads artifact from given `downloadUrl`. | 10 | * Downloads artifact from given `downloadUrl`. |
@@ -38,19 +37,15 @@ export async function downloadArtifact( | |||
38 | async (progress, _cancellationToken) => { | 37 | async (progress, _cancellationToken) => { |
39 | let lastPrecentage = 0; | 38 | let lastPrecentage = 0; |
40 | const filePermissions = 0o755; // (rwx, r_x, r_x) | 39 | const filePermissions = 0o755; // (rwx, r_x, r_x) |
41 | await downloadFile(downloadUrl, installationPath, filePermissions, throttle( | 40 | await downloadFile(downloadUrl, installationPath, filePermissions, (readBytes, totalBytes) => { |
42 | 200, | 41 | const newPercentage = (readBytes / totalBytes) * 100; |
43 | /* noTrailing: */ true, | 42 | progress.report({ |
44 | (readBytes, totalBytes) => { | 43 | message: newPercentage.toFixed(0) + "%", |
45 | const newPercentage = (readBytes / totalBytes) * 100; | 44 | increment: newPercentage - lastPrecentage |
46 | progress.report({ | 45 | }); |
47 | message: newPercentage.toFixed(0) + "%", | ||
48 | increment: newPercentage - lastPrecentage | ||
49 | }); | ||
50 | 46 | ||
51 | lastPrecentage = newPercentage; | 47 | lastPrecentage = newPercentage; |
52 | }) | 48 | }); |
53 | ); | ||
54 | } | 49 | } |
55 | ); | 50 | ); |
56 | } | 51 | } |
diff --git a/editors/code/src/installation/fetch_artifact_release_info.ts b/editors/code/src/installation/fetch_artifact_release_info.ts index 1b6fc8d48..b1b5a3485 100644 --- a/editors/code/src/installation/fetch_artifact_release_info.ts +++ b/editors/code/src/installation/fetch_artifact_release_info.ts | |||
@@ -4,41 +4,61 @@ import { log } from "../util"; | |||
4 | 4 | ||
5 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; | 5 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; |
6 | 6 | ||
7 | |||
8 | /** | 7 | /** |
9 | * Fetches the release with `releaseTag` (or just latest release when not specified) | 8 | * Fetches the release with `releaseTag` from GitHub `repo` and |
10 | * from GitHub `repo` and returns metadata about `artifactFileName` shipped with | 9 | * returns metadata about `artifactFileName` shipped with |
11 | * this release or `null` if no such artifact was published. | 10 | * this release. |
11 | * | ||
12 | * @throws Error upon network failure or if no such repository, release, or artifact exists. | ||
12 | */ | 13 | */ |
13 | export async function fetchArtifactReleaseInfo( | 14 | export async function fetchArtifactReleaseInfo( |
14 | repo: GithubRepo, artifactFileName: string, releaseTag?: string | 15 | repo: GithubRepo, |
15 | ): Promise<null | ArtifactReleaseInfo> { | 16 | artifactFileName: string, |
17 | releaseTag: string | ||
18 | ): Promise<ArtifactReleaseInfo> { | ||
16 | 19 | ||
17 | const repoOwner = encodeURIComponent(repo.owner); | 20 | const repoOwner = encodeURIComponent(repo.owner); |
18 | const repoName = encodeURIComponent(repo.name); | 21 | const repoName = encodeURIComponent(repo.name); |
19 | 22 | ||
20 | const apiEndpointPath = releaseTag | 23 | const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}`; |
21 | ? `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}` | ||
22 | : `/repos/${repoOwner}/${repoName}/releases/latest`; | ||
23 | 24 | ||
24 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; | 25 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; |
25 | 26 | ||
26 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) | ||
27 | |||
28 | log.debug("Issuing request for released artifacts metadata to", requestUrl); | 27 | log.debug("Issuing request for released artifacts metadata to", requestUrl); |
29 | 28 | ||
30 | // FIXME: handle non-ok response | 29 | const response = await fetch(requestUrl, { headers: { Accept: "application/vnd.github.v3+json" } }); |
31 | const response: GithubRelease = await fetch(requestUrl, { | ||
32 | headers: { Accept: "application/vnd.github.v3+json" } | ||
33 | }) | ||
34 | .then(res => res.json()); | ||
35 | 30 | ||
36 | const artifact = response.assets.find(artifact => artifact.name === artifactFileName); | 31 | if (!response.ok) { |
32 | log.error("Error fetching artifact release info", { | ||
33 | requestUrl, | ||
34 | releaseTag, | ||
35 | artifactFileName, | ||
36 | response: { | ||
37 | headers: response.headers, | ||
38 | status: response.status, | ||
39 | body: await response.text(), | ||
40 | } | ||
41 | }); | ||
42 | |||
43 | throw new Error( | ||
44 | `Got response ${response.status} when trying to fetch ` + | ||
45 | `"${artifactFileName}" artifact release info for ${releaseTag} release` | ||
46 | ); | ||
47 | } | ||
37 | 48 | ||
38 | if (!artifact) return null; | 49 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) |
50 | const release: GithubRelease = await response.json(); | ||
51 | |||
52 | const artifact = release.assets.find(artifact => artifact.name === artifactFileName); | ||
53 | |||
54 | if (!artifact) { | ||
55 | throw new Error( | ||
56 | `Artifact ${artifactFileName} was not found in ${release.name} release!` | ||
57 | ); | ||
58 | } | ||
39 | 59 | ||
40 | return { | 60 | return { |
41 | releaseName: response.name, | 61 | releaseName: release.name, |
42 | downloadUrl: artifact.browser_download_url | 62 | downloadUrl: artifact.browser_download_url |
43 | }; | 63 | }; |
44 | 64 | ||
diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index 685abfdc6..cb5e56844 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts | |||
@@ -63,7 +63,7 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n | |||
63 | 63 | ||
64 | async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { | 64 | async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { |
65 | try { | 65 | try { |
66 | const releaseInfo = (await fetchArtifactReleaseInfo(source.repo, source.file, source.version))!; | 66 | const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.version); |
67 | 67 | ||
68 | await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); | 68 | await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); |
69 | await setServerVersion(source.storage, releaseInfo.releaseName); | 69 | await setServerVersion(source.storage, releaseInfo.releaseName); |
@@ -88,9 +88,12 @@ async function downloadServer(source: BinarySource.GithubRelease): Promise<boole | |||
88 | return false; | 88 | return false; |
89 | } | 89 | } |
90 | 90 | ||
91 | if (!isBinaryAvailable(path.join(source.dir, source.file))) assert(false, | 91 | const binaryPath = path.join(source.dir, source.file); |
92 | |||
93 | assert(isBinaryAvailable(binaryPath), | ||
92 | `Downloaded language server binary is not functional.` + | 94 | `Downloaded language server binary is not functional.` + |
93 | `Downloaded from: ${JSON.stringify(source, null, 4)}` | 95 | `Downloaded from GitHub repo ${source.repo.owner}/${source.repo.name} ` + |
96 | `to ${binaryPath}` | ||
94 | ); | 97 | ); |
95 | 98 | ||
96 | vscode.window.showInformationMessage( | 99 | vscode.window.showInformationMessage( |