forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-example.js
140 lines (123 loc) · 4.73 KB
/
create-example.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const fs = require('fs-extra');
const glob = require('glob');
const ignore = require('ignore');
const path = require('canonical-path');
const shelljs = require('shelljs');
const yargs = require('yargs');
const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH, STACKBLITZ_CONFIG_FILENAME} =
require('./constants');
const BASIC_SOURCE_PATH = path.resolve(SHARED_PATH, 'example-scaffold');
shelljs.set('-e');
if (require.main === module) {
const options =
yargs(process.argv.slice(2))
.command(
'$0 <name> [source]',
[
'Create a new <name> example.',
'',
'If [source] is provided then the relevant files from the CLI project at that path are copied into the example.',
].join('\n'))
.strict()
.version(false)
.argv;
const exampleName = options.name;
const examplePath = path.resolve(EXAMPLES_BASE_PATH, exampleName);
console.log('Creating new example at', examplePath);
createEmptyExample(exampleName, examplePath);
const sourcePath =
options.source !== undefined ? path.resolve(options.source) : BASIC_SOURCE_PATH;
console.log('Copying files from', sourcePath);
copyExampleFiles(sourcePath, examplePath, exampleName);
console.log(`The new "${exampleName}" example has been created.`);
console.log('Now run "yarn boilerplate:add" to set it up for development.');
console.log(
'You can find more info on working with docs examples in aio/tools/examples/README.md.')
}
/**
* Create the directory and marker files for the new example.
*/
function createEmptyExample(exampleName, examplePath) {
ensureExamplePath(examplePath);
writeExampleConfigFile(examplePath);
writeStackBlitzFile(exampleName, examplePath);
}
/**
* Ensure that the new example directory exists.
*/
function ensureExamplePath(examplePath) {
if (fs.existsSync(examplePath)) {
throw new Error(
`Unable to create example. The path to the new example already exists: ${examplePath}`);
}
fs.ensureDirSync(examplePath);
}
/**
* Write the `example-config.json` file to the new example.
*/
function writeExampleConfigFile(examplePath) {
fs.writeFileSync(path.resolve(examplePath, EXAMPLE_CONFIG_FILENAME), '');
}
/**
* Write the `stackblitz.json` file into the new example.
*/
function writeStackBlitzFile(exampleName, examplePath) {
const config = {
description: titleize(exampleName),
files: ['!**/*.d.ts', '!**/*.js', '!**/*.[1,2].*'],
tags: [exampleName.split('-')]
};
fs.writeFileSync(
path.resolve(examplePath, STACKBLITZ_CONFIG_FILENAME),
JSON.stringify(config, null, 2) + '\n');
}
/**
* Copy all the files from the `sourcePath`, which are not ignored by the `.gitignore` file in the
* `EXAMPLES_BASE_PATH`, to the `examplePath`.
*/
function copyExampleFiles(sourcePath, examplePath, exampleName) {
const gitIgnoreSource = getGitIgnore(sourcePath);
const gitIgnoreExamples = getGitIgnore(EXAMPLES_BASE_PATH);
// Grab the files in the source folder and filter them based on the gitignore rules.
const sourceFiles =
glob.sync('**/*', {
cwd: sourcePath,
dot: true,
ignore: ['**/node_modules/**', '.git/**', '.gitignore'],
mark: true
})
// Filter out the directories, leaving only files
.filter(filePath => !/\/$/.test(filePath))
// Filter out files that match the source directory .gitignore rules
.filter(filePath => !gitIgnoreSource.ignores(filePath))
// Filter out files that match the examples directory .gitignore rules
.filter(filePath => !gitIgnoreExamples.ignores(path.join(exampleName, filePath)));
for (const sourceFile of sourceFiles) {
console.log(' - ', sourceFile);
const destPath = path.resolve(examplePath, sourceFile)
fs.ensureDirSync(path.dirname(destPath));
fs.copySync(path.resolve(sourcePath, sourceFile), destPath);
}
}
function getGitIgnore(directory) {
const gitIgnoreMatcher = ignore();
const gitignoreFilePath = path.resolve(directory, '.gitignore');
if (fs.existsSync(gitignoreFilePath)) {
const gitignoreFile = fs.readFileSync(gitignoreFilePath, 'utf8');
gitIgnoreMatcher.add(gitignoreFile);
}
return gitIgnoreMatcher;
}
/**
* Convert a kebab-case string to space separated Title Case string.
*/
function titleize(input) {
return input.replace(
/(-|^)(.)/g, (_, pre, char) => `${pre === '-' ? ' ' : ''}${char.toUpperCase()}`);
}
exports.createEmptyExample = createEmptyExample;
exports.ensureExamplePath = ensureExamplePath;
exports.writeExampleConfigFile = writeExampleConfigFile;
exports.writeStackBlitzFile = writeStackBlitzFile;
exports.copyExampleFiles = copyExampleFiles;
exports.titleize = titleize;