Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bake-cli

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bake-cli - npm Package Compare versions

Comparing version 0.0.4 to 0.1.0

bin/bake-init.js

45

bin/bake.js

@@ -5,11 +5,16 @@ #!/usr/bin/env node

const path = require('path');
const debug = require('debug')('bake');
const which = require('which');
const { existsSync: exists } = fs;
const { spawn } = require('child_process');
const { CLI } = require('..');
const { format } = require('util');
const { existsSync: exists } = fs;
const { CLI, Bake } = require('..');
const { verbose, info, warn, error } = require('../src/log');
const { fail } = CLI;
const assign = Object.assign || require('object-assign');
const separator = process.platform === 'win32' ? ';' : ':';
// Init
let separator = process.platform === 'win32' ? ';' : ':';
let env = assign({}, process.env, {

@@ -23,4 +28,32 @@ PATH: process.env.PATH + separator + path.resolve('./node_modules/.bin')

let cli = new CLI(bakefile, {
let bake = new Bake(bakefile, {
env: env
});
bake.on(Bake.UNKNOWN_TARGET, (target, targets) => {
var cmd = 'bake-' + target;
which(cmd, (err, filename) => {
if (err) {
fail(err.message);
return bake.help(targets);
}
// var args = bake.argv._.slice(1);
var args = process.argv.slice(3);
info('Go for it', filename, args);
var sh = spawn(filename, args, {
stdio: 'inherit',
env: bake.env
});
// sh.on('error', error.bind(null));
sh.on('close', (code) => {
if (code === 0) return;
// fail(new Error(format('%s exited with code %d', cmd, code)));
process.exit(code);
});
});
});

@@ -5,2 +5,22 @@ # Change Log

<a name="0.1.0"></a>
# [0.1.0](https://github.com/mklabs/bake/compare/v0.0.4...v0.1.0) (2016-05-25)
### Bug Fixes
* improve log output, merge dependencies ([838a08c](https://github.com/mklabs/bake/commit/838a08c))
### Features
* --help output list of available templates ([b58eb43](https://github.com/mklabs/bake/commit/b58eb43))
* "global" commands, bake-<target> ([ce6572d](https://github.com/mklabs/bake/commit/ce6572d))
* Add --skip flag, merge .eslintrc / .babelrc ([091e28c](https://github.com/mklabs/bake/commit/091e28c))
* add cli template ([3e90cef](https://github.com/mklabs/bake/commit/3e90cef))
* bake init <template> ([34b788b](https://github.com/mklabs/bake/commit/34b788b))
* implement template hook for start / install ([5990fa6](https://github.com/mklabs/bake/commit/5990fa6))
<a name="0.0.4"></a>

@@ -7,0 +27,0 @@ ## [0.0.4](https://github.com/mklabs/bake/compare/v0.0.3...v0.0.4) (2016-05-24)

@@ -1,3 +0,8 @@

var bake = module.exports = require('./src/parser');
var bake = module.exports;
bake.log = require('./src/log');
bake.parser = require('./src/parser');
bake.CLI = require('./src/cli');
bake.Bake = require('./src/bake');
bake.Template = require('./src/template');

278

lib/cli.js

@@ -1,208 +0,172 @@

const fs = require('fs');
const path = require('path');
const minimist = require('minimist');
const chalk = require('chalk');
const events = require('events');
const debug = require('debug');
const log = require('./log');
const logsymbols = require('log-symbols');
const fsutil = require('./util');
const { spawn } = require('child_process');
const debug = require('debug');
const padding = 20;
const PADDING = 20;
const exists = fs.existsSync;
// CLI
//
// This class exposes various utilities for parsing options and logging purpose.
//
// - this.argv - minimist result from options.argv or process.argv.slice(2)
// - this.debug - debug module logger, enabled with -d flag
// - this.alias - if defined, is used to parse arguments with minimist
// - this.env - options.env or a clone of process.env
// - this.start - Timestamp marking instance creation, namely used to report
// build time.
//
// And these static methods:
//
// - CLI.fail - to invoke with an error, log the error with npmlog error level
// - CLI.end - Log options.success message with elapsed time as a parameter
//
// Options:
//
// - this.options.namespace - Define the debug namespace (eg. require('debug')(namespace)).
// Default: bake:cli
// - this.options.success - Success message to print with end()
export default class CLI extends events.EventEmitter {
const bake = require('..');
const log = bake.log;
get example() { return ''; }
export default class CLI {
// Used to parse arguments with minimist
get alias() {
return {
alias: {
h: 'help',
v: 'version',
d: 'debug'
}
h: 'help',
v: 'version',
d: 'debug'
};
}
constructor(filename, opts = {}) {
this.options = opts;
this.env = this.options.env || {};
this.argv = minimist(this.options.argv || process.argv.slice(2), this.alias);
// Used to generate the help output
get flags() {
return {
help: 'Show this help output',
version: 'Show package version'
};
}
if (opts.debug || this.argv.debug) {
debug.enable('bake*');
}
if (!filename) {
return CLI.fail('Missing %s Makefile / Bakefile', filename);
}
this.debug = debug('bake:cli');
constructor(opts = {}) {
super();
this.start = Date.now();
this.debug('Bake init CLI with %s options', Object.keys(opts).join(' '));
this.bakefile = filename;
this.init();
}
this.options = opts;
this.options.namespace = this.options.namespace || 'bake:cli';
this.options.success = this.options.success || ('Build success in %sms');
init() {
let argv = this.argv;
if (argv.help && !this.bakefile) {
return CLI.help();
}
this.options.name = this.options.name || process.argv[1].split('/').slice(-1)[0];
if (argv.version) {
return console.log(require('../package.json').version);
}
this.argv = this.parse(this.options.argv);
this.args = this.argv._.concat();
this.env = this.options.env || Object.assign({}, process.env);
if (!this.bakefile) {
log('No Makefile/Bakefile in the current folder');
return this.generate('Makefile', argv);
if (this.options.debug || this.argv.debug) {
debug.enable(this.options.namespace);
}
this.file = fs.readFileSync(this.bakefile, 'utf8');
this.result = bake(this.file);
this.debug = debug(this.options.namespace);
}
this.targets = this.result.targets;
this.variables = this.result.variables;
if (argv.help) {
return CLI.help(this.targets);
}
let args = argv._;
if (this.bakefile !== 'Bakefile' && this.bakefile !== 'Makefile') args = args.slice(1);
if (!args[0]) args[0] = 'all';
// Run!
this.run(args);
parse(argv = process.argv.slice(2), alias = this.alias) {
return minimist(argv, { alias });
}
run(targets) {
this.debug('Run %s targets', targets.join(' '));
var argv = targets.concat();
exec(recipe, opts = { env: this.env, stdio: 'inherit' }) {
return new Promise((r, errback) => {
(function next(name) {
if (!name) return CLI.end(this.start, r);
this.debug('exec:', recipe);
this.silly('env:', opts.env);
spawn('bash', ['-c', recipe], opts)
.on('error', errback)
.on('close', (code) => {
if (code !== 0) {
this.error(recipe);
return errback(new Error('Recipe exited with code %d', code));
}
this.executeTarget(name)
.then(() => {
next.call(this, argv.shift());
})
.catch((err) => {
CLI.fail(argv.debug ? err : err.message);
errback(err);
});
}).call(this, argv.shift());
r();
});
});
}
executeTarget(target) {
return new Promise((r, errback) => {
if (!this.targets[target]) {
CLI.help(this.targets);
return errback(new Error('No target matching "' + target + '"'));
}
log.info('Invoking %s target', target);
var name = this.targets[target];
return this.executeRecipe(name, target)
.then(r)
.catch(errback)
});
end(cb) {
var time = Date.now() - this.start;
return CLI.end(this.options.success, time, cb);
}
executeRecipe(target, name) {
return new Promise((r, errback) => {
var prerequities = target.prerequities;
help(targets = {}) {
let targetList = '';
let leftpad = this.options.leftpad || ' ';
if (Object.keys(targets).length) targetList += ' Targets:\n';
// deps on this recipe, execute rules right away
if (!prerequities.length) return this.executeRules(target)
.then(r)
.catch(errback);
var keys = Object.keys(targets);
targetList += keys.map((t) => {
return leftpad + t + this.pad(t) + 'Run target ' + t;
}).join('\n');
// found prereq, execute them before executing rules
this.debug('Prerequities "%s" for target %s', prerequities.join(' '), name);
return this.executePrereq(target)
.then(() => {
return this.executeRules(target)
.then(r)
.catch(errback);
})
.catch(errback);
});
}
var options = '';
if (this.flags) {
options += 'Options:\n';
options += Object.keys(this.flags).map((flag) => {
return leftpad + '--' + flag + this.pad('--' + flag) + this.flags[flag];
}).join('\n');
}
executePrereq(target) {
return new Promise((r, errback) => {
var prerequities = target.prerequities;
let opts = {
example: this.example || this.options.example,
name: this.options.name,
commands: targetList,
more: this.more,
options,
};
// Before executing this recipe, execute any prerequities first
(function nextPrereq(pre) {
if (!pre) return r();
return CLI.help(opts);
}
this.executeTarget(pre)
.catch(errback)
.then(() => {
nextPrereq.call(this, prerequities.shift());
});
}).call(this, prerequities.shift());
});
pad(str, padding = PADDING) {
let len = padding - str.length;
return new Array(len <= 1 ? 2 : len).join(' ');
}
executeRules(target) {
var recipe = target.recipe;
return new Promise((r, errback) => {
this.debug('bash:', recipe);
// Help output
//
// Options:
//
// - name - Used in the generated example (ex: $ name --help)
// - example - Used in the generated example instead of the default one
// - options - Used in the generated example instead of the default one
static help(options = {}) {
options.name = options.name || '';
options.example = options.example || (options.name + ' --help');
var sh = spawn('bash', ['-c', recipe], {
stdio: 'inherit',
env: this.env
});
sh.on('error', errback);
sh.on('close', (code) => {
if (code != 0) {
return errback(new Error('%s exited with code %d', target.name, code));
}
r();
});
});
}
static help(targets = []) {
console.log(`
$ bake <target> [options]
$ ${options.example}
Options:
-h, --help Show this help
-v, --version Show package version
-d, --debug Enable extended output
`);
${options.options}`);
if (Object.keys(targets).length) console.log(' Targets:');
if (options.commands) console.log('\n', options.commands);
if (options.more) console.log(options.more);
var keys = Object.keys(targets);
var str = keys.map((t) => {
let pad = new Array(padding - t.length).join(' ');
return ' ' + t + pad + 'Run target ' + t;
});
console.log(str.join('\n'));
console.log();
}
static fail() {
static fail(e, exit) {
log.error.apply(log, arguments);
process.exit(1);
if (exit) process.exit(isNaN(exit) ? 1 : exit);
}
static end(start, cb) {
var time = Date.now() - start;
log.info(logsymbols.success + ' Build sucess in %sms', time);
static end(message, time, cb) {
log.info(message, time);
cb && cb();
}
}
CLI.PADDING = PADDING;
Object.assign(CLI.prototype, log);
Object.assign(CLI.prototype, fsutil);
const chalk = require('chalk');
const chalk = require('chalk');
const npmlog = require('npmlog');
const prefix = 'bake';
const { format } = require('util');
const { error, info, success, warning } = require('log-symbols');
let log = module.exports = npmlog;

@@ -13,1 +16,31 @@ log.heading = prefix;

});
// Few logsymbols log helper
log.success = (...args) => {
let msg = format.apply(null, args);
let level = chalk.green('info');
let symbol = success;
console.error(`${log.heading} ${symbol} ${level} ${msg}`);
};
log.warning = (...args) => {
let msg = format.apply(null, args);
let level = chalk.yellow('warn');
let symbol = warning;
console.error(`${log.heading} ${symbol} ${level} ${msg}`);
};
// let _info = log.info;
log.info = (...args) => {
let msg = format.apply(null, args);
let level = chalk.green('info');
let symbol = info;
console.error(`${log.heading} ${symbol} ${level} ${msg}`);
};
log.error = (...args) => {
let msg = format.apply(null, args);
let level = chalk.red('ERR ');
let symbol = error;
console.error(`${log.heading} ${symbol} ${level} ${msg}`);
};

@@ -14,3 +14,3 @@

// reference to last parsed target
var last;
var last = {};

@@ -17,0 +17,0 @@ var tokens = {

{
"name": "bake-cli",
"version": "0.0.4",
"version": "0.1.0",
"description": "Make like Task runner",
"bin": {
"bake": "bin/bake.js"
},
"main": "index.js",
"scripts": {
"test": "bake test"
"test": "mocha -R spec"
},
"devDependencies": {
"babel-cli": "^6.9.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.9.0",
"bake-cli": "0.0.4",
"eslint": "^2.10.2",
"eslint-config-standard": "^5.3.1",
"eslint-plugin-promise": "^1.1.0",
"eslint-plugin-standard": "^1.3.2",
"mocha": "^2.5.2",
"standard-version": "^2.2.1",
"watchd": "github:mklabs/watchd"
},
"bin": {
"bake": "bin/bake.js",
"bake-init": "bin/bake-init.js"
},
"dependencies": {
"chalk": "^1.1.3",
"debug": "^2.2.0",
"jsonlint": "^1.6.2",
"log-symbols": "^1.0.2",
"minimist": "^1.2.0",
"npmlog": "^2.0.3"
"npmlog": "^2.0.3",
"which": "^1.2.9"
},
"devDependencies": {
"babel-cli": "^6.7.5",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.6.0",
"standard-version": "^2.2.1",
"watchd": "github:mklabs/watchd"
},
"repository": {

@@ -27,0 +36,0 @@ "type": "git",

@@ -1,5 +0,7 @@

# Bake
# bake [![Build Status](https://secure.travis-ci.org/mklabs/bake.png)](http://travis-ci.org/mklabs/bake)
> Make like task runner, with npm script goodness
> Make like task runner
npm install bake-cli -g
## The Gist

@@ -53,3 +55,4 @@

Targets:
foo2 Run target foo2
all Run target all
build Run target build
foo Run target foo

@@ -60,2 +63,8 @@ prefoo Run target prefoo

$ bake init <template> [options]
default Scaffold an ES6 setup (babel, eslint, ...)
cli Scaffold an ES6 CLI setup (minimist, ...)
## What is Bake ?

@@ -93,6 +102,80 @@

### Makefiles goodness
## bake init
#### Bash scripting
Basic scaffolding command
Its purpose is to init a project Makefile with sensible defaults for various
development needs.
The default list of templates should be configurable. Adding new ones or
overriding existing ones should be a simple process.
Looking in
- ~/.config/bake/templates
- ~/.bake/templates
Where the templates directories have the following structure:
```
templates/
├── es6
│   ├── .babelrc
│   ├── .eslintrc
│   ├── Makefile
│   ├── package.json
│   └── .travis.yml
└── frontend
├── Makefile
├── package.json
└── webpack.config.js
```
The subdirectory name is the template name (invoked with bake init <name>).
If no name is defined, it defaults to "default"
- `Makefile` - Is the template Makefile to use
- `package.json` - JSON file to merge with project's package.json (usually to include devDependencies)
- `*.json` - Every JSON files generated is merged with existing files
(`.eslintrc` and `.babelrc` are handled as JSON files)
- Every other top level files is copied to destination, existing files are skipped
The package.json file can have a "bake" field (removed when merged with
package.json), with the following properties:
- "scripts" - Similar to npm scripts, a list of hooks for bake to invoke
- "scripts.start" - Executed when the generation process starts
- "scripts.install" - Executed when the template has been generated
- "description" - Optional description for this template (used on `--help`)
These hooks can be used to further customize the template generation (like
running `npm install` in "scripts.install")
See [the default template](./templates/default) package.json file:
```json
"bake": {
"description": "Scaffold a basic ES6 setup",
"scripts": {
"start": "echo Starting generation of default template",
"prestart": "echo prestart",
"poststart": "echo poststart",
"install": "npm install --loglevel http --cache-min Infinity",
"preinstall": "echo Installing dependencies ...",
"postinstall": "npm ls --depth 1"
}
}
```
**Note** `--cache-min Infinity` is used to bypass the HTTP network checks to
the registry for already installed packages.
## Makefile
Here is a quick description of Makefiles syntax, with bake differences highlighted.
### Bash scripting
```make

@@ -126,3 +209,3 @@ help:

#### Make like variables
### Make like variables

@@ -142,3 +225,3 @@ ```make

#### Task dependencies
### Task dependencies

@@ -172,3 +255,3 @@ Use prerequities to specify tasks that depends on other tasks.

#### path
### path

@@ -189,1 +272,59 @@ If you depend on modules that define executable scripts, like test suites,

is exported into the `node_modules/.bin` directory on `npm install`.
## Tests
npm test
Outputs help.
```js
cli()
.use('bake -h')
.expect('bake <target...> [options]')
.expect('Options:')
.expect(0)
.end(done);
```
bake foo.
```js
cli()
.use('bake foo')
.expect('prefoo\nblahblah\nfoo')
.expect(0)
.end(done);
```
bake all.
```js
cli()
.use('bake')
.expect('prefoo\nblahblah\nfoo\nfoo2\nblahblah\nfoobar')
.expect(0)
.end(done);
```
bake maoow - Outputs help on UNKNOWN_TARGET.
```js
cli()
.use('bake maoow')
.expect('bake <target...> [options]')
.expect('Options:')
.expect(0)
.end(done);
```
bake init.
```js
cli({ cwd: join(__dirname, 'examples') })
.use('bake init --skip')
.expect('Running default template')
.expect(/Makefile\s+already exists, skipping/)
.expect(/Build success in \d+ms/)
.expect(0)
.end(done);
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc