Skip to content

Commit 7cda9e3

Browse files
committed
[DEVTOOLS-283] Allow regeneration based on yo config file
1 parent 37e6a23 commit 7cda9e3

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ OPTIONS
181181

182182
_See code: [src/commands/new.ts](https://github.com/forumone/forumone-cli/blob/v1.5.0/src/commands/new.ts)_
183183

184+
## `f1 regen CONFIG TARGET`
185+
186+
Regenerate a new project from an existing .yo-rc.json file.
187+
188+
```
189+
USAGE
190+
$ f1 regen CONFIG TARGET
191+
192+
ARGUMENTS
193+
CONFIG path of .yo-rc.json file or project directory
194+
TARGET directory name to create
195+
196+
OPTIONS
197+
-h, --help show CLI help
198+
--dry-run print command instead of running
199+
--next use prerelease generator for testing
200+
```
201+
184202
## `f1 run SERVICE`
185203

186204
run an arbitrary compose service

src/commands/regen.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import Command, { flags } from '@oclif/command';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import validFilename from 'valid-filename';
5+
6+
import recreateProject from '../project/recreateProject';
7+
8+
9+
function mkdirDryRun(target: string) {
10+
const relative = path.relative(process.cwd(), target);
11+
process.stdout.write(`mkdir ${relative}\n`);
12+
}
13+
14+
function findConfigFile(filePath: string): string {
15+
if (!fs.existsSync(filePath)) {
16+
throw new Error(`Path '${filePath}' does not exist.`);
17+
}
18+
19+
if (fs.statSync(filePath).isDirectory()) {
20+
return findConfigFile(path.join(filePath, '.yo-rc.json'));
21+
}
22+
23+
if (!fs.statSync(filePath).isFile()) {
24+
throw new Error(`Path '${filePath}' is not a file.`);
25+
}
26+
27+
return filePath;
28+
}
29+
30+
export default class Regen extends Command {
31+
static description = 'Regenerate a new project from an existing .yo-rc.json file.';
32+
33+
static flags = {
34+
help: flags.help({ char: 'h' }),
35+
'dry-run': flags.boolean({
36+
description: 'print command instead of running',
37+
}),
38+
next: flags.boolean({
39+
description: 'use prerelease generator for testing',
40+
}),
41+
};
42+
43+
static args = [
44+
{
45+
name: 'config',
46+
description: 'path of .yo-rc.json file or project directory',
47+
required: true,
48+
},
49+
{
50+
name: 'target',
51+
description: 'directory name to create',
52+
required: true,
53+
},
54+
];
55+
56+
async run() {
57+
const { args, flags } = this.parse(Regen);
58+
59+
if (!validFilename(args.target)) {
60+
return this.error(`Argument '${args.target}' is not a valid filename.`, {
61+
exit: 1,
62+
});
63+
}
64+
65+
const directory = path.join(process.cwd(), args.target);
66+
const configPath = path.join(process.cwd(), args.config);
67+
68+
let configFile;
69+
try {
70+
configFile = findConfigFile(configPath);
71+
} catch (e) {
72+
return this.error(e.getMessage(), {
73+
exit: 1,
74+
});
75+
}
76+
77+
try {
78+
const createDirectory = flags['dry-run'] ? mkdirDryRun : fs.mkdirSync;
79+
createDirectory(directory);
80+
} catch (error) {
81+
if (error.code === 'EEXIST') {
82+
return this.error(
83+
`Failed to create '${args.target}' because it already exists.`,
84+
{ exit: 1 },
85+
);
86+
}
87+
88+
return this.error(error, { exit: 1 });
89+
}
90+
91+
const command = recreateProject({
92+
configFile,
93+
directory,
94+
next: flags.next,
95+
});
96+
97+
return flags['dry-run'] ? command.dryRun() : command.run();
98+
}
99+
}

src/project/recreateProject.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import runNpx from '../process/runNpx';
2+
3+
export interface RecreateProjectOptions {
4+
configFile: string;
5+
directory: string;
6+
next: boolean;
7+
}
8+
9+
// Use `npx' to ensure that users always have the latest generator version.
10+
function recreateProject({ configFile, directory, next }: RecreateProjectOptions) {
11+
const tagSuffix = next ? '@next' : '';
12+
13+
// yo-gen-run --name web-starter --config ./tmp-wp/.yo-rc.json --out ./tmp-wp2
14+
return runNpx([
15+
'yo-gen-run',
16+
'--name', 'web-starter',
17+
'--config', configFile,
18+
'--out', directory,
19+
], {
20+
cwd: directory,
21+
packages: ['yo', 'yeoman-gen-run', 'generator-web-starter' + tagSuffix],
22+
});
23+
}
24+
25+
export default recreateProject;

0 commit comments

Comments
 (0)