aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/installation
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/installation')
-rw-r--r--editors/code/src/installation/download_artifact.ts21
-rw-r--r--editors/code/src/installation/fetch_artifact_release_info.ts58
-rw-r--r--editors/code/src/installation/server.ts9
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
6import { ArtifactReleaseInfo } from "./interfaces"; 6import { ArtifactReleaseInfo } from "./interfaces";
7import { downloadFile } from "./download_file"; 7import { downloadFile } from "./download_file";
8import { 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
5const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; 5const 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 */
13export async function fetchArtifactReleaseInfo( 14export 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
64async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { 64async 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(