diff --git a/bin/ngbp b/bin/ngbp deleted file mode 100755 index 5c6969f..0000000 --- a/bin/ngbp +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env node - -process.title = 'ngbp'; - -var nopt = require('nopt'); -var resolve = require( 'resolve' ).sync; -var path = require( 'path' ); -var fs = require( 'fs' ); -var pkg = require( '../package.json' ); -var spawn = require( 'child_process' ).spawn; - -var basedir = process.cwd(); -var ngbpPath, gruntPath, grunt; - -var optlist = { - help: { - short: 'h', - info: 'Display this help text.', - type: Boolean - }, - version: { - short: 'V', - info: 'Print the grunt version. Combine with --verbose for more info.', - type: Boolean - } -}; - -// Parse `optlist` into a form that nopt can handle. -var aliases = {}; -var known = {}; - -Object.keys(optlist).forEach(function(key) { - var short = optlist[key].short; - if (short) { - aliases[short] = '--' + key; - } - known[key] = optlist[key].type; -}); - -var options = nopt( known, aliases, process.argv, 2 ); -var tasks = options.argv.remain; -delete options.argv; - -function version () { - console.log( "ngbp-cli version " + pkg.version ); - process.exit(); -} - -function help () { - console.log( "ngbp-cli help not yet implemented." ); - process.exit(); -} - -function fatal ( msg, code ) { - console.log( msg ); - process.exit( code || 1 ); -} - -function init () { - if ( tasks.length <= 1 ) { - fatal( 'You must provide a name for your project.', 91 ); - } - - if ( fs.existsSync( './Gruntfile.js' ) ) { - fatal( "You already have a gruntfile. This isn't supported yet, so you'll have to modify it manually.", 92 ); - } - - var name = tasks[1]; - console.log( "Creating project '" + name + "'..." ); - - if ( fs.existsSync( './package.json' ) ) { - var pkg = JSON.parse( fs.readFileSync( './package.json' ) ); - if ( ! pkg.ngbpModules || ! pkg.ngbpModules.length ) { - pkg.ngbpModules = [ "ngbp-contrib-core" ] - } - - if ( ! pkg.devDependencies ) { - pkg.devDependencies = { "ngbp": "~0.4" }; - } else { - var found = false; - Object.keys( pkg.devDependencies ).forEach( function ( mod ) { - if ( mod === "ngbp" ) { - found = true; - } - }); - - if ( ! found ) { - pkg.devDependencies["ngbp"] = "~0.4"; - } - } - - fs.writeFileSync( './package.json', JSON.stringify( pkg, undefined, " " ) ); - } else { - var pkgfile = [ - '{', - ' "name": "' + name + '",', - ' "version": "0.0.1",', - ' "author": "' + process.env['USER'] + '",', - ' "devDependencies": {', - ' "ngbp": "~0.4",', - ' "ngbp-contrib-clean": "~0.0.1",', - ' "ngbp-contrib-copy": "~0.0.1",', - ' "ngbp-contrib-tpl": "~0.0.1",', - ' "ngbp-contrib-lintjs": "~0.0.1",', - ' "ngbp-contrib-lintcss": "~0.0.1",', - ' "ngbp-contrib-mincss": "~0.0.1",', - ' "ngbp-contrib-minjs": "~0.0.1"', - ' }', - '}' - ].join( "\n" ); - - fs.writeFileSync( './package.json', pkgfile ); - } - - if ( ! fs.existsSync( './bower.json' ) ) { - var bowerfile = [ - '{', - ' "name": "' + name + '",', - ' "version": "0.0.1",', - '}' - ].join( "\n" ); - - fs.writeFileSync( './bower.json', bowerfile ); - } - - var change_vendor_dir = false; - if ( fs.existsSync( './.bowerrc' ) ) { - var bower = JSON.parse( fs.readFileSync( './.bowerrc' ) ); - if ( ! bower.directory ) { - change_vendor_dir = 'bower_components'; - } else if ( bower.directory !== 'vendor' ) { - change_vendor_dir = bower.directory; - } - } else { - change_vendor_dir = 'bower_components'; - } - - var gruntfile = [ - 'var grunt = require( "grunt" );', - '', - 'module.exports = function ( grunt ) {', - ' grunt.config.init({', - ' pkg: grunt.file.readJSON( "./package.json" )' + ( change_vendor_dir ? ',' : '' ), - '' + ( change_vendor_dir ? ' ngbp: { paths: { vendor: "' + change_vendor_dir + '" } }' : '' ), - ' });', - '', - ' grunt.loadNpmTasks( "ngbp" );', - '};' - ].join( "\n" ); - - fs.writeFileSync( './Gruntfile.js', gruntfile ); - - if ( ! fs.existsSync( './src' ) ) { - fs.mkdirSync( './src' ); - } - - if ( ! fs.existsSync( './src/index.html' ) ) { - var index = [ - '', - '', - ' ', - ' ngbp', - '', - ' <% ngbp.styles.forEach( function ( file ) { %>', - ' <% }); %>', - '', - ' <% ngbp.scripts.forEach( function ( file ) { %>', - ' <% }); %>', - ' ', - ' ', - '

