cane 2.3.0 → 2.4.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 +7 -0
- data/README.md +5 -1
- data/lib/cane/cli/parser.rb +18 -2
- data/lib/cane/doc_check.rb +11 -9
- data/lib/cane/rake_task.rb +7 -0
- data/lib/cane/threshold_check.rb +20 -4
- data/lib/cane/version.rb +1 -1
- data/spec/doc_check_spec.rb +3 -0
- data/spec/parser_spec.rb +12 -0
- data/spec/rake_task_spec.rb +15 -0
- data/spec/threshold_check_spec.rb +43 -6
- metadata +3 -3
data/HISTORY.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Cane History
|
2
2
|
|
3
|
+
## 2.4.0 - 21 October 2012 (46949e77)
|
4
|
+
|
5
|
+
* Feature: Rake task can load configuration from a `.cane` file.
|
6
|
+
* Feature: Coverage threshold can be specifed in a file.
|
7
|
+
* Feature: Provide `--all` option for working with single files.
|
8
|
+
* Bugfix: Allow README file to be lowercase.
|
9
|
+
|
3
10
|
## 2.3.0 - 16 September 2012 (229252ff)
|
4
11
|
|
5
12
|
* Feature: `--json` option for machine-readable output.
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ a non-zero exit code if any quality checks fail. Also, a report:
|
|
24
24
|
lib/cane.rb:20 Line length >80
|
25
25
|
lib/cane.rb:42 Trailing whitespace
|
26
26
|
|
27
|
-
Class definitions require explanatory comments on
|
27
|
+
Class definitions require explanatory comments on preceding line (1):
|
28
28
|
lib/cane:3 SomeClass
|
29
29
|
|
30
30
|
Customize behaviour with a wealth of options:
|
@@ -52,6 +52,7 @@ Customize behaviour with a wealth of options:
|
|
52
52
|
|
53
53
|
--gte FILE,THRESHOLD If FILE contains a number, verify it is >= to THRESHOLD
|
54
54
|
|
55
|
+
-f, --all FILE Apply all checks to given file
|
55
56
|
--max-violations VALUE Max allowed violations (default: 0)
|
56
57
|
--parallel Use all processors. Slower on small projects, faster on large.
|
57
58
|
|
@@ -86,6 +87,9 @@ Command-line arguments will override arguments specified in the `.cane` file.
|
|
86
87
|
warn "cane not available, quality task not provided."
|
87
88
|
end
|
88
89
|
|
90
|
+
Loading options from a `.cane` file is supported by setting `canefile=` to the
|
91
|
+
file name.
|
92
|
+
|
89
93
|
Rescuing `LoadError` is a good idea, since `rake -T` failing is totally
|
90
94
|
frustrating.
|
91
95
|
|
data/lib/cane/cli/parser.rb
CHANGED
@@ -28,6 +28,7 @@ module Cane
|
|
28
28
|
Cane.default_checks.each do |check|
|
29
29
|
add_check_options(check)
|
30
30
|
end
|
31
|
+
add_checks_shortcut
|
31
32
|
|
32
33
|
add_cane_options
|
33
34
|
|
@@ -48,8 +49,12 @@ module Cane
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def get_default_options
|
51
|
-
|
52
|
-
|
52
|
+
read_options_from_file './.cane'
|
53
|
+
end
|
54
|
+
|
55
|
+
def read_options_from_file(file)
|
56
|
+
if Cane::File.exists?(file)
|
57
|
+
Cane::File.contents(file).split(/\s+/m)
|
53
58
|
else
|
54
59
|
[]
|
55
60
|
end
|
@@ -116,6 +121,17 @@ BANNER
|
|
116
121
|
parser.separator ""
|
117
122
|
end
|
118
123
|
|
124
|
+
def add_checks_shortcut
|
125
|
+
description = "Apply all checks to given file"
|
126
|
+
parser.on("-f", "--all FILE", description) do |f|
|
127
|
+
# This is a bit of a hack, but provides a really useful UI for
|
128
|
+
# dealing with single files. Let's see how it evolves.
|
129
|
+
options[:abc_glob] = f
|
130
|
+
options[:style_glob] = f
|
131
|
+
options[:doc_glob] = f
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
119
135
|
def add_version
|
120
136
|
parser.on_tail("-v", "--version", "Show version") do
|
121
137
|
stdout.puts Cane::VERSION
|
data/lib/cane/doc_check.rb
CHANGED
@@ -4,11 +4,11 @@ require 'cane/task_runner'
|
|
4
4
|
module Cane
|
5
5
|
|
6
6
|
# Creates violations for class definitions that do not have an explantory
|
7
|
-
# comment immediately
|
7
|
+
# comment immediately preceding.
|
8
8
|
class DocCheck < Struct.new(:opts)
|
9
9
|
|
10
10
|
DESCRIPTION =
|
11
|
-
"Class definitions require explanatory comments on
|
11
|
+
"Class definitions require explanatory comments on preceding line"
|
12
12
|
|
13
13
|
def self.key; :doc; end
|
14
14
|
def self.name; "documentation checking"; end
|
@@ -54,13 +54,15 @@ module Cane
|
|
54
54
|
|
55
55
|
def missing_file_violations
|
56
56
|
result = []
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
return result if opts[:no_readme]
|
58
|
+
|
59
|
+
filenames = ['README', 'readme']
|
60
|
+
extensions = ['', '.txt', '.md']
|
61
|
+
combinations = filenames.product(extensions)
|
62
|
+
|
63
|
+
if combinations.none? {|n, x| Cane::File.exists?(n + x) }
|
64
|
+
result << { description: 'Missing documentation',
|
65
|
+
label: 'No README found' }
|
64
66
|
end
|
65
67
|
result
|
66
68
|
end
|
data/lib/cane/rake_task.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rake'
|
|
2
2
|
require 'rake/tasklib'
|
3
3
|
|
4
4
|
require 'cane/cli/options'
|
5
|
+
require 'cane/cli/parser'
|
5
6
|
|
6
7
|
module Cane
|
7
8
|
# Creates a rake task to run cane with given configuration.
|
@@ -42,6 +43,12 @@ module Cane
|
|
42
43
|
@options[:checks] = @options[:checks] + [check]
|
43
44
|
end
|
44
45
|
|
46
|
+
def canefile=(file)
|
47
|
+
canefile = Cane::CLI::Parser.new
|
48
|
+
canefile.parser.parse!(canefile.read_options_from_file(file))
|
49
|
+
options.merge! canefile.options
|
50
|
+
end
|
51
|
+
|
45
52
|
def initialize(task_name = nil)
|
46
53
|
self.name = task_name || :cane
|
47
54
|
@gte = []
|
data/lib/cane/threshold_check.rb
CHANGED
@@ -9,17 +9,26 @@ module Cane
|
|
9
9
|
def self.key; :threshold; end
|
10
10
|
def self.options
|
11
11
|
{
|
12
|
-
gte: ["
|
12
|
+
gte: ["Check the number in FILE is >= to THRESHOLD " +
|
13
|
+
"(a number or another file name)",
|
13
14
|
variable: "FILE,THRESHOLD",
|
14
15
|
type: Array]
|
15
16
|
}
|
16
17
|
end
|
17
18
|
|
18
19
|
def violations
|
19
|
-
thresholds.map do |operator, file,
|
20
|
-
value =
|
20
|
+
thresholds.map do |operator, file, threshold|
|
21
|
+
value = normalized_limit(file)
|
22
|
+
limit = normalized_limit(threshold)
|
21
23
|
|
22
|
-
|
24
|
+
if !limit.real?
|
25
|
+
{
|
26
|
+
description: 'Quality threshold could not be read',
|
27
|
+
label: "%s is not a number or a file" % [
|
28
|
+
threshold
|
29
|
+
]
|
30
|
+
}
|
31
|
+
elsif !value.send(operator, limit)
|
23
32
|
{
|
24
33
|
description: 'Quality threshold crossed',
|
25
34
|
label: "%s is %s, should be %s %s" % [
|
@@ -30,6 +39,12 @@ module Cane
|
|
30
39
|
end.compact
|
31
40
|
end
|
32
41
|
|
42
|
+
def normalized_limit(limit)
|
43
|
+
Float(limit)
|
44
|
+
rescue ArgumentError
|
45
|
+
value_from_file(limit)
|
46
|
+
end
|
47
|
+
|
33
48
|
def value_from_file(file)
|
34
49
|
begin
|
35
50
|
contents = Cane::File.contents(file).chomp.to_f
|
@@ -49,6 +64,7 @@ module Cane
|
|
49
64
|
class UnavailableValue
|
50
65
|
def >=(_); false end
|
51
66
|
def to_s; 'unavailable' end
|
67
|
+
def real?; false; end
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
data/lib/cane/version.rb
CHANGED
data/spec/doc_check_spec.rb
CHANGED
@@ -60,6 +60,9 @@ class Doc; end
|
|
60
60
|
file.should_receive(:exists?).with("README").and_return(false)
|
61
61
|
file.should_receive(:exists?).with("README.md").and_return(false)
|
62
62
|
file.should_receive(:exists?).with("README.txt").and_return(false)
|
63
|
+
file.should_receive(:exists?).with("readme").and_return(false)
|
64
|
+
file.should_receive(:exists?).with("readme.md").and_return(false)
|
65
|
+
file.should_receive(:exists?).with("readme.txt").and_return(false)
|
63
66
|
|
64
67
|
violations = check("").violations
|
65
68
|
violations.length.should == 1
|
data/spec/parser_spec.rb
CHANGED
@@ -27,6 +27,18 @@ describe Cane::CLI::Parser do
|
|
27
27
|
result[:max_violations].should == 1
|
28
28
|
end
|
29
29
|
|
30
|
+
it 'uses positional arguments as shortcut for individual files' do
|
31
|
+
output, result = run("--all mysinglefile")
|
32
|
+
result[:abc_glob].should == 'mysinglefile'
|
33
|
+
result[:style_glob].should == 'mysinglefile'
|
34
|
+
result[:doc_glob].should == 'mysinglefile'
|
35
|
+
|
36
|
+
output, result = run("--all mysinglefile --abc-glob myotherfile")
|
37
|
+
result[:abc_glob].should == 'myotherfile'
|
38
|
+
result[:style_glob].should == 'mysinglefile'
|
39
|
+
result[:doc_glob].should == 'mysinglefile'
|
40
|
+
end
|
41
|
+
|
30
42
|
it 'displays a help message' do
|
31
43
|
output, result = run("--help")
|
32
44
|
|
data/spec/rake_task_spec.rb
CHANGED
@@ -32,6 +32,21 @@ describe Cane::RakeTask do
|
|
32
32
|
out.should include("theopt")
|
33
33
|
end
|
34
34
|
|
35
|
+
it 'can be configured using a .cane file' do
|
36
|
+
conf = "--gte 90,99"
|
37
|
+
|
38
|
+
task = Cane::RakeTask.new(:canefile_quality) do |cane|
|
39
|
+
cane.canefile = make_file(conf)
|
40
|
+
end
|
41
|
+
|
42
|
+
task.should_receive(:abort)
|
43
|
+
out = capture_stdout do
|
44
|
+
Rake::Task['canefile_quality'].invoke
|
45
|
+
end
|
46
|
+
|
47
|
+
out.should include("Quality threshold crossed")
|
48
|
+
end
|
49
|
+
|
35
50
|
after do
|
36
51
|
Rake::Task.clear
|
37
52
|
end
|
@@ -3,11 +3,48 @@ require 'spec_helper'
|
|
3
3
|
require 'cane/threshold_check'
|
4
4
|
|
5
5
|
describe Cane::ThresholdCheck do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
|
7
|
+
context "checking violations" do
|
8
|
+
|
9
|
+
context "when the current coverage cannot be read" do
|
10
|
+
it 'reports a violation' do
|
11
|
+
check = Cane::ThresholdCheck.new(gte: [['bogus_file', '20']])
|
12
|
+
violations = check.violations
|
13
|
+
violations.length.should == 1
|
14
|
+
violations[0][:label].should ==
|
15
|
+
'bogus_file is unavailable, should be >= 20.0'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when the coverage threshold is incorrectly specified" do
|
20
|
+
it 'reports a violation' do
|
21
|
+
check = Cane::ThresholdCheck.new(gte: [['20', 'bogus_file']])
|
22
|
+
violations = check.violations
|
23
|
+
violations.length.should == 1
|
24
|
+
violations[0][:label].should ==
|
25
|
+
'bogus_file is not a number or a file'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "normalizing a user supplied value to a threshold" do
|
32
|
+
it "normalizes an integer to itself" do
|
33
|
+
subject.normalized_limit(99).should == 99
|
34
|
+
end
|
35
|
+
|
36
|
+
it "normalizes a float to itself" do
|
37
|
+
subject.normalized_limit(99.6).should == 99.6
|
38
|
+
end
|
39
|
+
|
40
|
+
it "normalizes a valid file to its contents" do
|
41
|
+
subject.normalized_limit(make_file('99.5')).should == 99.5
|
42
|
+
end
|
43
|
+
|
44
|
+
it "normalizes an invalid file to an unavailable value" do
|
45
|
+
limit = subject.normalized_limit("/File.does.not.exist")
|
46
|
+
limit.should be_a Cane::ThresholdCheck::UnavailableValue
|
47
|
+
end
|
12
48
|
end
|
49
|
+
|
13
50
|
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.
|
4
|
+
version: 2.4.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-
|
12
|
+
date: 2012-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parallel
|
@@ -154,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
154
|
version: '0'
|
155
155
|
requirements: []
|
156
156
|
rubyforge_project:
|
157
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.23
|
158
158
|
signing_key:
|
159
159
|
specification_version: 3
|
160
160
|
summary: Fails your build if code quality thresholds are not met. Provides complexity
|