cane 2.2.3 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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