ngbp generated me!

', - ' ', - '' - ].join( "\n" ); - - fs.writeFileSync( './src/index.html', index ); - } - - // run npm install - var npm = spawn( 'npm', [ 'install' ], { - cwd: process.cwd() - }); - - npm.stdout.pipe( process.stdout ); - npm.stderr.pipe( process.stderr ); - - npm.on('close', function ( code ) { - console.log( "New ngbp project created successfully. Happy coding!" ); - process.exit(); - }); -} - -// Do stuff based on CLI options. -if ( options.version ) { - version(); -} else if ( options.help || tasks.indexOf( 'help' ) >= 0 ) { - help(); -} else if ( tasks.indexOf( 'init' ) >= 0 ) { - init(); -} else { - /** - * Ensure there is a local installation of ngbp. - */ - try { - ngbpPath = resolve( 'ngbp', { basedir: basedir } ); - } catch ( ex ) { - fatal( 'Unable to find local ngbp. Have you run `ngbp init` yet?', 99 ); - } - - /** - * Ensure there is a local installation of grunt, since we'll pass most commands to it. - */ - try { - gruntPath = resolve( 'grunt', { basedir: basedir } ); - grunt = require( gruntPath ); - } catch ( ex ) { - fatal( 'Unable to find local grunt. Have you run `ngbp init` yet?', 99 ); - } - - if ( ! tasks.length ) { - console.log( 'You must provide some command for me to run. Here\'s some help:' ); - help(); - } - - /** - * Just pass the whatever tasks onto grunt, prefixing all of them with 'ngbp:'. - */ - grunt.tasks( tasks.map( function ( t ) { return 'ngbp-'+t; } ), options ); -} - diff --git a/bin/warlock b/bin/warlock new file mode 100755 index 0000000..f44fbd2 --- /dev/null +++ b/bin/warlock @@ -0,0 +1,129 @@ +#!/usr/bin/env node + +process.title = 'warlock'; + +// Node.js libs +var READLINE = require( 'readline' ); +var SPAWN = require( 'child_process' ).spawn; + +// 3rd Party Modules +var Q = require( 'q' ); +var COLORS = require( 'colors' ); +var FINDUP = require('findup-sync'); +var RESOLVE = require('resolve').sync; + +// Local libs +var PKG = require( './../package.json' ); + +function log ( msg ) { + console.log( "[warlock] " + msg ); +} + +function writeln ( msg ) { + console.log( msg ); +} + +function error ( msg, fatal ) { + msg = "[warlock] " + msg; + console.log( msg.red ); + + if ( fatal ) { + process.exit( 1 ); + } +} + +function header ( msg ) { + msg = "[warlock] " + msg; + console.log( msg.underline.magenta ); +} + +function installWarlockIfNeeded () { + var deferred = Q.defer(); + + /** + * Ensure there is a local installation of warlock. + */ + try { + warlockPath = RESOLVE( 'warlock', { basedir: process.cwd() } ); + deferred.resolve( warlockPath ); + } catch ( e ) { + error( "Encountered error: " + e ); + warlockPath = FINDUP( 'lib/warlock.js' ); + + // No warlock install found! + if ( warlockPath ) { + deferred.resolve( warlockPath ); + } else { + header( "Local warlock not installed." ); + + // Ensure the user is okay with installing it here. + var rl = READLINE.createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.question( "Install warlock in the current directory? [Yn] ", function ( answer ) { + rl.close(); + + if ( answer && [ 'y', 'Y', 'yes', 'Yes', 'YES' ].indexOf( answer ) === -1 ) { + deferred.reject( "I can't function without a local warlock installation." ); + return; + } + + /** + * This will install warlock and its dependencies locally, and if there is a `package.json` + * file it will save the requirement to the `devDependencies` array. + */ + var npm = SPAWN( 'npm', [ 'link', '--save-dev', 'warlock' ], { + // var npm = SPAWN( 'npm', [ 'install', '--save-dev', 'warlock' ], { + cwd: process.cwd() + }); + + npm.stderr.on( 'data', function ( data ) { + if (/^execvp\(\)/.test( data ) ) { + deferred.reject( "Could not start NPM." ); + } + }); + + npm.stdout.pipe( process.stdout ); + npm.stderr.pipe( process.stderr ); + + npm.on( 'close', function ( code ) { + if ( code === 0 ) { + deferred.resolve( RESOLVE( 'warlock', { basedir: process.cwd() } ) ); + } else { + deferred.reject( "NPM exited with status " + code + "." ); + } + }); + }); + } + } + + return deferred.promise; +} + +/** + * Print out the version, if necessary. + */ +if( process.argv.indexOf( '--version' ) !== -1 || process.argv.indexOf( '-V' ) !== -1 ) { + writeln( "warlock-cli v" + PKG.version ); +} + +/** + * Ensure that warlock is installed, then load the CLI. + */ +installWarlockIfNeeded() +.then( function ( warlockPath ) { + return require( warlockPath ).cli(); +}) +.done( function () { + // FIXME(jdm): I'm almost certain this shouldn't be necessary... + process.exit(); +}, function ( err ) { + if ( err.stack ) { + console.log( err.stack ); + } + + error( "Well, shoot-darn. " + err + " Exiting...", true ); +}); + diff --git a/package.json b/package.json index 3e5ff62..3fd1283 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,36 @@ { - "name": "ngbp-cli", - "version": "0.0.1-1", - "description": "Command-line interface to ngbp", - "homepage": "https://github.com/ngbp/ngbp-cli", + "name": "warlock-cli", + "version": "1.0.0-alpha.1", + "description": "Command-line interface to warlock", + "homepage": "https://github.com/ngbp/warlock-cli", "author": { - "name": "NGBP Team", - "url": "http://ngbp.org" + "name": "Warlock Team", + "url": "http://getwarlock.com" }, "repository": { "type": "git", - "url": "git://github.com/ngbp/ngbp-cli.git" + "url": "git://github.com/ngbp/warlock-cli.git" }, "bugs": { - "url": "https://github.com/ngbp/ngbp-cli" + "url": "https://github.com/ngbp/warlock-cli" }, "licenses": [ { "type": "MIT", - "url": "https://github.com/ngbp/ngbp-cli/blob/master/LICENSE" + "url": "https://github.com/ngbp/warlock-cli/blob/master/LICENSE" } ], "engines": { "node": ">= 0.8.0" }, - "devDependencies": { - "grunt": "*" - }, - "peerDependencies": {}, "dependencies": { "resolve": "~0.6.1", - "nopt": "~2.1.2" + "colors": "~0.6.2", + "findup-sync": "~0.1.2", + "q": "~0.9.7" }, "preferGlobal": true, "bin": { - "ngbp": "bin/ngbp" + "warlock": "bin/warlock" } }