Skip to content

Commit cd549f8

Browse files
fix: Avoid "install packages" action option when no packages are selected
1 parent d63a585 commit cd549f8

File tree

5 files changed

+97
-17
lines changed

5 files changed

+97
-17
lines changed

locales/bundle.l10n.jsonc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"No fix available yet.": "", // The flaw is not yet known to be resolved in a future release.
3535
"If possible, downgrade to version {0}.": "", // But it is possible to downgrade to a version where the flaw does not exist.
3636
"Details": "", // Link where you can learn more about the flaw.
37-
"Install packages": "", // Forces the display of the notification suggesting to update the package.
37+
"Install package": "", // Forces the display of the notification suggesting to update the package (one package to be installed).
38+
"Install packages": "", // Forces the display of the notification suggesting to update the package (two or more packages to be installed).
3839

3940
// DocumentDecoration.ts related.
4041
"Install pending": "", // The package was never installed, but the version entered by the user is the latest available.

locales/bundle.l10n.pt-br.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"No fix available yet.": "Ainda não há uma correção disponível.",
2626
"If possible, downgrade to version {0}.": "Se possível, realize um downgrade para a versão {0}.",
2727
"Details": "Detalhes",
28+
"Install package": "Instalar dependência",
2829
"Install packages": "Instalar dependências",
2930

3031
"Install pending": "Instalação pendente",

src/CodeAction.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "vscode"
1111

1212
import { COMMAND_INSTALL_REQUEST } from "./Command"
13-
import { PackageRelatedDiagnostic } from "./Diagnostic"
13+
import { DiagnosticType, PackageRelatedDiagnostic } from "./Diagnostic"
1414
import { name as packageName } from "./plugin.json"
1515
import { hasMajorUpdateProtection } from "./Settings"
1616

@@ -30,7 +30,8 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
3030
(diagnostic) =>
3131
typeof diagnostic.code === "object" &&
3232
diagnostic.code.value === DIAGNOSTIC_ACTION &&
33-
(!PackageRelatedDiagnostic.is(diagnostic) || diagnostic.isSelectable)
33+
(!PackageRelatedDiagnostic.is(diagnostic) ||
34+
diagnostic.type === DiagnosticType.GENERAL)
3435
) as PackageRelatedDiagnostic[]
3536

3637
// Checks if an CodeAction comes through a diagnostic.
@@ -39,21 +40,27 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
3940
)
4041

4142
// Checks if there are any packages waiting to be installed.
42-
let requiresInstall = false
43+
let requiresInstallCount = 0
4344

4445
for (const diagnostic of diagnosticsAll) {
4546
if (
4647
PackageRelatedDiagnostic.is(diagnostic) &&
47-
(await diagnostic.packageRelated.requiresInstallCommand())
48+
diagnostic.type === DiagnosticType.READY_TO_INSTALL &&
49+
diagnostic.range.intersection(range) !== undefined
4850
) {
49-
requiresInstall = true
50-
break
51+
requiresInstallCount++
52+
53+
if (requiresInstallCount >= 2) {
54+
break
55+
}
5156
}
5257
}
5358

5459
if (!diagnosticsSelected.length) {
55-
if (requiresInstall) {
56-
return Promise.all([this.createInstallAction(document)])
60+
if (requiresInstallCount) {
61+
return Promise.all([
62+
this.createInstallAction(document, requiresInstallCount),
63+
])
5764
}
5865

5966
return Promise.resolve([])
@@ -161,8 +168,10 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
161168
}
162169
}
163170

164-
if (requiresInstall) {
165-
diagnosticsPromises.push(this.createInstallAction(document))
171+
if (requiresInstallCount) {
172+
diagnosticsPromises.push(
173+
this.createInstallAction(document, requiresInstallCount)
174+
)
166175
}
167176

168177
return Promise.all(diagnosticsPromises)
@@ -247,10 +256,13 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
247256
}
248257

249258
private async createInstallAction(
250-
document: TextDocument
259+
document: TextDocument,
260+
requiresInstallCount: number
251261
): Promise<CodeAction> {
252262
const action = new CodeAction(
253-
l10n.t("Install packages"),
263+
requiresInstallCount === 1
264+
? l10n.t("Install package")
265+
: l10n.t("Install packages"),
254266
CodeActionKind.QuickFix
255267
)
256268

src/Diagnostic.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,19 @@ export const diagnosticSubscribe = (
108108
)
109109
}
110110

