Skip to content

Commit

Permalink
Added cli scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduard Kyvenko committed Sep 4, 2016
1 parent b9c3404 commit 24243d9
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 0 deletions.
42 changes: 42 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "elm-app-create",
"version": "0.1.0",
"description": "Elm apps with zero configuration",
"keywords": [
"elm",
"cli"
],
"author": "Eduard Kyvenko <duardeco@gmail.com>",
"license": "MIT",
"engines": {
"node": ">=4"
},
"bin": {
"elm-app": "./bin/global-cli.js",
"create-elm-app": "./bin/create-elm-app-cli.js"
},
"files": [
"bin",
"config",
"scripts",
"template",
"README.md"
],
"dependencies": {
"chalk": "^1.1.3",
"clean-webpack-plugin": "^0.1.10",
"cli-table": "0.3.1",
"cross-spawn": "^4.0.0",
"elm": "^0.17.1",
"elm-hot-loader": "^0.3.3",
"elm-webpack-loader": "^3.0.5",
"fs-extra": "^0.30.0",
"html-webpack-plugin": "^2.22.0",
"install": "0.8.1",
"minimist": "^1.2.0",
"opn": "^4.0.2",
"path-exists": "^3.0.0",
"webpack": "^1.13.2",
"webpack-dev-server": "1.15.1"
}
}
29 changes: 29 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const pathExists = require('path-exists');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config/webpack.config.prod');

if (pathExists.sync('elm-package.json') === false) {
console.log('Please, run the build script from project root directory');
process.exit(1);
}

console.log('\nStarting production build...\n');

// Initialize webpack, using the long way: http://webpack.github.io/docs/node.js-api.html#the-long-way
webpack(config).run(function (err, stats) {

if (err !== null) {
console.log(chalk.red(err));
process.exit(1);
} else {
var statsFormatted = stats.toString({
chunks: false,
colors: true
});

console.log(chalk.green('\n' + statsFormatted));
}
});


46 changes: 46 additions & 0 deletions scripts/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const copySync = require('fs-extra').copySync;
const path = require('path');
const chalk = require('chalk');
const pathExists = require('path-exists');
const spawnSync = require('child_process').spawnSync;
const argv = require('minimist')(process.argv.slice(2));
const commands = argv._;
const executablePaths = require('elm/platform').executablePaths;

if (commands.length === 0 || commands[ 0 ] === '') {
console.error(
'\nUsage: elm-app create <project-directory>'
);
process.exit(1);
}

createElmApp(commands[ 0 ]);

function createElmApp (name) {

console.log(`\nCreating ${name} project...\n`);

let root = path.resolve(name);
let template = path.join(__dirname, '../template');

if (!pathExists.sync(name)) {

try {
copySync(template, root);
} catch (err) {
console.log(err);
process.exit(1);
}

} else {
console.log(`'The directory ${name} already exists. Aborting.`);
process.exit(1);
}

process.chdir(root);

// Run initial `elm-package install -y`
spawnSync(executablePaths[ 'elm-package' ], [ 'install', '-y' ], { stdio: 'inherit' });

console.log(chalk.green(`\nProject is successfully created in \`${root}\`.`));
}
112 changes: 112 additions & 0 deletions scripts/eject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const path = require('path');
const chalk = require('chalk');
const pathExists = require('path-exists');
const spawn = require('cross-spawn');
const { writeFileSync, readFileSync } = require('fs');
const { copySync } = require('fs-extra');
const extend = require('extend');
const Table = require('cli-table');
const pkgOwn = require(path.join(__dirname, '../package.json'));

let pkgEjected;
let devDependencies = pkgOwn.dependencies;
let scripts = {
build: 'node scripts/build.js',
start: 'node scripts/start.js'
};

if (pathExists.sync('elm-package.json') === false) {
console.log('Please, run the build script from project root directory');
process.exit(1);
}

// Remove create-elm-app dependencies.
delete devDependencies[ 'cross-spawn' ];
delete devDependencies[ 'fs-extra' ];
delete devDependencies[ 'minimist' ];
delete devDependencies[ 'cli-table' ];
delete devDependencies[ 'extend' ];

