maximus 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7967be47ba9de75aa1e59c138a2af4b01c5242a4
4
- data.tar.gz: c2332ff9d712472bea8babb615ea3c8ccd1a8069
3
+ metadata.gz: 70e71aa9bf1801ab2da6baad0c7a6de45759d5b2
4
+ data.tar.gz: 1f3fc9752270915bfe051d3e76ba034816c7c42b
5
5
  SHA512:
6
- metadata.gz: afcc4bdd7489bd5e5c0f54fdd2c5dc6039a0f81ada004df458e69a3d24ebc2df521a7e50a8c313a3346439def9a05d3bb0eed672c593aa23399a8c2e66c2b9ff
7
- data.tar.gz: de955683da789d3027c4c6adaca3d1a3624dd2df33ff9fdc4c91a0ec0e4e35c9e46e2b76764030f9de5bc40f65ef131b9cde2963c9e8cc6a806a8ff3c078c9cc
6
+ metadata.gz: 2d24180804d7722eeaef5faedabc1ef5b0915af20ff9cee8cb30ce230cff669bd994f1de046894d6e96c35894f35aab4cce5b6248ab4a6d48b39961099bd287a
7
+ data.tar.gz: 04e6694a21cc3926fc9338b26827480f8423e104fb5562ead917959edb7a563f12a01c180ad154ded26ab4c4bb4ff6433bcc9f684d4ced8559ae98a71fc6334a
data/README.md CHANGED
@@ -1,5 +1,7 @@
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)
4
+
3
5
  The all-in-one linting solution.
4
6
 
5
7
  Plays nice with Middleman and Rails.
@@ -4,7 +4,6 @@ require 'maximus/helper'
4
4
  require 'maximus/git_control'
5
5
  require 'maximus/lint'
6
6
  require 'maximus/statistic'
7
- require 'maximus/rake_tasks'
8
7
 
9
8
  # Get statistics
10
9
  Dir[File.expand_path('maximus/statistics/*.rb', File.dirname(__FILE__))].each do |file|
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
 
3
+ # @since 0.1.0
3
4
  class Maximus::CLI < Thor
4
5
  include Thor::Actions
5
6
  class_option :path, aliases: ["-p", "-u", "\--url"], default: nil, desc: "Space-separated path(s) to URLs or files"
@@ -46,7 +47,7 @@ class Maximus::CLI < Thor
46
47
  return Maximus::GitControl.new({ commit: options[:commit], is_dev: true }).lints_and_stats(true)
47
48
  end
48
49
 
49
- # TODO - something better than just installing in the global npm file
50
+ # @todo something better than just installing in the global npm file
50
51
  # and including phantomjs
51
52
  desc "install", "Install all dependencies"
52
53
  def install
@@ -1,3 +1,5 @@
1
1
  # Global application constants.
2
+ #
3
+ # @since 0.1.0
2
4
  module Maximus
3
5
  end
@@ -5,10 +5,23 @@ require 'rainbow'
5
5
  require 'rainbow/ext/string'
6
6
 
7
7
  module Maximus
8
+ # @since 0.1.0
8
9
  class GitControl
9
10
 
10
11
  include Helper
11
12
 
13
+ # Git management
14
+ #
15
+ # @param opts [Hash] the options to initialize and pass to other classes
16
+ # @option opts [Boolean] :is_dev whether or not the class was initialized from the command line
17
+ # @option opts [String] :log ('log/maximus_git.log') path to log file
18
+ # @option opts [String] :root_dir base directory
19
+ # @option opts [String] :base_url ('http://localhost:3000') the host - used for Statistics
20
+ # @option opts [String, Integer] :port port number - used for Statistics
21
+ # @option opts [String, Array] :path ('') path to files. Accepts glob notation
22
+ # @option opts [String] :commit accepts sha, "working", "last", or "master".
23
+ # Used in the command line
24
+ # @return [void] this method is used to set up instance variables
12
25
  def initialize(opts = {})
13
26
  opts[:is_dev] ||= false
14
27
  opts[:log] = Logger.new('log/maximus_git.log') if opts[:log].nil?
