cane 2.2.3 → 2.3.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.3.0 - 16 September 2012 (229252ff)
4
+
5
+ * Feature: `--json` option for machine-readable output.
6
+ * Feature: absence of a README will cause a failure.
7
+ * Bugfix: `--no-style` option actually works now.
8
+
3
9
  ## 2.2.3 - 3 September 2012 (e4fe90ee)
4
10
 
5
11
  * Bugfix: Allow multiple spaces before class name. (#34)
data/README.md CHANGED
@@ -78,7 +78,7 @@ Command-line arguments will override arguments specified in the `.cane` file.
78
78
  cane.abc_max = 10
79
79
  cane.add_threshold 'coverage/covered_percent', :>=, 99
80
80
  cane.no_style = true
81
- cane.abc_exclude = %w(Foo::Bar.some_method)
81
+ cane.abc_exclude = %w(Foo::Bar#some_method)
82
82
  end
83
83
 
84
84
  task :default => :quality
@@ -192,6 +192,18 @@ dealt with. In the background job case:
192
192
  * What if it failed 5 days ago and we're only looking at it now?
193
193
  * Who cares that this job failed?
194
194
 
195
+ ### Writing a readme
196
+
197
+ A good README should include at a minimum:
198
+
199
+ * Why the project exists.
200
+ * How to get started with development.
201
+ * How to deploy the project (if applicable).
202
+ * Status of the project (spike, active development, stable in production).
203
+ * Compatibility notes (1.8, 1.9, JRuby).
204
+ * Any interesting technical or architectural decisions made on the project
205
+ (this could be as simple as a to an external design document).
206
+
195
207
  ## Compatibility
196
208
 
197
209
  Requires MRI 1.9, since it depends on the `ripper` library to calculate
@@ -1,58 +1,2 @@
1
- require 'parallel'
2
-
3
- require 'cane/violation_formatter'
4
-
5
- module Cane
6
- def run(*args)
7
- Runner.new(*args).run
8
- end
9
- module_function :run
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
-
29
- # Orchestrates the running of checks per the provided configuration, and
30
- # hands the result to a formatter for display. This is the core of the
31
- # application, but for the actual entry point see `Cane::CLI`.
32
- class Runner
33
- def initialize(spec)
34
- @opts = spec
35
- @checks = spec[:checks]
36
- end
37
-
38
- def run
39
- outputter.print ViolationFormatter.new(violations)
40
-
41
- violations.length <= opts.fetch(:max_violations)
42
- end
43
-
44
- protected
45
-
46
- attr_reader :opts, :checks
47
-
48
- def violations
49
- @violations ||= checks.
50
- map {|check| check.new(opts).violations }.
51
- flatten
52
- end
53
-
54
- def outputter
55
- opts.fetch(:out, $stdout)
56
- end
57
- end
58
- end
1
+ require 'cane/cli'
2
+ require 'cane/version'
@@ -2,6 +2,7 @@ require 'ripper'
2
2
  require 'set'
3
3
 
4
4
  require 'cane/file'
5
+ require 'cane/task_runner'
5
6
 
6
7
  module Cane
7
8
 
@@ -1,4 +1,4 @@
1
- require 'cane'
1
+ require 'cane/runner'
2
2
  require 'cane/version'
3
3
 
4
4
  require 'cane/cli/parser'
@@ -106,6 +106,9 @@ 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(--json),
110
+ "Output as JSON", default: false
111
+
109
112
  add_option %w(--parallel),
110
113
  "Use all processors. Slower on small projects, faster on large.",
111
114
  cast: ->(x) { x }
@@ -1,4 +1,5 @@
1
1
  require 'cane/file'
2
+ require 'cane/task_runner'
2
3
 
3
4
  module Cane
4
5
 
@@ -13,11 +14,12 @@ module Cane
13
14
  def self.name; "documentation checking"; end
14
15
  def self.options
15
16
  {
16
- doc_glob: ['Glob to run doc checks over',
17
- default: '{app,lib}/**/*.rb',
18
- variable: 'GLOB',
19
- clobber: :no_doc],
20
- no_doc: ['Disable documentation checking', cast: ->(x) { !x }]
17
+ doc_glob: ['Glob to run doc checks over',
18
+ default: '{app,lib}/**/*.rb',
19
+ variable: 'GLOB',
20
+ clobber: :no_doc],
21
+ no_readme: ['Disable readme checking', cast: ->(x) { !x }],
22
+ no_doc: ['Disable documentation checking', cast: ->(x) { !x }]
21
23
  }
22
24
  end
23
25
 
@@ -29,7 +31,7 @@ module Cane
29
31
  def violations
30
32
  return [] if opts[:no_doc]
31
33
 
32
- worker.map(file_names) {|file_name|
34
+ missing_file_violations + worker.map(file_names) {|file_name|
33
35
  find_violations(file_name)
34
36
  }.flatten
35
37
  end
@@ -50,6 +52,19 @@ module Cane
50
52
  end.compact
51
53
  end
52
54
 
55
+ def missing_file_violations
56
+ result = []
57
+ unless opts[:no_readme]
58
+ unless ['', '.txt', '.md'].any? {|x| Cane::File.exists?("README#{x}") }
59
+ result << {
60
+ description: 'Missing documentation',
61
+ label: 'No README found'
62
+ }
63
+ end
64
+ end
65
+ result
66
+ end
67
+
53
68
  def file_names
54
69
  Dir[opts.fetch(:doc_glob)]
55
70
  end
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ module Cane
4
+
5
+ # Computes a machine-readable JSON representation from an array of violations
6
+ # computed by the checks.
7
+ class JsonFormatter
8
+ def initialize(violations)
9
+ @violations = violations
10
+ end
11
+
12
+ def to_s
13
+ @violations.to_json
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,49 @@
1
+ require 'parallel'
2
+
3
+ require 'cane/violation_formatter'
4
+ require 'cane/json_formatter'
5
+
6
+ module Cane
7
+ def run(*args)
8
+ Runner.new(*args).run
9
+ end
10
+ module_function :run
11
+
12
+ # Orchestrates the running of checks per the provided configuration, and
13
+ # hands the result to a formatter for display. This is the core of the
14
+ # application, but for the actual entry point see `Cane::CLI`.
15
+ class Runner
16
+ def initialize(spec)
17
+ @opts = spec
18
+ @checks = spec[:checks]
19
+ end
20
+
21
+ def run
22
+ outputter.print formatter.new(violations)
23
+
24
+ violations.length <= opts.fetch(:max_violations)
25
+ end
26
+
27
+ protected
28
+
29
+ attr_reader :opts, :checks
30
+
31
+ def violations
32
+ @violations ||= checks.
33
+ map {|check| check.new(opts).violations }.
34
+ flatten
35
+ end
36
+
37
+ def outputter
38
+ opts.fetch(:out, $stdout)
39
+ end
40
+
41
+ def formatter
42
+ if opts[:json]
43
+ JsonFormatter
44
+ else
45
+ ViolationFormatter
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
 
3
3
  require 'cane/file'
4
+ require 'cane/task_runner'
4
5
 
5
6
  module Cane
6
7
 
@@ -27,7 +28,7 @@ module Cane
27
28
  type: Array,
28
29
  default: [],
29
30
  clobber: :no_style],
30
- no_style: ['Disable style checking']
31
+ no_style: ['Disable style checking', cast: ->(x) { !x }]
31
32
  }
32
33
  end
33
34
 
@@ -0,0 +1,19 @@
1
+ module Cane
2
+ def task_runner(opts)
3
+ if opts[:parallel]
4
+ Parallel
5
+ else
6
+ SimpleTaskRunner
7
+ end
8
+ end
9
+ module_function :task_runner
10
+
11
+ # Mirrors the Parallel gem's interface but does not provide any parralleism.
12
+ # This is faster for smaller tasks since it doesn't incur any overhead for
13
+ # creating new processes and communicating between them.
14
+ class SimpleTaskRunner
15
+ def self.map(enumerable, &block)
16
+ enumerable.map(&block)
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module Cane
2
- VERSION = '2.2.3'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -3,6 +3,7 @@ require "stringio"
3
3
  require 'cane/cli'
4
4
 
5
5
  require 'cane/rake_task'
6
+ require 'cane/task_runner'
6
7
 
7
8
  # Acceptance tests
8
9
  describe 'The cane application' do
@@ -53,4 +53,19 @@ class Doc; end
53
53
  file_name, 4, "AlsoNoDoc"
54
54
  ]