function diffTable (target, mixin, head = [ chalk.grey('Name'), chalk.yellow('Old'), chalk.green('New') ]) {
let table = new Table({
head: head
});

for (let propName in target) {
if (propName in mixin) {
let targetPropValue = target[ propName ];
let mixinPropValue = mixin[ propName ];
// If found and is not equal
if (targetPropValue !== mixinPropValue) {
table.push([ propName, targetPropValue, mixinPropValue ]);
}
}
}

return table;
}

function prompt() {
process.stdin.once('Would you like to continue? [Y/n]', function(val){
if (val.search(/^y(es)?$/i) === -1) {
process.exit(0);
}
}).resume();
}

console.log(chalk.yellow('Ejecting will overwrite your exsisting "devDependencies"\n'));

if (pathExists.sync('./package.json') === true) {
pkgEjected = JSON.parse(readFileSync('./package.json'));

if (pkgEjected.hasOwnProperty('devDependencies')) {
let diff = diffTable(pkgEjected.devDependencies, devDependencies);
if (diff.length !== 0) {
console.log(diff.toString());
console.log('Ejecting wil overwrite your "devDependencies" in package.json\n');
prompt();
pkgEjected.devDependencies = extend({}, devDependencies, pkgEjected.devDependencies);
}
}

if (pkgEjected.hasOwnProperty('scripts')) {
let diff = diffTable(pkgEjected.scripts, scripts);
if (diff.length !== 0) {
console.log(diff.toString());
console.log('Ejecting wil overwrite your "scripts" in package.json\n');
prompt();
pkgEjected.scripts = extend({}, scripts, pkgEjected.scripts);
}
}

} else {
console.log(chalk.green('New package.json is created for your project'));
pkgEjected = {
name: '',
version: '0.0.1',
private: true,
scripts: scripts,
devDependencies: devDependencies
};
}

// Copy the configuration and start/build scripts.
try {
copySync(path.resolve(__dirname, 'build.js'), './scripts/build.js');
copySync(path.resolve(__dirname, 'start.js'), './scripts/start.js');
copySync(path.resolve(__dirname, '../config'), './config');
} catch (err) {
console.log(chalk.red('Failed to copy scripts, the error is:\n'));
console.log(err);
process.exit(1);
}

writeFileSync('package.json', JSON.stringify(pkgEjected, null, 2));

spawn.sync(
'npm',
[ 'install' ],
{ stdio: 'inherit' }
);

console.log('Ejected successfully!');
71 changes: 71 additions & 0 deletions scripts/start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const pathExists = require('path-exists');
const chalk = require('chalk');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('../config/webpack.config.dev');
const opn = require('opn');

function clear () {
console.log('\x1Bc');
}

process.env.NODE_ENV = 'development';

if (pathExists.sync('elm-package.json') === false) {
console.log('Please, run the build script from project root directory');
process.exit(0);
}

// http://webpack.github.io/docs/node.js-api.html#the-long-way
let compiler = webpack(config);
let port = 3000;

compiler.plugin('invalid', function () {
clear();
console.log('Compiling...');
});

compiler.plugin('done', function (stats) {
clear();

let hasErrors = stats.hasErrors();
let hasWarnings = stats.hasWarnings();

if (!hasErrors && !hasWarnings) {
console.log(chalk.green('Compiled successfully!'));
console.log('\nThe app is running at:');
console.log('\n ' + chalk.cyan('http://localhost:' + port + '/'));
console.log('\nTo create production build, run:');
console.log('\n elm-app build');
return;
}

if (hasErrors) {
console.log(chalk.red('Compilation failed.\n'));

var json = stats.toJson({}, true);

json.errors.forEach(message => {
console.log(message);
console.log();
});
}
});

const devServer = new WebpackDevServer(compiler, {
hot: true,
inline: true,
publicPath: '/',
quiet: true
});

// Launch WebpackDevServer.
devServer.listen(port, (err) => {
if (err) {
return console.log(err);
}
});

opn('http://localhost:' + port + '/');


0 comments on commit 24243d9

Please sign in to comment.