freshpack
Version:
Command line scaffolding tool for react apps
218 lines (194 loc) • 4.88 kB
JavaScript
const fs = require('fs');
const path = require('path');
const spawn = require('child_process').spawn;
const entries = require('object.entries');
const elegantSpinner = require('elegant-spinner');
const logUpdate = require('log-update');
const colors = require('colors');
const spacer = '##'.hidden;
const spinner = elegantSpinner();
const workingDir = process.cwd();
let currentPath = '';
let start = 0;
let started = 0;
let finished = 0;
let ivalMain = null;
let ivalSpinner = null;
let cmdLineArgs = {};
const next = () => {
finished = started;
};
const getTimestamp = () => Date.now();
const getTimer = startx => Date.now() - startx;
const startSpinner = () => {
clearInterval(ivalSpinner);
ivalSpinner = setInterval(() => {
logUpdate(
spacer +
colors.bold('installing dependencies ') +
colors.yellow(spinner()) +
colors.dim(' (') +
colors.dim(getTimer(start)) +
colors.dim(' ms)')
);
}, 50);
};
const log = (msg) => {
console.log(spacer + msg);
next();
};
const chdir = (dir) => {
try {
process.chdir(dir);
next();
} catch (err) {
console.log('CHDIR:ERROR: ' + err);
}
};
const createFolder = (parts, i) => {
if (typeof parts[i] !== 'undefined') {
currentPath += '/' + parts[i];
log(colors.white(currentPath));
}
const dir = path.join.apply(null, parts.slice(0, i));
fs.existsSync(dir) || fs.mkdirSync(dir);
};
const createFolders = (dirPath) => {
const parts = dirPath.split(path.sep);
currentPath = '.';
for (let i = 1; i <= parts.length; i += 1) {
if (i !== parts.length) {
createFolder(parts, i);
} else {
createFolder(parts, i, next);
}
}
};
const writeFile = (filePath, content) => {
if (
(filePath.includes('eslint') && !cmdLineArgs.lint) ||
(filePath.includes('jest') && !cmdLineArgs.test)
) {
next();
return;
}
fs.writeFile(filePath, content, (err) => {
if (err) return log(err);
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
filePath = filePath.substring(0, filePath.lastIndexOf('/'));
const msg = colors.white(filePath + '/') + colors.yellow(fileName);
log(msg);
return next();
});
};
const execCommand = (cmdString) => {
startSpinner();
const cmd = cmdString.split(' ').slice(0, 1)[0];
const args = cmdString.split(' ').slice(1);
const prc = spawn(cmd, args);
prc.stdout.setEncoding('utf8');
prc.stdout.on('data', (data) => {
const str = data.toString();
const lines = str.split(/(\r?\n)/g);
lines.forEach((line) => {
if (line.trim() !== '') {
// console.log(line);
}
});
});
prc.stdout.on('end', () => {
setTimeout(next, 0);
});
};
const sequence = (actions) => {
started -= 1;
ivalMain = setInterval(() => {
// console.log(actions.length, started, finished);
if (actions.length !== finished && (started === finished || started === -1)) {
clearInterval(ivalSpinner);
started += 1;
if (actions.length > started) {
const args = actions[started].slice(1);
if (args.length === 1) {
actions[started][0].call(this, args[0]);
} else {
actions[started][0].apply(this, args);
}
} else {
startSpinner();
}
}
}, 100);
};
const displayDependencies = (dir) => {
const pkg = require(path.join(workingDir, '/', dir, '/package.json'));
const dependencies = entries(Object.assign(pkg.dependencies, pkg.devDependencies));
dependencies.forEach((dependency) => {
log(
colors.white(dependency[0]) +
': '.white + colors.yellow(dependency[1])
);
});
};
const exit = (dir) => {
const pkg = require(path.join(workingDir, '/', dir, '/package.json'));
const port = pkg.scripts.start.split('--port ')[1];
logUpdate(spacer + 'installed dependencies'.bold);
displayDependencies(dir);
log('');
log(colors.bold('finished in ~' + Math.round(getTimer(start) / 1000) + ' s'));
log('');
log('Usage:');
log('');
log('$ cd ' + dir);
log('');
log('$ yarn start');
log('# or');
log('$ npm start');
log('');
log('$ open http://localhost:' + port + '/');
if (cmdLineArgs.lint) {
log('');
log('$ yarn lint');
log('# or');
log('$ npm run start');
}
if (cmdLineArgs.lint) {
log('');
log('$ yarn test');
log('# or');
log('$ npm start');
}
log('');
clearInterval(ivalMain);
clearInterval(ivalSpinner);
};
const sleep = (delay) => {
setTimeout(() => {
next();
}, delay);
};
const starting = (headertext) => {
start = getTimestamp();
log(colors.bold(headertext));
next();
};
const init = (args) => {
cmdLineArgs = args;
next();
};
module.exports = {
chdir,
createFolders,
exec: execCommand,
exit,
getTimestamp,
getTimer,
init,
log,
next,
sequence,
sleep,
starting,
writeFile
};