55
55
  end
56
+
57
+ it 'creates a violation for missing README' do
58
+ file = fire_replaced_class_double("Cane::File")
59
+ stub_const("Cane::File", file)
60
+ file.should_receive(:exists?).with("README").and_return(false)
61
+ file.should_receive(:exists?).with("README.md").and_return(false)
62
+ file.should_receive(:exists?).with("README.txt").and_return(false)
63
+
64
+ violations = check("").violations
65
+ violations.length.should == 1
66
+
67
+ violations[0].values_at(:description, :label).should == [
68
+ "Missing documentation", "No README found"
69
+ ]
70
+ end
56
71
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ require 'cane/json_formatter'
4
+
5
+ describe Cane::JsonFormatter do
6
+ it 'outputs violations as JSON' do
7
+ violations = [{description: 'Fail', line: 3}]
8
+ JSON.parse(described_class.new(violations).to_s).should ==
9
+ [{'description' => 'Fail', 'line' => 3}]
10
+ end
11
+ end
@@ -97,4 +97,14 @@ describe Cane::CLI::Parser do
97
97
  output.should include("Usage:")
98
98
  result.should_not be
99
99
  end
100
+
101
+ it 'handles no_readme option' do
102
+ _, result = run("--no-readme")
103
+ result[:no_readme].should be
104
+ end
105
+
106
+ it 'handles json option' do
107
+ _, result = run("--json")
108
+ result[:json].should be
109
+ end
100
110
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- require 'cane'
3
+ require 'cane/runner'
4
4
 
