@euglena/cli
Version:
Command Line Interface to create and manage euglena projects as simple as possible
252 lines (238 loc) • 11.7 kB
text/typescript
import * as path from "path";
import * as program from "commander";
import * as ProgressBar from "progress";
import { mkdirSync, readFile, writeFile, exists, constants, truncateSync } from "fs";
import { exec, spawnSync, spawn } from 'child_process';
const beautify = require("json-beautify");
const packageJson = require('../package.json');
process.title = '@euglena/cli';
var child;
var isWin = /^win/.test(process.platform);
// executes `pwd`
program
.version(packageJson.version);
let typelist = "Here is the supported types : \n\n" +
"\tnode generates a Nodejs Application\n" +
"\tangular generates an Angular Application\n";
function npm_install(name: string) {
console.log("installing dependencies...");
let child = spawn(isWin ? 'npm.cmd' : 'npm', ['install'], { cwd: name });
child.on("exit", () => console.log("done."))
}
program
.command('new <name>')
.alias('n')
.description('generate a new Euglena structed application')
.option("-t, --type <type>", "Which environment Euglena work within\n\n" + typelist)
.action((name: string, options: { type: string }) => {
let barOpts = {
width: 20,
total: 100,
clear: true
};
let bar = new ProgressBar(' generating [:bar] :percent :etas', barOpts);
let templateFolder = path.join(__dirname, "../src", options.type);
let packageFile = "";
let child_process;
let particlesTsFile = "";
switch (options.type) {
case "organelle":
//bar.tick(10);
console.log("Generating directory structure.");
mkdirSync(name);
//bar.tick(20);
//copy sample files into new app folder
console.log("Copying files into the new project "+name);
child_process = exec(isWin ? 'xcopy ' + templateFolder + ' ' + name + ' /i /e' : 'cp -r ' + templateFolder + '/** ' + name, (err, stdout, stderr) => {
if (err) console.error(err);
});
child_process.on('error', (err) => console.log(err));
//bar.tick(40);
/**
* Wait for the package.json
*/
packageFile = name + "/package.json";
waitForPathToBeCreated(packageFile).then(() => {
//Inserting dependencies into pacakge.json
readFile(name + "/package.json", "utf-8", (err, text) => {
let json = JSON.parse(text);
json.scripts.test = "mocha .dist/test/index.js";
json.scripts.build = "gulp build";
json.scripts.deploy = "gulp deploy";
json.scripts.start = "npm run build && npm test && node .";
json.main = ".dist/src/index.js";
json.dependencies = {
"cessnalib": "^0.7.0",
"@euglena/core": "0.1.6",
"@euglena/template": "2.0.0",
"@euglena/organelle.time.js": "^0.1.0",
"jsonminify": "^0.4.1"
};
json.devDependencies = {
"@types/node": "^7.0.14",
"@types/mocha": "^2.2.40",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-mocha": "^4.3.1",
"gulp-typescript": "^3.0.1",
"typescript": "^2.3.3",
"gulp-sourcemaps": "^2.6.1",
"merge2": "^1.2.0"
};
text = beautify(json, null, 2, 10);
writeFile(packageFile, text, { "encoding": "utf-8" }, (err) => {
err_back(err, packageFile + " has been updated.");
/**
* install dependencies
* run npm install
*/
npm_install(name);
});
});
});
/**
* Generate package.json
*/
spawn(isWin ? 'npm.cmd' : 'npm', ['init', '--force'], { cwd: name });
break;
case "node":
//bar.tick(10);
console.log("Generating directory structure.");
mkdirSync(name);
//bar.tick(20);
//copy sample files into new app folder
console.log("Copying files into the new project "+name);
child_process = exec(isWin ? 'xcopy ' + templateFolder + ' ' + name + ' /i /e' : 'cp -r ' + templateFolder + '/** ' + name, (err, stdout, stderr) => {
if (err) console.error(err);
});
child_process.on('error', (err) => console.log(err));
//bar.tick(40);
/**
* Wait for the package.json
*/
packageFile = name + "/package.json";
waitForPathToBeCreated(packageFile).then(() => {
//Inserting dependencies into pacakge.json
readFile(name + "/package.json", "utf-8", (err, text) => {
let json = JSON.parse(text);
json.scripts.test = "mocha .dist/test/index.js";
json.scripts.build = "gulp build";
json.scripts.deploy = "gulp deploy";
json.scripts.start = "npm run build && npm test && node .";
json.main = ".dist/src/index.js";
json.dependencies = {
"cessnalib": "^0.2.0",
"@euglena/core": "0.1.6",
"@euglena/template": "1.0.1",
"@euglena/organelle.time.js": "^0.1.0",
"jsonminify": "^0.4.1"
};
json.devDependencies = {
"@types/node": "^7.0.14",
"@types/mocha": "^2.2.40",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-mocha": "^4.3.1",
"gulp-typescript": "^3.0.1",
"typescript": "^2.3.3",
"child_process": "^1.0.2",
"gulp-sourcemaps": "^2.6.1",
"merge2": "^1.2.0"
};
text = beautify(json, null, 2, 10);
writeFile(packageFile, text, { "encoding": "utf-8" }, (err) => {
err_back(err, packageFile + " has been updated.");
/**
* install dependencies
* run npm install
*/
npm_install(name);
});
});
});
/**
* Generate package.json
*/
spawn(isWin ? 'npm.cmd' : 'npm', ['init', '--force'], { cwd: name });
/**
* Wait for the particles.ts
*/
particlesTsFile = name + "/src/particles.ts";
waitForPathToBeCreated(particlesTsFile).then(() => {
readFile(particlesTsFile, "utf-8", (err, data) => {
data = data.replace('$myself', name);
writeFile(particlesTsFile, data, { "encoding": "utf-8" }, (err) => {
err_back(err, particlesTsFile + " has been updated.");
});
});
});
break;
case "angular":
let child2 = spawn('node', [__dirname + "/../node_modules/@angular/cli/bin/ng", "new", name]);
child2.stdout.setEncoding('utf-8');
child2.stdout.on("data", (data: any) => {
console.log(data);
});
child2.stderr.setEncoding('utf-8');
child2.stderr.on("data", (data) => {
console.error(data);
process.abort();
});
waitForPathToBeCreated(name + "/package.json").then(() => {
//Inserting dependencies into pacakge.json
readFile(name + "/package.json", "utf-8", (err, text) => {
let json = JSON.parse(text);
json.dependencies["cessnalib"] = "^0.2.0";
json.dependencies["@euglena/core"] = "0.1.6";
json.dependencies["@euglena/template"] = "1.0.1";
json.dependencies["@euglena/organelle.time.js"] = "^0.1.0";
text = beautify(json, null, 2, 10);
writeFile(name + "/package.json", text, { "encoding": "utf-8" }, (err) => {
err_back(err, "package.json has been updated!");
npm_install(name);
});
});
});
waitForPathToBeCreated([name + "/src/app/app.component.ts", name + "/src/app/app.module.ts"]).then(() => {
//Copying file
console.log("Copying files into the new project.");
exec(isWin ? 'xcopy ' + templateFolder + ' ' + name + '/src /i /e' : 'cp -r ' + templateFolder + '/** ' + name + "/src", (err, stdout, stderr) => {
if (err) console.error(err);
});
});
particlesTsFile = name + "/src/euglena/particles.ts";
waitForPathToBeCreated(particlesTsFile).then(() => {
readFile(particlesTsFile, "utf-8", (err, data) => {
data = data.replace('$myself', name);
writeFile(particlesTsFile, data, { "encoding": "utf-8" }, (err) => {
err_back(err, particlesTsFile + " has been updated.");
});
});
});
break;
}
});
program.parse(process.argv);
function err_back(err: Error, success?: string) {
if (err) console.log(err)
else if (success) console.log(success);
}
function waitForPathToBeCreated(path: string | string[]): Promise<{}> {
if (path instanceof Array) {
let promises = [];
for (let p of path) {
promises.push(waitForPathToBeCreated(p));
}
return Promise.all(promises);
} else {
return new Promise((next: any, reject: any) => {
exists(path, x => {
if (x) {
next();
} else {
console.log("waiting for " + path + " to be created.");
setTimeout(() => waitForPathToBeCreated(path).then(next), 500);
}
});
});
}
}