Skip to content

Commit 49cae43

Browse files
committed
[cli] Fix file processing
1 parent 6c88e7e commit 49cae43

File tree

3 files changed

+176
-117
lines changed

3 files changed

+176
-117
lines changed

src/cli.js

Lines changed: 151 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,67 @@
66
* Usage example:
77
* ./node_modules/.bin/csscomb [options] [file1 [dir1 [fileN [dirN]]]]
88
*/
9-
var format = require('./format');
109
var fs = require('fs');
1110
var parseArgs = require('minimist');
1211
var path = require('path');
13-
var vow = require('vow');
12+
1413
var Comb = require('./csscomb');
14+
var Errors = require('./errors');
15+
16+
17+
var getInputData = new Promise(function(resolve) {
18+
var input = '';
19+
process.stdin.resume();
20+
process.stdin.setEncoding('utf8');
21+
process.stdin.on('data', function(data) {
22+
input += data;
23+
});
24+
process.stdin.on('end', function() {
25+
resolve(input);
26+
});
27+
});
28+
1529
var comb = new Comb();
30+
var options = getOptions();
31+
32+
if (options.help) {
33+
displayHelp();
34+
process.exit(0);
35+
}
36+
37+
if (options.detect) {
38+
const config = detectConfig();
39+
process.stdout.write(config);
40+
process.exit(0);
41+
}
42+
43+
var config = getConfig();
44+
comb.configure(config);
45+
46+
if (options.fix && process.stdin.isTTY) {
47+
processFiles(options._);
48+
} else if (options.fix) {
49+
processSTDIN();
50+
} else if (process.stdin.isTTY) {
51+
lintFiles(options._);
52+
} else {
53+
lintSTDIN();
54+
}
55+
56+
57+
function getOptions() {
58+
var parserOptions = {
59+
boolean: ['help', 'fix', 'verbose'],
60+
alias: {
61+
config: 'c',
62+
detect: 'd',
63+
fix: 'f',
64+
help: 'h',
65+
verbose: 'v'
66+
}
67+
};
68+
return parseArgs(process.argv.slice(2), parserOptions);
69+
}
1670

