cane 2.1.0 → 2.2.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.
data/HISTORY.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Cane History
2
2
 
3
+ ## 2.2.0 - 26 August 2012 (f4198619)
4
+
5
+ * Gracefully handle ambiguous options like `-abc-max` (#27)
6
+ * Provide the `--parallel` option to use all processors. This will be faster on
7
+ larger projects, but slower on smaller ones (#28)
8
+
3
9
  ## 2.1.0 - 26 August 2012 (2962d8fb)
4
10
 
5
11
  * Support for user-defined checks (#30)
data/README.md CHANGED
@@ -53,6 +53,7 @@ Customize behaviour with a wealth of options:
53
53
  --gte FILE,THRESHOLD If FILE contains a number, verify it is >= to THRESHOLD
54
54
 
55
55
  --max-violations VALUE Max allowed violations (default: 0)
56
+ --parallel Use all processors. Slower on small projects, faster on large.
56
57
 
57
58
  -v, --version Show version
58
59
  -h, --help Show this message
@@ -27,6 +27,7 @@ Gem::Specification.new do |gem|
27
27
  gem.executables << "cane"
28
28
  gem.version = Cane::VERSION
29
29
  gem.has_rdoc = false
30
+ gem.add_dependency 'parallel'
30
31
  gem.add_development_dependency 'rspec', '~> 2.0'
31
32
  gem.add_development_dependency 'rake'
32
33
  gem.add_development_dependency 'simplecov'
@@ -1,3 +1,5 @@
1
+ require 'parallel'
2
+
1
3
  require 'cane/violation_formatter'
2
4
 
3
5
  module Cane
@@ -6,6 +8,24 @@ module Cane
6
8
  end
7
9
  module_function :run
8
10
 
11
+ def task_runner(opts)
12
+ if opts[:parallel]
13
+ Parallel
14
+ else
15
+ SimpleTaskRunner
16
+ end
17
+ end
18
+ module_function :task_runner
19
+
20
+ # Mirrors the Parallel gem's interface but does not provide any parralleism.
21
+ # This is faster for smaller tasks since it doesn't incur any overhead for
22
+ # creating new processes and communicating between them.
23
+ class SimpleTaskRunner
24
+ def self.map(enumerable, &block)
25
+ enumerable.map(&block)
26
+ end
27
+ end
28
+
9
29
  # Orchestrates the running of checks per the provided configuration, and
10
30
  # hands the result to a formatter for display. This is the core of the
11
31
  # application, but for the actual entry point see `Cane::CLI`.
@@ -35,7 +35,7 @@ module Cane
35
35
  def violations
36
36
  return [] if opts[:no_abc] == false
37
37
 
38
- order file_names.map {|file_name|
38
+ order worker.map(file_names) {|file_name|
39
39
  find_violations(file_name)
40
40
  }.flatten
41
41
  end
@@ -192,5 +192,9 @@ module Cane
192
192
  def exclusions
193
193
  opts.fetch(:abc_exclude, []).flatten.to_set
194
194
  end
195
+
196
+ def worker
197
+ Cane.task_runner(opts)
198
+ end
195
199
  end
196
200
  end
@@ -39,7 +39,7 @@ module Cane
39
39
  parser.parse!(get_default_options + args)
40
40
 
41
41
  Cane::CLI.default_options.merge(options)
42
- rescue OptionParser::InvalidOption
42
+ rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption
43
43
  args = %w(--help)
44
44
  ret = false
45
45
  retry
@@ -106,6 +106,10 @@ BANNER
106
106
  add_option %w(--max-violations VALUE),
107
107
  "Max allowed violations", default: 0, cast: :to_i
108
108
 
109
+ add_option %w(--parallel),
110
+ "Use all processors. Slower on small projects, faster on large.",
111
+ cast: ->(x) { x }
112
+
109
113
  parser.separator ""
110
114
  end
111
115
 
@@ -24,7 +24,7 @@ module Cane
24
24
  def violations
25
25
  return [] if opts[:no_doc]
26
26
 
27
- file_names.map {|file_name|
27
+ worker.map(file_names) {|file_name|
28
28
  find_violations(file_name)
29
29
  }.flatten
30
30
  end
@@ -60,6 +60,10 @@ module Cane
60
60
  def extract_class_name(line)
61
61
  line.match(/class ([^\s;]+)/)[1]
62
62
  end
63
+
64
+ def worker
65
+ Cane.task_runner(opts)
66
+ end
63
67
  end
64
68
 
65
69
  end
@@ -34,7 +34,7 @@ module Cane
34
34
  def violations
35
35
  return [] if opts[:no_style]
36
36
 
37
- file_list.map do |file_path|
37
+ worker.map(file_list) do |file_path|
38
38
  map_lines(file_path) do |line, line_number|
39
39
  violations_for_line(line.chomp).map {|message| {
40
40
  file: file_path,
@@ -77,6 +77,10 @@ module Cane
77
77
  def excluded?(file)
78
78
  exclusions.include?(file)
79
79
  end
80
+
81
+ def worker
82
+ Cane.task_runner(opts)
83
+ end
80
84
  end
81
85
 
82
86
  end
@@ -1,3 +1,3 @@
1
1
  module Cane
2
- VERSION = '2.1.0'
2
+ VERSION = '2.2.0'
3
3
  end
@@ -62,6 +62,12 @@ describe 'The cane application' do
62
62
  exitstatus.should == 0
63
63
  end
64
64
 
65
+ it 'can run tasks in parallel' do
66
+ # This spec isn't great, but there is no good way to actually observe that
67
+ # tasks run in parallel and we want to verify the conditional is correct.
68
+ Cane.task_runner(parallel: true).should == Parallel
69
+ end
70
+
65
71
  after do
66
72
  if Object.const_defined?(class_name)
67
73
  Object.send(:remove_const, class_name)
@@ -86,4 +86,15 @@ describe Cane::CLI::Parser do
86
86
  result[:abc_glob].should == 'myfile'
87
87
  result[:style_glob].should == 'myotherfile'
88
88
  end
89
+
90
+ it 'allows parallel option' do
91
+ _, result = run("--parallel")
92
+ result[:parallel].should be
93
+ end
94
+
95
+ it 'handles ambiguous options' do
96
+ output, result = run("-abc-max")
97
+ output.should include("Usage:")
98
+ result.should_not be
99
+ end
89
100
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-26 00:00:00.000000000 Z
12
+ date: 2012-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: parallel
16
+ requirement: &2152738700 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152738700
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: rspec
16
- requirement: &2152567380 !ruby/object:Gem::Requirement
27
+ requirement: &2152737580 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ~>
@@ -21,10 +32,10 @@ dependencies:
21
32
  version: '2.0'
22
33
  type: :development
23
34
  prerelease: false
24
- version_requirements: *2152567380
35
+ version_requirements: *2152737580
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rake
27
- requirement: &2152566600 !ruby/object:Gem::Requirement
38
+ requirement: &2152736720 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ! '>='
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: '0'
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *2152566600
46
+ version_requirements: *2152736720
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: simplecov
38
- requirement: &2152565760 !ruby/object:Gem::Requirement
49
+ requirement: &2152736000 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *2152565760
57
+ version_requirements: *2152736000
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rspec-fire
49
- requirement: &2152564960 !ruby/object:Gem::Requirement
60
+ requirement: &2152751720 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,7 +65,7 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *2152564960
68
+ version_requirements: *2152751720
58
69
  description: Fails your build if code quality thresholds are not met
59
70
  email:
60
71
  - xavier@squareup.com