Skip to content

Commit 39e50bd

Browse files
committed
add setup script
1 parent 0f31428 commit 39e50bd

4 files changed

Lines changed: 242 additions & 2 deletions

File tree

bin/helpers/get_npm_config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const fs = require("fs");
2+
3+
module.exports = JSON.parse(fs.readFileSync("package.json", "utf8"));

bin/setup.js

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#!/usr/bin/env node
2+
3+
const { exec } = require("child_process");
4+
const path = require("path");
5+
const fs = require("fs");
6+
const readline = require("readline");
7+
const compareVersions = require("compare-versions");
8+
// const shell = require("shelljs");
9+
// const chalk = require("chalk");
10+
11+
const npmConfig = require("./helpers/get_npm_config.js");
12+
13+
process.stdin.resume();
14+
process.stdin.setEncoding("utf8");
15+
16+
process.stdout.write("\n");
17+
let interval = -1;
18+
19+
function deleteFileInCurrentDir(file) {
20+
return new Promise((resolve, reject) => {
21+
fs.unlink(path.join(__dirname, file), (err) => reject(new Error(err)));
22+
resolve();
23+
});
24+
}
25+
26+
function removeGitRepository() {
27+
return new Promise((resolve, reject) => {
28+
exec("rm -rf .git/", (error) => {
29+
if (error) reject(new Error(error));
30+
31+
resolve();
32+
});
33+
});
34+
}
35+
36+
function askUserIfWeShouldRemoveRepo() {
37+
return new Promise((resolve) => {
38+
process.stdout.write(
39+
"\nDo you want to start with a new repository? [Y/n] "
40+
);
41+
process.stdin.resume();
42+
process.stdin.on("data", (pData) => {
43+
const answer = pData.toString().trim().toLowerCase() || "y";
44+
45+
/* eslint-disable-next-line no-unused-expressions */
46+
answer === "y" ? resolve(true) : resolve(false);
47+
});
48+
});
49+
}
50+
51+
async function cleanCurrentRepository() {
52+
const hasGitRepo = await hasGitRepository().catch((reason) =>
53+
reportError(reason)
54+
);
55+
56+
// We are not under Git version control. So, do nothing
57+
if (hasGitRepo === false) {
58+
return false;
59+
}
60+
61+
const answer = await askUserIfWeShouldRemoveRepo();
62+
63+
if (answer === true) {
64+
process.stdout.write("Removing current repository");
65+
await removeGitRepository().catch((reason) => reportError(reason));
66+
// addCheckMark();
67+
}
68+
69+
return answer;
70+
}
71+
72+
function installPackages() {
73+
return new Promise((resolve, reject) => {
74+
process.stdout.write(
75+
"\nInstalling dependencies... (This might take a while)"
76+
);
77+
78+
setTimeout(() => {
79+
readline.cursorTo(process.stdout, 0);
80+
// interval = animateProgress("Installing dependencies");
81+
}, 500);
82+
83+
exec("npm install", (err) => {
84+
if (err) {
85+
reject(new Error(err));
86+
}
87+
88+
clearInterval(interval);
89+
// addCheckMark();
90+
resolve("Packages installed");
91+
});
92+
});
93+
}
94+
95+
function initGitRepository() {
96+
return new Promise((resolve, reject) => {
97+
exec("git init", (err, stdout) => {
98+
if (err) {
99+
reject(new Error(err));
100+
} else {
101+
resolve(stdout);
102+
}
103+
});
104+
});
105+
}
106+
107+
function addToGitRepository() {
108+
return new Promise((resolve, reject) => {
109+
exec("git add .", (err, stdout) => {
110+
if (err) {
111+
reject(new Error(err));
112+
} else {
113+
resolve(stdout);
114+
}
115+
});
116+
});
117+
}
118+
119+
function commitToGitRepository() {
120+
return new Promise((resolve, reject) => {
121+
exec('git commit -m "Initial commit"', (err, stdout) => {
122+
if (err) {
123+
reject(new Error(err));
124+
} else {
125+
resolve(stdout);
126+
}
127+
});
128+
});
129+
}
130+
131+
function checkNodeVersion(minimalNodeVersion) {
132+
return new Promise((resolve, reject) => {
133+
exec("node --version", (err, stdout) => {
134+
const nodeVersion = stdout.trim();
135+
if (err) {
136+
reject(new Error(err));
137+
} else if (compareVersions(nodeVersion, minimalNodeVersion) === -1) {
138+
reject(
139+
new Error(
140+
`You need Node.js v${minimalNodeVersion} or above but you have v${nodeVersion}`
141+
)
142+
);
143+
}
144+
145+
resolve("Node version OK");
146+
});
147+
});
148+
}
149+
150+
function checkNpmVersion(minimalNpmVersion) {
151+
return new Promise((resolve, reject) => {
152+
exec("npm --version", (err, stdout) => {
153+
const npmVersion = stdout.trim();
154+
if (err) {
155+
reject(new Error(err));
156+
} else if (compareVersions(npmVersion, minimalNpmVersion) === -1) {
157+
reject(
158+
new Error(
159+
`You need NPM v${minimalNpmVersion} or above but you have v${npmVersion}`
160+
)
161+
);
162+
}
163+
164+
resolve("NPM version OK");
165+
});
166+
});
167+
}
168+
169+
function endProcess() {
170+
clearInterval(interval);
171+
process.stdout.write("\n\nDone!\n");
172+
process.exit(0);
173+
}
174+
175+
function reportError(error) {
176+
clearInterval(interval);
177+
178+
if (error) {
179+
process.stdout.write("\n\n");
180+
addXMark(() => process.stderr.write(chalk.red(` ${error}\n`)));
181+
process.exit(1);
182+
}
183+
}
184+
185+
(async () => {
186+
const repoRemoved = await cleanCurrentRepository();
187+
188+
// Take the required Node and NPM version from package.json
189+
const {
190+
engines: { node, npm },
191+
} = npmConfig;
192+
193+
const requiredNodeVersion = node.match(/([0-9.]+)/g)[0];
194+
await checkNodeVersion(requiredNodeVersion).catch((reason) =>
195+
reportError(reason)
196+
);
197+
198+
const requiredNpmVersion = npm.match(/([0-9.]+)/g)[0];
199+
await checkNpmVersion(requiredNpmVersion).catch((reason) =>
200+
reportError(reason)
201+
);
202+
203+
await installPackages().catch((reason) => reportError(reason));
204+
await deleteFileInCurrentDir("setup.js").catch((reason) =>
205+
reportError(reason)
206+
);
207+
208+
if (repoRemoved) {
209+
process.stdout.write("\n");
210+
// interval = animateProgress("Initialising new repository");
211+
process.stdout.write("Initialising new repository");
212+
213+
try {
214+
await initGitRepository();
215+
await addToGitRepository();
216+
await commitToGitRepository();
217+
} catch (err) {
218+
reportError(err);
219+
}
220+
221+
// addCheckMark();
222+
clearInterval(interval);
223+
}
224+
225+
endProcess();
226+
})();

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"watch": "webpack --watch",
1111
"test": "jest",
1212
"test:watch": "jest --watch",
13-
"test:coverage": "jest --coverage"
13+
"test:coverage": "jest --coverage",
14+
"setup": "node ./bin/setup.js"
1415
},
1516
"keywords": [],
1617
"author": "",
@@ -36,6 +37,7 @@
3637
"webpack-dev-server": "^3.11.2"
3738
},
3839
"dependencies": {
40+
"compare-versions": "^3.6.0",
3941
"dotenv": "^8.2.0",
4042
"prop-types": "^15.7.2",
4143
"react": "^17.0.1",

readme.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
# Basic React Boilerplate
22

33
## Features
4+
45
React v17<br>
56
Webpack 5<br>
67
SCSS<br>
78
Jest/React Testing Library<br>
8-
.env files<br>
9+
Env Files<br>
10+
PropTypes<br>
11+
12+
## Commands
13+
14+
Run `npm i` to install all dependencies<br>
15+
Run `npm run dev` to run app in development mode<br>
16+
Run `npm run start` to serve files to `/public` folder<br>
17+
Run `npm run test` to run tests<br>

0 commit comments

Comments
 (0)