5
5
  describe Cane::Runner do
6
6
  describe '#run' do
@@ -8,5 +8,17 @@ describe Cane::Runner do
8
8
  described_class.new(checks: [], max_violations: 0).run.should be
9
9
  described_class.new(checks: [], max_violations: -1).run.should_not be
10
10
  end
11
+
12
+ it 'returns JSON output' do
13
+ formatter = fire_replaced_class_double("Cane::JsonFormatter")
14
+ formatter.should_receive(:new).and_return("JSON")
15
+ buffer = StringIO.new("")
16
+
17
+ described_class.new(
18
+ out: buffer, checks: [], max_violations: 0, json: true
19
+ ).run
20
+
21
+ buffer.string.should == "JSON"
22
+ end
11
23
  end
12
24
  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.2.3
4
+ version: 2.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-03 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parallel
@@ -104,6 +104,7 @@ files:
104
104
  - spec/cli_spec.rb
105
105
  - spec/doc_check_spec.rb
106
106
  - spec/encoding_aware_iterator_spec.rb
107
+ - spec/json_formatter_spec.rb
107
108
  - spec/parser_spec.rb
108
109
  - spec/rake_task_spec.rb
109
110
  - spec/runner_spec.rb
@@ -119,8 +120,11 @@ files:
119
120
  - lib/cane/doc_check.rb
120
121
  - lib/cane/encoding_aware_iterator.rb
121
122
  - lib/cane/file.rb
123
+ - lib/cane/json_formatter.rb
122
124
  - lib/cane/rake_task.rb
125
+ - lib/cane/runner.rb
123
126
  - lib/cane/style_check.rb
127
+ - lib/cane/task_runner.rb
124
128
  - lib/cane/threshold_check.rb
125
129
  - lib/cane/version.rb
126
130
  - lib/cane/violation_formatter.rb
@@ -161,6 +165,7 @@ test_files:
161
165
  - spec/cli_spec.rb
162
166
  - spec/doc_check_spec.rb
163
167
  - spec/encoding_aware_iterator_spec.rb
168
+ - spec/json_formatter_spec.rb
164
169
  - spec/parser_spec.rb
165
170
  - spec/rake_task_spec.rb
166
171
  - spec/runner_spec.rb