diff --git a/.travis.yml b/.travis.yml
index 8b95a9ff..5dc3337f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
language: node_js
+sudo: false
node_js:
- - "0.10"
+ - "4"
+ - "5"
after_script:
- npm run coveralls
diff --git a/lib/api/new.coffee b/lib/api/new.coffee
index d5f2d0d6..8e7d75a5 100644
--- a/lib/api/new.coffee
+++ b/lib/api/new.coffee
@@ -77,10 +77,10 @@ class New
W.promise (resolve, reject) ->
qs = []
for question in questions
- qs.push(question) unless _.contains(skip, question.name)
+ qs.push(question) unless _.includes(skip, question.name)
inquirer.prompt qs, (answers) -> resolve(answers)
- W.resolve(_.contains(_.keys(sprout.templates), base_tpl_name))
+ W.resolve(_.includes(_.keys(sprout.templates), base_tpl_name))
.then (res) ->
if not res
sprout.add(base_tpl_name, base_tpl_url)
diff --git a/lib/api/template.coffee b/lib/api/template.coffee
index 6eaf1c55..45f41439 100644
--- a/lib/api/template.coffee
+++ b/lib/api/template.coffee
@@ -66,7 +66,7 @@ exports.default = (args = {}) ->
if not args.name
return W.reject(new Error('please provide a template name'))
- if not _.contains(_.keys(sprout.templates), args.name)
+ if not _.includes(_.keys(sprout.templates), args.name)
return W.reject(new Error "you do not have this template installed")
config = global_config()
diff --git a/lib/api/watch.coffee b/lib/api/watch.coffee
index 1183e5ac..8bc93a39 100644
--- a/lib/api/watch.coffee
+++ b/lib/api/watch.coffee
@@ -1,6 +1,6 @@
-chokidar = require 'chokidar'
-minimatch = require 'minimatch'
-_ = require 'lodash'
+chokidar = require 'chokidar'
+mm = require 'micromatch'
+_ = require 'lodash'
###*
* @class Watcher
@@ -42,7 +42,7 @@ class Watcher
ignore = (p) ->
f = p.replace(@roots.root, '').slice(1)
@roots.config.watcher_ignores
- .map (i) -> minimatch(f, i, { dot: true })
+ .map (i) -> mm.isMatch(f, i, { dot: true })
.filter (i) -> i
.length
diff --git a/lib/cli/watch.coffee b/lib/cli/watch.coffee
index ad4fd348..bc952a03 100644
--- a/lib/cli/watch.coffee
+++ b/lib/cli/watch.coffee
@@ -1,4 +1,5 @@
open = require 'open'
+node = require 'when/node'
Roots = require '../../lib'
Server = require '../local_server'
@@ -24,6 +25,7 @@ module.exports = (cli, args) ->
project = new Roots args.path,
env: args.env
verbose: args.verbose
+ no_open: args.no_open
app = new Server(project)
port = process.env.port or args.port
@@ -39,12 +41,8 @@ module.exports = (cli, args) ->
project.watch()
.then (w) ->
res.watcher = w
- res.server = app.start(port)
- if project.config.open_browser and not args.no_open
- if project.config.open_browser == true
- open("http://localhost:#{port}/")
- else
- open(project.config.open_browser)
+ res.server = app
+ node.call(app.start.bind(app), port)
.yield(res)
###*
diff --git a/lib/compiler.coffee b/lib/compiler.coffee
index 7f655cb1..475218bb 100644
--- a/lib/compiler.coffee
+++ b/lib/compiler.coffee
@@ -64,7 +64,7 @@ class CompileFile
constructor: (@roots, @extensions, @compile_options, @category, @file) ->
@adapters = get_adapters.call(@)
- @is_compiled = !!_(@adapters).pluck('name').compact().value().length
+ @is_compiled = !!_(@adapters).map('name').compact().value().length
@out_ext = _.last(@adapters).output
@file_options = {filename: @file.path, _path: url_path.call(@)}
@@ -157,7 +157,7 @@ class CompileFile
process_write_hook_results = (results) ->
if results.length < 1 then return [write_task.call(@)]
- if _.contains(results, false) then return []
+ if _.includes(results, false) then return []
write_tasks = []
normal_write_pushed = false
@@ -258,7 +258,7 @@ class CompileFile
for ext in _.clone(extensions).reverse()
compiler = _.find @roots.config.compilers, (c) ->
- _.contains(c.extensions, ext)
+ _.includes(c.extensions, ext)
adapters.push(if compiler then compiler else { output: ext })
diff --git a/lib/config.coffee b/lib/config.coffee
index fc331326..84913018 100644
--- a/lib/config.coffee
+++ b/lib/config.coffee
@@ -52,7 +52,7 @@ class Config
@verbose = opts.verbose ? false
@debug = false
@live_reload = true
- @open_browser = true
+ @open_browser = !opts.no_open ? true
load_config.call(@)
@@ -144,7 +144,7 @@ class Config
out: (f, ext) ->
res = f.relative.split(path.sep)
- if _.contains(@dump_dirs, res[0]) then res.shift()
+ if _.includes(@dump_dirs, res[0]) then res.shift()
res.unshift(@output_path())
res = res.join(path.sep)
if ext
diff --git a/lib/extensions/compiled.coffee b/lib/extensions/compiled.coffee
index efdf5894..dcdd0e9c 100644
--- a/lib/extensions/compiled.coffee
+++ b/lib/extensions/compiled.coffee
@@ -28,4 +28,4 @@ module.exports = ->
detect_fn = (f) ->
exts = _(@roots.config.compilers).map((i)->i.extensions).flatten().value()
- _.contains(exts, path.extname(f.relative).slice(1))
+ _.includes(exts, path.extname(f.relative).slice(1))
diff --git a/lib/fs_parser.coffee b/lib/fs_parser.coffee
index b2cb0876..f1511237 100644
--- a/lib/fs_parser.coffee
+++ b/lib/fs_parser.coffee
@@ -1,11 +1,11 @@
-fs = require 'graceful-fs'
-path = require 'path'
-W = require 'when'
-readdirp = require 'readdirp'
-_ = require 'lodash'
-minimatch = require 'minimatch'
-pipeline = require 'when/pipeline'
-File = require 'vinyl'
+fs = require 'graceful-fs'
+path = require 'path'
+W = require 'when'
+readdirp = require 'readdirp'
+_ = require 'lodash'
+mm = require 'micromatch'
+pipeline = require 'when/pipeline'
+File = require 'vinyl'
###*
* @class FS Parser
@@ -150,7 +150,7 @@ class FSParser
if not detected then return false
cat = extfs.category ? ext.category
@ast[cat] ?= []
- @ast[cat].push(file) unless _.contains(@ast[cat], file)
+ @ast[cat].push(file) unless _.includes(@ast[cat], file)
return extfs.extract
###*
@@ -175,8 +175,8 @@ class FSParser
ignored = (f) ->
@config.ignores
- .map (i) -> minimatch(f, i, dot: true)
- .filter (i) -> i
+ .map((i) -> mm.isMatch(f, i, dot: true))
+ .filter((i) -> i)
.length
module.exports = FSParser
diff --git a/lib/local_server.coffee b/lib/local_server.coffee
index 94230f40..b4459c00 100644
--- a/lib/local_server.coffee
+++ b/lib/local_server.coffee
@@ -1,6 +1,8 @@
path = require 'path'
serve_static = require 'serve-static'
charge = require 'charge'
+browsersync = require 'browser-sync'
+_ = require 'lodash'
###*
* @class Server
@@ -17,6 +19,7 @@ class Server
###
constructor: (@project) ->
+ @bs = browsersync.create()
###*
* Start the local server on the given port.
@@ -26,52 +29,70 @@ class Server
###
start: (port, cb) ->
- opts = @project.config.server ? {}
- opts.log = false
-
- if @project.config.env is 'development'
- opts.write = content:
- "
-
- "
- opts.cache_control = {'**': 'max-age=0, no-cache, no-store'}
-
- app = charge(@project.config.output_path(), opts)
-
- if @project.config.env is 'development'
- app.stack.splice app.stack.length - 2, 0,
- route: '/__roots__'
- handle: serve_static(path.resolve(__dirname, 'browser'))
-
- @server = app.start(port, cb)
+ bs_options =
+ port: port
+ logLevel: 'silent'
+ open: @project.config.open_browser
+ server:
+ baseDir: @project.config.output_path()
+
+ if @project.config.browser then _.merge(bs_options, @project.config.browser)
+
+ # add charge middleware after merge to prevent errors
+ opts = @project.config.server or {}
+ middlewares = []
+
+ if opts.clean_urls
+ middlewares.push(charge.hygienist(@project.config.output_path()))
+ if opts.exclude
+ middlewares.push(charge.escapist(opts.exclude))
+ if opts.auth
+ middlewares.push(charge.publicist(opts.auth))
+ if opts.cache_control
+ middlewares.push(charge.archivist(opts.cache_control))
+ if opts.gzip
+ middlewares.push(charge.minimist(opts.gzip))
+ if opts.log
+ middlewares.push(charge.journalist(opts.log))
+ if opts.error_page
+ middlewares.push(charge.apologist(opts.error_page))
+
+ bs_options.server.middleware = middlewares
+
+ @bs.init(bs_options, cb)
###*
* Close the server and remove it.
###
stop: (cb) ->
- @server.close(cb)
- delete @server
+ @bs.exit()
+ cb()
###*
- * Send a message through websockets to the browser.
- *
- * @param {String} k - message key
- * @param {*} v - message value
+ * Reload the browser
###
- send_msg: (k, v) ->
- @server.send(type: k, data: v)
+ reload: ->
+ @bs.reload()
+
+ ###*
+ * Inject loading spinner while compiling
+ ###
+ compiling: ->
+ @bs.notify('compiling...')
###*
- * These three methods send 'reload', 'compiling', and 'error' messages
- * through to the browser.
+ * Sanitize error message and inject into page
+ * @param {Error} err - an error object
###
- reload: -> @send_msg('reload')
- compiling: -> @send_msg('compiling')
show_error: (err) ->
err = err.toString() if err instanceof Error
- @send_msg('error', err)
+ cleanError = if err.replace
+ err.replace(/(\r\n|\n|\r)/gm, '
')
+ else
+ "compile error!"
+ @bs.notify(cleanError, 100000)
module.exports = Server
diff --git a/package.json b/package.json
index 1c640805..b2f95c2b 100644
--- a/package.json
+++ b/package.json
@@ -10,29 +10,30 @@
"Sam Saccone "
],
"dependencies": {
- "accord": "0.20.x",
+ "accord": "0.21.x",
"argparse": "1.x",
- "charge": "0.0.4",
- "chokidar": "1.0.x",
- "coffee-script": "1.9.x",
+ "browser-sync": "2.x",
+ "charge": "0.1.x",
+ "chokidar": "1.x",
+ "coffee-script": "1.10.x",
"colors": "1.x",
"configstore": "0.3.x",
"graceful-fs": "4.x",
- "inquirer": "0.9.x",
+ "inquirer": "0.11.x",
"keen.io": "0.1.x",
- "lodash": "3.x",
- "minimatch": "2.x",
+ "lodash": "4.x",
+ "micromatch": "2.x",
"mkdirp": "0.5.x",
- "npm": "2.x",
+ "npm": "3.x",
"open": "0.0.5",
"osenv": "0.1.x",
- "readdirp": "1.x",
+ "readdirp": "2.x",
"rimraf": "2.x",
"serve-static": "1.x",
"ship": "0.2.x",
"sprout": "0.4.x",
- "update-notifier": "0.5.x",
- "vinyl": "0.5.x",
+ "update-notifier": "0.6.x",
+ "vinyl": "1.x",
"when": "3.x"
},
"devDependencies": {
@@ -46,7 +47,6 @@
"mocha": "2.x",
"mocha-lcov-reporter": "0.0.2",
"mockery": "1.x",
- "phantomjs": "1.x",
"roots-util": "0.1.x",
"selenium-webdriver": "2.x",
"sinon": "1.x",
diff --git a/test/cli.coffee b/test/cli.coffee
index 11c33d2c..86154afe 100644
--- a/test/cli.coffee
+++ b/test/cli.coffee
@@ -184,7 +184,7 @@ describe 'cli', ->
cli.removeListener('inline', spy)
cli.removeListener('data', spy)
cli.removeListener('err', spy)
- obj.server.close(done)
+ obj.server.stop(done)
it 'should error when trying to compile invalid code'
diff --git a/test/new.coffee b/test/new.coffee
index a12f996d..cbd22cfe 100644
--- a/test/new.coffee
+++ b/test/new.coffee
@@ -7,7 +7,7 @@ new_path = path.join(base_path, 'new/testing')
before ->
@starting_templates = Roots.template.list()
- if _.contains(@starting_templates, 'roots-base')
+ if _.includes(@starting_templates, 'roots-base')
# remove roots-base to verify 'base template added'
# functionality in lib/api/new.coffee
Roots.template.remove(name: 'roots-base')