maximus 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +66 -0
- data/Rakefile +2 -0
- data/bin/maximus +15 -0
- data/lib/maximus.rb +25 -0
- data/lib/maximus/cli.rb +106 -0
- data/lib/maximus/config/.jshintignore +2 -0
- data/lib/maximus/config/jshint.json +9 -0
- data/lib/maximus/config/phantomas.json +4 -0
- data/lib/maximus/config/phantomas_urls.yaml +1 -0
- data/lib/maximus/config/rubocop.yml +1007 -0
- data/lib/maximus/config/scsslint.yml +58 -0
- data/lib/maximus/config/stylestats.json +30 -0
- data/lib/maximus/config/wraith.yaml +56 -0
- data/lib/maximus/config/wraith/casper.js +20 -0
- data/lib/maximus/config/wraith/nojs.js +85 -0
- data/lib/maximus/config/wraith/snap.js +85 -0
- data/lib/maximus/constants.rb +3 -0
- data/lib/maximus/git_control.rb +255 -0
- data/lib/maximus/helper.rb +137 -0
- data/lib/maximus/lint.rb +201 -0
- data/lib/maximus/lints/brakeman.rb +61 -0
- data/lib/maximus/lints/jshint.rb +20 -0
- data/lib/maximus/lints/railsbp.rb +51 -0
- data/lib/maximus/lints/rubocop.rb +18 -0
- data/lib/maximus/lints/scsslint.rb +17 -0
- data/lib/maximus/rake_tasks.rb +13 -0
- data/lib/maximus/reporter/git-lines.sh +57 -0
- data/lib/maximus/reporter/jshint.js +28 -0
- data/lib/maximus/reporter/rubocop.rb +49 -0
- data/lib/maximus/statistic.rb +65 -0
- data/lib/maximus/statistics/phantomas.rb +32 -0
- data/lib/maximus/statistics/stylestats.rb +111 -0
- data/lib/maximus/statistics/wraith.rb +88 -0
- data/lib/maximus/tasks/be.rake +35 -0
- data/lib/maximus/tasks/fe.rake +30 -0
- data/lib/maximus/tasks/maximus.rake +39 -0
- data/lib/maximus/tasks/statistic.rake +26 -0
- data/lib/maximus/version.rb +3 -0
- data/maximus.gemspec +32 -0
- data/roadmap.md +17 -0
- metadata +243 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
scss_files: 'app/assets/stylesheets/'
|
2
|
+
|
3
|
+
# exclude: 'app/assets/stylesheets/admin/'
|
4
|
+
|
5
|
+
format: 'JSON'
|
6
|
+
|
7
|
+
linters:
|
8
|
+
Compass::*:
|
9
|
+
enabled: true
|
10
|
+
Compass::PropertyWithMixin:
|
11
|
+
ignore:
|
12
|
+
- 'inline-block'
|
13
|
+
- 'border-radius'
|
14
|
+
- 'box-shadow'
|
15
|
+
- 'opacity'
|
16
|
+
- 'text-shadow'
|
17
|
+
Indentation:
|
18
|
+
enabled: false
|
19
|
+
character: tab
|
20
|
+
severity: warning
|
21
|
+
width: 1
|
22
|
+
NameFormat:
|
23
|
+
convention: BEM
|
24
|
+
enabled: false
|
25
|
+
SelectorFormat:
|
26
|
+
enabled: false
|
27
|
+
DeclarationOrder:
|
28
|
+
enabled: false
|
29
|
+
EmptyLineBetweenBlocks:
|
30
|
+
enabled: false
|
31
|
+
NestingDepth:
|
32
|
+
max_depth: 6
|
33
|
+
severity: error
|
34
|
+
SelectorDepth:
|
35
|
+
max_depth: 5
|
36
|
+
severity: error
|
37
|
+
LeadingZero:
|
38
|
+
enabled: false
|
39
|
+
PlaceholderInExtend:
|
40
|
+
enabled: false
|
41
|
+
PropertySortOrder:
|
42
|
+
enabled: false
|
43
|
+
QualifyingElement:
|
44
|
+
enabled: true
|
45
|
+
allow_element_with_attribute: true
|
46
|
+
SpaceAfterPropertyColon:
|
47
|
+
enabled: false
|
48
|
+
UnnecessaryParentReference:
|
49
|
+
severity: error
|
50
|
+
VendorPrefixes:
|
51
|
+
exclude:
|
52
|
+
- '-webkit-tap-highlight-color'
|
53
|
+
- '-webkit-font-smoothing'
|
54
|
+
- '-moz-osx-font-smoothing'
|
55
|
+
- '-webkit-appearance'
|
56
|
+
- '-moz-placeholder'
|
57
|
+
- '-ms-input-placeholder'
|
58
|
+
- '-moz-pre-wrap'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
"published": false,
|
3
|
+
"paths": false,
|
4
|
+
"stylesheets": false,
|
5
|
+
"styleElements": true,
|
6
|
+
"size": true,
|
7
|
+
"dataUriSize": true,
|
8
|
+
"ratioOfDataUriSize": true,
|
9
|
+
"gzippedSize": false,
|
10
|
+
"simplicity": true,
|
11
|
+
"rules": true,
|
12
|
+
"selectors": true,
|
13
|
+
"mostIdentifier": true,
|
14
|
+
"mostIdentifierSelector": true,
|
15
|
+
"lowestCohesion": true,
|
16
|
+
"lowestCohesionSelector": true,
|
17
|
+
"totalUniqueFontSizes": true,
|
18
|
+
"uniqueFontSize": true,
|
19
|
+
"totalUniqueColors": true,
|
20
|
+
"uniqueColor": true,
|
21
|
+
"idSelectors": true,
|
22
|
+
"universalSelectors": true,
|
23
|
+
"unqualifiedAttributeSelectors": true,
|
24
|
+
"javascriptSpecificSelectors": "[#\\.]js\\-",
|
25
|
+
"importantKeywords": true,
|
26
|
+
"floatProperties": true,
|
27
|
+
"mediaQueries": true,
|
28
|
+
"propertiesCount": 10,
|
29
|
+
"requestOptions": {}
|
30
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#Headless browser option
|
2
|
+
browser:
|
3
|
+
phantomjs: "phantomjs"
|
4
|
+
# slimerjs: "slimerjs"
|
5
|
+
# phantomjs: "casperjs"
|
6
|
+
|
7
|
+
#If you want to have multiple snapping files, set the file name here
|
8
|
+
snap_file: "config/wraith/snap.js"
|
9
|
+
# snap_file: "config/wraith/nojs.js"
|
10
|
+
|
11
|
+
# Type the name of the directory that shots will be stored in
|
12
|
+
directory: 'maximus_wraith'
|
13
|
+
history_dir: 'maximus_wraith_history'
|
14
|
+
|
15
|
+
domains:
|
16
|
+
main: "http://localhost:3000"
|
17
|
+
|
18
|
+
#Type screen widths below, here are a couple of examples
|
19
|
+
screen_widths:
|
20
|
+
- 767
|
21
|
+
- 1024
|
22
|
+
- 1280
|
23
|
+
|
24
|
+
#Type page URL paths below
|
25
|
+
paths:
|
26
|
+
home: /
|
27
|
+
|
28
|
+
# Casper/component example config
|
29
|
+
# paths:
|
30
|
+
# home:
|
31
|
+
# path: /
|
32
|
+
# selector: '.site-brand'
|
33
|
+
|
34
|
+
#Amount of fuzz ImageMagick will use
|
35
|
+
fuzz: '20%'
|
36
|
+
|
37
|
+
#Set the filename of the spider file to use, if not specified it will fallback to spider.txt
|
38
|
+
# spider_file: bbc_co_uk_spider.txt
|
39
|
+
|
40
|
+
#Set the number of days to keep the site spider file
|
41
|
+
spider_days:
|
42
|
+
- 10
|
43
|
+
|
44
|
+
#A list of URLs to skip when spidering. Ruby regular expressions can be
|
45
|
+
#used, if prefixed with !ruby/regexp as defined in the YAML Cookbook
|
46
|
+
#http://www.yaml.org/YAML_for_ruby.html#regexps
|
47
|
+
#
|
48
|
+
# spider_skips:
|
49
|
+
# - /foo/bar.html # Matches /foo/bar.html explcitly
|
50
|
+
# - !ruby/regexp /^\/baz\// # Matches any URLs that start with /baz
|
51
|
+
|
52
|
+
#Choose how results are displayed, by default alphanumeric. Different screen widths are always grouped.
|
53
|
+
#alphanumeric - all paths (with, and without, a difference) are shown, sorted by path
|
54
|
+
#diffs_first - all paths (with, and without, a difference) are shown, sorted by difference size (largest first)
|
55
|
+
#diffs_only - only paths with a difference are shown, sorted by difference size (largest first)
|
56
|
+
#mode: diffs_first
|
@@ -0,0 +1,20 @@
|
|
1
|
+
var system = require('system');
|
2
|
+
var page = require('webpage').create();
|
3
|
+
var fs = require('fs');
|
4
|
+
var casper = require("casper").create();
|
5
|
+
|
6
|
+
var url = casper.cli.get(0);
|
7
|
+
var view_port_width = casper.cli.get(1);
|
8
|
+
var image_name = casper.cli.get(2);
|
9
|
+
var selector = casper.cli.get(3);
|
10
|
+
|
11
|
+
casper.start(url, function() {
|
12
|
+
this.viewport(view_port_width, 1500).then(function(){
|
13
|
+
this.wait(2000, function() {
|
14
|
+
this.captureSelector(image_name, selector);
|
15
|
+
console.log('Snapping ' + url + ' at width ' + view_port_width);
|
16
|
+
});
|
17
|
+
});
|
18
|
+
});
|
19
|
+
|
20
|
+
casper.run();
|
@@ -0,0 +1,85 @@
|
|
1
|
+
var system = require('system');
|
2
|
+
var page = require('webpage').create();
|
3
|
+
var fs = require('fs');
|
4
|
+
|
5
|
+
if (system.args.length === 3) {
|
6
|
+
console.log('Usage: snap.js <some URL> <view port width> <target image name>');
|
7
|
+
phantom.exit();
|
8
|
+
}
|
9
|
+
|
10
|
+
var url = system.args[1];
|
11
|
+
var image_name = system.args[3];
|
12
|
+
var view_port_width = system.args[2];
|
13
|
+
var current_requests = 0;
|
14
|
+
var last_request_timeout;
|
15
|
+
var final_timeout;
|
16
|
+
|
17
|
+
|
18
|
+
page.viewportSize = { width: view_port_width, height: 1500};
|
19
|
+
page.settings = { loadImages: true, javascriptEnabled: false };
|
20
|
+
|
21
|
+
// If you want to use additional phantomjs commands, place them here
|
22
|
+
page.settings.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.17';
|
23
|
+
|
24
|
+
// You can place custom headers here, example below.
|
25
|
+
// page.customHeaders = {
|
26
|
+
|
27
|
+
// 'X-Candy-OVERRIDE': 'https://api.live.bbc.co.uk/'
|
28
|
+
|
29
|
+
// };
|
30
|
+
|
31
|
+
// If you want to set a cookie, just add your details below in the following way.
|
32
|
+
|
33
|
+
// phantom.addCookie({
|
34
|
+
// 'name': 'ckns_policy',
|
35
|
+
// 'value': '111',
|
36
|
+
// 'domain': '.bbc.co.uk'
|
37
|
+
// });
|
38
|
+
// phantom.addCookie({
|
39
|
+
// 'name': 'locserv',
|
40
|
+
// 'value': '1#l1#i=6691484:n=Oxford+Circus:h=e@w1#i=8:p=London@d1#1=l:2=e:3=e:4=2@n1#r=40',
|
41
|
+
// 'domain': '.bbc.co.uk'
|
42
|
+
// });
|
43
|
+
|
44
|
+
page.onResourceRequested = function(req) {
|
45
|
+
current_requests += 1;
|
46
|
+
};
|
47
|
+
|
48
|
+
page.onResourceReceived = function(res) {
|
49
|
+
if (res.stage === 'end') {
|
50
|
+
current_requests -= 1;
|
51
|
+
debounced_render();
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
page.open(url, function(status) {
|
56
|
+
if (status !== 'success') {
|
57
|
+
console.log('Error with page ' + url);
|
58
|
+
phantom.exit();
|
59
|
+
}
|
60
|
+
});
|
61
|
+
|
62
|
+
|
63
|
+
function debounced_render() {
|
64
|
+
clearTimeout(last_request_timeout);
|
65
|
+
clearTimeout(final_timeout);
|
66
|
+
|
67
|
+
// If there's no more ongoing resource requests, wait for 1 second before
|
68
|
+
// rendering, just in case the page kicks off another request
|
69
|
+
if (current_requests < 1) {
|
70
|
+
clearTimeout(final_timeout);
|
71
|
+
last_request_timeout = setTimeout(function() {
|
72
|
+
console.log('Snapping ' + url + ' at width ' + view_port_width);
|
73
|
+
page.render(image_name);
|
74
|
+
phantom.exit();
|
75
|
+
}, 1000);
|
76
|
+
}
|
77
|
+
|
78
|
+
// Sometimes, straggling requests never make it back, in which
|
79
|
+
// case, timeout after 5 seconds and render the page anyway
|
80
|
+
final_timeout = setTimeout(function() {
|
81
|
+
console.log('Snapping ' + url + ' at width ' + view_port_width);
|
82
|
+
page.render(image_name);
|
83
|
+
phantom.exit();
|
84
|
+
}, 5000);
|
85
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
var system = require('system');
|
2
|
+
var page = require('webpage').create();
|
3
|
+
var fs = require('fs');
|
4
|
+
|
5
|
+
if (system.args.length === 3) {
|
6
|
+
console.log('Usage: snap.js <some URL> <view port width> <target image name>');
|
7
|
+
phantom.exit();
|
8
|
+
}
|
9
|
+
|
10
|
+
var url = system.args[1];
|
11
|
+
var image_name = system.args[3];
|
12
|
+
var view_port_width = system.args[2];
|
13
|
+
var current_requests = 0;
|
14
|
+
var last_request_timeout;
|
15
|
+
var final_timeout;
|
16
|
+
|
17
|
+
|
18
|
+
page.viewportSize = { width: view_port_width, height: 1500};
|
19
|
+
page.settings = { loadImages: true, javascriptEnabled: true };
|
20
|
+
|
21
|
+
// If you want to use additional phantomjs commands, place them here
|
22
|
+
page.settings.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.17';
|
23
|
+
|
24
|
+
// You can place custom headers here, example below.
|
25
|
+
// page.customHeaders = {
|
26
|
+
|
27
|
+
// 'X-Candy-OVERRIDE': 'https://api.live.bbc.co.uk/'
|
28
|
+
|
29
|
+
// };
|
30
|
+
|
31
|
+
// If you want to set a cookie, just add your details below in the following way.
|
32
|
+
|
33
|
+
// phantom.addCookie({
|
34
|
+
// 'name': 'ckns_policy',
|
35
|
+
// 'value': '111',
|
36
|
+
// 'domain': '.bbc.co.uk'
|
37
|
+
// });
|
38
|
+
// phantom.addCookie({
|
39
|
+
// 'name': 'locserv',
|
40
|
+
// 'value': '1#l1#i=6691484:n=Oxford+Circus:h=e@w1#i=8:p=London@d1#1=l:2=e:3=e:4=2@n1#r=40',
|
41
|
+
// 'domain': '.bbc.co.uk'
|
42
|
+
// });
|
43
|
+
|
44
|
+
page.onResourceRequested = function(req) {
|
45
|
+
current_requests += 1;
|
46
|
+
};
|
47
|
+
|
48
|
+
page.onResourceReceived = function(res) {
|
49
|
+
if (res.stage === 'end') {
|
50
|
+
current_requests -= 1;
|
51
|
+
debounced_render();
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
page.open(url, function(status) {
|
56
|
+
if (status !== 'success') {
|
57
|
+
console.log('Error with page ' + url);
|
58
|
+
phantom.exit();
|
59
|
+
}
|
60
|
+
});
|
61
|
+
|
62
|
+
|
63
|
+
function debounced_render() {
|
64
|
+
clearTimeout(last_request_timeout);
|
65
|
+
clearTimeout(final_timeout);
|
66
|
+
|
67
|
+
// If there's no more ongoing resource requests, wait for 1 second before
|
68
|
+
// rendering, just in case the page kicks off another request
|
69
|
+
if (current_requests < 1) {
|
70
|
+
clearTimeout(final_timeout);
|
71
|
+
last_request_timeout = setTimeout(function() {
|
72
|
+
console.log('Snapping ' + url + ' at width ' + view_port_width);
|
73
|
+
page.render(image_name);
|
74
|
+
phantom.exit();
|
75
|
+
}, 1000);
|
76
|
+
}
|
77
|
+
|
78
|
+
// Sometimes, straggling requests never make it back, in which
|
79
|
+
// case, timeout after 5 seconds and render the page anyway
|
80
|
+
final_timeout = setTimeout(function() {
|
81
|
+
console.log('Snapping ' + url + ' at width ' + view_port_width);
|
82
|
+
page.render(image_name);
|
83
|
+
phantom.exit();
|
84
|
+
}, 5000);
|
85
|
+
}
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'rainbow'
|
5
|
+
require 'rainbow/ext/string'
|
6
|
+
|
7
|
+
module Maximus
|
8
|
+
class GitControl
|
9
|
+
|
10
|
+
include Helper
|
11
|
+
|
12
|
+
def initialize(opts = {})
|
13
|
+
opts[:is_dev] ||= false
|
14
|
+
opts[:log] = Logger.new('log/maximus_git.log') if opts[:log].nil?
|
15
|
+
opts[:base_url] ||= 'http://localhost:3000'
|
16
|
+
opts[:port] ||= ''
|
17
|
+
opts[:root_dir] ||= root_dir
|
18
|
+
log = opts[:log] ? log : nil
|
19
|
+
@@log = mlog
|
20
|
+
@@is_dev = opts[:is_dev]
|
21
|
+
@opts = opts
|
22
|
+
|
23
|
+
@psuedo_commit = (!@opts[:commit].blank? && @opts[:commit] == 'working')
|
24
|
+
@g = Git.open(@opts[:root_dir], :log => log)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns Hash of commit data
|
28
|
+
def commit_export(commitsha = sha)
|
29
|
+
ce_commit = vccommit(commitsha)
|
30
|
+
ce_diff = diff(ce_commit, @g.object('HEAD^'))
|
31
|
+
{
|
32
|
+
commitsha: commitsha,
|
33
|
+
branch: branch,
|
34
|
+
message: ce_commit.message,
|
35
|
+
remote_repo: remote,
|
36
|
+
git_author: ce_commit.author.name,
|
37
|
+
git_author_email: ce_commit.author.email,
|
38
|
+
diff: ce_diff
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Compare two commits and get line number ranges of changed patches
|
43
|
+
# Returns Hash grouped by file extension (defined in assoc) => { filename, changes: (changed line ranges) }
|
44
|
+
# Example: 'sha' => { rb: {filename: 'file.rb', changes: { ['0..4'], ['10..20'] } }}
|
45
|
+
def compare(sha1 = master_commit.sha, sha2 = sha)
|
46
|
+
diff_return = {}
|
47
|
+
|
48
|
+
if @opts[:commit]
|
49
|
+
sha1 = case @opts[:commit]
|
50
|
+
when 'master' then master_commit.sha
|
51
|
+
when 'last' then @g.object('HEAD^').sha
|
52
|
+
when 'working' then 'working'
|
53
|
+
else @opts[:commit]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# if working directory, just have a single item array
|
58
|
+
# the space here is important because git-lines checks for a second arg,
|
59
|
+
# and if one is present, it runs git diff without a commit
|
60
|
+
# or a comparison to a commit
|
61
|
+
git_diff = @psuedo_commit ? ['working directory'] : `git rev-list #{sha1}..#{sha2} --no-merges`.split("\n")
|
62
|
+
|
63
|
+
# Include the first sha because rev-list is doing a traversal
|
64
|
+
# So sha1 is never included
|
65
|
+
git_diff << sha1 unless @psuedo_commit
|
66
|
+
|
67
|
+
# Reverse so that we go in chronological order
|
68
|
+
git_diff.reverse.each do |git_sha|
|
69
|
+
new_lines = lines_added(git_sha)
|
70
|
+
|
71
|
+
# Grab all files in that commit and group them by extension
|
72
|
+
# If working copy, just give the diff names of the files changed
|
73
|
+
files = @psuedo_commit ? `git diff --name-only` : `git show --pretty="format:" --name-only #{git_sha}`
|
74
|
+
files = files.split("\n").group_by { |f| f.split('.').pop }
|
75
|
+
|
76
|
+
# Don't worry about files that we don't have a lint or a statistic for
|
77
|
+
flat_associations = associations.clone.flatten(2)
|
78
|
+
files.delete_if { |k,v| !flat_associations.include?(k) || k.nil? }
|
79
|
+
|
80
|
+
associations.each do |ext, related|
|
81
|
+
files[ext] ||= []
|
82
|
+
related.each do |child|
|
83
|
+
unless files[child].blank?
|
84
|
+
files[child].each do |c|
|
85
|
+
# hack to ignore deleted files
|
86
|
+
files[child] = new_lines[c].blank? ? [] : [ filename: "#{@opts[:root_dir]}/#{c}", changes: new_lines[c] ]
|
87
|
+
end
|
88
|
+
files[ext].concat(files[child])
|
89
|
+
files.delete(child)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
files.delete_if { |k,v| v.blank? }
|
94
|
+
diff_return[git_sha.to_sym] = files
|
95
|
+
end
|
96
|
+
diff_return
|
97
|
+
end
|
98
|
+
|
99
|
+
# Run appropriate lint for every sha in commit history
|
100
|
+
# Creates new branch based on each sha, then deletes it
|
101
|
+
# Different from above method as it returns the entire lint, not just the lines relevant to commit
|
102
|
+
# Returns Hash with all data grouped by task
|
103
|
+
# Example: { 'sha': { lints: { scsslint: { files_inspec... }, statisti... } }, 'sha...' }
|
104
|
+
def lints_and_stats(lint_by_path = false, git_shas = compare)
|
105
|
+
return false if git_shas.blank?
|
106
|
+
base_branch = branch
|
107
|
+
git_output = {}
|
108
|
+
git_shas.each do |sha, exts|
|
109
|
+
# TODO - better way to silence git, in case there's a real error?
|
110
|
+
quietly { `git checkout #{sha} -b maximus_#{sha}` } unless @psuedo_commit
|
111
|
+
puts sha.to_s.color(:blue) if @@is_dev
|
112
|
+
git_output[sha.to_sym] = {
|
113
|
+
lints: {},
|
114
|
+
statistics: {}
|
115
|
+
}
|
116
|
+
lints = git_output[sha.to_sym][:lints]
|
117
|
+
statistics = git_output[sha.to_sym][:statistics]
|
118
|
+
lint_opts = {
|
119
|
+
is_dev: @@is_dev,
|
120
|
+
root_dir: @opts[:root_dir],
|
121
|
+
commit: !@opts[:commit].blank?
|
122
|
+
}
|
123
|
+
stat_opts = {
|
124
|
+
is_dev: @@is_dev,
|
125
|
+
base_url: @opts[:base_url],
|
126
|
+
port: @opts[:port],
|
127
|
+
root_dir: @opts[:root_dir]
|
128
|
+
}
|
129
|
+
# This is where everything goes down
|
130
|
+
exts.each do |ext, files|
|
131
|
+
# For relevant_lines data
|
132
|
+
lint_opts[:git_files] = files
|
133
|
+
lint_opts[:path] = lint_file_paths(files, ext) if lint_by_path
|
134
|
+
case ext
|
135
|
+
when :scss
|
136
|
+
lints[:scsslint] = Maximus::Scsslint.new(lint_opts).result
|
137
|
+
|
138
|
+
# Do not run statistics if called by rake task :compare
|
139
|
+
if lint_opts[:commit].blank?
|
140
|
+
|
141
|
+
# stylestat is singular here because model name in Rails is singular.
|
142
|
+
# But adding a .classify when it's converted to a model chops off the end s on 'phantomas',
|
143
|
+
# which breaks the model name. This could be a TODO
|
144
|
+
statistics[:stylestat] = Maximus::Stylestats.new(stat_opts).result
|
145
|
+
|
146
|
+
# TODO - double pipe here is best way to say, if it's already run, don't run again, right?
|
147
|
+
statistics[:phantomas] ||= Maximus::Phantomas.new(stat_opts).result
|
148
|
+
statistics[:wraith] = Maximus::Wraith.new(stat_opts).result
|
149
|
+
end
|
150
|
+
when :js
|
151
|
+
lints[:jshint] = Maximus::Jshint.new(lint_opts).result
|
152
|
+
|
153
|
+
# Do not run statistics if called by rake task :compare
|
154
|
+
if lint_opts[:commit].blank?
|
155
|
+
|
156
|
+
statistics[:phantomas] = Maximus::Phantomas.new(stat_opts).result
|
157
|
+
|
158
|
+
# TODO - double pipe here is best way to say, if it's already run, don't run again, right?
|
159
|
+
statistics[:wraith] ||= Maximus::Wraith.new(stat_opts).result
|
160
|
+
end
|
161
|
+
when :ruby
|
162
|
+
lints[:rubocop] = Maximus::Rubocop.new(lint_opts).result
|
163
|
+
lints[:railsbp] = Maximus::Railsbp.new(lint_opts).result
|
164
|
+
lints[:brakeman] = Maximus::Brakeman.new(lint_opts).result
|
165
|
+
when :rails
|
166
|
+
lints[:railsbp] ||= Maximus::Railsbp.new(lint_opts).result
|
167
|
+
end
|
168
|
+
end
|
169
|
+
# TODO - better way to silence git, in case there's a real error?
|
170
|
+
quietly {
|
171
|
+
@g.branch(base_branch).checkout
|
172
|
+
@g.branch("maximus_#{sha}").delete
|
173
|
+
} unless @psuedo_commit
|
174
|
+
end
|
175
|
+
git_output
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
protected
|
180
|
+
|
181
|
+
# Get list of file paths
|
182
|
+
# Returns String delimited by comma or space
|
183
|
+
def lint_file_paths(files, ext)
|
184
|
+
file_list = files.map { |f| f[:filename] }.compact
|
185
|
+
# Lints accept files differently
|
186
|
+
ext == :ruby ? file_list.join(' ') : file_list.join(',')
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns Array of ranges by lines added in a commit by file name
|
190
|
+
# {'filename' => ['0..10', '11..14']}
|
191
|
+
def lines_added(git_sha)
|
192
|
+
new_lines = {}
|
193
|
+
lines_added = `#{File.join(File.dirname(__FILE__), 'reporter/git-lines.sh')} #{git_sha}`.split("\n")
|
194
|
+
lines_added.each do |filename|
|
195
|
+
fsplit = filename.split(':')
|
196
|
+
# if file isn't already part of the array
|
197
|
+
new_lines[fsplit[0]] ||= []
|
198
|
+
new_lines[fsplit[0]] << fsplit[1] unless fsplit[1].nil?
|
199
|
+
# no repeats
|
200
|
+
new_lines[fsplit[0]].uniq!
|
201
|
+
end
|
202
|
+
new_lines.delete("/dev/null")
|
203
|
+
new_lines
|
204
|
+
end
|
205
|
+
|
206
|
+
# Get last commit on current branch
|
207
|
+
# Returns String
|
208
|
+
def sha
|
209
|
+
@g.object('HEAD').sha
|
210
|
+
end
|
211
|
+
|
212
|
+
# Get branch name
|
213
|
+
# Returns String
|
214
|
+
def branch
|
215
|
+
`env -i git rev-parse --abbrev-ref HEAD`.strip!
|
216
|
+
end
|
217
|
+
|
218
|
+
# Get last commit on the master branch
|
219
|
+
# Returns Git::Object
|
220
|
+
def master_commit
|
221
|
+
@g.branches[:master].gcommit
|
222
|
+
end
|
223
|
+
|
224
|
+
# Store last commit as Ruby Git::Object
|
225
|
+
# Returns Git::Object
|
226
|
+
def vccommit(commitsha = sha)
|
227
|
+
@g.gcommit(commitsha)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Get general stats of commit on HEAD versus last commit on master branch
|
231
|
+
# Roadmap - include lines_added in this method's output
|
232
|
+
# Returns Git::Diff
|
233
|
+
def diff(new_commit = vccommit, old_commit = master_commit)
|
234
|
+
@g.diff(new_commit, old_commit).stats
|
235
|
+
end
|
236
|
+
|
237
|
+
# Get remote URL
|
238
|
+
# Returns String or nil if remotes is blank
|
239
|
+
def remote
|
240
|
+
@g.remotes.first.url unless @g.remotes.blank?
|
241
|
+
end
|
242
|
+
|
243
|
+
# Define associations to linters based on file extension
|
244
|
+
# Returns Hash of linters and extension arrays
|
245
|
+
def associations
|
246
|
+
{
|
247
|
+
scss: ['scss', 'sass'],
|
248
|
+
js: ['js'],
|
249
|
+
ruby: ['rb', 'Gemfile', 'lock', 'yml', 'Rakefile', 'ru', 'rdoc'],
|
250
|
+
rails: ['slim', 'haml']
|
251
|
+
}
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
end
|