Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/list/cmd.ts
3583 views
1
/*
2
* cmd.ts
3
*
4
* Copyright (C) 2021-2022 Posit Software, PBC
5
*/
6
import { Command } from "cliffy/command/mod.ts";
7
import { Table } from "cliffy/table/mod.ts";
8
import { initYamlIntelligenceResourcesFromFilesystem } from "../../core/schema/utils.ts";
9
import { createTempContext } from "../../core/temp.ts";
10
11
import { info } from "../../deno_ral/log.ts";
12
import { createExtensionContext } from "../../extension/extension.ts";
13
import { extensionIdString } from "../../extension/extension-shared.ts";
14
import { Extension, ExtensionContext } from "../../extension/types.ts";
15
import { projectContext } from "../../project/project-context.ts";
16
import { outputTools } from "../../tools/tools-console.ts";
17
import { notebookContext } from "../../render/notebook/notebook-context.ts";
18
19
export const listCommand = new Command()
20
.name("list")
21
.arguments("<type:string>")
22
.description(
23
"Lists an extension or global dependency.",
24
)
25
.example(
26
"List installed extensions",
27
"quarto list extensions",
28
)
29
.example(
30
"List global tools",
31
"quarto list tools",
32
)
33
.action(
34
async (_options: unknown, type: string) => {
35
await initYamlIntelligenceResourcesFromFilesystem();
36
const temp = createTempContext();
37
const extensionContext = createExtensionContext();
38
try {
39
if (type.toLowerCase() === "extensions") {
40
await outputExtensions(Deno.cwd(), extensionContext);
41
} else if (type.toLowerCase() === "tools") {
42
await outputTools();
43
} else {
44
// This is an unrecognized type option
45
info(
46
`Unrecognized option '${type}' - please choose 'tools' or 'extensions'.`,
47
);
48
}
49
} finally {
50
temp.cleanup();
51
}
52
},
53
);
54
55
async function outputExtensions(
56
path: string,
57
extensionContext: ExtensionContext,
58
) {
59
const nbContext = notebookContext();
60
// Provide the with with a list
61
const project = await projectContext(path, nbContext);
62
const extensions = await extensionContext.extensions(
63
path,
64
project?.config,
65
project?.dir,
66
{ builtIn: false },
67
);
68
if (extensions.length === 0) {
69
info(
70
`No extensions are installed in this ${
71
project ? "project" : "directory"
72
}.`,
73
);
74
} else {
75
const extensionEntries: string[][] = [];
76
const provides = (extension: Extension) => {
77
const contribs: string[] = [];
78
if (
79
extension.contributes.filters &&
80
extension.contributes.filters?.length > 0
81
) {
82
contribs.push("filters");
83
}
84
85
if (
86
extension.contributes.shortcodes &&
87
extension.contributes.shortcodes?.length > 0
88
) {
89
contribs.push("shortcodes");
90
}
91
92
if (
93
extension.contributes.formats &&
94
Object.keys(extension.contributes.formats).length > 0
95
) {
96
contribs.push("formats");
97
}
98
return contribs.join(", ");
99
};
100
101
extensions.forEach((ext) => {
102
const row = [
103
extensionIdString(ext.id),
104
ext.version?.toString() || "(none)",
105
`${provides(ext)}`,
106
];
107
extensionEntries.push(row);
108
});
109
110
const table = new Table().header(["Id", "Version", "Contributes"]).body(
111
extensionEntries,
112
).padding(4);
113
info(table.toString());
114
}
115
}
116
117