Skip to content

Commit 4b5f964

Browse files
authored
feat(vscode): add update-cli command (#751)
1 parent 5e764e7 commit 4b5f964

File tree

10 files changed

+159
-12
lines changed

10 files changed

+159
-12
lines changed

extensions/vscode/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Dart Frog can be installed from the [VS Code Marketplace](https://marketplace.vi
1414
| Command | Description |
1515
| --------------------------- | -------------------------- |
1616
| `Dart Frog: Install CLI` | Installs Dart Frog CLI |
17+
| `Dart Frog: Update CLI` | Updates Dart Frog CLI |
1718
| `Dart Frog: New Route` | Generates a new route |
1819
| `Dart Frog: New Middleware` | Generates a new middleware |
1920

extensions/vscode/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
"command": "extension.install-cli",
3636
"title": "Dart Frog: Install CLI"
3737
},
38+
{
39+
"command": "extension.update-cli",
40+
"title": "Dart Frog: Update CLI"
41+
},
3842
{
3943
"command": "extension.new-route",
4044
"title": "Dart Frog: New Route"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from "./install-cli";
2+
export * from "./update-cli";
23
export * from "./new-route";
34
export * from "./new-middleware";

extensions/vscode/src/commands/install-cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
const cp = require("child_process");
22

33
import { window, ProgressOptions } from "vscode";
4-
import { isDartFrogCliInstalled } from "../utils/utils";
4+
import { isDartFrogCLIInstalled } from "../utils/utils";
55

66
/**
77
* Installs Dart Frog CLI in the user's system if not already installed.
88
*/
99
export const installCLI = async (): Promise<void> => {
10-
if (!isDartFrogCliInstalled()) {
10+
if (!isDartFrogCLIInstalled()) {
1111
const options: ProgressOptions = {
1212
location: 15,
1313
title: "Installing Dart Frog CLI...",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const cp = require("child_process");
2+
3+
import { window, ProgressOptions } from "vscode";
4+
import { isDartFrogCLIInstalled } from "../utils/utils";
5+
6+
/**
7+
* Update Dart Frog CLI in the user's system.
8+
*
9+
* If Dart Frog CLI is not installed, this function does nothing.
10+
*/
11+
export const updateCLI = async (): Promise<void> => {
12+
if (!isDartFrogCLIInstalled()) {
13+
return;
14+
}
15+
16+
const options: ProgressOptions = {
17+
location: 15,
18+
title: "Updating Dart Frog CLI...",
19+
};
20+
window.withProgress(options, updateDartFrogCLIVersion);
21+
};
22+
23+
/**
24+
* Updates Dart Frog CLI to the latest version.
25+
*
26+
* @returns {Promise<void>} A promise that resolves when the update is
27+
* complete.
28+
*/
29+
async function updateDartFrogCLIVersion(): Promise<void> {
30+
await cp.exec(
31+
`dart_frog update`,
32+
function (error: Error, stdout: String, stderr: String) {
33+
if (error) {
34+
window.showErrorMessage(error.message);
35+
}
36+
}
37+
);
38+
}

extensions/vscode/src/extension.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as vscode from "vscode";
2-
import { installCLI, newRoute, newMiddleware } from "./commands";
2+
import { installCLI, newRoute, newMiddleware, updateCLI } from "./commands";
33

44
/**
55
* This method is called when the extension is activated.
@@ -16,6 +16,7 @@ export function activate(
1616

1717
context.subscriptions.push(
1818
vscode.commands.registerCommand("extension.install-cli", installCLI),
19+
vscode.commands.registerCommand("extension.update-cli", updateCLI),
1920
vscode.commands.registerCommand("extension.new-route", newRoute),
2021
vscode.commands.registerCommand("extension.new-middleware", newMiddleware)
2122
);

extensions/vscode/src/test/suite/commands/install-cli.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { afterEach, beforeEach } from "mocha";
55
import * as assert from "assert";
66

77
suite("install-cli command", () => {
8-
const updateCommand = `dart pub global activate dart_frog_cli`;
8+
const installCommand = `dart pub global activate dart_frog_cli`;
99

1010
let vscodeStub: any;
1111
let childProcessStub: any;
@@ -24,7 +24,7 @@ suite("install-cli command", () => {
2424
execSync: sinon.stub(),
2525
};
2626
utilsStub = {
27-
isDartFrogCliInstalled: sinon.stub(),
27+
isDartFrogCLIInstalled: sinon.stub(),
2828
};
2929

3030
command = proxyquire("../../../commands/install-cli", {
@@ -41,19 +41,19 @@ suite("install-cli command", () => {
4141
});
4242

4343
test("does not install if Dart Frog CLI is already installed", async () => {
44-
utilsStub.isDartFrogCliInstalled.returns(true);
44+
utilsStub.isDartFrogCLIInstalled.returns(true);
4545

4646
await command.installCLI();
4747

4848
const wantedCalls = childProcessStub.exec
4949
.getCalls()
50-
.filter((call: any) => call.args[0] === updateCommand);
50+
.filter((call: any) => call.args[0] === installCommand);
5151
assert.equal(wantedCalls.length, 0);
5252
});
5353

5454
suite("installs Dart Frog CLI", () => {
5555
beforeEach(() => {
56-
utilsStub.isDartFrogCliInstalled.returns(false);
56+
utilsStub.isDartFrogCLIInstalled.returns(false);
5757
});
5858

5959
test("when not already installed", async () => {
@@ -62,7 +62,7 @@ suite("install-cli command", () => {
6262
let progressFunction = vscodeStub.window.withProgress.getCall(0).args[1];
6363
await progressFunction();
6464

65-
sinon.assert.calledWith(childProcessStub.exec, updateCommand);
65+
sinon.assert.calledWith(childProcessStub.exec, installCommand);
6666
});
6767

6868
test("shows progress", async () => {
@@ -76,7 +76,7 @@ suite("install-cli command", () => {
7676

7777
test("shows error message on failure", async () => {
7878
const error = new Error("Command failed");
79-
childProcessStub.exec.withArgs(updateCommand).yields(error);
79+
childProcessStub.exec.withArgs(installCommand).yields(error);
8080

8181
await command.installCLI();
8282

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
const sinon = require("sinon");
2+
var proxyquire = require("proxyquire");
3+
4+
import { afterEach, beforeEach } from "mocha";
5+
import * as assert from "assert";
6+
7+
suite("update-cli", () => {
8+
const updateCommand = `dart_frog update`;
9+
10+
let vscodeStub: any;
11+
let childProcessStub: any;
12+
let utilsStub: any;
13+
let command: any;
14+
15+
beforeEach(() => {
16+
vscodeStub = {
17+
window: {
18+
showErrorMessage: sinon.stub(),
19+
withProgress: sinon.stub(),
20+
},
21+
};
22+
childProcessStub = {
23+
exec: sinon.stub(),
24+
execSync: sinon.stub(),
25+
};
26+
utilsStub = {
27+
isDartFrogCLIInstalled: sinon.stub(),
28+
};
29+
30+
command = proxyquire("../../../commands/update-cli", {
31+
vscode: vscodeStub,
32+
// eslint-disable-next-line @typescript-eslint/naming-convention
33+
child_process: childProcessStub,
34+
// eslint-disable-next-line @typescript-eslint/naming-convention
35+
"../utils/utils": utilsStub,
36+
});
37+
});
38+
39+
afterEach(() => {
40+
sinon.restore();
41+
});
42+
43+
suite("updates Dart Frog CLI", () => {
44+
beforeEach(() => {
45+
utilsStub.isDartFrogCLIInstalled.returns(true);
46+
});
47+
48+
test("when already installed", async () => {
49+
await command.updateCLI();
50+
51+
let progressFunction = vscodeStub.window.withProgress.getCall(0).args[1];
52+
await progressFunction();
53+
54+
sinon.assert.calledWith(childProcessStub.exec, updateCommand);
55+
});
56+
57+
test("shows progress", async () => {
58+
await command.updateCLI();
59+
60+
const progressOptions = vscodeStub.window.withProgress.getCall(0).args[0];
61+
62+
assert.strictEqual(progressOptions.title, "Updating Dart Frog CLI...");
63+
assert.strictEqual(progressOptions.location, 15);
64+
});
65+
66+
test("shows error message on failure", async () => {
67+
const error = new Error("Command failed");
68+
childProcessStub.exec.withArgs(updateCommand).yields(error);
69+
70+
await command.updateCLI();
71+
72+
const progressFunction =
73+
vscodeStub.window.withProgress.getCall(0).args[1];
74+
await progressFunction();
75+
76+
sinon.assert.calledWith(
77+
vscodeStub.window.showErrorMessage,
78+
error.message
79+
);
80+
});
81+
});
82+
83+
test("does nothing when not installed", async () => {
84+
utilsStub.isDartFrogCLIInstalled.returns(false);
85+
86+
await command.updateCLI();
87+
88+
sinon.assert.notCalled(childProcessStub.exec);
89+
sinon.assert.notCalled(vscodeStub.window.withProgress);
90+
sinon.assert.notCalled(vscodeStub.window.showErrorMessage);
91+
});
92+
});

extensions/vscode/src/test/suite/extension.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var proxyquire = require("proxyquire");
33

44
import * as assert from "assert";
55
import * as vscode from "vscode";
6-
import { installCLI, newMiddleware, newRoute } from "../../commands";
6+
import { installCLI, newMiddleware, newRoute, updateCLI } from "../../commands";
77
import { afterEach, beforeEach } from "mocha";
88

99
suite("activate", () => {
@@ -51,6 +51,16 @@ suite("activate", () => {
5151
);
5252
});
5353

54+
test("update-cli", async () => {
55+
extension.activate(context);
56+
57+
sinon.assert.calledWith(
58+
vscodeStub.commands.registerCommand,
59+
"extension.update-cli",
60+
updateCLI
61+
);
62+
});
63+
5464
test("new-route", async () => {
5565
extension.activate(context);
5666

extensions/vscode/src/utils/cli-version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ export function isCompatibleCLIVersion(version: String): Boolean {
4141
* @returns {boolean} True if the user has Dart Frog CLI installed in their
4242
* system, false otherwise.
4343
*/
44-
export function isDartFrogCliInstalled(): boolean {
44+
export function isDartFrogCLIInstalled(): boolean {
4545
return readDartFrogVersion() !== undefined;
4646
}

0 commit comments

Comments
 (0)