Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/create-project/cmd.ts
6458 views
1
/*
2
* cmd.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { basename } from "../../deno_ral/path.ts";
8
9
import { Command } from "cliffy/command/mod.ts";
10
11
import { executionEngine, executionEngines } from "../../execute/engine.ts";
12
import { initializeProjectContextAndEngines } from "../command-utils.ts";
13
14
import { projectCreate } from "../../project/project-create.ts";
15
import {
16
parseProjectType,
17
projectType,
18
projectTypeAliases,
19
projectTypes,
20
} from "../../project/types/project-types.ts";
21
import { kMarkdownEngine } from "../../execute/types.ts";
22
23
// ensures project types are registered
24
import "../../project/types/register.ts";
25
26
const kProjectTypes = projectTypes();
27
const kProjectTypeAliases = projectTypeAliases();
28
const kProjectTypesAndAliases = [...kProjectTypes, ...kProjectTypeAliases];
29
30
const kEditorTypes = ["source", "visual"];
31
32
export const createProjectCommand = new Command()
33
.name("create-project")
34
.description("Create a project for rendering multiple documents")
35
.arguments("[dir:string]")
36
.hidden()
37
.option(
38
"--title <title:string>",
39
"Project title",
40
)
41
.option(
42
"--type <type:string>",
43
`Project type (${kProjectTypes.join(", ")})`,
44
)
45
.option(
46
"--template <type:string>",
47
`Use a specific project template`,
48
)
49
.option(
50
"--engine <engine:string>",
51
"Use execution engine (jupyter, knitr, markdown, ...)",
52
{
53
value: (value: string): string[] => {
54
value = value || kMarkdownEngine;
55
// Parse engine:kernel syntax
56
const match = value.match(/(\w+)(:(.+))?$/);
57
if (match) {
58
return [match[1], match[3]];
59
} else {
60
return [value];
61
}
62
},
63
},
64
)
65
.option(
66
"--editor <editor:string>",
67
"Default editor for project ('source' or 'visual')",
68
)
69
.option(
70
"--with-venv [packages:string]",
71
"Create a virtualenv for this project",
72
)
73
.option(
74
"--with-condaenv [packages:string]",
75
"Create a condaenv for this project",
76
)
77
.option(
78
"--no-scaffold",
79
"Don't create initial project file(s)",
80
)
81
.example(
82
"Create a project in the current directory",
83
"quarto create-project",
84
)
85
.example(
86
"Create a project in the 'myproject' directory",
87
"quarto create-project myproject",
88
)
89
.example(
90
"Create a website project",
91
"quarto create-project mysite --type website",
92
)
93
.example(
94
"Create a blog project",
95
"quarto create-project mysite --type website --template blog",
96
)
97
.example(
98
"Create a book project",
99
"quarto create-project mybook --type book",
100
)
101
.example(
102
"Create a website project with jupyter",
103
"quarto create-project mysite --type website --engine jupyter",
104
)
105
.example(
106
"Create a website project with jupyter + kernel",
107
"quarto create-project mysite --type website --engine jupyter:python3",
108
)
109
.example(
110
"Create a book project with knitr",
111
"quarto create-project mybook --type book --engine knitr",
112
)
113
.example(
114
"Create jupyter project with virtualenv",
115
"quarto create-project myproject --engine jupyter --with-venv",
116
)
117
.example(
118
"Create jupyter project with virtualenv + packages",
119
"quarto create-project myproject --engine jupyter --with-venv pandas,matplotlib",
120
)
121
.example(
122
"Create jupyter project with condaenv ",
123
"quarto create-project myproject --engine jupyter --with-condaenv",
124
)
125
.example(
126
"Create jupyter project with condaenv + packages",
127
"quarto create-project myproject --engine jupyter --with-condaenv pandas,matplotlib",
128
)
129
// deno-lint-ignore no-explicit-any
130
.action(async (options: any, dir?: string) => {
131
// Initialize project context and register engines (including external ones)
132
await initializeProjectContextAndEngines();
133
134
if (dir === undefined || dir === ".") {
135
dir = Deno.cwd();
136
}
137
138
const engine = options.engine || [];
139
140
// Validate the engine (after engines are initialized)
141
if (engine[0]) {
142
const engineInstance = executionEngine(engine[0]);
143
if (!engineInstance) {
144
throw new Error(
145
`Unknown execution engine: ${engine[0]}. ` +
146
`Available engines: ${
147
executionEngines().map((e) => e.name).join(", ")
148
}`,
149
);
150
}
151
}
152
153
const envPackages = typeof (options.withVenv) === "string"
154
? options.withVenv.split(",").map((pkg: string) => pkg.trim())
155
: typeof (options.withCondaenv) === "string"
156
? options.withCondaenv.split(",").map((pkg: string) => pkg.trim())
157
: undefined;
158
159
// Parse the project type and template
160
const { type, template } = parseProjectType(options.type);
161
const projectTemplate = options.template || template;
162
163
// Validate the type
164
if (kProjectTypesAndAliases.indexOf(type) === -1) {
165
throw new Error(
166
`Project type must be one of ${
167
kProjectTypes.join(", ")
168
}, but got "${type}".`,
169
);
170
}
171
172
// Validate the editor
173
const editorType = options.editor;
174
if (editorType && !kEditorTypes.includes(editorType)) {
175
throw new Error(
176
`Editor type must be one of ${
177
kEditorTypes.join(", ")
178
}, but got "${editorType}".`,
179
);
180
}
181
182
// Validate the template
183
const projType = projectType(type);
184
if (projectTemplate && !projType.templates?.includes(projectTemplate)) {
185
if (projType.templates) {
186
throw new Error(
187
`Project template must be one of ${
188
projType.templates.join(", ")
189
}, but got "${projectTemplate}".`,
190
);
191
} else {
192
throw new Error(
193
`The project type ${type} does not support any templates.`,
194
);
195
}
196
}
197
198
await projectCreate({
199
dir,
200
type: type,
201
title: options.title || basename(dir),
202
scaffold: !!options.scaffold,
203
engine: engine[0] || kMarkdownEngine,
204
kernel: engine[1],
205
editor: editorType,
206
venv: !!options.withVenv,
207
condaenv: !!options.withCondaenv,
208
envPackages,
209
template: projectTemplate,
210
});
211
});
212
213