Skip to content

Instantly share code, notes, and snippets.

@martinhbramwell
Created July 29, 2015 12:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinhbramwell/fb7681569b5482f23f63 to your computer and use it in GitHub Desktop.
Save martinhbramwell/fb7681569b5482f23f63 to your computer and use it in GitHub Desktop.
#! /usr/bin/env node
var DEBUG = false;
if ( process.env.DEBUG ) {
DEBUG = true;
}
//==================================================================================================
// REQUIRED IMPORTS
// child_process lets us exec and spawn external commands
var childProcess = require( "child_process" );
// github-download allows us to clone repos into our application
var githubDownload = require( "github-download" );
// minimist lets us cleanly parse our cli arguments into an object
var minimist = require( "minimist" );
//var arguments = require("minimist")(process.argv.slice(2));
// fs-extra lets us recursively copy directories and do advance file management
var fs = require( "fs-extra" );
// file-exists allows us to make sure config files exist
var fileExists = require( "file-exists" );
// http allows us to detect if instances of meteor are running in expected locations
var http = require( "http" );
// request allows us to query external websites
var request = require( "request" );
// replace allows us to refactor contents of file
var replace = require( "replace" );
// so we can find the NODE_PATH
var path = require( "path" );
// fibers and futures allow us to make remote async calls
var Fiber = require( "fibers" );
var Future = require( "fibers/future" );
// so we can get the npm install prefix
var npm = require( "npm" );
// for _.extend()ing the process.env object
var _ = require( "underscore" );
// so we can read files from the filesystem
var filesystem = require( "fs" );
// cheerio provides DOM/jQuery utilities to lets us parse html
var cheerio = require( "cheerio" );
// unzip lets us uncompress files
var unzip = require( "unzip" );
// prompt lets us accept input from the keyboard
// https://www.npmjs.com/package/prompt
var prompt = require( "prompt" );
// for accessing meteor collections
// https://github.com/oortcloud/node-ddp-client
// https://www.npmjs.com/package/ddp
var ddp = require( "ddp" );
//==================================================================================================
// FILE LINKING
var help = require( "../tool/help.js" );
var auditPermissions = require( "../tool/audit-permissions.js" );
var clone = require( "../tool/clone.js" );
var displayEnv = require( "../tool/display-env.js" );
var extractClasses = require( "../tool/extract-classes.js" );
var extractIds = require( "../tool/extract-ids.js" );
var extractTestsFor = require( "../tool/extract-tests-for.js" );
var findAndReplace = require( "../tool/find-and-replace.js" );
var generateTravis = require( "../tool/generate-travis.js" );
var pattern = require( "../tool/pattern.js" );
var refactor = require( "../tool/refactor.js" );
var rename = require( "../tool/rename.js" );
var sample = require( "../tool/sample.js" );
// var scaffold = require( "../tool/scaffold.js" );
var generateReleaseJson = require( "../tool/generate-release-json.js" );
var extractTools = require( "../tool/extract-tools.js" );
var downloadTools = require( "../tool/download-tools.js" );
var createPackage = require( "../tool/create.js" );
var publishPackage = require( "../tool/publish.js" );
// deprecated APIs
var runFramework = require( "../tool/run-framework.js" );
var runTests = require( "../tool/run-tests.js" );
var locateFireFox = require( "../tool/locate-firefox.js" );
var findTestDirs = require( "../tool/find-test-dirs.js" );
var generateAutoConfig = require( "../tool/generate-autoconfig.js" );
var compactFiles = require( "../tool/compact.js" );
var generateLinters = require( "../tool/generate-linters.js" );
//==================================================================================================
// DEBUGGING
if ( process.env.DEBUG ) {
console.dir( process.argv );
console.log( "arg0: ", process.argv[ 0 ] );
console.log( "arg1: ", process.argv[ 1 ] );
console.log( "arg2: ", process.argv[ 2 ] );
console.log( "arg3: ", process.argv[ 3 ] );
console.log( "STARRYNIGHT_FRAMEWORK: " + process.env.STARRYNIGHT_FRAMEWORK );
console.log( "STARRYNIGHT_FRAMEWORK_CONFIG: " + process.env.STARRYNIGHT_FRAMEWORK_CONFIG );
}
//**************************************************************************************************
// VARIABLES
var isReadyToRun = true;
//**************************************************************************************************
// PROCESSING COMMAND LINE ARGUMENTS
// most of StarySky uses a two argument syntax
var firstArgument = ( process.argv[ 2 ] || "" );
var secondArgument = ( process.argv[ 3 ] || "" );
var thirdArgument = ( process.argv[ 4 ] || "" );
var fourthArgument = ( process.argv[ 5 ] || "" );
var fifthArgument = ( process.argv[ 5 ] || "" );
// otherwise we'll want to pass in all of the arguments
var options = minimist( process.argv );
DEBUG && console.log( options );
if ( options.help ) {
help();
process.exit( 0 );
}
const commandDispatch = {};
commandDispatch.scaffold = require( "../tool/scaffold.js" );
commandDispatch[ "run-tests" ] = require( "../tool/run-tests.js" );
commandDispatch.help = require( "../tool/help.js" );
npm.load( function ( error, npm ) {
if ( error ) {
throw error;
}
var npmPrefix = npm.config.get( "prefix" );
DEBUG && console.log( "npm prefix is", npmPrefix );
try {
console.log( "####### Calling new dispatcher ########" );
commandDispatch[ firstArgument ](npmPrefix, process.argv, options);
}
catch ( error ) {
// if ( -1 < err.message.indexOf( "not a function" ) ) {
if ( error.name === "TypeError" ) {
console.log( "Getting help." );
commandDispatch.help();
} else {
throw error;
}
}
} );
//**************************************************************************************************
// HELPER FUNCTIONS
checkIfInAppRoot = function () {
console.log( "This command should be run in the root of an application." );
};
@martinhbramwell
Copy link
Author

