aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/installation
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-03-16 18:23:38 +0000
committerAleksey Kladov <[email protected]>2020-03-16 21:02:11 +0000
commitae662617a2bc49d025adaf9c4a8ff2dfa557d36c (patch)
treef321ad0a529283bbb276095da7644d8f1ba663d2 /editors/code/src/installation
parent2e9b6320e66cb764b9683a38c284a06b7c35aab6 (diff)
Separate persistent mutable state from config
That way, we clearly see which things are not change, and we also clearly see which things are persistent.
Diffstat (limited to 'editors/code/src/installation')
-rw-r--r--editors/code/src/installation/extension.ts16
-rw-r--r--editors/code/src/installation/server.ts21
2 files changed, 20 insertions, 17 deletions
diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts
index eea6fded2..a1db96f05 100644
--- a/editors/code/src/installation/extension.ts
+++ b/editors/code/src/installation/extension.ts
@@ -7,6 +7,7 @@ import { Config, UpdatesChannel } from "../config";
7import { ArtifactReleaseInfo, ArtifactSource } from "./interfaces"; 7import { ArtifactReleaseInfo, ArtifactSource } from "./interfaces";
8import { downloadArtifactWithProgressUi } from "./downloads"; 8import { downloadArtifactWithProgressUi } from "./downloads";
9import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; 9import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info";
10import { PersistentState } from "../persistent_state";
10 11
11const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25; 12const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25;
12 13
@@ -14,7 +15,7 @@ const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25;
14 * Installs `stable` or latest `nightly` version or does nothing if the current 15 * Installs `stable` or latest `nightly` version or does nothing if the current
15 * extension version is what's needed according to `desiredUpdateChannel`. 16 * extension version is what's needed according to `desiredUpdateChannel`.
16 */ 17 */
17export async function ensureProperExtensionVersion(config: Config): Promise<never | void> { 18export async function ensureProperExtensionVersion(config: Config, state: PersistentState): Promise<never | void> {
18 // User has built lsp server from sources, she should manage updates manually 19 // User has built lsp server from sources, she should manage updates manually
19 if (config.serverSource?.type === ArtifactSource.Type.ExplicitPath) return; 20 if (config.serverSource?.type === ArtifactSource.Type.ExplicitPath) return;
20 21
@@ -23,7 +24,7 @@ export async function ensureProperExtensionVersion(config: Config): Promise<neve
23 24
24 if (currentUpdChannel === UpdatesChannel.Stable) { 25 if (currentUpdChannel === UpdatesChannel.Stable) {
25 // Release date is present only when we are on nightly 26 // Release date is present only when we are on nightly
26 await config.installedNightlyExtensionReleaseDate.set(null); 27 await state.installedNightlyExtensionReleaseDate.set(null);
27 } 28 }
28 29
29 if (desiredUpdChannel === UpdatesChannel.Stable) { 30 if (desiredUpdChannel === UpdatesChannel.Stable) {
@@ -39,10 +40,10 @@ export async function ensureProperExtensionVersion(config: Config): Promise<neve
39 if (currentUpdChannel === UpdatesChannel.Stable) { 40 if (currentUpdChannel === UpdatesChannel.Stable) {
40 if (!await askToDownloadProperExtensionVersion(config)) return; 41 if (!await askToDownloadProperExtensionVersion(config)) return;
41 42
42 return await tryDownloadNightlyExtension(config); 43 return await tryDownloadNightlyExtension(config, state);
43 } 44 }
44 45
45 const currentExtReleaseDate = config.installedNightlyExtensionReleaseDate.get(); 46 const currentExtReleaseDate = state.installedNightlyExtensionReleaseDate.get();
46 47
47 if (currentExtReleaseDate === null) { 48 if (currentExtReleaseDate === null) {
48 void vscode.window.showErrorMessage( 49 void vscode.window.showErrorMessage(
@@ -66,9 +67,9 @@ export async function ensureProperExtensionVersion(config: Config): Promise<neve
66 return; 67 return;
67 } 68 }
68 69
69 await tryDownloadNightlyExtension(config, releaseInfo => { 70 await tryDownloadNightlyExtension(config, state, releaseInfo => {
70 assert( 71 assert(
71 currentExtReleaseDate.getTime() === config.installedNightlyExtensionReleaseDate.get()?.getTime(), 72 currentExtReleaseDate.getTime() === state.installedNightlyExtensionReleaseDate.get()?.getTime(),
72 "Other active VSCode instance has reinstalled the extension" 73 "Other active VSCode instance has reinstalled the extension"
73 ); 74 );
74 75
@@ -111,6 +112,7 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "")
111 */ 112 */
112const tryDownloadNightlyExtension = notReentrant(async ( 113const tryDownloadNightlyExtension = notReentrant(async (
113 config: Config, 114 config: Config,
115 state: PersistentState,
114 shouldDownload: (releaseInfo: ArtifactReleaseInfo) => boolean = () => true 116 shouldDownload: (releaseInfo: ArtifactReleaseInfo) => boolean = () => true
115): Promise<never | void> => { 117): Promise<never | void> => {
116 const vsixSource = config.nightlyVsixSource; 118 const vsixSource = config.nightlyVsixSource;
@@ -124,7 +126,7 @@ const tryDownloadNightlyExtension = notReentrant(async (
124 const vsixPath = path.join(vsixSource.dir, vsixSource.file); 126 const vsixPath = path.join(vsixSource.dir, vsixSource.file);
125 127
126 await vscodeInstallExtensionFromVsix(vsixPath); 128 await vscodeInstallExtensionFromVsix(vsixPath);
127 await config.installedNightlyExtensionReleaseDate.set(releaseInfo.releaseDate); 129 await state.installedNightlyExtensionReleaseDate.set(releaseInfo.releaseDate);
128 await fs.unlink(vsixPath); 130 await fs.unlink(vsixPath);
129 131
130 await vscodeReloadWindow(); // never returns 132 await vscodeReloadWindow(); // never returns
diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts
index 05730a778..05d326131 100644
--- a/editors/code/src/installation/server.ts
+++ b/editors/code/src/installation/server.ts
@@ -7,8 +7,9 @@ import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info";
7import { downloadArtifactWithProgressUi } from "./downloads"; 7import { downloadArtifactWithProgressUi } from "./downloads";
8import { log, assert, notReentrant } from "../util"; 8import { log, assert, notReentrant } from "../util";
9import { Config, NIGHTLY_TAG } from "../config"; 9import { Config, NIGHTLY_TAG } from "../config";
10import { PersistentState } from "../persistent_state";
10 11
11export async function ensureServerBinary(config: Config): Promise<null | string> { 12export async function ensureServerBinary(config: Config, state: PersistentState): Promise<null | string> {
12 const source = config.serverSource; 13 const source = config.serverSource;
13 14
14 if (!source) { 15 if (!source) {
@@ -37,7 +38,7 @@ export async function ensureServerBinary(config: Config): Promise<null | string>
37 return null; 38 return null;
38 } 39 }
39 case ArtifactSource.Type.GithubRelease: { 40 case ArtifactSource.Type.GithubRelease: {
40 if (!shouldDownloadServer(source, config)) { 41 if (!shouldDownloadServer(state, source)) {
41 return path.join(source.dir, source.file); 42 return path.join(source.dir, source.file);
42 } 43 }
43 44
@@ -50,24 +51,24 @@ export async function ensureServerBinary(config: Config): Promise<null | string>
50 if (userResponse !== "Download now") return null; 51 if (userResponse !== "Download now") return null;
51 } 52 }
52 53
53 return await downloadServer(source, config); 54 return await downloadServer(state, source);
54 } 55 }
55 } 56 }
56} 57}
57 58
58function shouldDownloadServer( 59function shouldDownloadServer(
60 state: PersistentState,
59 source: ArtifactSource.GithubRelease, 61 source: ArtifactSource.GithubRelease,
60 config: Config
61): boolean { 62): boolean {
62 if (!isBinaryAvailable(path.join(source.dir, source.file))) return true; 63 if (!isBinaryAvailable(path.join(source.dir, source.file))) return true;
63 64
64 const installed = { 65 const installed = {
65 tag: config.serverReleaseTag.get(), 66 tag: state.serverReleaseTag.get(),
66 date: config.serverReleaseDate.get() 67 date: state.serverReleaseDate.get()
67 }; 68 };
68 const required = { 69 const required = {
69 tag: source.tag, 70 tag: source.tag,
70 date: config.installedNightlyExtensionReleaseDate.get() 71 date: state.installedNightlyExtensionReleaseDate.get()
71 }; 72 };
72 73
73 log.debug("Installed server:", installed, "required:", required); 74 log.debug("Installed server:", installed, "required:", required);
@@ -86,16 +87,16 @@ function shouldDownloadServer(
86 * Enforcing no reentrancy for this is best-effort. 87 * Enforcing no reentrancy for this is best-effort.
87 */ 88 */
88const downloadServer = notReentrant(async ( 89const downloadServer = notReentrant(async (
90 state: PersistentState,
89 source: ArtifactSource.GithubRelease, 91 source: ArtifactSource.GithubRelease,
90 config: Config,
91): Promise<null | string> => { 92): Promise<null | string> => {
92 try { 93 try {
93 const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag); 94 const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag);
94 95
95 await downloadArtifactWithProgressUi(releaseInfo, source.file, source.dir, "language server"); 96 await downloadArtifactWithProgressUi(releaseInfo, source.file, source.dir, "language server");
96 await Promise.all([ 97 await Promise.all([
97 config.serverReleaseTag.set(releaseInfo.releaseName), 98 state.serverReleaseTag.set(releaseInfo.releaseName),
98 config.serverReleaseDate.set(releaseInfo.releaseDate) 99 state.serverReleaseDate.set(releaseInfo.releaseDate)
99 ]); 100 ]);
100 } catch (err) { 101 } catch (err) {
101 log.downloadError(err, "language server", source.repo.name); 102 log.downloadError(err, "language server", source.repo.name);