Skip to content

Commit 2c674e4

Browse files
committed
Review comments 2
1 parent 784bb1f commit 2c674e4

16 files changed

+1016
-997
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@
316316
"eventsource": "^3.0.6",
317317
"find-process": "https://github.com/coder/find-process#fix/sequoia-compat",
318318
"jsonc-parser": "^3.3.1",
319-
"memfs": "^4.17.1",
320319
"node-forge": "^1.3.1",
321320
"openpgp": "^6.2.0",
322321
"pretty-bytes": "^7.0.0",
@@ -351,6 +350,7 @@
351350
"eslint-plugin-prettier": "^5.4.1",
352351
"glob": "^10.4.2",
353352
"jsonc-eslint-parser": "^2.4.0",
353+
"memfs": "^4.46.0",
354354
"nyc": "^17.1.0",
355355
"prettier": "^3.5.3",
356356
"ts-loader": "^9.5.1",

src/__mocks__/testHelpers.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,62 @@ export class MockUserInteraction {
213213
);
214214
}
215215
}
216+
217+
// Simple in-memory implementation of Memento
218+
export class InMemoryMemento implements vscode.Memento {
219+
private storage = new Map<string, unknown>();
220+
221+
get<T>(key: string): T | undefined;
222+
get<T>(key: string, defaultValue: T): T;
223+
get<T>(key: string, defaultValue?: T): T | undefined {
224+
return this.storage.has(key) ? (this.storage.get(key) as T) : defaultValue;
225+
}
226+
227+
async update(key: string, value: unknown): Promise<void> {
228+
if (value === undefined) {
229+
this.storage.delete(key);
230+
} else {
231+
this.storage.set(key, value);
232+
}
233+
return Promise.resolve();
234+
}
235+
236+
keys(): readonly string[] {
237+
return Array.from(this.storage.keys());
238+
}
239+
}
240+
241+
// Simple in-memory implementation of SecretStorage
242+
export class InMemorySecretStorage implements vscode.SecretStorage {
243+
private secrets = new Map<string, string>();
244+
private isCorrupted = false;
245+
246+
onDidChange: vscode.Event<vscode.SecretStorageChangeEvent> = () => ({
247+
dispose: () => {},
248+
});
249+
250+
async get(key: string): Promise<string | undefined> {
251+
if (this.isCorrupted) {
252+
return Promise.reject(new Error("Storage corrupted"));
253+
}
254+
return this.secrets.get(key);
255+
}
256+
257+
async store(key: string, value: string): Promise<void> {
258+
if (this.isCorrupted) {
259+
return Promise.reject(new Error("Storage corrupted"));
260+
}
261+
this.secrets.set(key, value);
262+
}
263+
264+
async delete(key: string): Promise<void> {
265+
if (this.isCorrupted) {
266+
return Promise.reject(new Error("Storage corrupted"));
267+
}
268+
this.secrets.delete(key);
269+
}
270+
271+
corruptStorage(): void {
272+
this.isCorrupted = true;
273+
}
274+
}
Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import fs from "fs/promises";
22
import os from "os";
33
import path from "path";
44
import { beforeAll, describe, expect, it } from "vitest";
5-
import * as cli from "./cliManager";
5+
import * as cli from "./cliUtils";
66

7-
describe("cliManager", () => {
7+
describe("cliUtils", () => {
88
const tmp = path.join(os.tmpdir(), "vscode-coder-tests");
99

1010
beforeAll(async () => {
@@ -25,14 +25,6 @@ describe("cliManager", () => {
2525
expect((await cli.stat(binPath))?.size).toBe(4);
2626
});
2727

28-
it("rm", async () => {
29-
const binPath = path.join(tmp, "rm");
30-
await cli.rm(binPath);
31-
32-
await fs.writeFile(binPath, "test");
33-
await cli.rm(binPath);
34-
});
35-
3628
// TODO: CI only runs on Linux but we should run it on Windows too.
3729
it("version", async () => {
3830
const binPath = path.join(tmp, "version");

src/cliManager.ts renamed to src/cliUtils.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,6 @@ export async function stat(binPath: string): Promise<Stats | undefined> {
2121
}
2222
}
2323

24-
/**
25-
* Remove the path. Throw if unable to remove.
26-
*/
27-
export async function rm(binPath: string): Promise<void> {
28-
try {
29-
await fs.rm(binPath, { force: true });
30-
} catch (error) {
31-
// Just in case; we should never get an ENOENT because of force: true.
32-
if ((error as NodeJS.ErrnoException)?.code !== "ENOENT") {
33-
throw error;
34-
}
35-
}
36-
}
37-
3824
// util.promisify types are dynamic so there is no concrete type we can import
3925
// and we have to make our own.
4026
type ExecException = ExecFileException & { stdout?: string; stderr?: string };

src/commands.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import * as vscode from "vscode";
99
import { createWorkspaceIdentifier, extractAgents } from "./api/api-helper";
1010
import { CoderApi } from "./api/coderApi";
1111
import { needToken } from "./api/utils";
12-
import { BinaryManager } from "./core/binaryManager";
13-
import { CliConfigManager } from "./core/cliConfig";
12+
import { CliManager } from "./core/cliManager";
1413
import { MementoManager } from "./core/mementoManager";
1514
import { PathResolver } from "./core/pathResolver";
1615
import { SecretsManager } from "./core/secretsManager";
@@ -25,7 +24,6 @@ import {
2524
} from "./workspacesProvider";
2625

2726
export class Commands {
28-
private readonly cliConfigManager: CliConfigManager;
2927
// These will only be populated when actively connected to a workspace and are
3028
// used in commands. Because commands can be executed by the user, it is not
3129
// possible to pass in arguments, so we have to store the current workspace
@@ -44,10 +42,8 @@ export class Commands {
4442
private readonly pathResolver: PathResolver,
4543
private readonly mementoManager: MementoManager,
4644
private readonly secretsManager: SecretsManager,
47-
private readonly binaryManager: BinaryManager,
48-
) {
49-
this.cliConfigManager = new CliConfigManager(pathResolver);
50-
}
45+
private readonly cliManager: CliManager,
46+
) {}
5147

5248
/**
5349
* Find the requested agent if specified, otherwise return the agent if there
@@ -209,7 +205,7 @@ export class Commands {
209205
await this.secretsManager.setSessionToken(res.token);
210206

211207
// Store on disk to be used by the cli.
212-
await this.cliConfigManager.configure(label, url, res.token);
208+
await this.cliManager.configure(label, url, res.token);
213209

214210
// These contexts control various menu items and the sidebar.
215211
await vscode.commands.executeCommand(
@@ -515,7 +511,7 @@ export class Commands {
515511
if (!url) {
516512
throw new Error("No coder url found for sidebar");
517513
}
518-
const binary = await this.binaryManager.fetchBinary(
514+
const binary = await this.cliManager.fetchBinary(
519515
this.restClient,
520516
toSafeHost(url),
521517
);

0 commit comments

Comments
 (0)