shampoo
Version:
The ultimate Grunt Browserify task. Run once or watch files for changes. Uses a cache for super speed (instant builds). CoffeeScript support built in. Alias mappings. Shimming. Everything in one easy to use package.
131 lines (119 loc) • 4.16 kB
text/coffeescript
# Runs the Shampoofile using Grunt but without actually having to run Grunt
# from the command line.
grunt = require 'grunt'
_ = require 'lodash'
path = require 'path'
argv = process.argv
class ShampooCLI
constructor: (argv) ->
@initArgs(_.clone(argv))
initArgs: (args) ->
mode = null
lang = null
force = null
names = []
# shift off the first two arguments because they are just running of this
# program and not the actual arguments
args.shift()
args.shift()
_.each args, (arg) =>
# If run with --init or --init-js then initialize for Javascript
if arg == '--init' || arg == '--init-js'
mode = "init"
lang = "js"
# If run with --init-coffee then initialize for CoffeeScript
else if arg == '--init-coffee'
mode = 'init'
lang = 'coffee'
# If run with --force, then allow initialization to overwrite existing
# Shampoofile
else if arg == '--force'
force = true
# For everything else, we just push the argument onto the list of names.
# The first name found is always the build destination.
else
names.push arg
if mode == 'init'
if lang == 'coffee'
@copyTemplate('Shampoofile.coffee', force)
else if lang == 'js'
@copyTemplate('Shampoofile.js', force)
else if names.length == 0
@runFromShampoofile('default')
else if names.length == 1
@runFromShampoofile(names[0])
else
console.log '782374893728947328947328974893'
console.log names
@runFromArguments(names...)
copyTemplate: (filename, force) ->
# fs = require 'fs'
templatePath = __dirname + "/../templates/#{filename}"
localPath = path.join(process.cwd(), filename)
if grunt.file.exists(localPath) && !force
@warn(
"#{filename} already exists in this directory",
"To force overwrite, add --force to arguments"
)
else
grunt.file.copy templatePath, localPath
console.log "Successfully created #{filename}"
runFromShampoofile: (taskSubName) ->
# look for both a JavaScript and CoffeeScript file.
# If both, throw an error.
# If none, throw an error.
# If one, then process it.
jsPath = path.join(process.cwd(), "Shampoofile.js")
coffeePath = path.join(process.cwd(), "Shampoofile.coffee")
jsFileExists = grunt.file.exists(jsPath)
coffeeFileExists = grunt.file.exists(coffeePath)
if jsFileExists and coffeeFileExists
@warn "Both 'Shampoofile.js' and 'Shampoofile.coffee' exists.", "Please delete or rename one."
return
else if jsFileExists
shampooPath = jsPath
ShampoofileOptions = require jsPath
else if coffeeFileExists
shampooPath = coffeePath
ShampoofileOptions = require coffeePath
else
@warn "Could not find 'Shampoofile.js' or 'Shampoofile.coffee'"
return
# Setup Grunt to run the config
grunt.initConfig(
shampoo: ShampoofileOptions
)
shampooConfig = grunt.config.get('shampoo')
if shampooConfig[taskSubName]
@runTask("shampoo:#{taskSubName}")
else
@warn(
"Could not find a key named '#{taskSubName}' in the Shampoofile at:",
shampooPath
)
runFromArguments: (buildPath) ->
sourcePaths = _.toArray(arguments)
# shift off the buildPath
sourcePaths.shift()
argvOptions = {
files: {}
}
argvOptions.files[buildPath] = sourcePaths
grunt.initConfig(
shampoo:
argv: argvOptions
)
@runTask("shampoo:argv")
# Loads the tasks defined for this project in ./tasks and then runs the
# task with the given taskName
runTask: (taskName) ->
grunt.loadTasks path.join(__dirname, '../tasks')
grunt.task.run taskName
grunt.task.start()
# Outputs a nicely formatted warning message to the console.
warn: (msg) ->
console.log ""
console.log "=== WARNING ==="
_.each arguments, (msg) ->
console.log msg
shampooCLI = new ShampooCLI(process.argv)