This Gist shows an alternate way of dispatching commands, with many advantages.
The "active ingredient" is line 169.

To test it, temporarily replace your starrynight.js with this one and run these three commands :

starrynight scaffold --framework nightwatch-minimal

starrynight run-tests --framework nightwatch

starrynight crap

You should see the following :

yourself@yourpc:~/projects/helloworld$ starrynight scaffold --framework nightwatch-minimal
####### Calling new dispatcher ########
Minimal Nightwatch validation testing framework scaffolded into project!
yourself@yourpc:~/projects/helloworld$
yourself@yourpc:~/projects/helloworld$
yourself@yourpc:~/projects/helloworld$ starrynight run-tests --framework nightwatch
####### Calling new dispatcher ########
Launching StarryNight.  Analyzing meteor environment...
Detected a meteor instance on port 3000
Launching nightwatch bridge...
Found .meteor/nightwatch.json
Starting selenium server... 
started - PID:  5270
[App Layout] Test Suite
=======================

Running:  Layout & Static Pages
✔ Testing if element <body> is present.
OK. 1 assertions passed. (6.16s)

Finished!  Nightwatch ran all the tests!
yourself@yourpc:~/projects/helloworld$
yourself@pkgtstvid:~/projects/helloworld$ 
yourself@pkgtstvid:~/projects/helloworld$ 
yourself@pkgtstvid:~/projects/helloworld$ starrynight crap
####### Calling new dispatcher ########
Getting help.
StarryNight... managing your application life-cycle from installation to testing to deployment.
Usage:
  display-env
  audit-permissions
  generate-autoconfig
  run-tests --framework <frameworkName> --autogenerated
  scaffold --boilerplate <boilerplateName> --framework <frameworkName>
  pattern --url http://github.com/account/repo
  rename --from <originalTerm> --to <newTerm> -root <directoryRoot>
  find-and-replace --from <originalTerm> --to <newTerm> -root <directoryRoot>
  refactor --from <originalTerm> --to <newTerm> -root <directoryRoot>
  create --package foo:mypackage --from /path/to/component
  extract-ids /path/to/<filename>
  extract-classes /path/to/<filename>
  extract-tests-for /path/to/<filename>
  generate-release-json
  generate-travis
  generate-linters
  compact
yourself@pkgtstvid:~/projects/helloworld$

Those are the only commands that will work for now.

@awatson1978
Copy link

Nice! This is very reminiscent of the slidedeck from jsconf that I started implementing a few months ago. If you haven't done so, take a look:

http://michaelbrooks.ca/deck/jsconf2013/#/69

In general, I'm on board with moving towards a dispatcher system. Let's stage this on a separate feature branch, however, rather than commit directly to master. When it goes in, let's have all the commands added, rather than piecemealed. It would also be nice to have a sample rspec test (even if it's only a single one) that creates a pseudo-dispatcher when running tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment