cane 1.0.0 → 1.1.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,13 @@
1
1
  # Cane History
2
2
 
3
+ ## 1.1.0 - 24 March 2012 (ba8a74fc)
4
+
5
+ * `app` added to default globs
6
+ * Added `cane/rake_task`
7
+ * `class << obj` syntax ignore by documentation check
8
+ * Line length checks no longer include trailing new lines
9
+ * Add support for a `.cane` file for setting per-project default options.
10
+
3
11
  ## 1.0.0 - 14 January 2012 (4e400534)
4
12
 
5
- Initial release.
13
+ * Initial release.
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+
2
+ Copyright 2012 Square Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
data/README.md CHANGED
@@ -31,24 +31,57 @@ Customize behaviour with a wealth of options:
31
31
 
32
32
  > cane --help
33
33
  Usage: cane [options]
34
- --abc-glob GLOB Glob to run ABC metrics over (default: lib/**/*.rb)
35
- --abc-max VALUE Report any methods with complexity greater than VALUE (default: 15)
34
+
35
+ You can also put these options in a .cane file.
36
+
37
+ --abc-glob GLOB Glob to run ABC metrics over (default: {app,lib}/**/*.rb)
38
+ --abc-max VALUE Ignore methods under this complexity (default: 15)
36
39
  --no-abc Disable ABC checking
37
40
 
38
- --style-glob GLOB Glob to run style metrics over (default: {lib,spec}/**/*.rb)
41
+ --style-glob GLOB Glob to run style metrics over (default: {app,lib,spec}/**/*.rb)
39
42
  --style-measure VALUE Max line length (default: 80)
40
43
  --no-style Disable style checking
41
44
 
42
- --doc-glob GLOB Glob to run documentation metrics over (default: lib/**/*.rb)
45
+ --doc-glob GLOB Glob to run documentation checks over (default: {app,lib}/**/*.rb)
43
46
  --no-doc Disable documentation checking
44
47
 
45
- --gte FILE,THRESHOLD If FILE contains a single number, verify it is >= to THRESHOLD.
48
+ --gte FILE,THRESHOLD If FILE contains a number, verify it is >= to THRESHOLD.
46
49
 
47
50
  --max-violations VALUE Max allowed violations (default: 0)
48
51
 
49
52
  --version Show version
50
53
  -h, --help Show this message
51
54
 
55
+ Set default options into a `.cane` file:
56
+
57
+ > cat .cane
58
+ --no-doc
59
+ --abc-glob **/*.rb
60
+ > cane
61
+
62
+ It works just like this:
63
+
64
+ > cane --no-doc --abc-glob '**/*.rb'
65
+
66
+ ## Integrating with Rake
67
+
68
+ begin
69
+ require 'cane/rake_task'
70
+
71
+ desc "Run cane to check quality metrics"
72
+ Cane::RakeTask.new(:quality) do |cane|
73
+ cane.abc_max = 10
74
+ cane.add_threshold 'coverage/covered_percent', :>=, 99
75
+ end
76
+
77
+ task :default => :quality
78
+ rescue LoadError
79
+ warn "cane not available, quality task not provided."
80
+ end
81
+
82
+ Rescuing `LoadError` is a good idea, since `rake -T` failing is totally
83
+ frustrating.
84
+
52
85
  ## Adding to a legacy project
53
86
 
54
87
  Cane can be configured to still pass in the presence of a set number of
@@ -87,3 +120,16 @@ Requires MRI 1.9, since it depends on the `ripper` library to calculate
87
120
  complexity metrics. This only applies to the Ruby used to run Cane, not the
88
121
  project it is being run against. In other words, you can run Cane against your
89
122
  1.8 project.
123
+
124
+ ## Support
125
+
126
+ [Ask questions on Stack
127
+ Overflow](http://stackoverflow.com/questions/ask?tags=ruby+cane). We keep an
128
+ eye on new cane questions.
129
+
130
+ ## Contributing
131
+
132
+ Fork and patch! Before any changes are merged to master, we need you to sign an
133
+ [Individual Contributor
134
+ Agreement](https://spreadsheets.google.com/a/squareup.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1)
135
+ (Google Form).
data/bin/cane CHANGED
@@ -1,9 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
-
5
- $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
6
-
7
3
  require 'cane/cli'
8
4
 
9
5
  result = Cane::CLI.run(ARGV)
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.files = Dir.glob("{spec,lib}/**/*.rb") + %w(
18
18
  README.md
19
19
  HISTORY.md
20
+ LICENSE
20
21
  cane.gemspec
21
22
  )
22
23
  gem.test_files = Dir.glob("spec/**/*.rb")
@@ -1,3 +1,4 @@
1
+ require 'optparse'
1
2
  require 'cane/cli/translator'
2
3
 
3
4
  module Cane
@@ -7,11 +8,11 @@ module Cane
7
8
  # documentation, parsing, and default values.
8
9
  class Spec
9
10
  DEFAULTS = {
10
- abc_glob: 'lib/**/*.rb',
11
+ abc_glob: '{app,lib}/**/*.rb',
11
12
  abc_max: '15',
12
- style_glob: '{lib,spec}/**/*.rb',
13
+ style_glob: '{app,lib,spec}/**/*.rb',
13
14
  style_measure: '80',
14
- doc_glob: 'lib/**/*.rb',
15
+ doc_glob: '{app,lib}/**/*.rb',
15
16
  max_violations: '0',
16
17
  }
17
18
 
@@ -20,6 +21,8 @@ module Cane
20
21
  class OptionsHandled < RuntimeError; end
21
22
 
22
23
  def initialize
24
+ add_banner
25
+
23
26
  add_abc_options
24
27
  add_style_options
25
28
  add_doc_options
@@ -31,12 +34,30 @@ module Cane
31
34
  end
32
35
 
33
36
  def parse(args)
34
- parser.parse!(args)
37
+ parser.parse!(get_default_options + args)
38
+
35
39
  Translator.new(options, DEFAULTS).to_hash
36
40
  rescue OptionsHandled
37
41
  nil
38
42
  end
39
43
 
44
+ def get_default_options
45
+ if File.exists?('./.cane')
46
+ File.read('./.cane').gsub("\n", ' ').split(' ')
47
+ else
48
+ []
49
+ end
50
+ end
51
+
52
+ def add_banner
53
+ parser.banner = <<-BANNER
54
+ Usage: cane [options]
55
+
56
+ You can also put these options in a .cane file.
57
+
58
+ BANNER
59
+ end
60
+
40
61
  def add_abc_options
41
62
  add_option %w(--abc-glob GLOB), "Glob to run ABC metrics over"
42
63
  add_option %w(--abc-max VALUE), "Ignore methods under this complexity"
@@ -37,7 +37,9 @@ module Cane
37
37
  end
38
38
 
39
39
  def check_disabled(check, params)
40
- ((params + [check]) & options.keys) == [check]
40
+ relevant_options = options.keys & params + [check]
41
+
42
+ check == relevant_options[-1]
41
43
  end
42
44
 
43
45
  def option_with_default(key)
@@ -25,7 +25,7 @@ module Cane
25
25
  end
26
26
 
27
27
  def class_definition?(line)
28
- line =~ /^\s*class\s/
28
+ line =~ /^\s*class\s+/ and $'.index('<<') != 0
29
29
  end
30
30
 
31
31
  def comment?(line)
@@ -0,0 +1,75 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ module Cane
5
+ # Creates a rake task to run cane with given configuration.
6
+ #
7
+ # Examples
8
+ #
9
+ # desc "Run code quality checks"
10
+ # Cane::RakeTask.new(:quality) do |cane|
11
+ # cane.abc_max = 10
12
+ # cane.doc_glob = 'lib/**/*.rb'
13
+ # cane.add_threshold 'coverage/covered_percent', :>=, 99
14
+ # end
15
+ class RakeTask < ::Rake::TaskLib
16
+ attr_accessor :name
17
+
18
+ # Glob to run ABC metrics over (default: "lib/**/*.rb")
19
+ attr_accessor :abc_glob
20
+ # Max complexity of methods to allow (default: 15)
21
+ attr_accessor :abc_max
22
+ # Glob to run style checks over (default: "{lib,spec}/**/*.rb")
23
+ attr_accessor :style_glob
24
+ # Max line length (default: 80)
25
+ attr_accessor :style_measure
26
+ # Glob to run doc checks over (default: "lib/**/*.rb")
27
+ attr_accessor :doc_glob
28
+ # Max violations to tolerate (default: 0)
29
+ attr_accessor :max_violations
30
+
31
+ # Add a threshold check. If the file exists and it contains a number,
32
+ # compare that number with the given value using the operator.
33
+ def add_threshold(file, operator, value)
34
+ @threshold << [operator, file, value]
35
+ end
36
+
37
+ def initialize(task_name = nil)
38
+ self.name = task_name || :cane
39
+ @threshold = []
40
+ yield self if block_given?
41
+
42
+ unless ::Rake.application.last_comment
43
+ desc %(Check code quality metrics with cane)
44
+ end
45
+
46
+ task name do
47
+ require 'cane/cli'
48
+ abort unless Cane.run(translated_options)
49
+ end
50
+ end
51
+
52
+ def options
53
+ [
54
+ :abc_glob,
55
+ :abc_max,
56
+ :doc_glob,
57
+ :max_violations,
58
+ :style_glob,
59
+ :style_measure
60
+ ].inject(threshold: @threshold) do |opts, setting|
61
+ value = self.send(setting)
62
+ opts[setting] = value unless value.nil?
63
+ opts
64
+ end
65
+ end
66
+
67
+ def default_options
68
+ Cane::CLI::Spec::DEFAULTS
69
+ end
70
+
71
+ def translated_options
72
+ Cane::CLI::Translator.new(options, default_options).to_hash
73
+ end
74
+ end
75
+ end
@@ -81,7 +81,7 @@ module Cane
81
81
 
82
82
  # Copy of parent method using a configurable line length.
83
83
  def too_long?
84
- length = self.length
84
+ length = self.chomp.length
85
85
  if length > line_length_max
86
86
  print_problem "Line is >#{line_length_max} characters (#{length})"
87
87
  return true
@@ -1,3 +1,3 @@
1
1
  module Cane
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -14,8 +14,7 @@ describe 'Cane' do
14
14
  def run(cli_args)
15
15
  result = nil
16
16
  output = capture_stdout do
17
- default_cli_opts = %w(--no-style --no-abc --no-doc)
18
- result = Cane::CLI.run(default_cli_opts + cli_args.split(' '))
17
+ result = Cane::CLI.run(cli_args.split(' '))
19
18
  end
20
19
 
21
20
  [output, result ? 0 : 1]
@@ -55,6 +54,14 @@ describe 'Cane' do
55
54
  output.should include("Lines violated style requirements")
56
55
  end
57
56
 
57
+ it 'does not include trailing new lines in the character count' do
58
+ file_name = make_file('#' * 80 + "\n" + '#' * 80)
59
+
60
+ output, exitstatus = run("--style-glob #{file_name} --style-measure 80")
61
+ exitstatus.should == 0
62
+ output.should be_empty
63
+ end
64
+
58
65
  it 'allows upper bound of failed checks' do
59
66
  file_name = make_file("whitespace ")
60
67
 
@@ -79,6 +86,24 @@ describe 'Cane' do
79
86
  output.should include("Classes are not documented")
80
87
  end
81
88
 
89
+ context 'with a .cane file' do
90
+ before(:each) do
91
+ file_name = make_file("class NoDoc")
92
+ make_dot_cane("--doc-glob #{file_name}")
93
+ end
94
+
95
+ after(:each) do
96
+ unmake_dot_cane
97
+ end
98
+
99
+ it 'loads options from a .cane file' do
100
+ output, exitstatus = run('')
101
+
102
+ exitstatus.should == 1
103
+ output.should include("Classes are not documented")
104
+ end
105
+ end
106
+
82
107
  it 'displays a help message' do
83
108
  output, exitstatus = run("--help")
84
109
 
@@ -92,4 +117,14 @@ describe 'Cane' do
92
117
  exitstatus.should == 0
93
118
  output.should include(Cane::VERSION)
94
119
  end
120
+
121
+ it 'uses the last of conflicting arguments' do
122
+ file_name = make_file("class NoDoc")
123
+
124
+ run("--doc-glob #{file_name} --no-doc").should ==
125
+ run("--no-doc")
126
+
127
+ run("--no-doc --doc-glob #{file_name}").should ==
128
+ run("--doc-glob #{file_name}")
129
+ end
95
130
  end
@@ -11,6 +11,9 @@ class NoDoc; end # No doc
11
11
  class AlsoNoDoc; end
12
12
  [:class]
13
13
  # class Ignore
14
+ class Meta
15
+ class << self; end
16
+ end
14
17
  RUBY
15
18
 
16
19
  violations = described_class.new(files: file_name).violations
@@ -12,6 +12,16 @@ def make_file(content)
12
12
  tempfile.path
13
13
  end
14
14
 
15
+ def make_dot_cane(content)
16
+ File.open('./.cane', 'w') do |f|
17
+ f.puts content
18
+ end
19
+ end
20
+
21
+ def unmake_dot_cane
22
+ FileUtils.rm('./.cane')
23
+ end
24
+
15
25
  require 'simplecov'
16
26
 
17
27
  class SimpleCov::Formatter::QualityFormatter
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: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-14 00:00:00.000000000 Z
12
+ date: 2012-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: tailor
16
- requirement: &2156048880 !ruby/object:Gem::Requirement
16
+ requirement: &2160572120 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156048880
24
+ version_requirements: *2160572120
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2156048380 !ruby/object:Gem::Requirement
27
+ requirement: &2160571620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2156048380
35
+ version_requirements: *2160571620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &2156047960 !ruby/object:Gem::Requirement
38
+ requirement: &2160571200 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2156047960
46
+ version_requirements: *2160571200
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: simplecov
49
- requirement: &2156047500 !ruby/object:Gem::Requirement
49
+ requirement: &2160570720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2156047500
57
+ version_requirements: *2160570720
58
58
  description: Fails your build if code quality thresholds are not met
59
59
  email:
60
60
  - xavier@squareup.com
@@ -76,6 +76,7 @@ files:
76
76
  - lib/cane/cli/translator.rb
77
77
  - lib/cane/cli.rb
78
78
  - lib/cane/doc_check.rb
79
+ - lib/cane/rake_task.rb
79
80
  - lib/cane/style_check.rb
80
81
  - lib/cane/style_violation.rb
81
82
  - lib/cane/threshold_check.rb
@@ -85,6 +86,7 @@ files:
85
86
  - lib/cane.rb
86
87
  - README.md
87
88
  - HISTORY.md
89
+ - LICENSE
88
90
  - cane.gemspec
89
91
  - bin/cane
90
92
  homepage: http://github.com/square/cane
@@ -107,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
109
  version: '0'
108
110
  requirements: []
109
111
  rubyforge_project:
110
- rubygems_version: 1.8.10
112
+ rubygems_version: 1.8.6
111
113
  signing_key:
112
114
  specification_version: 3
113
115
  summary: Fails your build if code quality thresholds are not met. Provides complexity