grunt-hustler
Version:
A collection of grunt tasks
221 lines (149 loc) • 4.91 kB
text/coffeescript
module.exports = (grunt) ->
grunt.registerMultiTask 'shimmer', 'Creates a RequireJS main file', ->
src = @data.src
return grunt.log.warn('src is required') if !src
cwd = @data.cwd ? './'
files = grunt.file.expand {cwd}, src
path = require 'path'
deDupe = ->
previousFile = null
files.forEach (file, index) ->
dirname = path.dirname file
ext = path.extname file
basename = path.basename file, ext
if previousFile and previousFile.dirname is dirname and previousFile.basename is basename and previousFile.ext is '.coffee' and ext is '.js'
delete files[index]
previousFile = {
dirname
ext
basename
}
deDupe()
return grunt.verbose.warn('No src files found') if !files.length is 0
_ = grunt.util._
order = @data.order ? []
return grunt.log.warn('order must be an array') if !_.isArray(order)
removeFromFiles = (filePath) ->
position = files.indexOf filePath
if position isnt -1
delete files[position]
mainFileName = 'main.coffee'
removeFromFiles mainFileName
unixifyPath = (p) ->
regex = /\\/g
p.replace regex, '/'
filter = (filePath) ->
file = path.relative cwd, filePath
unixified = unixifyPath file
index = files.indexOf unixified
inSrc = index isnt -1
expand = (glob) ->
grunt.file.expand {cwd, filter}, glob
groups = []
processGroupFilePaths = (groupFilePaths) ->
filtered = []
groupFilePaths.forEach (groupFilePath) ->
position = files.indexOf groupFilePath
if position isnt -1
filtered.push groupFilePath
delete files[position]
groups.push filtered
handleArray = (group) ->
groupFilePaths = []
group.forEach (nestedGroup) ->
nestedGroupFilePaths = expand nestedGroup
groupFilePaths = groupFilePaths.concat nestedGroupFilePaths
processGroupFilePaths groupFilePaths
apps = {}
handleObject = (group) ->
for app, modules of group
mods = []
groupFilePaths = []
for module, filePath of modules
mods.push module
groupFilePaths.push filePath
processGroupFilePaths groupFilePaths
# isNgApp = app.substr(0, 5) is 'NGAPP'
# appName = if isNgApp then app.split('(')[1].split(')')[0] else app
appName = if app is 'NGAPP' then 'app' else app
appFile = "#{appName}.coffee"
removeFromFiles appFile
groups.push [appFile]
apps[app] = mods
handleString = (group) ->
groupFilePaths = expand group
processGroupFilePaths groupFilePaths
normalizeGroups = ->
order.forEach (group) ->
return handleString(group) if _.isString(group)
return handleArray(group) if _.isArray(group)
return handleObject(group) if _.isObject(group)
normalizeGroups()
getTemplate = (templateFileName) ->
template = grunt.file.read "#{__dirname}/shimmer-templates/#{templateFileName}"
createApp = (app, moduleNames) ->
template = getTemplate 'app.coffee'
config =
app: app
modules: JSON.stringify(moduleNames)
compiled = grunt.template.process template, data: config: config
fileName = "#{app}.coffee"
dest = path.resolve cwd, fileName
grunt.file.write dest, compiled
createApps = ->
for app, modules of apps
appName = if app is 'NGAPP' then 'app' else app
createApp appName, modules
createApps apps
req = @data.require
createRequire = ->
return if !req
req = 'bootstrap.coffee' if req is 'NGBOOTSTRAP'
template = getTemplate 'bootstrap.coffee'
compiled = grunt.template.process template
dest = path.resolve cwd, req
removeFromFiles req
grunt.file.write dest, compiled
createRequire()
loads = []
handleRemaining = ->
files.forEach (file) ->
console.log 'remaining', file
loads.push(file) if file
groups.push loads
handleRemaining()
getFileNameWithoutExtension = (file) ->
ext = path.extname file
extLength = ext.length
fileLength = file.length
file.substr(0, fileLength - extLength)
trimFiles = (preTrimmedFiles) ->
trimmedFiles = []
preTrimmedFiles.forEach (group) ->
trimmedGroup = []
group.forEach (module) ->
trimmedModule = getFileNameWithoutExtension module
trimmedGroup.push trimmedModule
trimmedFiles.push trimmedGroup
trimmedFiles
groups = trimFiles groups
shim = {}
deps = []
createShim = ->
groups.forEach (group) ->
group.forEach (module) ->
shim[module] = {deps}
deps = group
createShim()
loads = trimFiles([loads])[0]
processShim = ->
template = getTemplate mainFileName
trimmedRequire = getFileNameWithoutExtension req
config =
shim: JSON.stringify(shim)
loads: JSON.stringify(['require'].concat(loads))
req: if req then "require ['#{trimmedRequire}']" else ''
compiled = grunt.template.process template, data: config: config
dest = path.resolve cwd, mainFileName
grunt.file.write dest, compiled
processShim()