maximus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|