@@ -24,7 +37,10 @@ module Maximus
24
37
  @g = Git.open(@opts[:root_dir], :log => log)
25
38
  end
26
39
 
27
- # Returns Hash of commit data
40
+ # 30,000 foot view of a commit
41
+ #
42
+ # @param commitsha [String] the sha of the commit
43
+ # @return [Hash] commit data
28
44
  def commit_export(commitsha = sha)
29
45
  ce_commit = vccommit(commitsha)
30
46
  ce_diff = diff(ce_commit, @g.object('HEAD^'))
@@ -40,8 +56,21 @@ module Maximus
40
56
  end
41
57
 
42
58
  # 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'] } }}
59
+ #
60
+ # @example output from the method
61
+ # {
62
+ # 'sha': {
63
+ # rb: {
64
+ # filename: 'file.rb',
65
+ # changes: {
66
+ # ['0..4'],
67
+ # ['10..20']
68
+ # }
69
+ # }
70
+ # }
71
+ # }
72
+ #
73
+ # @return [Hash] diff_return files changed grouped by file extension and line number
45
74
  def compare(sha1 = master_commit.sha, sha2 = sha)
46
75
  diff_return = {}
47
76
 
@@ -54,10 +83,10 @@ module Maximus
54
83
  end
55
84
  end
56
85
 
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
86
+ # If working directory, just have a single item array.
87
+ # The space here is important because git-lines checks for a second arg,
88
+ # and if one is present, it runs git diff without a commit
89
+ # or a comparison to a commit.
61
90
  git_diff = @psuedo_commit ? ['working directory'] : `git rev-list #{sha1}..#{sha2} --no-merges`.split("\n")
62
91
 
63
92
  # Include the first sha because rev-list is doing a traversal
@@ -96,17 +125,29 @@ module Maximus
96
125
  diff_return
97
126
  end
98
127
 
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...' }
128
+ # Run appropriate lint for every sha in commit history.
129
+ # For each sha a new branch is created then deleted
130
+ #
131
+ # @example sample output
132
+ # {
133
+ # 'sha': {
134
+ # lints: {
135
+ # scsslint: {
136
+ # files_inspec...
137
+ # },
138
+ # },
139
+ # statisti...
140
+ # },
141
+ # 'sha'...
142
+ # }
143
+ #
144
+ # @return [Hash] data all data grouped by task
104
145
  def lints_and_stats(lint_by_path = false, git_shas = compare)
105
146
  return false if git_shas.blank?
106
147
  base_branch = branch
107
148
  git_output = {}
108
149
  git_shas.each do |sha, exts|
109
- # TODO - better way to silence git, in case there's a real error?
150
+ # @todo better way to silence git, in case there's a real error?
110
151
  quietly { `git checkout #{sha} -b maximus_#{sha}` } unless @psuedo_commit
111
152
  puts sha.to_s.color(:blue) if @@is_dev
112
153
  git_output[sha.to_sym] = {
@@ -126,6 +167,7 @@ module Maximus
126
167
  port: @opts[:port],
127
168
  root_dir: @opts[:root_dir]
128
169
  }
170
+
129
171
  # This is where everything goes down
130
172
  exts.each do |ext, files|
131
173
  # For relevant_lines data
@@ -135,27 +177,27 @@ module Maximus
135
177
  when :scss
136
178
  lints[:scsslint] = Maximus::Scsslint.new(lint_opts).result
137
179
 
138
- # Do not run statistics if called by rake task :compare
180
+ # Do not run statistics if called from command line
139
181
  if lint_opts[:commit].blank?
140
182
 
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
183
+ # @todo stylestat is singular here because model name in Rails is singular.
184
+ # But adding a .classify when it's converted to a model chops off the end s on 'phantomas',
185
+ # which breaks the model name.
144
186
  statistics[:stylestat] = Maximus::Stylestats.new(stat_opts).result
145
187
 
146
- # TODO - double pipe here is best way to say, if it's already run, don't run again, right?
188
+ # @todo double pipe here is best way to say, if it's already run, don't run again, right?
147
189
  statistics[:phantomas] ||= Maximus::Phantomas.new(stat_opts).result
