UNPKG

capt

Version:

Command line tool for creating backbone.js applications with coffeescript

277 lines (208 loc) 8.52 kB
fs = require('fs') sys = require('sys') Path = require("path") Glob = require("glob").globSync root = __dirname + "/../" router = require("#{root}/lib/router") request = require("#{root}/lib/request") _ = require("#{root}/lib/underscore") yaml = require("#{root}/lib/yaml") server = router.getServer() Project = require("#{root}/src/project").Project String.prototype.capitalize = -> this.charAt(0).toUpperCase() + this.substring(1).toLowerCase() OptionParser = require("#{root}/lib/parseopt").OptionParser parser = new OptionParser { minargs : 0 maxargs : 10 } $usage = ''' Usage: capt new projectname - create a new project capt server - serve the current project on port 3000 capt watch - watch the current project and recompile as needed Code generators: * capt generate model post * capt generate router posts * capt generate view posts show ''' # Parse command line data = parser.parse() # # Raise an error # raise = (error) -> sys.puts error process.exit() task = (command, description, func) -> length = command.split(' ').length if data.arguments.slice(0,length).join(" ") == command func(data.arguments.slice(length)) task.done = true # # Start the server # task 'server', 'start a webserver', (arguments) -> project = new Project(process.cwd()) server.get "/", (req, res, match) -> ejs = fs.readFileSync("#{project.root}/index.jst") + "" _.template(ejs, { project : project }) server.get "/spec/", (req, res) -> ejs = fs.readFileSync("#{project.root}/spec/index.jst") + "" _.template(ejs, { project : project }) server.get /(.*)/, router.staticDirHandler(project.root, '/') project.watchAndBuild() server.listen(3000) task 'build', 'concatenate and minify all javascript and stylesheets for production', (arguments) -> project = new Project(process.cwd()) sys.puts "Building #{project.name()}..." try fs.mkdirSync "#{project.root}/build", 0755 catch e # .. ok .. output = "#{project.root}/build" try fs.mkdirSync output, 0755 catch e # .. ok .. sys.puts " * Building css and js componenets" # Todo - emit an event from project when the build is complete project.build() setTimeout( => sys.puts " * #{output}/bundled-javascript.js" project.bundleJavascript("#{output}/bundled-javascript.js") project.bundleStylesheet("#{output}/bundled-stylesheet.css") # Recompile the index.html to use the bundled urls sys.puts " * #{output}/index.html" project.scriptIncludes = -> project.getScriptTagFor('./build/bundled-javascript.js') project.stylesheetIncludes = -> project.getStyleTagFor('./build/bundled-stylesheet.css') for file in project.getDependencies('static') project.compileFile(file) # ejs = fs.readFileSync("#{project.root}/index.jst") + "" # fs.writeFileSync("#{output}/index.html", _.template(ejs, { project : project })) , 2000) # sys.puts " * #{output}/bundled-stylesheet.css" # sys.puts " - " + project.getStylesheetDependencies().join("\n - ") # # project.bundleStylesheet("#{output}/bundled-stylesheet.css") # task 'watch', 'watch files and compile as needed', (arguments) -> project = new Project(process.cwd()) project.watchAndBuild() task 'new', 'create a new project', (arguments) -> project = arguments[0] or raise("Must supply a name for new project.") sys.puts " * Creating folders" dirs = ["", "spec", "spec/jasmine", "spec/models", "spec/routers", "spec/views", "app", "app/views", "app/templates", "app/routers", "app/models", "lib", "public", "public/stylesheets", "spec/fixtures"] for dir in dirs fs.mkdirSync "#{project}/#{dir}", 0755 sys.puts " * Creating directory structure" libs = { "lib/jquery.js" : "lib/jquery.js", "lib/underscore.js" : "lib/underscore.js" "lib/backbone.js" : "lib/backbone.js" "lib/less.js" : "lib/less.js" "app/routers/application.coffee" : "routers/application.coffee" "spec/jasmine/jasmine-html.js" : "lib/jasmine-html.js" "spec/jasmine/jasmine.css" : "lib/jasmine.css" "spec/jasmine/jasmine.js" : "lib/jasmine.js" "config.yml" : "config.yml" "index.jst" : "html/index.jst" "spec/index.jst" : "html/runner.jst" } downloadLibrary = (path, lib) -> request { uri : lib }, (error, response, body) -> if (!error && response.statusCode == 200) sys.puts " * " + Path.basename(path) fs.writeFileSync("#{project}/#{path}", body) else sys.puts " * [ERROR] Could not download " + Path.basename(path) copyLibrary = (path, lib) -> fs.writeFileSync(Path.join(project, path), fs.readFileSync(lib) + "") for path, lib of libs if lib.match(/^http/) downloadLibrary(path, lib) else copyLibrary(path, Path.join(root, "templates/", lib)) task 'generate model', 'create a new model', (arguments) -> project = new Project(process.cwd()) if arguments[0] model = arguments[0].toLowerCase() else raise("Must supply a name for the model") copyFile = (from, to) -> ejs = fs.readFileSync(from) + "" fs.writeFileSync(Path.join(project.root, to), _.template(ejs, { project : project, model : model })) sys.puts " * Created #{to}" copyFile "#{root}/templates/models/model.coffee", "app/models/#{model}.#{project.language()}" copyFile "#{root}/templates/models/spec.coffee", "spec/models/#{model}.#{project.language()}" task 'generate collection', 'create a new collection', (arguments) -> project = new Project(process.cwd()) if arguments[0] model = arguments[0].toLowerCase() else raise("Must supply a name for the model") copyFile = (from, to) -> ejs = fs.readFileSync(from) + "" fs.writeFileSync(Path.join(project.root, to), _.template(ejs, { project : project, model : model })) sys.puts " * Created #{to}" copyFile "#{root}/templates/collection/collection.coffee", "app/models/#{model}_collection.#{project.language()}" copyFile "#{root}/templates/collection/spec.coffee", "spec/models/#{model}_collection.#{project.language()}" task 'generate router', 'create a new router', (arguments) -> project = new Project(process.cwd()) if arguments[0] router = arguments[0].toLowerCase() else raise("Must supply a name for the router") copyFile = (from, to) -> ejs = fs.readFileSync(from) + "" fs.writeFileSync(Path.join(project.root, to), _.template(ejs, { project : project, router : router })) sys.puts " * Created #{to}" try fs.mkdirSync "#{project.root}/app/views/#{router}", 0755 fs.mkdirSync "#{project.root}/spec/views/#{router}", 0755 fs.mkdirSync "#{project.root}/app/templates/#{router}", 0755 catch e # ... copyFile "#{root}/templates/routers/router.coffee", "app/routers/#{router}_router.#{project.language()}" copyFile "#{root}/templates/routers/spec.coffee", "spec/routers/#{router}_router.#{project.language()}" task 'generate view', 'create a new view', (arguments) -> project = new Project(process.cwd()) if arguments[0] and arguments[1] router = arguments[0].toLowerCase() view = arguments[1].toLowerCase() else raise("Must supply a name for the router and then view") copyFile = (from, to) -> ejs = fs.readFileSync(from).toString() fs.writeFileSync(Path.join(project.root, to), _.template(ejs, { project : project, router: router, view : view })) sys.puts " * Created #{to}" if !Path.existsSync("#{project.root}/app/views/#{router}") fs.mkdirSync "#{project.root}/app/views/#{router}", 0755 if !Path.existsSync("#{project.root}/app/templates/#{router}") fs.mkdirSync "#{project.root}/app/templates/#{router}", 0755 copyFile "#{root}/templates/views/view.coffee", "app/views/#{router}/#{view}.#{project.language()}" copyFile "#{root}/templates/templates/template.eco", "app/templates/#{router}/#{view}.eco" copyFile "#{root}/templates/views/spec.coffee", "spec/views/#{router}/#{view}.#{project.language()}" # task 'spec', 'run the specs', (arguments) -> # project = new Project(process.cwd()) # # sys.puts " * Running specs..." # # jasmine = require('jasmine-node') # # runLogger = (runner, log) -> # if runner.results().failedCount == 0 # process.exit 0 # else # process.exit 1 # # jasmine.executeSpecsInFolder "spec/models", runLogger, true, true # No task was specified... if !task.done sys.puts $usage process.exit()