maximus 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/README.md +35 -14
- data/lib/maximus/cli.rb +1 -0
- data/lib/maximus/config.rb +148 -135
- data/lib/maximus/git_control.rb +96 -96
- data/lib/maximus/helper.rb +1 -0
- data/lib/maximus/lint.rb +119 -118
- data/lib/maximus/lints/brakeman.rb +14 -14
- data/lib/maximus/lints/railsbp.rb +13 -13
- data/lib/maximus/reporter/git-lines.sh +40 -11
- data/lib/maximus/statistic.rb +30 -25
- data/lib/maximus/statistics/phantomas.rb +11 -11
- data/lib/maximus/statistics/stylestats.rb +52 -55
- data/lib/maximus/statistics/wraith.rb +21 -25
- data/lib/maximus/version.rb +1 -1
- data/maximus.gemspec +4 -0
- data/roadmap.md +3 -6
- data/spec/maximus/config_spec.rb +44 -0
- data/spec/spec_helper.rb +4 -0
- metadata +51 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8843e2de02ffdfdbe667056bbb99a3a346a6c2aa
|
4
|
+
data.tar.gz: 4d60b2e41051e130c5d6749c584430f6d3d49681
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bfa472047e078d6d46220e88a5e0fe2f350ddc321c39c4967d89c5e0015b1da40af853448501966bc197abe1238e3d0e2791ecaface6bc08c8755b24049c3bc
|
7
|
+
data.tar.gz: 4d41a262ca94d0dc8444b8ce2a4d43978ae4945010ecc2ac670519dcddb375a0af61f4baa903042d77bdf54c3bb53271cb24d15efd46528791ab72ba6b699c73
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Maximus
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/maximus.svg)](http://badge.fury.io/rb/maximus) [![Code Climate](https://codeclimate.com/github/wearefine/maximus/badges/gpa.svg)](https://codeclimate.com/github/wearefine/maximus)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/maximus.svg)](http://badge.fury.io/rb/maximus) [![Code Climate](https://codeclimate.com/github/wearefine/maximus/badges/gpa.svg)](https://codeclimate.com/github/wearefine/maximus) [![Build Status](https://travis-ci.org/wearefine/maximus.svg)](https://travis-ci.org/wearefine/maximus) [![Inline docs](http://inch-ci.org/github/wearefine/maximus.svg?branch=master&style=flat)](http://inch-ci.org/github/wearefine/maximus)
|
4
4
|
|
5
5
|
The all-in-one linting solution.
|
6
6
|
|
@@ -12,13 +12,23 @@ Plays nice with Middleman and Rails.
|
|
12
12
|
* Elsewhere/command line: `gem install maximus`
|
13
13
|
* Globally with RVM (~/.rvm/gemsets/global.gems): `maximus`
|
14
14
|
|
15
|
-
Maximus has several node dependencies that can be installed
|
15
|
+
Maximus has several node dependencies that can be installed via the command line:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ npm install -g jshint phantomas stylestats
|
19
|
+
```
|
20
|
+
|
21
|
+
or once the gem is successfully installed:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ maximus install
|
25
|
+
```
|
16
26
|
|
17
27
|
## Config
|
18
28
|
|
19
29
|
Lints and statistics can be configured turned on or off with a `maximus.yml` file in the root directory maximus is being called in. `config/maximus.yml` will be checked if a config file isn't found in the root, and if there's still no luck, [the default config](lib/maximus/config/maximus.yml) will be loaded.
|
20
30
|
|
21
|
-
Parent options are identical to the [command line flags](#
|
31
|
+
Parent options are identical to the [command line flags](#flags) with the exception of `include` and `exclude`.
|
22
32
|
|
23
33
|
```yaml
|
24
34
|
domain: 'http://localhost'
|
@@ -61,12 +71,14 @@ lints: true # all lints including brakeman will run
|
|
61
71
|
|
62
72
|
### [Sample Config](lib/maximus/config/maximus-example.yml)
|
63
73
|
|
64
|
-
## Command Line
|
74
|
+
## Command Line
|
75
|
+
|
76
|
+
### Flags
|
65
77
|
|
66
78
|
Flag | Accepts | Description
|
67
79
|
--------------------|----------------------------------|--------------------
|
68
80
|
`-fp`/`--filepaths` | String/Array | Space-separated path(s) to files
|
69
|
-
`-u`/`--urls` | String/Array | Statistics only - Space-separated path(s) to relative
|
81
|
+
`-u`/`--urls` | String/Array | Statistics only - Space-separated path(s) to relative URLs
|
70
82
|
`-d`/`--domain` | String | Statistics only - Web address (prepended to paths)
|
71
83
|
`-po`/`--port` | String/Numeric | Statistics only - Port to use if required (appended to domain)
|
72
84
|
`-f`/`--frontend` | Boolean/Blank | Run all front-end lints
|
@@ -75,14 +87,14 @@ Flag | Accepts | Description
|
|
75
87
|
`-a`/`--all` | Boolean/Blank | Run everything
|
76
88
|
`-i`/`--include` | String/Array | Include specific lints or statistics
|
77
89
|
`-i`/`--exclude` | String/Array | Exclude specific lints or statistics
|
78
|
-
`-git`/`--sha` | String | Run maximus based on a git commit
|
90
|
+
`-git`/`--sha` | String | Run maximus based on a git commit. See [below](#git-examples)
|
79
91
|
`-c`/`--config` | String | Path to config file
|
80
92
|
|
81
93
|
|
82
94
|
* Lint tasks can accept glob notation, i.e. `**/*.scss`
|
83
95
|
* Arrays are space-separated, i.e. `--urls=/ /about`
|
84
96
|
|
85
|
-
|
97
|
+
### Commands
|
86
98
|
|
87
99
|
Command | Description
|
88
100
|
----------------------|---------------------------
|
@@ -91,24 +103,24 @@ Command | Description
|
|
91
103
|
`backend` | Runs all back-end lints
|
92
104
|
`statistics` | Runs all statistics
|
93
105
|
|
94
|
-
### Examples
|
106
|
+
### Git Examples
|
107
|
+
|
108
|
+
`$ maximus -g working`
|
95
109
|
|
96
110
|
Default. Lints based on your working directory
|
97
111
|
|
98
|
-
|
112
|
+
`$ maximus -g last`
|
99
113
|
|
100
114
|
Lints based on the previous commit by `HEAD^`
|
101
115
|
|
102
|
-
|
116
|
+
`$ maximus -g master`
|
103
117
|
|
104
118
|
Lints based on the commit on the master branch
|
105
119
|
|
106
|
-
|
120
|
+
`$ maximus -g d96a8e23`
|
107
121
|
|
108
122
|
Lints based on commit d96a8e23
|
109
123
|
|
110
|
-
`maximus -g d96a8e23`
|
111
|
-
|
112
124
|
## Lint syntax
|
113
125
|
|
114
126
|
When adding new lints, the JSON output should obey the following format:
|
@@ -125,7 +137,16 @@ When adding new lints, the JSON output should obey the following format:
|
|
125
137
|
|
126
138
|
## Changelog
|
127
139
|
|
128
|
-
### 0.1.3
|
140
|
+
### 0.1.4 (January 3, 2015)
|
141
|
+
|
142
|
+
Bugfixes:
|
143
|
+
|
144
|
+
* Added basic tests
|
145
|
+
* Modified git-lines to show unified=1 instead of unified=0
|
146
|
+
* Remove tmp files error
|
147
|
+
* Better documentation to README
|
148
|
+
|
149
|
+
### 0.1.3 (December 22, 2014)
|
129
150
|
|
130
151
|
Features:
|
131
152
|
|
data/lib/maximus/cli.rb
CHANGED
data/lib/maximus/config.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
module Maximus
|
2
|
+
|
3
|
+
# Global options and configuration
|
2
4
|
# @since 0.1.3
|
3
5
|
# @attr_reader settings [Hash] all the options
|
4
6
|
# @attr_reader temp_files [Hash] Filename without extension => path to temp file
|
@@ -25,7 +27,7 @@ module Maximus
|
|
25
27
|
# @option opts [Hash] :paths ({home: '/'}) labeled relative path to URLs. Statistics only
|
26
28
|
# @option opts [String] :commit accepts sha, "working", "last", or "master".
|
27
29
|
# @option opts [String] :config_file ('maximus.yml') path to config file
|
28
|
-
# @return [
|
30
|
+
# @return [#load_config_file #group_families #evaluate_yaml] this method is used to set up instance variables
|
29
31
|
def initialize(opts = {})
|
30
32
|
opts[:is_dev] ||= false
|
31
33
|
|
@@ -42,18 +44,7 @@ module Maximus
|
|
42
44
|
opts[:port] ||= is_rails? ? 3000 : ''
|
43
45
|
opts[:paths] ||= { 'home' => '/' }
|
44
46
|
|
45
|
-
|
46
|
-
if opts[:paths].is_a?(Array)
|
47
|
-
new_paths = {}
|
48
|
-
opts[:paths].each do |p|
|
49
|
-
if p.split('/').length > 1
|
50
|
-
new_paths[p.split('/').last.to_s] = p
|
51
|
-
else
|
52
|
-
new_paths['home'] = '/'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
opts[:paths] = new_paths
|
56
|
-
end
|
47
|
+
opts[:paths] = parse_cli_config(opts[:paths]) if opts[:paths].is_a?(Array)
|
57
48
|
|
58
49
|
# What we're really interested in
|
59
50
|
@settings = opts
|
@@ -61,20 +52,9 @@ module Maximus
|
|
61
52
|
# Instance variables for Config class only
|
62
53
|
@temp_files = {}
|
63
54
|
|
64
|
-
|
65
|
-
|
66
|
-
@yaml = YAML.load_file(conf_location)
|
55
|
+
load_config_file(opts[:config_file])
|
67
56
|
|
68
|
-
|
69
|
-
@yaml['domain'] ||= @settings[:domain]
|
70
|
-
@yaml['paths'] ||= @settings[:paths]
|
71
|
-
@yaml['port'] ||= @settings[:port]
|
72
|
-
set_families('lints', ['jshint', 'scsslint', 'rubocop', 'brakeman', 'railsbp'])
|
73
|
-
set_families('frontend', ['jshint', 'scsslint', 'phantomas', 'stylestats', 'wraith'])
|
74
|
-
set_families('backend', ['rubocop', 'brakeman', 'railsbp'])
|
75
|
-
set_families('ruby', ['rubocop', 'brakeman', 'railsbp'])
|
76
|
-
set_families('statistics', ['phantomas', 'stylestats', 'wraith'])
|
77
|
-
set_families('all', ['lints', 'statistics'])
|
57
|
+
group_families
|
78
58
|
|
79
59
|
# Override options with any defined in a discovered config file
|
80
60
|
evaluate_yaml
|
@@ -175,13 +155,14 @@ module Maximus
|
|
175
155
|
@settings
|
176
156
|
end
|
177
157
|
|
158
|
+
# If output should be returned to console
|
159
|
+
# in a pretty display
|
178
160
|
# @return [Boolean]
|
179
161
|
def is_dev?
|
180
162
|
@settings[:is_dev]
|
181
163
|
end
|
182
164
|
|
183
165
|
# Defines base logger
|
184
|
-
#
|
185
166
|
# @param out [String, STDOUT] location for logging
|
186
167
|
# Accepts file path
|
187
168
|
# @return [Logger] self.log
|
@@ -193,26 +174,15 @@ module Maximus
|
|
193
174
|
end
|
194
175
|
|
195
176
|
# Remove all or one created temporary config file
|
196
|
-
#
|
197
|
-
# @
|
198
|
-
|
199
|
-
#
|
200
|
-
# @param filename [String] (nil) file to destroy
|
201
|
-
# If nil, destroy all temp files
|
202
|
-
# @return [void]
|
203
|
-
def destroy_temp(filename = nil)
|
177
|
+
# @see temp_it
|
178
|
+
# @param filename [String] file to destroy
|
179
|
+
def destroy_temp(filename)
|
204
180
|
return if @temp_files[filename.to_sym].blank?
|
205
|
-
|
206
|
-
|
207
|
-
@temp_files = {}
|
208
|
-
else
|
209
|
-
@temp_files[filename.to_sym].unlink
|
210
|
-
@temp_files.delete(filename.to_sym)
|
211
|
-
end
|
181
|
+
@temp_files[filename.to_sym].unlink
|
182
|
+
@temp_files.delete(filename.to_sym)
|
212
183
|
end
|
213
184
|
|
214
185
|
# Combine domain with port if necessary
|
215
|
-
#
|
216
186
|
# @return [String] complete domain/host address
|
217
187
|
def domain
|
218
188
|
(!@settings[:port].blank? || @settings[:domain].include?(':')) ? "#{@settings[:domain]}:#{@settings[:port]}" : @settings[:domain]
|
@@ -221,109 +191,152 @@ module Maximus
|
|
221
191
|
|
222
192
|
private
|
223
193
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
194
|
+
# Look for a maximus config file
|
195
|
+
#
|
196
|
+
# Checks ./maximus.yml, ./maximus.yaml, ./config/maximus.yaml in order.
|
197
|
+
# If there hasn't been a file discovered yet, checks ./config/maximus.yml
|
198
|
+
# and if there still isn't a file, load the default one included with the
|
199
|
+
# maximus gem.
|
200
|
+
#
|
201
|
+
# @since 0.1.4
|
202
|
+
# @param file_path [String]
|
203
|
+
# @return @yaml [Hash]
|
204
|
+
def load_config_file(file_path)
|
205
|
+
|
206
|
+
conf_location = if !file_path.nil? && File.exist?(file_path)
|
207
|
+
file_path
|
208
|
+
else
|
209
|
+
config_exists('maximus.yml') || config_exists('maximus.yaml') || config_exists('config/maximus.yaml') || check_default_config_path('maximus.yml')
|
210
|
+
end
|
211
|
+
|
212
|
+
@yaml = YAML.load_file(conf_location)
|
213
|
+
|
214
|
+
# Match defaults
|
215
|
+
@yaml['domain'] ||= @settings[:domain]
|
216
|
+
@yaml['paths'] ||= @settings[:paths]
|
217
|
+
@yaml['port'] ||= @settings[:port]
|
218
|
+
|
237
219
|
end
|
238
|
-
end
|
239
220
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
221
|
+
# Allow shorthand to be declared for groups Maximus executions
|
222
|
+
#
|
223
|
+
# @example disable statistics
|
224
|
+
# @yaml['statistics'] = false
|
225
|
+
# set_families('statistics', ['phantomas', 'stylestats', 'wraith'])
|
226
|
+
#
|
227
|
+
# Sets as Boolean based on whether or not the queried label is `true`
|
228
|
+
# @param head_of_house [String] @yaml key and group label
|
229
|
+
# @param family [Array] group of other @yaml keys to be disabled
|
230
|
+
# @return [void] modified @yaml
|
231
|
+
def set_families(head_of_house, family)
|
232
|
+
if @yaml.has_key?(head_of_house)
|
233
|
+
family.each { |f| @yaml[f] = @yaml[head_of_house].is_a?(TrueClass) }
|
234
|
+
end
|
252
235
|
end
|
253
|
-
end
|
254
236
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
file.path
|
270
|
-
end
|
237
|
+
# Load config files if filename supplied
|
238
|
+
#
|
239
|
+
# @param value [Mixed] value from base config file
|
240
|
+
# @param [Hash] return blank hash if file not found so
|
241
|
+
# the reset of the process doesn't break
|
242
|
+
def load_config(value)
|
243
|
+
return value unless value.is_a?(String)
|
244
|
+
if File.exist?(value)
|
245
|
+
return YAML.load_file(value)
|
246
|
+
else
|
247
|
+
puts "#{value} not found"
|
248
|
+
return {}
|
249
|
+
end
|
250
|
+
end
|
271
251
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
252
|
+
# Create a temp file with config data
|
253
|
+
#
|
254
|
+
# Stores all temp files in @temp_files or self.temp_files
|
255
|
+
# In Hash with filename minus extension as the key.
|
256
|
+
#
|
257
|
+
# @param filename [String] the preferred name/identifier of the file
|
258
|
+
# @param data [Mixed] config data important to each lint or statistic
|
259
|
+
# @return [String] absolute path to new config file
|
260
|
+
def temp_it(filename, data)
|
261
|
+
ext = filename.split('.')
|
262
|
+
file = Tempfile.new([filename, ".#{ext[1]}"])
|
263
|
+
file.write(data)
|
264
|
+
file.close
|
265
|
+
@temp_files[ext[0].to_sym] = file
|
266
|
+
file.path
|
267
|
+
end
|
283
268
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
269
|
+
# See if a config file exists
|
270
|
+
#
|
271
|
+
# @see load_config_file
|
272
|
+
#
|
273
|
+
# This is used exclusively for the load_config_file method
|
274
|
+
# @param file [String] file name
|
275
|
+
# @return [String, FalseClass] if file is found return the absolute path
|
276
|
+
# otherwise return false so we can keep checking
|
277
|
+
def config_exists(file)
|
278
|
+
File.exist?(File.join(File.dirname(__FILE__), file)) ? File.join(File.dirname(__FILE__), file) : false
|
279
|
+
end
|
295
280
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
# @see #domain
|
311
|
-
value['domains']['main'] = domain
|
281
|
+
# Accounting for space-separated command line arrays
|
282
|
+
# @since 0.1.4
|
283
|
+
# @param paths [Array]
|
284
|
+
# @return [Hash]
|
285
|
+
def parse_cli_config(paths)
|
286
|
+
new_paths = {}
|
287
|
+
paths.each do |p|
|
288
|
+
if p.split('/').length > 1
|
289
|
+
new_paths[p.split('/').last.to_s] = p
|
290
|
+
else
|
291
|
+
new_paths['home'] = '/'
|
292
|
+
end
|
293
|
+
end
|
294
|
+
new_paths
|
312
295
|
end
|
313
296
|
|
314
|
-
#
|
315
|
-
|
297
|
+
# Group families of extensions
|
298
|
+
# @since 0.1.4
|
299
|
+
# @todo the command line options are overriden here and it should be the other way around
|
300
|
+
def group_families
|
301
|
+
set_families('lints', ['jshint', 'scsslint', 'rubocop', 'brakeman', 'railsbp'])
|
302
|
+
set_families('frontend', ['jshint', 'scsslint', 'phantomas', 'stylestats', 'wraith'])
|
303
|
+
set_families('backend', ['rubocop', 'brakeman', 'railsbp'])
|
304
|
+
set_families('ruby', ['rubocop', 'brakeman', 'railsbp'])
|
305
|
+
set_families('statistics', ['phantomas', 'stylestats', 'wraith'])
|
306
|
+
set_families('all', ['lints', 'statistics'])
|
307
|
+
end
|
316
308
|
|
317
|
-
|
318
|
-
|
309
|
+
# Wraith is a complicated gem with significant configuration
|
310
|
+
#
|
311
|
+
# @see yaml_evaluate
|
312
|
+
# @see temp_it
|
313
|
+
#
|
314
|
+
# @param value [Hash] modified data from a wraith config or injected data
|
315
|
+
# @param name [String] ('wraith') config file name to write and eventually load
|
316
|
+
# @return [String] temp file path
|
317
|
+
def wraith_setup(value, name = 'phantomjs')
|
318
|
+
|
319
|
+
if @yaml.include?('urls')
|
320
|
+
value['domains'] = yaml_data['urls']
|
321
|
+
else
|
322
|
+
value['domains'] = {}
|
323
|
+
# @see #domain
|
324
|
+
value['domains']['main'] = domain
|
325
|
+
end
|
319
326
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
+
# Wraith requires this screen_width config to be present
|
328
|
+
value['screen_widths'] ||= [767, 1024, 1280]
|
329
|
+
|
330
|
+
value['paths'] = @yaml['paths']
|
331
|
+
value['threshold'] ||= 0
|
332
|
+
|
333
|
+
# Wraith requires config files have .yaml extensions
|
334
|
+
# https://github.com/BBC-News/wraith/blob/2aff771eba01b76e61600cccb2113869bfe16479/lib/wraith/wraith.rb
|
335
|
+
file = Tempfile.new([name, '.yaml'])
|
336
|
+
file.write(value.to_yaml)
|
337
|
+
file.close
|
338
|
+
file.path
|
339
|
+
end
|
327
340
|
|
328
341
|
end
|
329
342
|
end
|