148
190
  statistics[:wraith] = Maximus::Wraith.new(stat_opts).result
149
191
  end
150
192
  when :js
151
193
  lints[:jshint] = Maximus::Jshint.new(lint_opts).result
152
194
 
153
- # Do not run statistics if called by rake task :compare
195
+ # Do not run statistics if called from command line
154
196
  if lint_opts[:commit].blank?
155
197
 
156
198
  statistics[:phantomas] = Maximus::Phantomas.new(stat_opts).result
157
199
 
158
- # TODO - double pipe here is best way to say, if it's already run, don't run again, right?
200
+ # @todo double pipe here is best way to say, if it's already run, don't run again, right?
159
201
  statistics[:wraith] ||= Maximus::Wraith.new(stat_opts).result
160
202
  end
161
203
  when :ruby
@@ -166,7 +208,7 @@ module Maximus
166
208
  lints[:railsbp] ||= Maximus::Railsbp.new(lint_opts).result
167
209
  end
168
210
  end
169
- # TODO - better way to silence git, in case there's a real error?
211
+ # @todo better way to silence git, in case there's a real error?
170
212
  quietly {
171
213
  @g.branch(base_branch).checkout
172
214
  @g.branch("maximus_#{sha}").delete
@@ -179,15 +221,28 @@ module Maximus
179
221
  protected
180
222
 
181
223
  # Get list of file paths
182
- # Returns String delimited by comma or space
224
+ #
225
+ # @param files [Hash] hash of files denoted by key 'filename'
226
+ # @param ext [String] file extension - different extensions are joined different ways
227
+ # @return [String] file paths delimited by comma or space
183
228
  def lint_file_paths(files, ext)
184
229
  file_list = files.map { |f| f[:filename] }.compact
185
230
  # Lints accept files differently
186
231
  ext == :ruby ? file_list.join(' ') : file_list.join(',')
187
232
  end
188
233
 
189
- # Returns Array of ranges by lines added in a commit by file name
190
- # {'filename' => ['0..10', '11..14']}
234
+ # Determine which lines were added (where and how many) in a commit
235
+ #
236
+ # @example output from method
237
+ # {
238
+ # 'filename': [
239
+ # '0..10',
240
+ # '11..14'
241
+ # ]
242
+ # }
243
+ #
244
+ # @param git_sha [String] sha of the commit
245
+ # @return [Hash] ranges by lines added in a commit by file name
191
246
  def lines_added(git_sha)
192
247
  new_lines = {}
193
248
  lines_added = `#{File.join(File.dirname(__FILE__), 'reporter/git-lines.sh')} #{git_sha}`.split("\n")
@@ -204,44 +259,50 @@ module Maximus
204
259
  end
205
260
 
206
261
  # Get last commit on current branch
207
- # Returns String
262
+ #
263
+ # @return [String] sha
208
264
  def sha
209
265
  @g.object('HEAD').sha
210
266
  end
211
267
 
212
- # Get branch name
213
- # Returns String
268
+ # Get current branch name
269
+ #
270
+ # @return [String]
214
271
  def branch
215
272
  `env -i git rev-parse --abbrev-ref HEAD`.strip!
216
273
  end
217
274
 
218
275
  # Get last commit on the master branch
219
- # Returns Git::Object
276
+ #
277
+ # @return [Git::Object]
220
278
  def master_commit
221
279
  @g.branches[:master].gcommit
222
280
  end
223
281
 
224
282
  # Store last commit as Ruby Git::Object
225
- # Returns Git::Object
283
+ # @param commitsha [String]
284
+ # @return [Git::Object]
226
285
  def vccommit(commitsha = sha)
227
286
  @g.gcommit(commitsha)
228
287
  end
229
288
 
230
289
  # 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
290
+ #
291
+ # @return [Git::Diff]
233
292
  def diff(new_commit = vccommit, old_commit = master_commit)
234
293
  @g.diff(new_commit, old_commit).stats
235
294
  end
236
295
 
237
296
  # Get remote URL
238
- # Returns String or nil if remotes is blank
297
+ #
298
+ # @return [String, nil] nil returns if remotes is blank
239
299
  def remote
240
300
  @g.remotes.first.url unless @g.remotes.blank?
241
301
  end
242
302
 
243
303
  # Define associations to linters based on file extension
244
- # Returns Hash of linters and extension arrays
304
+ #
305
+ # @return [Hash] linters and extension arrays
245
306
  def associations
246
307
  {
247
308
  scss: ['scss', 'sass'],
@@ -5,51 +5,70 @@ require 'active_support/core_ext/object/blank'
5
5
  require 'yaml'
6
6
 
7
7
  module Maximus
8
+ # @since 0.1.0
8
9
  module Helper
9
10
 
10
- # See if Rails or a framework, i.e. Middleman
11
- # This will usually be stored as a class variable in the inherited class, like @@is_rails = is_rails? in lint.rb
12
- # Returns Boolean
11
+ # See if project linted is a Rails app
12
+ # This will usually be stored as a class variable in the inherited class
13
+ # @example class variable
14
+ # @@is_rails = is_rails?
15
+ #
16
+ # @see Lint#initialize
17
+ #
18
+ # @return [Boolean]
13
19
  def is_rails?
14
20
  defined?(Rails)
15
21
  end
16
22
 
17
23
  # Get root directory of file being called
18
- # Returns String (path)
24
+ #
25
+ # @return [String] absolute path to root directory
19
26
  def root_dir
20
27
  is_rails? ? Rails.root.to_s : Dir.pwd.to_s
21
28
  end
22
29
 
23
- # Verify that node module is installed on the box before continuing
24
- # Continues if module exists
25
- def node_module_exists(node_module, install_instructions = 'npm install -g')
26
- cmd = `if hash #{node_module} 2>/dev/null; then
30
+ # Verify that command is available on the box before continuing
31
+ #
32
+ # @param command [String] command to check
33
+ # @param install_instructions [String] how to install the missing command
34
+ # @return [void] aborts the action if command not found
35
+ def node_module_exists(command, install_instructions = 'npm install -g')
36
+ cmd = `if hash #{command} 2>/dev/null; then
27
37
  echo "true"
28
38
  else
29
39
  echo "false"
30
40
  fi`
31
41
  if cmd.include? "false"
32
- command_msg = "Missing command #{node_module}".color(:red)
33
- abort "#{command_msg}: Please run `#{install_instructions} #{node_module}` And try again\n"
42
+ command_msg = "Missing command #{command}".color(:red)
43
+ abort "#{command_msg}: Please run `#{install_instructions} #{command}` And try again\n"
44
+ exit 1
34
45
  end
35
46
  end
36
47
 
37
- # Look for a custom config in the app's config/ directory; otherwise, use the built-in one
38
- # TODO - best practice that this inherits the @opts from the model it's being included in?
39
- # Returns String
48
+ # Look for a custom config in the app's config/ directory;
49
+ # otherwise, use the built-in one.
50
+ # @todo best practice that this inherits the @opts from the model it's being included in?
51
+ #
52
+ # @param filename [String]
53
+ # @return [String] absolute path to the reporter file
40
54
  def check_default(filename)
41
55
  user_file = "#{@opts[:root_dir]}/config/#{filename}"
42
56
  File.exist?(user_file) ? user_file : File.join(File.dirname(__FILE__), "config/#{filename}")
43
57
  end
44
58
 
45
59
  # Grab the absolute path of the reporter file
46
- # Returns String
60
+ #
61
+ # @param filename [String]
62
+ # @return [String] absolute path to the reporter file
47
63
  def reporter_path(filename)
48
64
  File.join(File.dirname(__FILE__),"reporter/#{filename}")
49
65
  end
50
66
 
51
67
  # Find all files that were linted by extension
52
- # Returns Array
68
+ #
69
+ # @param path [String] path to folders
70
+ # @param ext [String] file extension to search for
71
+ # @return [Array<String>] list of file paths
53
72
  def file_list(path, ext = 'scss', remover = '')
54
73
  # Necessary so that directories aren't counted
55
74
  collect_path = path.include?("*") ? path : "#{path}/**/*.#{ext}"
@@ -58,20 +77,26 @@ module Maximus
58
77
  end
59
78
 
60
79
  # Count how many files were linted
61
- # Returns Integer
80
+ #
81
+ # @param path [String] path to folders
82
+ # @param ext [String] file extension to search for
83
+ # @return [Integer] number of files matched by the path
62
84
  def file_count(path, ext = 'scss')
63
85
  file_list(path, ext).length
64
86
  end
65
87
 
66
88
  # Convert string to boolean
67
- # Returns Boolean
89
+ #
90
+ # @param str [String] the string to evaluate
91
+ # @return [Boolean] whether or not the string is true
68
92
  def truthy(str)
69
93
  return true if str == true || str =~ (/^(true|t|yes|y|1)$/i)
70
94
  return false if str == false || str.blank? || str =~ (/^(false|f|no|n|0)$/i)
71
95
  end
72
96
 
73
97
  # Edit and save a YAML file
74
- # Returns closed File
98
+ #
99
+ # @return [void]
75
100
  def edit_yaml(yaml_location, &block)
76
101
  d = YAML.load_file(yaml_location)
77
102
  block.call(d)
@@ -79,41 +104,53 @@ module Maximus
79
104
  end
80
105
 
81
106
  # Request user input
82
- # Returns user input as String
107
+ #
108
+ # @param args [Array<String>] prompts to request
109
+ # @return [String] user input to use elsewhere
83
110
  def prompt(*args)
84
111
  print(*args)
85
112
  STDIN.gets
86
113
  end
87
114
 
88
- # Defines base log
89
- # Returns @@log variable for use
115
+ # Defines base logger
116
+ #
117
+ # @return [Logger] @@log for logging use
90
118
  def mlog
91
119
  @@log ||= Logger.new(STDOUT)
92
120
  @@log.level ||= Logger::INFO
93
121
  @@log
94
122
  end
95
123
 
96
- # Determine if current process was called by a rake task
97
- # Returns Boolean
98
- # http://stackoverflow.com/questions/2467208/how-can-i-tell-if-rails-code-is-being-run-via-rake-or-script-generate
99
- def is_rake_task?
100
- File.basename($0) == 'rake'
101
- end
102
-
103
124
  # Convert the array from lines_added into spelled-out ranges
104
- # Example: lines_added = {'filename' => ['0..10', '11..14']}
105
- # Becomes {'filename' => {[0,1,2,3,4,5,6,7,8,9,10], [11,12,13,14]}}
106
- # This is a git_control helper primarily but it's used in Lint
107
- # TODO - I'm sure there's a better way of doing this
108
- # TODO - figure out a better place to put this than in Helper
109
- # Returns Hash of spelled-out arrays of integers
125
+ # This is a GitControl helper but it's used in Lint
126
+ # @see GitControl#lines_added
127
+ # @see Lint#relevant_lint
128
+ #
129
+ # @example typical output
130
+ # lines_added = {'filename' => ['0..10', '11..14']}
131
+ # lines_added_to_range(lines_added)
132
+ # # output
133
+ # {
134
+ # 'filename': {
135
+ # {
136
+ # [0,1,2,3,4,5,6,7,8,9,10],
137
+ # [11,12,13,14]
138
+ # }
139
+ # }
140
+ # }
141
+ #
142
+ # @todo I'm sure there's a better way of doing this
143
+ # @todo figure out a better place to put this than in Helper
144
+ # @return [Hash] changes_array of spelled-out arrays of integers
110
145
  def lines_added_to_range(file)
111
146
  changes_array = file[:changes].map { |ch| ch.split("..").map(&:to_i) }
112
147
  changes_array.map { |e| (e[0]..e[1]).to_a }.flatten!
113
148
  end
114
149
 
115
- # Ensure @path exists
116
- # Returns Boolean
150
+ # Ensure path exists
151
+ #
152
+ # @param path [String, Array] path to files can be directory or glob
153
+ # @return [Boolean]
117
154
  def path_exists(path = @path)
118
155
  path = path.split(' ') if path.is_a?(String) && path.include?(' ')
119
156
  if path.is_a?(Array)