maximus 0.1.4 → 0.1.5
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 +4 -4
- data/.travis.yml +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +23 -5
- data/lib/maximus/cli.rb +8 -4
- data/lib/maximus/config.rb +161 -149
- data/lib/maximus/config/maximus.yml +60 -2
- data/lib/maximus/config/wraith/nojs.js +3 -1
- data/lib/maximus/config/wraith/snap.js +3 -1
- data/lib/maximus/git_control.rb +224 -119
- data/lib/maximus/helper.rb +7 -25
- data/lib/maximus/lint.rb +64 -88
- data/lib/maximus/lints/brakeman.rb +2 -9
- data/lib/maximus/lints/jshint.rb +1 -5
- data/lib/maximus/lints/railsbp.rb +12 -21
- data/lib/maximus/lints/rubocop.rb +1 -5
- data/lib/maximus/lints/scsslint.rb +1 -4
- data/lib/maximus/reporter/git-lines.sh +8 -22
- data/lib/maximus/statistic.rb +2 -2
- data/lib/maximus/statistics/phantomas.rb +0 -1
- data/lib/maximus/statistics/stylestats.rb +91 -56
- data/lib/maximus/statistics/wraith.rb +79 -21
- data/lib/maximus/version.rb +1 -1
- data/maximus.gemspec +8 -8
- data/roadmap.md +4 -0
- data/spec/maximus/config_spec.rb +98 -5
- data/spec/maximus/git_control_spec.rb +172 -0
- data/spec/maximus/helper_spec.rb +97 -0
- data/spec/maximus/lint_spec.rb +51 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/rubocop.yml +1 -0
- metadata +40 -33
- data/lib/maximus/config/rubocop.yml +0 -1007
@@ -3,16 +3,12 @@ module Maximus
|
|
3
3
|
class Rubocop < Maximus::Lint
|
4
4
|
|
5
5
|
# RuboCop
|
6
|
-
#
|
7
6
|
# @see Lint#initialize
|
8
7
|
def result
|
9
8
|
@task = 'rubocop'
|
10
|
-
|
11
|
-
return unless temp_config(@task)
|
12
|
-
|
13
9
|
@path = is_rails? ? "#{@settings[:root_dir]}/app" : "#{@settings[:root_dir]}/*.rb" if @path.blank?
|
14
10
|
|
15
|
-
return unless path_exists(@path)
|
11
|
+
return unless temp_config(@task) && path_exists?(@path)
|
16
12
|
|
17
13
|
rubo = `rubocop #{@path} --require #{reporter_path('rubocop')} --config #{temp_config(@task)} --format RuboCop::Formatter::MaximusRuboFormatter #{'-R' if is_rails?}`
|
18
14
|
|
@@ -3,15 +3,12 @@ module Maximus
|
|
3
3
|
class Scsslint < Maximus::Lint
|
4
4
|
|
5
5
|
# SCSS-Lint
|
6
|
-
#
|
7
6
|
# @see Lint#initialize
|
8
7
|
def result
|
9
8
|
@task = 'scsslint'
|
10
|
-
|
11
|
-
return unless temp_config(@task)
|
12
9
|
@path = is_rails? ? "#{@settings[:root_dir]}/app/assets/stylesheets" : "#{@settings[:root_dir]}/source/assets/stylesheets" if @path.blank?
|
13
10
|
|
14
|
-
return unless path_exists(@path)
|
11
|
+
return unless temp_config(@task) && path_exists?(@path)
|
15
12
|
|
16
13
|
scss = `scss-lint #{@path} -c #{temp_config(@task)} --format=JSON`
|
17
14
|
@output[:files_inspected] ||= files_inspected('scss')
|
@@ -59,28 +59,14 @@ function lines-added(){
|
|
59
59
|
fi
|
60
60
|
done
|
61
61
|
}
|
62
|
-
function diff-lines(){
|
63
|
-
local path=
|
64
|
-
local line=
|
65
|
-
while read; do
|
66
|
-
esc=$'\033'
|
67
|
-
if [[ $REPLY =~ ---\ (a/)?.* ]]; then
|
68
|
-
continue
|
69
|
-
elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
|
70
|
-
path=${BASH_REMATCH[2]}
|
71
|
-
elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
|
72
|
-
line=${BASH_REMATCH[2]}
|
73
|
-
elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
|
74
|
-
echo "$path:$line:$REPLY"
|
75
|
-
if [[ ${BASH_REMATCH[2]} != - ]]; then
|
76
|
-
((line++))
|
77
|
-
fi
|
78
|
-
fi
|
79
|
-
done
|
80
|
-
}
|
81
62
|
|
82
|
-
if [ -z "$
|
83
|
-
git
|
63
|
+
if [ -z "$3" ]; then
|
64
|
+
first_commit=$(git rev-list --max-parents=0 HEAD)
|
65
|
+
if [[ "$2" == "$first_commit" ]]; then
|
66
|
+
git -C $1 diff --unified=1 | lines-added
|
67
|
+
else
|
68
|
+
git -C $1 diff $2^ $2 --unified=1 | lines-added
|
69
|
+
fi
|
84
70
|
else
|
85
|
-
git diff --unified=1 | lines-added
|
71
|
+
git -C $1 diff --unified=1 | lines-added
|
86
72
|
fi
|
data/lib/maximus/statistic.rb
CHANGED
@@ -62,10 +62,10 @@ module Maximus
|
|
62
62
|
return false if stats_cli.blank?
|
63
63
|
|
64
64
|
stats = JSON.parse(stats_cli)
|
65
|
-
@output[:statistics][file_path.
|
65
|
+
@output[:statistics][file_path.to_s] ||= {}
|
66
66
|
|
67
67
|
# @todo is there a better way to do this?
|
68
|
-
fp = @output[:statistics][file_path.to_s
|
68
|
+
fp = @output[:statistics][file_path.to_s]
|
69
69
|
|
70
70
|
# @todo Can I do like a self << thing here?
|
71
71
|
stats.each do |stat, value|
|
@@ -20,7 +20,6 @@ module Maximus
|
|
20
20
|
phantomas_cli += @config.is_dev? ? '--colors' : '--reporter=json:no-skip'
|
21
21
|
phantomas_cli += " --proxy=#{@domain}"
|
22
22
|
@path.is_a?(Hash) ? @path.each { |label, url| phantomas_by_url(url, phantomas_cli) } : phantomas_by_url(@path, phantomas_cli)
|
23
|
-
@config.destroy_temp('phantomas')
|
24
23
|
@output
|
25
24
|
end
|
26
25
|
|
@@ -9,9 +9,17 @@ module Maximus
|
|
9
9
|
return if @settings[:stylestats].blank?
|
10
10
|
|
11
11
|
node_module_exists('stylestats')
|
12
|
-
@path = is_rails? ? "#{@settings[:root_dir]}/public/assets/**/*.css" : "#{@settings[:root_dir]}/**/*.css" if @path.blank?
|
13
12
|
|
14
|
-
|
13
|
+
if @path.blank?
|
14
|
+
@path = is_rails? ? "#{@settings[:root_dir]}/public/assets/**/*.css" : "#{@settings[:root_dir]}/**/*.css"
|
15
|
+
end
|
16
|
+
|
17
|
+
if @path.is_a?(Array)
|
18
|
+
css_files = @path
|
19
|
+
else
|
20
|
+
compile_scss if @settings[:compile_assets]
|
21
|
+
css_files = find_css
|
22
|
+
end
|
15
23
|
|
16
24
|
css_files.each do |file|
|
17
25
|
|
@@ -28,18 +36,7 @@ module Maximus
|
|
28
36
|
File.delete(file)
|
29
37
|
end
|
30
38
|
|
31
|
-
if
|
32
|
-
# @todo I'd rather Rake::Task but it's not working in different directories
|
33
|
-
Dir.chdir(@settings[:root_dir]) do
|
34
|
-
if @config.is_dev?
|
35
|
-
# @todo review that this may not be best practice, but it's really noisy in the console
|
36
|
-
quietly { `rake assets:clobber` }
|
37
|
-
else
|
38
|
-
`rake assets:clobber`
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
@config.destroy_temp('stylestats')
|
39
|
+
destroy_assets if @settings[:compile_assets]
|
43
40
|
@output
|
44
41
|
|
45
42
|
end
|
@@ -51,62 +48,100 @@ module Maximus
|
|
51
48
|
#
|
52
49
|
# Uses sprockets if Rails; Sass engine otherwise.
|
53
50
|
# Compass is supported
|
54
|
-
# @return [Array] CSS files
|
55
|
-
def
|
56
|
-
|
57
|
-
|
51
|
+
# @return [#compile_scss_rails, #compile_scss, Array] CSS files
|
52
|
+
def compile_scss
|
53
|
+
puts "\nCompiling assets for stylestats...".color(:blue)
|
58
54
|
if is_rails?
|
59
|
-
|
55
|
+
|
56
|
+
# Get rake tasks
|
60
57
|
Rails.application.load_tasks unless @config.is_dev?
|
58
|
+
compile_scss_rails
|
59
|
+
else
|
61
60
|
|
62
|
-
|
63
|
-
puts 'Compiling assets for stylestats...'.color(:blue)
|
61
|
+
load_compass
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# @todo review that this may not be best practice, but it's really noisy in the console
|
69
|
-
quietly { `rake assets:precompile` }
|
70
|
-
else
|
71
|
-
`rake assets:precompile`
|
72
|
-
end
|
73
|
-
end
|
63
|
+
compile_scss
|
64
|
+
end
|
65
|
+
end
|
74
66
|
|
75
|
-
|
76
|
-
|
67
|
+
# Load Compass paths if the gem exists
|
68
|
+
# @see find_css_files
|
69
|
+
# @since 0.1.5
|
70
|
+
def load_compass
|
71
|
+
if Gem::Specification::find_all_by_name('compass').any?
|
72
|
+
require 'compass'
|
73
|
+
Compass.sass_engine_options[:load_paths].each do |path|
|
74
|
+
Sass.load_paths << path
|
77
75
|
end
|
76
|
+
end
|
77
|
+
end
|
78
78
|
|
79
|
-
|
79
|
+
# Add directories to load paths
|
80
|
+
# @todo This function is here in case older versions of SCSS will need it
|
81
|
+
# because there shouldn't be a need to load paths, but there might be a need
|
82
|
+
# in older versions of SCSS, which should be tested (although the SCSSLint)
|
83
|
+
# dependency may dictate our scss version
|
84
|
+
# @since 0.1.5
|
85
|
+
def load_scss_load_paths
|
86
|
+
Dir.glob(@path).select { |d| File.directory? d}.each do |directory|
|
87
|
+
Sass.load_paths << directory
|
88
|
+
end
|
89
|
+
end
|
80
90
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
91
|
+
# Turns scss files into css files with the asset pipeline
|
92
|
+
# @see find_css_files
|
93
|
+
# @since 0.1.5
|
94
|
+
# @return [Array] compiled css files
|
95
|
+
def compile_scss_rails
|
96
|
+
searched_files = []
|
97
|
+
# @todo I'd rather Rake::Task but it's not working in different directories
|
98
|
+
Dir.chdir(@settings[:root_dir]) do
|
99
|
+
if @config.is_dev?
|
100
|
+
# @todo review that this may not be best practice, but it's really noisy in the console
|
101
|
+
quietly { `rake assets:precompile` }
|
102
|
+
else
|
103
|
+
`rake assets:precompile`
|
87
104
|
end
|
105
|
+
end
|
106
|
+
end
|
88
107
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
output_file << Sass::Engine.new(scss_file, { syntax: :scss, quiet: true, style: :compressed }).render
|
103
|
-
output_file.close
|
108
|
+
# Turn scss files into css files
|
109
|
+
# @see find_css_files
|
110
|
+
# @since 0.1.5
|
111
|
+
def compile_scss_normal
|
112
|
+
Dir["#{@path}.scss"].select { |f| File.file? f }.each do |file|
|
113
|
+
# @todo don't compile file if it starts with an underscore
|
114
|
+
scss_file = File.open(file, 'rb') { |f| f.read }
|
115
|
+
|
116
|
+
output_file = File.open( file.split('.').reverse.drop(1).reverse.join('.'), "w" )
|
117
|
+
output_file << Sass::Engine.new(scss_file, { syntax: :scss, quiet: true, style: :compressed }).render
|
118
|
+
output_file.close
|
119
|
+
end
|
120
|
+
end
|
104
121
|
|
105
|
-
|
122
|
+
# Remove all assets created
|
123
|
+
# @since 0.1.5
|
124
|
+
def destroy_assets
|
106
125
|
|
126
|
+
if is_rails?
|
127
|
+
# @todo I'd rather Rake::Task but it's not working in different directories
|
128
|
+
Dir.chdir(@settings[:root_dir]) do
|
129
|
+
if @config.is_dev?
|
130
|
+
# @todo review that this may not be best practice, but it's really noisy in the console
|
131
|
+
quietly { `rake assets:clobber` }
|
132
|
+
else
|
133
|
+
`rake assets:clobber`
|
134
|
+
end
|
107
135
|
end
|
108
136
|
end
|
109
|
-
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
# Find all css files
|
141
|
+
# @param path [String] globbed file path
|
142
|
+
# @return [Array] paths to compiled CSS files
|
143
|
+
def find_css(path = @path)
|
144
|
+
Dir.glob(path).select { |f| File.file? f }.map { |file| file }
|
110
145
|
end
|
111
146
|
|
112
147
|
end
|
@@ -3,6 +3,20 @@ module Maximus
|
|
3
3
|
class Wraith < Maximus::Statistic
|
4
4
|
|
5
5
|
# Generates screenshots for visual regression testing
|
6
|
+
#
|
7
|
+
# WARNING: If you call this class from a script,
|
8
|
+
# you should delete the images generated after they've been
|
9
|
+
# created.
|
10
|
+
# @example removing images after run
|
11
|
+
# dest = '/desired/root/directory'
|
12
|
+
# wraith_pics = Maximus::Wraith.new.result
|
13
|
+
# wraith_pics.each do |path_label, data|
|
14
|
+
# data[:images].each do |image|
|
15
|
+
# moved_image = "#{dest}/#{File.basename(image)}"
|
16
|
+
# FileUtils.mv image, moved_image, force: true
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
6
20
|
# @see Statistic#initialize
|
7
21
|
def result
|
8
22
|
|
@@ -14,22 +28,23 @@ module Maximus
|
|
14
28
|
|
15
29
|
# Run history or latest depending on the existence of a history directory as defined
|
16
30
|
# in each wraith config file.
|
17
|
-
#
|
18
|
-
# @todo this doesn't work very well. It puts the new shots in the history folder,
|
19
|
-
# even with absolute paths. Could be a bug in wraith
|
20
|
-
#
|
21
31
|
# @yieldparam browser [String] headless browser name
|
22
32
|
# @yieldparam configpath [String] path to temp config file (see Config#wraith_setup)
|
23
33
|
@settings[:wraith].each do |browser, configpath|
|
34
|
+
next unless File.file?(configpath) # prevents abortive YAML error if it can't find the file
|
24
35
|
wraith_yaml = YAML.load_file(configpath)
|
25
36
|
if File.directory?("#{@settings[:root_dir]}/#{wraith_yaml['history_dir']}")
|
26
37
|
puts `wraith latest #{configpath}`
|
27
|
-
|
28
|
-
|
38
|
+
|
39
|
+
# Reset history dir
|
40
|
+
# It puts the new shots in the history folder, even with absolute paths in the config.
|
41
|
+
# Could be a bug in wraith.
|
42
|
+
FileUtils.remove_dir("#{@settings[:root_dir]}/#{wraith_yaml['history_dir']}")
|
29
43
|
end
|
30
|
-
|
31
|
-
|
44
|
+
wraith_parse browser unless @config.is_dev?
|
45
|
+
puts `wraith history #{configpath}`
|
32
46
|
end
|
47
|
+
@output
|
33
48
|
|
34
49
|
end
|
35
50
|
|
@@ -38,25 +53,68 @@ module Maximus
|
|
38
53
|
|
39
54
|
# Get a diff percentage of all changes by label and screensize
|
40
55
|
#
|
41
|
-
# @example {:statistics=>{
|
56
|
+
# @example { :statistics => { "/" => { :browser=>"phantomjs", :name=>"home", :percent_changed=>{ 1024=>2.1, 1280=>1.8, 767=>3.4 } } } }
|
42
57
|
# @param browser [String] headless browser used to generate the gallery
|
43
|
-
# @return [Hash] { path: { percent_changed:
|
58
|
+
# @return [Hash] { path: { browser, path_label, percent_changed: { size: percent_diff ] } }
|
44
59
|
def wraith_parse(browser)
|
45
|
-
Dir.glob("#{@settings[:root_dir]}/maximus_wraith_#{browser}
|
46
|
-
|
60
|
+
Dir.glob("#{@settings[:root_dir]}/maximus_wraith_#{browser}/**/*").select { |f| File.file? f }.each do |file|
|
61
|
+
extension = File.extname(file)
|
62
|
+
next unless extension == '.png' || extension == '.txt'
|
63
|
+
|
47
64
|
orig_label = File.dirname(file).split('/').last
|
48
|
-
|
49
|
-
@
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
65
|
+
|
66
|
+
path = @settings[:paths][orig_label].to_s
|
67
|
+
|
68
|
+
@output[:statistics][path] = {
|
69
|
+
browser: browser.to_s,
|
70
|
+
name: orig_label
|
71
|
+
} if @output[:statistics][path].blank?
|
72
|
+
|
73
|
+
browser_output = @output[:statistics][path]
|
74
|
+
|
75
|
+
if extension == '.txt'
|
76
|
+
browser_output = wraith_percentage(file, browser_output)
|
77
|
+
else
|
78
|
+
browser_output[:images] ||= []
|
79
|
+
browser_output[:images] << wraith_image(file)
|
80
|
+
end
|
81
|
+
|
57
82
|
end
|
58
83
|
@output
|
59
84
|
end
|
60
85
|
|
86
|
+
# Grab the percentage change from previous snapshots
|
87
|
+
# @since 0.1.5
|
88
|
+
# @param file [String]
|
89
|
+
# @param browser_output [Hash]
|
90
|
+
# @return [Hash]
|
91
|
+
def wraith_percentage(file, browser_output)
|
92
|
+
file_object = File.open(file, 'rb')
|
93
|
+
browser_output[:percent_changed] ||= {}
|
94
|
+
browser_output[:percent_changed][File.basename(file).split('_')[0].to_i] = file_object.read.to_f
|
95
|
+
|
96
|
+
file_object.close
|
97
|
+
|
98
|
+
browser_output
|
99
|
+
end
|
100
|
+
|
101
|
+
# Make images temp files to save for later
|
102
|
+
# Once this script exits, the images will delete themselves.
|
103
|
+
# We need those images, so the finalizer is left undefined.
|
104
|
+
# http://stackoverflow.com/a/21286718
|
105
|
+
# @since 0.1.5
|
106
|
+
# @param file [String]
|
107
|
+
# @return [String] path to image
|
108
|
+
def wraith_image(file)
|
109
|
+
data = File.read(file)
|
110
|
+
image = Tempfile.new([File.basename(file), '.png']).tap do |f|
|
111
|
+
f.rewind
|
112
|
+
f.write(data)
|
113
|
+
ObjectSpace.undefine_finalizer(f)
|
114
|
+
f.close
|
115
|
+
end
|
116
|
+
image.path
|
117
|
+
end
|
118
|
+
|
61
119
|
end
|
62
120
|
end
|
data/lib/maximus/version.rb
CHANGED
data/maximus.gemspec
CHANGED
@@ -18,18 +18,18 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_runtime_dependency "git", "
|
22
|
-
spec.add_runtime_dependency "scss-lint", "~> 0.
|
21
|
+
spec.add_runtime_dependency "git", "~> 1.2.9"
|
22
|
+
spec.add_runtime_dependency "scss-lint", "~> 0.33.0"
|
23
23
|
spec.add_runtime_dependency "rainbow", "2.0.0"
|
24
|
-
spec.add_runtime_dependency "rubocop", "~> 0.
|
24
|
+
spec.add_runtime_dependency "rubocop", "~> 0.28"
|
25
25
|
spec.add_runtime_dependency "rails_best_practices", "~> 1.15"
|
26
|
-
spec.add_runtime_dependency "brakeman", "~>
|
27
|
-
spec.add_runtime_dependency "wraith", "~> 2.
|
28
|
-
spec.add_runtime_dependency "activesupport"
|
29
|
-
spec.add_runtime_dependency "thor"
|
26
|
+
spec.add_runtime_dependency "brakeman", "~> 3.0.1"
|
27
|
+
spec.add_runtime_dependency "wraith", "~> 2.3"
|
28
|
+
spec.add_runtime_dependency "activesupport", "~> 4.2.0"
|
29
|
+
spec.add_runtime_dependency "thor", "~> 0.19.1"
|
30
30
|
|
31
31
|
spec.add_development_dependency "bundler", "~> 1.6"
|
32
|
-
spec.add_development_dependency "nokogiri", "~> 1.6.0"
|
33
32
|
spec.add_development_dependency "yard", "~> 0.8"
|
34
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
34
|
+
spec.add_development_dependency "coveralls", "~> 0.7.8"
|
35
35
|
end
|
data/roadmap.md
CHANGED
@@ -9,5 +9,9 @@
|
|
9
9
|
* Add CSS lint (maybe)
|
10
10
|
* Add JSLint (maybe)
|
11
11
|
* Add W3 validator (maybe)
|
12
|
+
* Add Markdown lint (maybe)
|
13
|
+
* Add Flog support (maybe)
|
14
|
+
* Add Flay support (maybe)
|
12
15
|
* Regex path names on phantomas and wraith to defend against injection and bad characters
|
13
16
|
* Test for < ruby 2.0 or require 2.0 < in gemspec
|
17
|
+
* If no files to inspect in working, say so
|