1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 | var l = require('ergo-utils').log.module('ergo-api-watch');
|
7 | var _ = require('ergo-utils')._;
|
8 | var fs = require('ergo-utils').fs.extend(require('fs-extra'));
|
9 | var path = require('path')
|
10 | var build_api = require('./build');
|
11 | var Promise = require('bluebird')
|
12 |
|
13 |
|
14 | var _watcher = null;
|
15 |
|
16 | function _rebuild(options, context) {
|
17 | l.vlog("Changes detected. Rebuilding...");
|
18 | options = _.extend({working_dir: context.getBasePath()
|
19 | }, options)
|
20 | var execFile = Promise.promisify(require('child_process').execFile);
|
21 |
|
22 | var cmd = process.argv.slice(0,1).join('');
|
23 | var args = [
|
24 | process.argv.slice(1, 2).join(''),
|
25 | 'build',
|
26 | '--working_dir='+options.working_dir];
|
27 | if (options.clean)
|
28 | args.push('--clean')
|
29 |
|
30 | l.vvlog("Running '"+cmd+"' with args: " + l.dump(args))
|
31 | return execFile(cmd, args)
|
32 | .catch(function(err) {
|
33 | l.loge("Error when building:\n" + _.niceStackTrace(err));
|
34 | return false;
|
35 | })
|
36 | .then(function(response) {
|
37 | if (!response) {
|
38 | return false;
|
39 | }
|
40 |
|
41 |
|
42 | if (response.stderr && response.stderr.length>0)
|
43 | l.loge("Errors when building: "+ response.stderr);
|
44 |
|
45 | l.log("Build complete " + response);
|
46 | return true;
|
47 | });
|
48 | }
|
49 |
|
50 | function _watch(options, context) {
|
51 | if (!!_watcher)
|
52 | return _watcher;
|
53 |
|
54 | options.watch_dir = options.watch_dir || context.getBasePath();
|
55 | options.watch_delay = options.watch_delay || 300;
|
56 | var fswatch_options = {
|
57 | persistent: options.persistent || true
|
58 | , recursive: true
|
59 |
|
60 | };
|
61 | var build_options = {
|
62 | working_dir: context.getBasePath()
|
63 | };
|
64 | if (options.clean)
|
65 | build_options.clean = true;
|
66 |
|
67 | var _changeTimeout = null;
|
68 | var _changesWaiting = 0;
|
69 | var _buildPromise = null;
|
70 |
|
71 | var _rebuildTimerCallback = function() {
|
72 | _changeTimeout = null;
|
73 |
|
74 | if (!!_buildPromise) {
|
75 |
|
76 |
|
77 | _changesWaiting++;
|
78 | l.vvlog("Still building. Added to delayed build request.")
|
79 | }
|
80 | else
|
81 | {
|
82 | _changesWaiting = 0;
|
83 | _buildPromise = _rebuild(build_options, context)
|
84 | .then(function() {
|
85 | _buildPromise = null;
|
86 | if (_changesWaiting) {
|
87 | l.vlog("Re-invoking delayed build request.")
|
88 | _changeTimeout = setTimeout(_rebuildTimerCallback, options.watch_delay*5);
|
89 | }
|
90 | });
|
91 | }
|
92 | }
|
93 |
|
94 | if (options.build)
|
95 | _changeTimeout = setTimeout(_rebuildTimerCallback, options.watch_delay);
|
96 |
|
97 |
|
98 | options.watch_dir = path.resolve(options.watch_dir);
|
99 | l.log("Starting watch on: " + options.watch_dir);
|
100 | _watcher = fs.watch(options.watch_dir, fswatch_options, function(eventType, filename) {
|
101 | filename = path.resolve(options.watch_dir, filename);
|
102 |
|
103 | if (fs.isInDir(context.getOutPath(), filename)) {
|
104 | l.vlog("Ignoring changes for '" + filename + "'");
|
105 | return;
|
106 | }
|
107 | l.vlog(eventType + ": '"+ filename + "'");
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | if (_changeTimeout)
|
113 | clearTimeout(_changeTimeout);
|
114 | _changeTimeout = setTimeout(_rebuildTimerCallback, options.watch_delay);
|
115 |
|
116 | })
|
117 |
|
118 | return _watcher;
|
119 | }
|
120 |
|
121 | module.exports = function(options) {
|
122 | return Promise.try(function() {
|
123 | options = options || {};
|
124 |
|
125 | var context = require('./config').getContextSync(options.working_dir);
|
126 | context.mergeRuntimeOptions(options);
|
127 | return _watch(options, context);
|
128 | });
|
129 | };
|
130 |
|
131 |
|
132 | module.exports.watch = _watch;
|
133 | module.exports.build = _rebuild;
|
134 |
|
135 |
|