1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | var cli = require('cli'),
|
9 | debug = require('debug')('analyze-css:runner'),
|
10 | fs = require('fs'),
|
11 | resolve = require('path').resolve,
|
12 | analyzer = require('./index'),
|
13 | preprocessors = new(require('./preprocessors'))();
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | function getUserAgent() {
|
19 | var format = require('util').format,
|
20 | version = require('../package').version;
|
21 |
|
22 | return format(
|
23 | 'analyze-css/%s (%s %s, %s %s)',
|
24 | version,
|
25 | process.release.name,
|
26 | process.version,
|
27 | process.platform,
|
28 | process.arch
|
29 | );
|
30 | }
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | function request(requestOptions, callback) {
|
38 | var debug = require('debug')('analyze-css:http'),
|
39 | fetch = require('node-fetch');
|
40 |
|
41 | debug('GET %s', requestOptions.url);
|
42 | debug('Options: %j', requestOptions);
|
43 |
|
44 | fetch(requestOptions.url, requestOptions).
|
45 | then(function(resp) {
|
46 | debug('HTTP %d %s', resp.status, resp.statusText);
|
47 | debug('Headers: %j', resp.headers._headers);
|
48 |
|
49 | if (!resp.ok) {
|
50 | var err = new Error('HTTP request failed: ' + (err ? err.toString() : 'received HTTP ' + resp.status + ' ' + resp.statusText));
|
51 | callback(err);
|
52 | } else {
|
53 | return resp.text();
|
54 | }
|
55 | }).
|
56 | then(function(body) {
|
57 | debug('Received %d bytes of CSS', body.length);
|
58 | callback(null, body);
|
59 | }).
|
60 | catch(function(err) {
|
61 | debug(err);
|
62 | callback(err);
|
63 | });
|
64 | }
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | function runner(options, callback) {
|
70 |
|
71 | var analyzerOpts = {
|
72 | 'noOffenders': options.noOffenders,
|
73 | 'preprocessor': false,
|
74 | };
|
75 |
|
76 | function analyze(css) {
|
77 | new analyzer(css, analyzerOpts, callback);
|
78 | }
|
79 |
|
80 | if (options.url) {
|
81 | debug('Fetching remote CSS file: %s', options.url);
|
82 |
|
83 |
|
84 | var agentOptions = {},
|
85 | requestOptions = {
|
86 | url: options.url,
|
87 | headers: {
|
88 | 'User-Agent': getUserAgent()
|
89 | }
|
90 | };
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | if (options.ignoreSslErrors) {
|
97 | agentOptions.rejectUnauthorized = false;
|
98 | }
|
99 |
|
100 |
|
101 | if (options.authUser && options.authPass) {
|
102 | requestOptions.headers.Authorization = "Basic " + new Buffer(options.authUser + ":" + options.authPass, "utf8").toString("base64");
|
103 | }
|
104 |
|
105 |
|
106 | var client = require(/^https:/.test(options.url) ? 'https' : 'http');
|
107 | requestOptions.agent = new client.Agent(agentOptions);
|
108 |
|
109 |
|
110 | options.proxy = options.proxy || process.env.HTTP_PROXY;
|
111 |
|
112 | if (options.proxy) {
|
113 | debug('Using HTTP proxy: %s', options.proxy);
|
114 |
|
115 | requestOptions.agent = new(require('http-proxy-agent'))(options.proxy);
|
116 | }
|
117 |
|
118 | request(requestOptions, function(err, css) {
|
119 | if (err) {
|
120 | err.code = analyzer.EXIT_URL_LOADING_FAILED;
|
121 |
|
122 | debug(err);
|
123 | callback(err);
|
124 | } else {
|
125 | analyze(css);
|
126 | }
|
127 | });
|
128 | } else if (options.file) {
|
129 |
|
130 | options.file = resolve(process.cwd(), options.file);
|
131 | debug('Loading local CSS file: %s', options.file);
|
132 |
|
133 | fs.readFile(options.file, {
|
134 | encoding: 'utf-8'
|
135 | }, function(err, css) {
|
136 | if (err) {
|
137 | err = new Error('Loading CSS file failed: ' + err.toString());
|
138 | err.code = analyzer.EXIT_FILE_LOADING_FAILED;
|
139 |
|
140 | debug(err);
|
141 | callback(err);
|
142 | } else {
|
143 |
|
144 | if (analyzerOpts.preprocessor === false) {
|
145 | analyzerOpts.preprocessor = preprocessors.findMatchingByFileName(options.file);
|
146 | }
|
147 |
|
148 |
|
149 | analyzerOpts.file = options.file;
|
150 |
|
151 | analyze(css);
|
152 | }
|
153 | });
|
154 | } else if (options.stdin) {
|
155 | debug('Reading from stdin');
|
156 | cli.withStdin(analyze);
|
157 | }
|
158 | }
|
159 |
|
160 | module.exports = runner;
|