Skip to content

Commit 1df8ccd

Browse files
Merge pull request #1514 from markscott-ms/1505
Add --clear-output-directory as an option to calm template and docify - fixes #1505
2 parents 5a68b40 + 0c566fd commit 1df8ccd

File tree

7 files changed

+198
-29
lines changed

7 files changed

+198
-29
lines changed

cli/README.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Options:
7474
-p, --pattern <file> Path to the pattern file to use. May be a file path or a URL.
7575
-a, --architecture <file> Path to the pattern architecture file to use. May be a file path or a URL.
7676
-s, --schema-directory <path> Path to the directory containing the meta schemas to use. (default: "../calm/release")
77-
--strict When run in strict mode, the CLI will fail if any warnings are reported. (default: false)
77+
--strict When run in strict mode, the CLI will fail if any warnings are reported. (default: false)
7878
-f, --format <format> The format of the output (choices: "json", "junit", default: "json")
7979
-o, --output <file> Path location at which to output the generated file.
8080
-v, --verbose Enable verbose logging. (default: false)
@@ -198,14 +198,24 @@ Usage: calm template [options]
198198
Generate files from a CALM model using a Handlebars template bundle.
199199
200200
Options:
201-
-a, --architecture <path> Path to the CALM model JSON file.
202-
-b, --bundle <path> Path to the template bundle directory.
201+
-a, --architecture <path> Path to the CALM model JSON file.
203202
-o, --output <path> Path to output directory.
203+
--clear-output-directory Completely delete the contents of the output path before generation.
204+
-b, --bundle <path> Path to the template bundle directory.
205+
-t, --template <path> Path to a single .hbs or .md template file
206+
-d, --template-dir <path> Path to a directory of .hbs/.md templates
204207
-u, --url-to-local-file-mapping <path> Path to mapping file which maps URLs to local paths.
205208
-v, --verbose Enable verbose logging. (default: false)
206209
-h, --help display help for command
207210
```
208211
212+
`calm template` will create the output directory if it does not exist.
213+
214+
If the output directory exists, files will be modified if they already
215+
exist. Files that are not in the template bundle will be unmodified.
216+
The `--clear-output-directory` option changes this behaviour to delete all
217+
files and subdirectories from the output path first.
218+
209219
### Creating a Template Bundle
210220
211221
A template bundle consists of:
@@ -241,13 +251,23 @@ Usage: calm docify [options]
241251
Generate a documentation website off your CALM model.
242252
243253
Options:
244-
-a, --architecture <path> Path to the CALM model JSON file.
254+
-a, --architecture <path> Path to the CALM model JSON file.
245255
-o, --output <path> Path to output directory.
256+
--clear-output-directory Completely delete the contents of the output path before generation.
257+
-t, --template <path> Path to a single .hbs or .md template file
258+
-d, --template-dir <path> Path to a directory of .hbs/.md templates
246259
-u, --url-to-local-file-mapping <path> Path to mapping file which maps URLs to local paths.
247260
-v, --verbose Enable verbose logging. (default: false)
248261
-h, --help display help for command
249262
```
250263
264+
`calm docify` will create the output directory if it does not exist.
265+
266+
If the output directory exists, files will be modified if they already
267+
exist. Other files will be unmodified.
268+
The `--clear-output-directory` option changes this behaviour to delete all
269+
files and subdirectories from the output path first.
270+
251271
Sample usage for you to try is as follows (assuming at root of project)
252272
253273
```shell

cli/src/cli.spec.ts

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ describe('CLI Commands', () => {
133133
'templateDir',
134134
'outDir',
135135
expect.any(Map),
136-
'bundle'
136+
'bundle',
137+
false,
138+
false
137139
);
138140
});
139141

@@ -150,7 +152,9 @@ describe('CLI Commands', () => {
150152
'template.hbs',
151153
'outDir',
152154
expect.any(Map),
153-
'template'
155+
'template',
156+
false,
157+
false
154158
);
155159
});
156160

@@ -167,7 +171,29 @@ describe('CLI Commands', () => {
167171
'templates/',
168172
'outDir',
169173
expect.any(Map),
170-
'template-directory'
174+
'template-directory',
175+
false,
176+
false
177+
);
178+
});
179+
180+
it('should honour --clear-output-directory', async () => {
181+
await program.parseAsync([
182+
'node', 'cli.js', 'template',
183+
'--architecture', 'model.json',
184+
'--template-dir', 'templates/',
185+
'--output', 'outDir',
186+
'--clear-output-directory'
187+
]);
188+
189+
expect(processorConstructorSpy).toHaveBeenCalledWith(
190+
'model.json',
191+
'templates/',
192+
'outDir',
193+
expect.any(Map),
194+
'template-directory',
195+
false,
196+
true
171197
);
172198
});
173199

@@ -227,7 +253,27 @@ describe('CLI Commands', () => {
227253
'outDir',
228254
expect.any(Map),
229255
'bundle',
230-
undefined
256+
undefined,
257+
false
258+
);
259+
});
260+
261+
it('should honour --clear-output-directory', async () => {
262+
await program.parseAsync([
263+
'node', 'cli.js', 'docify',
264+
'--architecture', 'model.json',
265+
'--output', 'outDir',
266+
'--clear-output-directory'
267+
]);
268+
269+
expect(docifierConstructorSpy).toHaveBeenCalledWith(
270+
'WEBSITE',
271+
'model.json',
272+
'outDir',
273+
expect.any(Map),
274+
'bundle',
275+
undefined,
276+
true
231277
);
232278
});
233279

@@ -245,7 +291,8 @@ describe('CLI Commands', () => {
245291
'outDir',
246292
expect.any(Map),
247293
'template',
248-
'template.hbs'
294+
'template.hbs',
295+
false
249296
);
250297
});
251298

@@ -263,7 +310,8 @@ describe('CLI Commands', () => {
263310
'outDir',
264311
expect.any(Map),
265312
'template-directory',
266-
'templateDir'
313+
'templateDir',
314+
false
267315
);
268316
});
269317

cli/src/cli.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const BUNDLE_OPTION = '-b, --bundle <path>';
2828
const TEMPLATE_OPTION = '-t, --template <path>';
2929
const TEMPLATE_DIR_OPTION = '-d, --template-dir <path>';
3030
const URL_MAPPING_OPTION = '-u, --url-to-local-file-mapping <path>';
31+
const CLEAR_OUTPUT_DIRECTORY_OPTION = '--clear-output-directory';
3132

3233
export function setupCLI(program: Command) {
3334
program
@@ -101,6 +102,7 @@ export function setupCLI(program: Command) {
101102
.description('Generate files from a CALM model using a template bundle, a single file, or a directory of templates')
102103
.requiredOption(ARCHITECTURE_OPTION, 'Path to the CALM architecture JSON file')
103104
.requiredOption(OUTPUT_OPTION, 'Path to output directory or file')
105+
.option(CLEAR_OUTPUT_DIRECTORY_OPTION, 'Clear the output directory before processing', false)
104106
.option(BUNDLE_OPTION, 'Path to the template bundle directory')
105107
.option(TEMPLATE_OPTION, 'Path to a single .hbs or .md template file')
106108
.option(TEMPLATE_DIR_OPTION, 'Path to a directory of .hbs/.md templates')
@@ -139,7 +141,9 @@ export function setupCLI(program: Command) {
139141
templatePath,
140142
options.output,
141143
localDirectory,
142-
mode
144+
mode,
145+
false,
146+
options.clearOutputDirectory
143147
);
144148

145149
await processor.processTemplate();
@@ -150,6 +154,7 @@ export function setupCLI(program: Command) {
150154
.description('Generate a documentation website from your CALM model using a template or template directory')
151155
.requiredOption(ARCHITECTURE_OPTION, 'Path to the CALM architecture JSON file')
152156
.requiredOption(OUTPUT_OPTION, 'Path to output directory')
157+
.option(CLEAR_OUTPUT_DIRECTORY_OPTION, 'Clear the output directory before processing', false)
153158
.option(TEMPLATE_OPTION, 'Path to a single .hbs or .md template file')
154159
.option(TEMPLATE_DIR_OPTION, 'Path to a directory of .hbs/.md templates')
155160
.option(URL_MAPPING_OPTION, 'Path to mapping file which maps URLs to local paths')
@@ -190,7 +195,8 @@ export function setupCLI(program: Command) {
190195
options.output,
191196
localDirectory,
192197
templateProcessingMode,
193-
templatePath
198+
templatePath,
199+
options.clearOutputDirectory
194200
);
195201

196202
await docifier.docify();

shared/src/docify/docifier.spec.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,33 @@ describe('Docifier', () => {
3636
outputPath,
3737
urlToLocalPathMapping,
3838
'bundle',
39+
false,
3940
false
4041
);
4142
expect(processTemplateMock).toHaveBeenCalled();
4243
});
4344

45+
it('should pass clear-output-directory through to template processor', async () => {
46+
const processTemplateMock = vi.fn().mockResolvedValue(undefined);
47+
MockedTemplateProcessor.mockImplementationOnce(() => ({
48+
processTemplate: processTemplateMock,
49+
}));
50+
51+
const docifier = new Docifier('WEBSITE', inputPath, outputPath, urlToLocalPathMapping, 'bundle', undefined, true);
52+
await docifier.docify();
53+
54+
expect(MockedTemplateProcessor).toHaveBeenCalledWith(
55+
inputPath,
56+
expect.stringContaining('template-bundles/docusaurus'),
57+
outputPath,
58+
urlToLocalPathMapping,
59+
'bundle',
60+
false,
61+
true
62+
);
63+
expect(processTemplateMock).toHaveBeenCalled();
64+
});
65+
4466
it('should throw if USER_PROVIDED mode is used without templatePath', () => {
4567
expect(() => {
4668
new Docifier('USER_PROVIDED', inputPath, outputPath, urlToLocalPathMapping);
@@ -71,7 +93,8 @@ describe('Docifier', () => {
7193
outputPath,
7294
urlToLocalPathMapping,
7395
'template-directory',
74-
true
96+
true,
97+
false
7598
);
7699

77100
expect(processTemplateMock).toHaveBeenCalled();
@@ -109,7 +132,8 @@ describe('Docifier', () => {
109132
outputPath,
110133
urlToLocalPathMapping,
111134
'bundle',
112-
false // supportWidgetEngine should be false for WEBSITE mode
135+
false, // supportWidgetEngine should be false for WEBSITE mode
136+
false
113137
);
114138

115139
vi.clearAllMocks();
@@ -126,7 +150,8 @@ describe('Docifier', () => {
126150
outputPath,
127151
urlToLocalPathMapping,
128152
'bundle',
129-
true // supportWidgetEngine should be true for USER_PROVIDED mode
153+
true, // supportWidgetEngine should be true for USER_PROVIDED mode
154+
false
130155
);
131156
});
132157

@@ -148,7 +173,8 @@ describe('Docifier', () => {
148173
expect.any(String),
149174
expect.any(Map),
150175
expect.any(String),
151-
false // This reflects the TODO comment about widget clashing
176+
false, // This reflects the TODO comment about widget clashing
177+
false
152178
);
153179
});
154180
});

shared/src/docify/docifier.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {TemplateProcessingMode, TemplateProcessor} from '../template/template-processor.js';
1+
import { TemplateProcessingMode, TemplateProcessor } from '../template/template-processor.js';
22

33
export type DocifyMode = 'SAD' | 'WEBSITE' | 'USER_PROVIDED';
44

@@ -17,7 +17,8 @@ export class Docifier {
1717
outputPath: string,
1818
urlToLocalPathMapping: Map<string, string>,
1919
templateProcessingMode: TemplateProcessingMode = 'bundle',
20-
templatePath?: string
20+
templatePath?: string,
21+
clearOutputDirectory: boolean = false
2122
) {
2223
if (mode === 'SAD') {
2324
throw new Error('Mode "SAD" is not supported.');
@@ -39,7 +40,8 @@ export class Docifier {
3940
outputPath,
4041
urlToLocalPathMapping,
4142
templateProcessingMode,
42-
supportWidgetEngine
43+
supportWidgetEngine,
44+
clearOutputDirectory
4345
);
4446
}
4547

0 commit comments

Comments
 (0)