111+
export enum DiagnosticType {
112+
GENERAL,
113+
READY_TO_INSTALL,
114+
}
115+
111116
export class PackageRelatedDiagnostic extends Diagnostic {
112117
constructor(
113118
range: Range,
114119
message: string,
115120
severity: DiagnosticSeverity,
116121
document: TextDocument,
117122
public packageRelated: PackageInfo,
118-
public isSelectable = true
123+
public type = DiagnosticType.GENERAL
119124
) {
120125
super(range, message, severity)
121126

@@ -185,7 +190,7 @@ export const getPackageDiagnostic = async (
185190
DiagnosticSeverity.Information,
186191
document,
187192
packageInfo,
188-
false
193+
DiagnosticType.READY_TO_INSTALL
189194
)
190195
}
191196

src/extension.test.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,21 @@ describe("package diagnostics", () => {
183183

184184
expect(diagnostics[0]?.message).toContain("1.0.1")
185185
expect(decorations[0]).toContain("Update available:")
186+
expect(decorations[0]).not.toContain("(attention: major update!)")
187+
})
188+
189+
it("valid dependency, upgrading to major pre-release", async () => {
190+
const { decorations } = await vscodeSimulator({
191+
packageJson: { dependencies: { "npm-outdated": "^2.0.0-alpha" } },
192+
packagesInstalled: { "npm-outdated": "1.0.0" },
193+
packagesRepository: {
194+
"npm-outdated": ["1.0.0", "2.0.0-alpha", "2.0.0"],
195+
},
196+
})
197+
198+
expect(decorations[0]).toContain("Update available:")
199+
expect(decorations[0]).toContain("2.0.0")
200+
expect(decorations[0]).toContain("(attention: major update!)")
186201
})
187202

188203
it("valid dependency, latest available version", async () => {
@@ -349,14 +364,60 @@ describe("code actions", () => {
349364
expect(actions).toHaveLength(0)
350365
})
351366

352-
it("no package selected, awaiting for installing packages", async () => {
367+
it("no package selected, must not have any action", async () => {
353368
const { actions } = await vscodeSimulator({
354369
packageJson: { dependencies: { "npm-outdated": "^1.0.1" } },
355370
packagesInstalled: { "npm-outdated": "1.0.0" },
356371
packagesRepository: { "npm-outdated": ["1.0.0", "1.0.1"] },
357372
selectFirsts: 0,
358373
})
359374

375+
expect(actions).toHaveLength(0)
376+
})
377+
378+
it("selected a specific package, ready to install", async () => {
379+
const { actions } = await vscodeSimulator({
380+
packageJson: {
381+
dependencies: {
382+
"@types/jest": "^1.0.1",
383+
"npm-outdated": "^1.0.0",
384+
},
385+
},
386+
packagesInstalled: {
387+
"@types/jest": "1.0.0",
388+
"npm-outdated": "1.0.0",
389+
},
390+
packagesRepository: {
391+
"@types/jest": ["1.0.0", "1.0.1"],
392+
"npm-outdated": ["1.0.0", "1.0.1"],
393+
},
394+
selectFirsts: 2,
395+
})
396+
397+
expect(actions[0]?.title).toBe('Update "npm-outdated" to 1.0.1')
398+
expect(actions[1]?.title).toBe("Install package")
399+
expect(actions).toHaveLength(2)
400+
})
401+
402+
it("selected two packages, ready to install", async () => {
403+
const { actions } = await vscodeSimulator({
404+
packageJson: {
405+
dependencies: {
406+
"@types/jest": "^1.0.1",
407+
"npm-outdated": "^1.0.1",
408+
},
409+
},
410+
packagesInstalled: {
411+
"@types/jest": "1.0.0",
412+
"npm-outdated": "1.0.0",
413+
},
414+
packagesRepository: {
415+
"@types/jest": ["1.0.0", "1.0.1"],
416+
"npm-outdated": ["1.0.0", "1.0.1"],
417+
},
418+
selectFirsts: 2,
419+
})
420+
360421
expect(actions[0]?.title).toBe("Install packages")
361422
expect(actions).toHaveLength(1)
362423
})
@@ -471,7 +532,7 @@ describe("code actions", () => {
471532
})
472533

473534
expect(actions[0]?.title).toBe("Update 2 selected packages")
474-
expect(actions[1]?.title).toBe("Install packages")
535+
expect(actions[1]?.title).toBe("Install package")
475536
expect(actions).toHaveLength(2)
476537
})
477538

0 commit comments

Comments
 (0)