Skip to content

Commit 1235878

Browse files
feat: support creating a project in the current directory (#29)
* feat: generate project in the current directory * feat: support webpack v5 * chore: bump commander * test: assert for updated serve script * chore: update success message
1 parent 75a322c commit 1235878

File tree

8 files changed

+78
-65
lines changed

8 files changed

+78
-65
lines changed

.gitignore

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,21 @@
11
# Logs
22
logs
33
*.log
4-
npm-debug.log*
54
yarn-debug.log*
65
yarn-error.log*
76

8-
# Runtime data
9-
pids
10-
*.pid
11-
*.seed
12-
*.pid.lock
13-
147
# Es-5 compiled directory
158
lib
169

17-
# Directory for instrumented libs generated by jscoverage/JSCover
18-
lib-cov
19-
20-
# Coverage directory used by tools like istanbul
21-
coverage
22-
23-
# nyc test coverage
24-
.nyc_output
25-
26-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
27-
.grunt
28-
29-
# Bower dependency directory (https://bower.io/)
30-
bower_components
31-
32-
# node-waf configuration
33-
.lock-wscript
34-
35-
# Compiled binary addons (https://nodejs.org/api/addons.html)
36-
build/Release
37-
3810
# Dependency directories
3911
node_modules/
40-
jspm_packages/
4112

4213
# TypeScript v1 declaration files
4314
typings/
4415

45-
# Optional npm cache directory
46-
.npm
47-
4816
# Optional eslint cache
4917
.eslintcache
5018

51-
# Optional REPL history
52-
.node_repl_history
53-
5419
# Output of 'npm pack'
5520
*.tgz
5621

@@ -60,5 +25,5 @@ typings/
6025
# dotenv environment variables file
6126
.env
6227

63-
# next.js build output
64-
.next
28+
# Test artifacts
29+
test-app

__e2e__/commands/new.test.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
import fs from 'fs';
22
import path from 'path';
33

4-
import run from '../test-utils';
4+
import { rmTestDir, run } from '../test-utils';
55

66
jest.setTimeout(240000);
77

88
const testDirPath = path.join(__dirname, 'test-app');
99

1010
beforeEach(() => {
11-
if (fs.existsSync(testDirPath)) {
12-
fs.rmdirSync(testDirPath, { recursive: true });
13-
}
11+
rmTestDir(testDirPath);
1412
});
1513

1614
afterAll(() => {
17-
fs.rmdirSync(testDirPath, { recursive: true });
15+
rmTestDir(testDirPath);
1816
});
1917

2018
const generatedFiles = [
@@ -59,7 +57,7 @@ describe('new command', () => {
5957
// Assertion for the configured scripts
6058
expect(pkgJson.name).toBe('test-app');
6159
expect(pkgJson.scripts['build']).toBe('webpack');
62-
expect(pkgJson.scripts['serve']).toBe('webpack-dev-server --open');
60+
expect(pkgJson.scripts['serve']).toBe('webpack serve');
6361
});
6462

6563
it('uses npm on supplying --use-npm', async () => {
@@ -90,6 +88,38 @@ describe('new command', () => {
9088
// Assertion for the configured scripts
9189
expect(pkgJson.name).toBe('test-app');
9290
expect(pkgJson.scripts['build']).toBe('webpack');
93-
expect(pkgJson.scripts['serve']).toBe('webpack-dev-server --open');
91+
expect(pkgJson.scripts['serve']).toBe('webpack serve');
92+
93+
// Remove test-app directory
94+
rmTestDir(testDirPath);
95+
});
96+
97+
it('creates a project in the current directory', async () => {
98+
// Create test-app directory
99+
fs.mkdirSync(testDirPath);
100+
101+
const { exitCode } = await run(['new', '.'], {
102+
cwd: testDirPath,
103+
input: '\n',
104+
});
105+
106+
// Assertions
107+
expect(exitCode).toBe(0);
108+
generatedFiles.forEach(file =>
109+
expect(fs.existsSync(path.join(testDirPath, file))).toBeTruthy()
110+
);
111+
112+
const pkgJson = JSON.parse(
113+
fs.readFileSync(path.join(testDirPath, 'package.json'))
114+
);
115+
116+
// Assertion for the installed dependencies
117+
expect(pkgJson.dependencies).toBeFalsy();
118+
deps.forEach(dep => expect(pkgJson.devDependencies[dep]).toBeTruthy());
119+
120+
// Assertion for the configured scripts
121+
expect(pkgJson.name).toBe('test-app');
122+
expect(pkgJson.scripts['build']).toBe('webpack');
123+
expect(pkgJson.scripts['serve']).toBe('webpack serve');
94124
});
95125
});

__e2e__/test-utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import execa from 'execa';
2+
import fs from 'fs';
23
import path from 'path';
34

45
const CLI_PATH = path.join(__dirname, '..', 'bin');
56

6-
export default (
7+
export const run = (
78
args: string[],
89
options = {}
910
): execa.ExecaChildProcess<string> =>
1011
execa('node', [CLI_PATH].concat(args), options);
12+
13+
export const rmTestDir = (testDirPath: string): void => {
14+
if (fs.existsSync(testDirPath)) {
15+
fs.rmdirSync(testDirPath, { recursive: true });
16+
}
17+
};

bin/index.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@ program
1414
.description('Scaffolds a static site boilerplate template to work on.')
1515
.action(scaffoldProject);
1616

17-
program.arguments('<command>').action(cmd => {
17+
program.on('command:*', ([cmd]) => {
1818
program.outputHelp();
1919
console.log(` ` + kleur.red(`\n Unknown command ${kleur.yellow(cmd)}.`));
2020
console.log();
2121
});
2222

2323
program.parse(process.argv);
24-
25-
if (!program.args.length) {
26-
program.help();
27-
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
},
4343
"homepage": "https://github.com/jamesgeorge007/scaffold-static#readme",
4444
"dependencies": {
45-
"commander": "^5.0.0",
45+
"commander": "^6.2.1",
4646
"execa": "^4.0.0",
4747
"inquirer": "^6.2.1",
4848
"kleur": "^3.0.3",

src/commands/scaffold.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ export default async (
2929
process.exit(1);
3030
}
3131

32-
if (fs.existsSync(projectName)) {
32+
const isCurrentDir = projectName === '.';
33+
34+
if (isCurrentDir && fs.readdirSync('.').length) {
35+
logger.error(` The current directory isn't empty`);
36+
process.exit(1);
37+
}
38+
39+
if (!isCurrentDir && fs.existsSync(projectName)) {
3340
logger.error(` ${projectName} already exists in path`);
3441
process.exit(1);
3542
}
@@ -52,7 +59,7 @@ export default async (
5259
]);
5360

5461
// Create the project directory
55-
fs.mkdirSync(projectName);
62+
!isCurrentDir && fs.mkdirSync(projectName);
5663

5764
// Create css and js directory
5865
const cssDirPath = path.join(projectName, 'css');
@@ -83,8 +90,8 @@ export default async (
8390

8491
// Dependencies to be installed
8592
const deps = [
86-
'webpack@^4.44.2',
87-
'webpack-cli@^3.3.12',
93+
'webpack',
94+
'webpack-cli',
8895
'webpack-dev-server',
8996
'css-loader',
9097
'style-loader',
@@ -108,14 +115,16 @@ export default async (
108115
// Add build and serve scripts
109116
pkgJson = {
110117
...pkgJson,
111-
name: projectName,
112118
scripts: {
113-
...pkgJson.scripts,
114119
build: 'webpack',
115-
serve: 'webpack-dev-server --open',
120+
serve: 'webpack serve',
116121
},
117122
};
118123

124+
if (!isCurrentDir) {
125+
pkgJson.name = projectName;
126+
}
127+
119128
fs.writeFileSync(
120129
path.join(projectName, 'package.json'),
121130
JSON.stringify(pkgJson, null, 2)
@@ -132,6 +141,11 @@ export default async (
132141

133142
// Instructions to the user
134143
console.log();
135-
logger.success('Please follow these instructions:- ');
136-
logger.info(`cd ${projectName} && ${pm} run serve`);
144+
logger.success('Now, type in:');
145+
146+
let msg = `${pm} run serve`;
147+
if (!isCurrentDir) {
148+
msg = `cd ${projectName} && ${msg}`;
149+
}
150+
logger.info(msg);
137151
};

src/templates/webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = {
1111
},
1212
devServer: {
1313
contentBase: './dist',
14+
open: true,
1415
},
1516
plugins: [
1617
new HtmlWebpackPlugin({

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,16 +2117,16 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
21172117
dependencies:
21182118
delayed-stream "~1.0.0"
21192119

2120-
commander@^5.0.0:
2121-
version "5.1.0"
2122-
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
2123-
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
2124-
21252120
commander@^6.2.0:
21262121
version "6.2.0"
21272122
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75"
21282123
integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==
21292124

2125+
commander@^6.2.1:
2126+
version "6.2.1"
2127+
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
2128+
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
2129+
21302130
component-emitter@^1.2.1:
21312131
version "1.3.0"
21322132
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"

0 commit comments

Comments
 (0)