Skip to content

Commit

Permalink
Get dependency watching working, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanZim committed Jan 22, 2017
1 parent d81cbe4 commit aaf27b6
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 22 deletions.
44 changes: 22 additions & 22 deletions index.js
Expand Up @@ -13,6 +13,8 @@ const getStdin = require('get-stdin')
const postcss = require('postcss')
const postcssrc = require('postcss-load-config')

const getDependencyMessages = require('./lib/get-dependency-messages.js')

const logo = `
/|\\
// //
Expand Down Expand Up @@ -91,32 +93,36 @@ getConfig({}, argv.config)
console.warn('No files passed, reading from stdin')
return ['-']
})
.then(files => {
if (!files || !files.length) throw new Error('You must pass a valid list of files to parse')
if (files.length > 1 && argv.output) throw new Error('Must use --dir or --replace with multiple input files')
.then(expandedInput => {
input = expandedInput
if (!input || !input.length) throw new Error('You must pass a valid list of files to parse')
if (input.length > 1 && argv.output) throw new Error('Must use --dir or --replace with multiple input files')

return processFiles(files)
return processFiles(input)
})
.then(function () {
.then(function (results) {
if (argv.watch) {
spinner.text = 'Waiting for file changes...'

let watcher = chokidar
.watch(input)
.watch(input.concat(getDependencyMessages(results)))

watcher
.add(config.file)
.on('ready', (file) => spinner.start())
.on('change', (file) => {
if (file === config.file) {
return Promise.all([globber(input), getConfig()])
.then(arr => processFiles(arr[0]))
// If this is not a direct input file, process all:
if (input.indexOf(file) === -1) {
return getConfig()
.then(() => processFiles(input))
.then(results => watcher.add(getDependencyMessages(results)))
.catch(error)
}
spinner.text = `Processing ${chalk.green(`${file}`)}`

getConfig().then(() => processFiles(file, watcher))
.then(() => {
getConfig()
.then(() => processFiles(file))
.then(result => {
watcher.add(getDependencyMessages(result))
spinner.text = 'Waiting for file changes...'
spinner.start()
})
Expand All @@ -126,7 +132,7 @@ getConfig({}, argv.config)
})
.catch(error)

function processCSS (css, filename, watcher) {
function processCSS (css, filename) {
var spinner = ora(`Processing ${filename || 'your CSS'}`)
spinner.start()

Expand All @@ -141,12 +147,6 @@ function processCSS (css, filename, watcher) {

return postcss(config.plugins).process(css, options)
.then(result => {
if (watcher) {
result.messages
.filter((msg) => msg.type === 'dependency' ? msg : '')
.forEach((dep) => watcher.add(dep))
}

if (result.messages.some(msg => msg.type === 'warning')) spinner.fail()

var tasks = [fs.outputFile(options.to, result.css)]
Expand All @@ -161,16 +161,16 @@ function processCSS (css, filename, watcher) {
})
}

function processFiles (files, watcher) {
function processFiles (files) {
if (typeof files === 'string') files = [files]
return Promise.all(files.map(file => {
// Read from stdin
if (file === '-') {
return getStdin()
.then(css => processCSS(css, undefined, watcher))
.then(css => processCSS(css))
}
return fs.readFile(file)
.then(css => processCSS(css, file, watcher))
.then(css => processCSS(css, file))
}))
}

Expand Down
12 changes: 12 additions & 0 deletions lib/get-dependency-messages.js
@@ -0,0 +1,12 @@
module.exports = function (results) {
if (!Array.isArray(results)) results = [results]
let arr = []

results
.forEach(result => {
result.messages
.filter(msg => msg.type === 'dependency' ? msg : '')
.forEach(dep => arr.push(dep.file))
})
return arr
}
70 changes: 70 additions & 0 deletions test/watch.js
Expand Up @@ -147,3 +147,73 @@ test.cb('--watch watches postcss.config.js', function (t) {
// Timeout:
setTimeout(() => t.end('test timeout'), 50000)
})

test.cb('--watch watches dependencies', function (t) {
var cp

t.plan(2)

createEnv('', ['*a-red.css'])
.then(dir => {
// Init watcher:
var watcher = chokidar.watch('.', {
cwd: dir,
ignoreInitial: true,
awaitWriteFinish: true
})

// On the first output:
watcher.on('add', p => {
// Assert, then change the source file
if (p === 'out.css') {
isEqual(p, 'test/fixtures/a-red.css')
.then(() => read('test/fixtures/a-blue.css'))
.then(css => fs.writeFile(path.join(dir, 'a-red.css'), css))
.catch(done)
}
})

// When the change is picked up:
watcher.on('change', p => {
if (p === 'out.css') {
isEqual(p, 'test/fixtures/a-blue.css')
.then(() => done())
.catch(done)
}
})

// Start postcss-cli:
watcher.on('ready', () => {
cp = execFile(
path.resolve('bin/postcss'),
[
'imports-a-red.css',
'-o', 'out.css',
'-u', 'postcss-import',
'-w',
'--no-map'
],
{cwd: dir}
)
cp.on('error', t.end)
cp.on('exit', code => { if (code) t.end(code) })
})

// Helper functions:
function isEqual (p, expected) {
return Promise.all([read(path.join(dir, p)), read(expected)])
.then(([a, e]) => t.is(a, e))
}

function done (err) {
try {
cp.kill()
} catch (e) {}
t.end(err)
}
})
.catch(t.end)

// Timeout:
setTimeout(() => t.end('test timeout'), 50000)
})

0 comments on commit aaf27b6

Please sign in to comment.