Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[ALOY-522] add support for loading a custom UI via a module

[ALOY-523] fix problem with multiple log severity labels when running from CLI
[ALOY-524] show filename in error log
  • Loading branch information...
commit 92bbaf0c9f07878eb0c970e4f71831b061609f33 1 parent acefe52
Jeff Haynie authored

Showing 22 changed files with 134 additions and 38 deletions. Show diff stats Hide diff stats

  1. +8 1 Alloy/commands/compile/index.js
  2. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract.BarItemType.js
  3. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract.ButtonName.js
  4. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract.CoverFlowImageType.js
  5. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract.Option.js
  6. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract._BackboneClass.js
  7. +3 2 Alloy/commands/compile/parsers/Alloy.Abstract._ItemArray.js
  8. +1 1  Alloy/commands/compile/parsers/Alloy.Abstract._ItemContainer.js
  9. +4 4 Alloy/commands/compile/parsers/Alloy.Require.js
  10. +2 2 Alloy/commands/compile/parsers/Ti.Android.Menu.js
  11. +2 2 Alloy/commands/compile/parsers/Ti.UI.Picker.js
  12. +1 1  Alloy/commands/compile/parsers/Ti.UI.PickerColumn.js
  13. +2 2 Alloy/commands/compile/parsers/Ti.UI.Tab.js
  14. +1 1  Alloy/commands/compile/parsers/Ti.UI.TabGroup.js
  15. +1 1  Alloy/commands/compile/parsers/Ti.UI.TableView.js
  16. +2 2 Alloy/commands/compile/parsers/Ti.UI.iPad.SplitWindow.js
  17. +2 2 Alloy/commands/compile/parsers/Ti.UI.iPhone.NavigationGroup.js
  18. +17 0 Alloy/commands/compile/parsers/default.js
  19. +67 3 Alloy/utils.js
  20. +1 1  CHANGELOG.md
  21. +1 1  LICENSE
  22. +14 7 hooks/alloy.js
9 Alloy/commands/compile/index.js
@@ -119,7 +119,7 @@ module.exports = function(args, program) {
119 119 logger.debug('app path = ' + paths.app);
120 120
121 121 // create compile config from paths and various alloy config files
122   - compileConfig = CU.createCompileConfig(paths.app, paths.project, alloyConfig);
  122 + compileConfig = CU.compileConfig = CU.createCompileConfig(paths.app, paths.project, alloyConfig);
123 123 buildPlatform = compileConfig.alloyConfig.platform;
124 124 theme = compileConfig.theme;
125 125 logger.debug('platform = ' + buildPlatform);
@@ -192,6 +192,8 @@ module.exports = function(args, program) {
192 192 var fp = path.join(collection.dir,view.substring(0,view.lastIndexOf('.')));
193 193 if (tracker[fp]) { return; }
194 194
  195 + U.currentFile = path.join(collection.dir,CONST.DIR.VIEW,view);
  196 +
195 197 // generate runtime controller
196 198 logger.debug('[' + view + '] ' + (collection.manifest ? collection.manifest.id + ' ' : '') + 'view processing...');
197 199 parseAlloyComponent(view, collection.dir, collection.manifest);
@@ -207,6 +209,8 @@ module.exports = function(args, program) {
207 209 var fp = path.join(collection.dir,controller.substring(0,controller.lastIndexOf('.')));
208 210 if (tracker[fp]) { return; }
209 211
  212 + U.currentFile = path.join(collection.dir,CONST.DIR.CONTROLLER,controller);
  213 +
210 214 // generate runtime controller
211 215 logger.debug('[' + controller + '] ' + (collection.manifest ? collection.manifest.id + ' ' : '') + 'controller processing...');
212 216 parseAlloyComponent(controller, collection.dir, collection.manifest, true);
@@ -214,6 +218,9 @@ module.exports = function(args, program) {
214 218 }
215 219 });
216 220 });
  221 +
  222 + U.currentFile = null;
  223 +