1771
function displayHelp() {
1872
var help = [
@@ -30,43 +84,105 @@ function displayHelp() {
3084
' Run the tool in detect mode, returning detected options.',
3185
' -f, --fix',
3286
' Run the tool in fixer mode, modifying files when possible.',
87+
' -h, --help',
88+
' Display help message.',
3389
' -v, --verbose',
3490
' Whether to print logging info.'
3591
];
36-
console.log(help.join('\n'));
92+
process.stdout.write(help.join('\n'));
3793
}
3894

39-
var getInputData = new vow.Promise(function(resolve) {
40-
var input = '';
41-
process.stdin.resume();
42-
process.stdin.setEncoding('utf8');
43-
process.stdin.on('data', function(data) {
44-
input += data;
45-
});
46-
process.stdin.on('end', function() {
47-
resolve(input);
95+
function detectConfig() {
96+
const config = Comb.detectInFile(options.detect);
97+
return JSON.stringify(config, false, 4);
98+
}
99+
100+
function getConfig() {
101+
var configPath = options.config &&
102+
path.resolve(process.cwd(), options.config) ||
103+
Comb.getCustomConfigPath();
104+
105+
var config;
106+
if (!fs.existsSync(configPath)) {
107+
config = require('../config/csscomb.json');
108+
} else if (configPath.match(/\.css$/)) {
109+
config = Comb.detectInFile(configPath);
110+
} else {
111+
config = Comb.getCustomConfig(configPath);
112+
}
113+
114+
if (!config) {
115+
const errorMessage = Errors.configParsingError(configPath);
116+
process.stderr.write(errorMessage);
117+
process.exit(1);
118+
}
119+
120+
applyTemplate(config);
121+
if (options.verbose) config.verbose = options.verbose;
122+
123+
return config;
124+
}
125+
126+
function applyTemplate(config) {
127+
if (!config.template) return;
128+
129+
if (!fs.existsSync(config.template)) {
130+
const errorMessage = Errors.missingTemplateFile(config.template);
131+
process.stderr.write(errorMessage);
132+
process.exit(1);
133+
}
134+
135+
var templateConfig = Comb.detectInFile(config.template);
136+
for (var attrname in templateConfig) {
137+
if (templateConfig.hasOwnProperty(attrname) && !config[attrname]) {
138+
config[attrname] = templateConfig[attrname];
139+
}
140+
}
141+
}
142+
143+
function processFiles(files) {
144+
const promises = files.map(file => {
145+
return comb.processPath(file);
48146
});
49-
});
50147

51-
function processInputData(input) {
52-
comb.lintString(input).catch(e => {
53-
process.stderr.write(e.message);
148+
Promise.all(promises).catch(error => {
149+
process.stderr.write(error.stack);
54150
process.exit(1);
55-
}).then(output => {
56-
if (!output.length) {
57-
process.exit(0);
58-
} else {
59-
process.stdout.write(output);
60-
process.exit(1);
151+
}).then(c => {
152+
var tbchanged = c.filter(isChanged => {
153+
return isChanged !== undefined;
154+
}).reduce((a, b) => {
155+
return a + b;
156+
}, 0);
157+
158+
if (config.verbose) {
159+
let message = [
160+
`${c.length} file${c.length === 1 ? '' : 's'} processed`,
161+
`${tbchanged} file${tbchanged === 1 ? '' : 's'} fixed`,
162+
''
163+
].join('\n');
164+
process.stdout.write(message);
61165
}
166+
167+
process.exit(0);
62168
});
63169
}
64170

65171
function processSTDIN() {
66172
getInputData.then(processInputData);
67173
}
68174

69-
function processFiles(files) {
175+
function processInputData(input) {
176+
comb.processString(input).catch(e => {
177+
process.stderr.write(e.message);
178+
process.exit(1);
179+
}).then(output => {
180+
process.stdout.write(output);
181+
process.exit(0);
182+
});
183+
}
184+
185+
function lintFiles(files) {
70186
let anyErrorsFound = false;
71187

72188
const promises = files.map(file => {
@@ -108,88 +224,20 @@ function formatErrors(fileName, errors) {
108224
return message.join('\n');
109225
}
110226

111-
function getOptions() {
112-
var parserOptions = {
113-
boolean: ['verbose', 'lint'],
114-
alias: {
115-
config: 'c',
116-
detect: 'd',
117-
lint: 'l',
118-
verbose: 'v'
119-
}
120-
};
121-
return parseArgs(process.argv.slice(2), parserOptions);
227+
function lintSTDIN() {
228+
getInputData.then(lintInputData);
122229
}
123230

124-
function applyTemplate(config) {
125-
if (!config.template) return;
126-
127-
if (!fs.existsSync(config.template)) {
128-
let message = `Template configuration file ${config.template}
129-
was not found.`;
130-
process.stderr.write(format(message));
231+
function lintInputData(input) {
232+
comb.lintString(input).catch(e => {
233+
process.stderr.write(e.message);
131234
process.exit(1);
132-
}
133-
134-
var templateConfig = Comb.detectInFile(config.template);
135-
for (var attrname in templateConfig) {
136-
if (templateConfig.hasOwnProperty(attrname) && !config[attrname]) {
137-
config[attrname] = templateConfig[attrname];
235+
}).then(output => {
236+
if (!output.length) {
237+
process.exit(0);
238+
} else {
239+
process.stdout.write(output);
240+
process.exit(1);
138241
}
139-
}
140-
}
141-
142-
function getConfig(options) {
143-
var configPath = options.config &&
144-
path.resolve(process.cwd(), options.config) ||
145-
Comb.getCustomConfigPath();
146-
147-
var config;
148-
if (!fs.existsSync(configPath)) {
149-
config = require('../config/csscomb.json');
150-
} else if (configPath.match(/\.css$/)) {
151-
config = Comb.detectInFile(configPath);
152-
} else {
153-
config = Comb.getCustomConfig(configPath);
154-
}
155-
156-
if (!config) {
157-
let message = `Error parsing configuration file ${configPath}.`;
158-
process.stderr.write(format(message));
159-
process.exit(1);
160-
}
161-
162-
applyTemplate(config);
163-
if (options.verbose) config.verbose = options.verbose;
164-
165-
return config;
166-
}
167-
168-
function detectConfig(file) {
169-
var config = Comb.detectInFile(file);
170-
config = JSON.stringify(config, false, 4);
171-
process.stdout.write(config);
172-
process.exit(0);
173-
}
174-
175-
console.time('Time spent');
176-
177-
var options = getOptions();
178-
179-
if (options.help) {
180-
displayHelp();
181-
process.exit(0);
182-
}
183-
184-
if (options.detect) {
185-
detectConfig(options.detect);
186-
}
187-
188-
var config = getConfig(options);
189-
comb.configure(config);
190-
191-
if (process.stdin.isTTY) {
192-
processFiles(options._);
193-
} else {
194-
processSTDIN();
242+
});
195243
}

src/core.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,22 @@ class Comb {
185185

186186
if (!this._shouldProcessFile(path)) return;
187187

188-
return vfs.read(path, 'utf8').then(function(data) {
189-
let syntax = that._extractSyntax(path);
190-
that.processString(data, {
191-
syntax: syntax,
192-
filename: path
193-
}).then(function(processedData) {
194-
if (data === processedData) {
195-
if (that.verbose) console.log(' ', path);
196-
return 0;
197-
}
198-
199-
return vfs.write(path, processedData, 'utf8').then(function() {
200-
if (that.verbose) console.log('✓', path);
201-
return 1;
188+
return new Promise(resolve => {
189+
vfs.read(path, 'utf8').then(function(data) {
190+
let syntax = that._extractSyntax(path);
191+
that.processString(data, {
192+
syntax: syntax,
193+
filename: path
194+
}).then(function(processedData) {
195+
if (data === processedData) {
196+
if (that.verbose) console.log(' ', path);
197+
resolve(0);
198+
}
199+
200+
return vfs.write(path, processedData, 'utf8').then(function() {
201+
if (that.verbose) console.log('✓', path);
202+
resolve(1);
203+
});
202204
});
203205
});
204206
});

src/errors.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
let format = require('./format');
55

66
module.exports = {
7+
configParsingError(configPath) {
8+
return `Error parsing configuration file ${configPath}.`;
9+
},
10+
711
implementSetValue(valueType) {
812
if (typeof valueType === 'undefined') throw new Error();
913

@@ -27,6 +31,11 @@ module.exports = {
2731
return 'Plugin must list supported syntaxes.';
2832
},
2933

34+
missingTemplateFile(file) {
35+
return format(`Template configuration file ${file}
36+
was not found.`);
37+
},
38+
3039
twoPluginsWithSameName(pluginName) {
3140
if (typeof pluginName === 'undefined') throw new Error();
3241

0 commit comments

Comments
 (0)