217 224 logger.debug('');
218 225 // BENCHMARK('process all controllers');
219 226
2  Alloy/commands/compile/parsers/Alloy.Abstract.BarItemType.js
@@ -8,7 +8,7 @@ exports.parse = function(node, state) {
8 8
9 9 function parse(node, state, args) {
10 10 if (!state.itemsArray) {
11   - U.die('Invalid use of <Label>. Must be the child of <Labels>.');
  11 + U.dieWithNode(node, 'Invalid use of <Label>. Must be the child of <Labels>.');
12 12 }
13 13
14 14 // grab BarItemType attributes from node
2  Alloy/commands/compile/parsers/Alloy.Abstract.ButtonName.js
@@ -8,7 +8,7 @@ exports.parse = function(node, state) {
8 8
9 9 function parse(node, state, args) {
10 10 if (!state.itemsArray) {
11   - U.die('Invalid use of <ButtonName>. Must be the child of <ButtonNames>.');
  11 + U.didieWithNode(node, 'Invalid use of <ButtonName>. Must be the child of <ButtonNames>.');
12 12 }
13 13 var string = U.trim(U.XML.getNodeText(node) || '').replace(/"/g,'\\"');
14 14
2  Alloy/commands/compile/parsers/Alloy.Abstract.CoverFlowImageType.js
@@ -8,7 +8,7 @@ exports.parse = function(node, state) {
8 8
9 9 function parse(node, state, args) {
10 10 if (!state.itemsArray) {
11   - U.die('A CoverFlowImageType element must the child of a CoverFlowImageTypes element');
  11 + U.dieWithNode(node, 'A CoverFlowImageType element must the child of a CoverFlowImageTypes element');
12 12 }
13 13
14 14 var obj = {};
2  Alloy/commands/compile/parsers/Alloy.Abstract.Option.js
@@ -8,7 +8,7 @@ exports.parse = function(node, state) {
8 8
9 9 function parse(node, state, args) {
10 10 if (!state.itemsArray) {
11   - U.die('Invalid use of <Option>. Must be the child of <Options>.');
  11 + U.dieWithNode(node, 'Invalid use of <Option>. Must be the child of <Options>.');
12 12 }
13 13 var string = U.trim(U.XML.getNodeText(node) || '').replace(/"/g,'\\"');
14 14
2  Alloy/commands/compile/parsers/Alloy.Abstract._BackboneClass.js
@@ -59,7 +59,7 @@ function parse(node, state, args) {
59 59 if (isSingleton) {
60 60 if (id) {
61 61 logger.warn([
62   - 'Warning with <' + nodeName + '> at line ' + node.lineNumber,
  62 + 'Warning with <' + nodeName + '> at line ' + node.lineNumber + ' in ' + U.currentFile,
63 63 'id="' + id + '" will be ignored, as only ' + nodeName + ' instances can have ids, not singletons',
64 64 'To create an instance of the ' + nodeName + ', add instance="true"',
65 65 'This instance will be accessible in your controller as $.' + id,
5 Alloy/commands/compile/parsers/Alloy.Abstract._ItemArray.js
@@ -20,7 +20,8 @@ function parse(node, state, args) {
20 20
21 21 // Ensure that this _ItemArray has an appropriate parent
22 22 if (!state.itemsArray) {
23   - U.die([
  23 + U.dieWithNode(node,
  24 + [
24 25 'Invalid use of <' + node.nodeName + '> at line ' + node.lineNumber,
25 26 'Must be the child one of the following: [' + def.parents.join(',') + ']'
26 27 ]);
@@ -59,7 +60,7 @@ function parse(node, state, args) {
59 60
60 61 // Make sure the children match the parent
61 62 } else if (!_.contains(def.children, childArgs.fullname)) {
62   - U.die('Invalid child of <' + node.nodeName + '> on line ' + child.lineNumber + ': ' + childArgs.fullname);
  63 + U.dieWithNode(node, 'Invalid child of <' + node.nodeName + '> on line ' + child.lineNumber + ': ' + childArgs.fullname);
63 64 }
64 65 });
65 66
2  Alloy/commands/compile/parsers/Alloy.Abstract._ItemContainer.js
@@ -71,7 +71,7 @@ function parse(node, state, args) {
71 71 logger.warn('Additional views in ' + theNode + ' only supported on Android');
72 72 }
73 73 } else {
74   - U.die(theNode + ' can only have one androidView');
  74 + U.dieWithNode(theNode, theNode + ' can only have one androidView');
75 75 }
76 76 }
77 77 });
8 Alloy/commands/compile/parsers/Alloy.Require.js
@@ -18,9 +18,9 @@ function parse(node, state, args) {
18 18
19 19 // validate src
20 20 if (!src) {
21   - U.die('<Require> elements must have a "src" attribute.');
  21 + U.dieWithNode(node, '<Require> elements must have a "src" attribute.');
22 22 } else if (U.XML.getElementsFromNodes(node.childNodes).length !== 0) {
23   - U.die('<Require> elements may not have child elements.');
  23 + U.dieWithNode(node, '<Require> elements may not have child elements.');
24 24 }
25 25
26 26 // determine which Alloy method to use
@@ -39,7 +39,7 @@ function parse(node, state, args) {
39 39 alloyRequirePath = path.join(moduleRoot,'widgets',src,CONST.DIR.VIEW,CONST.NAME_WIDGET_DEFAULT);
40 40 break;
41 41 default:
42   - U.die('Invalid <Require> type "' + type + '"');
  42 + U.dieWithNode(node, 'Invalid <Require> type "' + type + '"');
43 43 }
44 44
45 45 // make sure the required file exists at compile time, rather than
@@ -52,7 +52,7 @@ function parse(node, state, args) {
52 52 }
53 53
54 54 if (!(path.existsSync(requirePath) || (type === 'widget' && path.existsSync(alloyRequirePath)))) {
55   - U.die(type + ' "' + src + '" at path "' + requirePath + '"' + (type === 'widget' ? ' or "' + alloyRequirePath + '"' : '') + ' does not exist.');
  55 + U.dieWithNode(node, type + ' "' + src + '" at path "' + requirePath + '"' + (type === 'widget' ? ' or "' + alloyRequirePath + '"' : '') + ' does not exist.');
56 56 }
57 57
58 58 // Remove <Require>-specific attributes from createArgs
4 Alloy/commands/compile/parsers/Ti.Android.Menu.js
@@ -31,7 +31,7 @@ function parse(node, state, args) {
31 31 // assert that the parent is a Ti.UI.Window
32 32 var parentNode = CU.validateNodeName(state.parent.node, 'Ti.UI.Window');
33 33 if (!parentNode) {
34   - U.die([
  34 + U.dieWithNode(node, [
35 35 'Invalid parent type for <Menu>: ' + state.parent.node.nodeName,
36 36 '<Menu> must have a Ti.UI.Window as a parent'
37 37 ]);
@@ -46,7 +46,7 @@ function parse(node, state, args) {
46 46
47 47 // Make sure we are dealing with MenuItems
48 48 if (!theNode) {
49   - U.die([
  49 + U.dieWithNode(node, [
50 50 'Invalid child type under <Menu>: ' + childArgs.fullname,
51 51 '<Menu> must have only <MenuItem> elements as children'
52 52 ]);
4 Alloy/commands/compile/parsers/Ti.UI.Picker.js
@@ -30,7 +30,7 @@ function parse(node, state, args) {
30 30 (childArgs.name === 'Column' && !child.getAttribute('ns'))) {
31 31 foundColumn = true;
32 32 if (foundRow) {
33   - U.die([
  33 + U.dieWithNode(node, [
34 34 err,
35 35 'You can\'t mix columns an rows as children of <Picker>'
36 36 ]);
@@ -40,7 +40,7 @@ function parse(node, state, args) {
40 40 (childArgs.name === 'Row' && !child.getAttribute('ns'))) {
41 41 foundRow = true;
42 42 if (foundColumn) {
43   - U.die([
  43 + U.dieWithNode(node, [
44 44 err,
45 45 'You can\'t mix columns an rows as children of <Picker>'
46 46 ]);
2  Alloy/commands/compile/parsers/Ti.UI.PickerColumn.js
@@ -26,7 +26,7 @@ function parse(node, state, args) {
26 26 (childArgs.name === 'Row' && !child.getAttribute('ns'))) {
27 27 child.nodeName = 'PickerRow';
28 28 } else {
29   - U.die(err);
  29 + U.dieWithNode(node, err);
30 30 }
31 31
32 32 // generate the code for each row and add it to the array
4 Alloy/commands/compile/parsers/Ti.UI.Tab.js
@@ -13,7 +13,7 @@ function parse(node, state, args) {
13 13
14 14 // Tab must have 1 window as a child
15 15 if (children.length !== 1) {
16   - U.die(err);
  16 + U.dieWithNode(node, err);
17 17 }
18 18
19 19 var child = children[0],
@@ -31,7 +31,7 @@ function parse(node, state, args) {
31 31 });
32 32 } else {
33 33 err.unshift('Invalid Tab child "' + childArgs.fullname + '"');
34   - U.die(err);
  34 + U.dieWithNode(node, err);
35 35 }
36 36
37 37 // create tab with window
2  Alloy/commands/compile/parsers/Ti.UI.TabGroup.js
@@ -23,7 +23,7 @@ function parse(node, state, args) {
23 23 }
24 24 });
25 25 } else {
26   - U.die([
  26 + U.dieWithNode(node, [
27 27 'Invalid <TabGroup> child type: ' + CU.getNodeFullname(child),
28 28 'All <TabGroup> children must be <Tab>'
29 29 ]);
2  Alloy/commands/compile/parsers/Ti.UI.TableView.js
@@ -38,7 +38,7 @@ function parse(node, state, args) {
38 38 // the table data, a searchbar, or a proxy property assigment
39 39 var theNode = CU.validateNodeName(child, ALL_VALID);
40 40 if (!theNode) {
41   - U.dieWithNode(child, 'Child element must be on of the following: [' + ALL_VALID.join(',') + ']');
  41 + U.dieWithNode(node, 'Child element must be on of the following: [' + ALL_VALID.join(',') + ']');
42 42 } else if (theNode === 'Ti.UI.SearchBar') {
43 43 isSearchBar = true;
44 44 } else if (_.contains(PROXY_PROPERTIES, theNode)) {
4 Alloy/commands/compile/parsers/Ti.UI.iPad.SplitWindow.js
@@ -13,7 +13,7 @@ function parse(node, state, args) {
13 13
14 14 // SplitWindow must have 2 windows as children
15 15 if (children.length !== 2) {
16   - U.die('SplitWindow must have exactly 2 children that are Windows, a master and detail respectively');
  16 + U.dieWithNode(node, 'SplitWindow must have exactly 2 children that are Windows, a master and detail respectively');
17 17 }
18 18
19 19 _.each(children, function(child) {
@@ -27,7 +27,7 @@ function parse(node, state, args) {
27 27 }
28 28 });
29 29 } else {
30   - U.die([
  30 + U.dieWithNode(node, [
31 31 'Invalid <SplitWindow> child type: ' + childArgs.fullname,
32 32 '<SplitWindow> must have 2 Windows as children'
33 33 ]);
4 Alloy/commands/compile/parsers/Ti.UI.iPhone.NavigationGroup.js
@@ -13,7 +13,7 @@ function parse(node, state, args) {
13 13
14 14 // NavigationGroup must have 1 window as a child
15 15 if (children.length !== 1) {
16   - U.die(err);
  16 + U.dieWithNode(node, err);
17 17 }
18 18
19 19 var child = children[0],
@@ -31,7 +31,7 @@ function parse(node, state, args) {
31 31 });
32 32 } else {
33 33 err.unshift('Invalid NavigationGroup child "' + childArgs.fullname + '"');
34   - U.die(err);
  34 + U.dieWithNode(node, err);
35 35 }
36 36
37 37 // create navgroup with window
17 Alloy/commands/compile/parsers/default.js
@@ -17,6 +17,23 @@ function parse(node, state, args) {
17 17 args.symbol = CU.generateUniqueId();
18 18 }
19 19
  20 + var module = node.getAttribute('module');
  21 +
  22 + // check to see if this tag's view is coming from a user module instead of builtin Ti API
  23 + // and if so, we need to load the module and use it by prefixing it to the API
  24 + if (module)
  25 + {
  26 + if (!U.tiapp.isModuleDeclared(module,CU.compileConfig.alloyConfig.platform))
  27 + {
  28 + U.dieWithNode(node,'Required module ' + module.yellow + ' is not declared in tiapp.xml or is not available for ' + CU.compileConfig.alloyConfig.platform.blue);
  29 + }
  30 + var p = module.split('.'),
  31 + m = p[p.length-1],
  32 + createFunc = node.getAttribute('method') || 'create' + m[0].toUpperCase() + m.substring(1) + 'View';
  33 + args.ns = 'require("'+module+'")';
  34 + delete args.createArgs['module'] && delete args.createArgs['method'];
  35 + }
  36 +
20 37 // Generate runtime code
21 38 code += (state.local ? 'var ' : '') + args.symbol + " = " + args.ns + "." + createFunc + "(\n";
22 39 code += CU.generateStyleParams(
70 Alloy/utils.js
@@ -14,6 +14,8 @@ var path = require('path'),
14 14 CONST = require('./common/constants')
15 15 ;
16 16
  17 +exports.currentFile = null;
  18 +
17 19 exports.XML = {
18 20 getNodeText: function(node) {
19 21 if (!node) { return ''; }
@@ -90,13 +92,21 @@ exports.XML = {
90 92 };
91 93
92 94 exports.tiapp = {
  95 + _xml:null,
  96 + getDocument: function() {
  97 + if (this._xml) return this._xml;
  98 + // shouldn't ever get here
  99 + U.die('programming error. called getDocument before parse has been called at least once');
  100 + },
93 101 parse: function(dir) {
  102 + if (this._xml) return this._xml;
94 103 dir || (dir = './');
95 104 var tiappPath = path.join(dir,'tiapp.xml');
96 105 if (!path.existsSync(tiappPath)) {
97 106 U.die('tiapp.xml file does not exist at "' + tiappPath + '"');
98 107 }
99   - return exports.XML.parseFromFile(tiappPath);
  108 + this._xml = exports.XML.parseFromFile(tiappPath);
  109 + return this._xml;
100 110 },
101 111 getTitaniumSdkVersion: function(doc) {
102 112 var elems = doc.documentElement.getElementsByTagName('sdk-version');
@@ -110,7 +120,59 @@ exports.tiapp = {
110 120 }
111 121 }
112 122 return null;
113   - },
  123 + },
  124 + isModuleDeclared: function (name, platform) {
  125 + var module = this.getModule(this._xml, name);
  126 + // if we've specified a platform, make sure we're running on that platform
  127 + if (module)
  128 + {
  129 + if (module.platform)
  130 + {
  131 + if (module.platform === platform)
  132 + {
  133 + return true;
  134 + }
  135 + else if (module.platform === 'ios' &&
  136 + (platform === 'ios' || platform === 'iphone' || platform === 'ipad'))
  137 + {
  138 + return true;
  139 + }
  140 + else if (module.platform === 'iphone' &&
  141 + (platform === 'ios' || platform === 'iphone'))
  142 + {
  143 + return true;
  144 + }
  145 + else if (module.platform === 'ipad' &&
  146 + (platform === 'ios' || platform === 'ipad'))
  147 + {
  148 + return true;
  149 + }
  150 + return false;
  151 + }
  152 + // otherwise if not specified, it's cross platform
  153 + return true;
  154 + }
  155 + // we couldn't find the module in tiapp.xml
  156 + return false;
  157 + },
  158 + getModule: function(doc, name) {
  159 + var modules = doc.documentElement.getElementsByTagName('modules');
  160 + if (modules.length > 0)
  161 + {
  162 + modules = modules.item(0).getElementsByTagName('module');
  163 + for (var i = 0; i < modules.length; i++) {
  164 + var node = modules.item(i);
  165 + var moduleId = exports.XML.getNodeText(node);
  166 + if (moduleId === name) {
  167 + return {
  168 + version: node.getAttribute('version'),
  169 + platform: node.getAttribute('platform')
  170 + }
  171 + }
  172 + }
  173 + }
  174 + return null;
  175 + },
114 176 upStackSizeForRhino: function(dir) {
115 177 var doc = exports.tiapp.parse(dir);
116 178 var runtime = exports.XML.getNodeText(exports.tiapp.getProperty(doc, 'ti.android.runtime'));
@@ -133,6 +195,7 @@ exports.tiapp = {
133 195
134 196 // serialize the xml and write to tiapp.xml
135 197 var serializer = new XMLSerializer();
  198 + this._xml = doc;
136 199 var newxml = serializer.serializeToString(doc);
137 200 fs.writeFileSync(path.join(dir,'tiapp.xml'),newxml,'utf8');
138 201 }
@@ -198,6 +261,7 @@ exports.tiapp = {
198 261
199 262 // serialize the xml and write to tiapp.xml
200 263 var serializer = new XMLSerializer();
  264 + this._xml = doc;
201 265 var newxml = serializer.serializeToString(doc);
202 266 fs.writeFileSync(tiappPath,newxml,'utf8');
203 267
@@ -570,7 +634,7 @@ exports.die = function(msg, e) {
570 634
571 635 exports.dieWithNode = function(node, msg) {
572 636 msg = _.isArray(msg) ? msg : [msg];
573   - msg.unshift('Error with <' + node.nodeName + '> at line ' + node.lineNumber);
  637 + msg.unshift('Error with <' + node.nodeName + '> at line ' + node.lineNumber + (exports.currentFile ? ' in '+exports.currentFile : ''));
574 638 exports.die(msg);
575 639 }
576 640
2  CHANGELOG.md
Source Rendered
@@ -144,7 +144,7 @@ The following deprecated APIs have been removed in this release:
144 144 | `Alloy.getModel` | method | Creates a local instance of a model. Use [Alloy.createModel](http://docs.appcelerator.com/titanium/latest/#!/api/Alloy-method-createModel) instead. |
145 145 | `Alloy.getWidget` | method | Creates a local instance of a widget. Use [Alloy.createWidget](http://docs.appcelerator.com/titanium/latest/#!/api/Alloy-method-createWidget) instead. |
146 146 | `Alloy.globals` | property | Global namespace. Use [Alloy.Globals](http://docs.appcelerator.com/titanium/latest/#!/api/Alloy-property-Globals) instead. |
147   -| `datatime.js` | builtin | Collection of functions for datetime formatting. Use [moment.js](http://docs.appcelerator.com/titanium/latest/#!/api/Alloy.builtins.moment) instead. |
  147 +| `datetime.js` | builtin | Collection of functions for datetime formatting. Use [moment.js](http://docs.appcelerator.com/titanium/latest/#!/api/Alloy.builtins.moment) instead. |
148 148 | `size` | XML/TSS attribute | Defines size-specific view components or styles. Use the `formFactor` attribute instead. |
149 149
150 150 ### New features
2  LICENSE
... ... @@ -1,6 +1,6 @@
1 1 ======================================
2 2 Alloy
3   -Copyright (c) 2012 Appcelerator, Inc.
  3 +Copyright (c) 2012-2013 Appcelerator, Inc.
4 4 ======================================
5 5
6 6 Licensed under the Apache License, Version 2.0 (the "License");
21 hooks/alloy.js
@@ -101,27 +101,34 @@ exports.init = function (logger, config, cli, appc) {
101 101 process.platform == 'win32' && cmd.shift();
102 102 logger.info(__('Executing Alloy compile: %s', cmd.join(' ').cyan));
103 103
  104 + logger.error('here');
104 105 var child = spawn(cmd.shift(), cmd);
105 106 // this regex is used to strip [INFO] and friends from alloy's output and re-log it using our logger
106   - re = new RegExp('(\u001b\\[\\d+m)?\\[?(' + logger.getLevels().join('|') + ')\\]?\s*(\u001b\\[\\d+m)?(.*)', 'i');
  107 + var re = new RegExp('(\u001b\\[\\d+m)?\\[?(' + logger.getLevels().join('|') + ')\\]?\s*(\u001b\\[\\d+m)?(.*)', 'i'),
  108 + // and this one test for output without colors
  109 + re2 = new RegExp('\\[?('+logger.getLevels().join('|')+')\\]?\s*','i');
107 110
108   - child.stdout.on('data', function (data) {
  111 + function filterLog(data, def)
  112 + {
109 113 data.toString().split('\n').forEach(function (line) {
110 114 if (line) {
111   - var m = line.match(re);
  115 + var m = line.match(re) || line.match(re2);
112 116 if (m) {
113 117 logger[m[2].toLowerCase()](m[4].trim());
114 118 } else {
115   - logger.debug(line);
  119 + def(line);
116 120 }
117 121 }
118 122 });
  123 + }
  124 +
  125 + child.stdout.on('data', function (data) {
  126 + filterLog(data,logger.debug);
119 127 });
120 128 child.stderr.on('data', function (data) {
121   - data.toString().split('\n').forEach(function (line) {
122   - line && logger.error(line);
123   - });
  129 + filterLog(data,logger.error);
124 130 });
  131 +
125 132 child.on('exit', function (code) {
126 133 if (code) {
127 134 logger.error(__('Alloy compiler failed'));

0 comments on commit 92bbaf0

Please sign in to comment.
Something went wrong with that request. Please try again.