skeptic 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c134d0e254360008e27fa9cb86c40c93db1927f4
4
- data.tar.gz: 4740e1bf1ad5a49988947f4271cc02670c02e8ec
3
+ metadata.gz: b186a1164cdf3aec83412da18189eea9b5f009af
4
+ data.tar.gz: 3a9179e3fcca3ecbecf2ebc0614e2d81819d82c8
5
5
  SHA512:
6
- metadata.gz: 15a38c21b6827006b04201c4cb85df642e9d23d222df9ae576e6de2bd7fa22f25c65eeb263e648a75e5c47d2fb3f65ead2d0209c6cb7435f2c097468b61372b0
7
- data.tar.gz: 18a09be7c9be915270ec24fea66cfe12d705083147afc6ab8984fc4749d43daf4ca7cbbefa6cf45a93702b333214fc6f7bd180a7cd61c3102f074b36173aca62
6
+ metadata.gz: 3bbc4449f25c944c6071b4f59f6c73d741b36159e08ab05c6300973d9f33a2da381cc471bc09a4908cf576516b452a1e49efc4c7d792b6c3fc1bb0c55dada27e
7
+ data.tar.gz: 67df5abdf016869af57e345edf652237854ef5f6512ac78ee5bce6805a3850b2a4563c70115e337e1a7edda532f1eccde4a91fa819d43567b34fa9e24934f953
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm --create 1.9.3@skeptic
1
+ rvm --create 2.1.2@skeptic
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## 0.0.8 (2014-10-12)
2
+
3
+ Features:
4
+ - Add a rule for max method arity (thanks to [milanov](https://github.com/milanov))
5
+ - Add support for checking recursively whole directories
6
+
7
+ Bugfixes:
8
+ - Fix detection of unary operators
9
+ - Add installation instructions in the readme (thanks to [mitio](https://github.com/mitio))
10
+ - Fix handling of case statements without a testable in max nesting depth rule
11
+
12
+ ## 0.0.7 (2013-12-15)
13
+
14
+ Bugfixes:
15
+ - Fix crashing in naming conventions rule
16
+ - Stop detecting unary - in space around operators rule
17
+ - Improve space around operators detection using ast context info
18
+
19
+ ## 0.0.6 (2013-12-14)
20
+
21
+ Bugfixes:
22
+ - Refine bad naming detection
23
+
24
+
1
25
  ## 0.0.5 (2013-11-15)
2
26
 
3
27
  Features:
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ gem 'trollop', '>= 1.16.2'
9
9
  gem "ffi-aspell"
10
10
 
11
11
  group :development do
12
- gem "rspec"
12
+ gem "rspec", "2.14.1"
13
13
  gem "cucumber"
14
14
  gem "aruba"
15
15
  gem "bundler"
data/README.markdown CHANGED
@@ -2,9 +2,21 @@
2
2
 
3
3
  _Skeptic_ is a *very* experimental static code analyzer for Ruby 1.9. It points out annoying things in your Ruby code.
4
4
 
5
- I am using it for a [Ruby course in the University of Sofia](http://fmi.ruby.bg/). All the assignments the students hand it should adhere to specific style, that is automatically checked with Skeptic. Assignments that fail to meet the critera are rejected outright. The main assumption is the "theory" of constraints - when one operates under constraints, one is more creative and ends up learning more.
5
+ I am using it for a [Ruby course in the University of Sofia](http://fmi.ruby.bg/). All the assignments the students hand it should adhere to specific style, that is automatically checked with Skeptic. Assignments that fail to meet the criteria are rejected outright. The main assumption is the "theory" of constraints - when one operates under constraints, one is more creative and ends up learning more.
6
6
 
7
- You should probably not use it for anythin.
7
+ You should probably not use it for anything.
8
+
9
+ ## Installation
10
+
11
+ Skeptic can be installed as a Ruby gem, either via `gem install skeptic`, or better yet via Bundler.
12
+
13
+ Make sure that you have the `aspell` package installed in your system, along with its shared libraries (`libaspell`). If you're on OS X, you can use [Homebrew](http://brew.sh/) to do that:
14
+
15
+ brew install aspell
16
+
17
+ On other Linux/Unix distributions, you are free to use a package manager or another installation method of choice.
18
+
19
+ For Windows systems, check out [GNU Aspell for Win32](http://aspell.net/win32/). Install Aspell using the "Full Installer" linked in that page, then locate `aspell-15.dll` in the installation and copy it somewhere in your `PATH` as `aspell.dll`.
8
20
 
9
21
  ## Rules
10
22
 
@@ -13,7 +25,7 @@ Skeptic checks if the code complies to a number of rules and reports the violati
13
25
  * **Valid syntax** - skeptic can check if your syntax is valid.
14
26
  * **Line length** - line length does not exceed a certain number.
15
27
  * **Lines per method** - methods are at most N lines long. Ignores empty lines and lines with `end`
16
- * **Max nesting depth** - at most N levels of nesting. blocks, conditions and loops are considered a level of nesting.
28
+ * **Max nesting depth** - at most N levels of nesting. Blocks, conditions and loops are considered a level of nesting.
17
29
  * **No semicolons** - stops you from using semicolons as expression delimiters.
18
30
  * **No trailing whitespace** - points out if your lines end on whitespace.
19
31
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.8
data/bin/skeptic CHANGED
@@ -7,36 +7,60 @@ parser = Trollop::Parser.new do
7
7
  banner <<BANNER
8
8
  Points out annoying things in your Ruby code. Just run with:
9
9
 
10
- skeptic [options] <path_to_file>
10
+ skeptic [options] <path>
11
11
 
12
- where [options] are:
12
+ where
13
+ <path> is a path to a file or a directory\
14
+ (which would be checked recursively) and
15
+ [options] are:
13
16
  BANNER
14
17
  Skeptic::Rules.table.each_rule do |klass, slug, option_type, description|
15
18
  opt slug, description, type: option_type
16
19
  end
17
- opt :file, 'Path to file to analyze', type: :string
20
+ opt :path, 'Path to file/directory to analyze', type: :string
18
21
  end
19
22
 
20
23
  opts = Trollop::with_standard_exception_handling parser do
21
24
  parsed = parser.parse ARGV
22
- parsed[:file] ||= ARGV.shift unless parsed[:file_given]
23
- raise Trollop::HelpNeeded unless parsed[:file]
25
+ parsed[:path] ||= ARGV.shift unless parsed[:path_given]
26
+ raise Trollop::HelpNeeded unless parsed[:path]
24
27
  raise Trollop::CommandlineError, "excessive arguments: #{ARGV.join(' ')}" unless ARGV.empty?
25
- raise Trollop::CommandlineError, "file does not exist: #{parsed[:file]}" unless File.exist? parsed[:file]
28
+ raise Trollop::CommandlineError, "resource does not exist: #{parsed[:path]}" unless File.exist? parsed[:path]
26
29
  parsed
27
30
  end
28
31
 
29
- code = File.read opts[:file]
30
- critic = Skeptic::Critic.new opts.select { |key, value| Skeptic::Rules.table.slugs.include? key }
31
- critic.criticize code
32
+ CRITIC_OPTS = opts.select { |key, value| Skeptic::Rules.table.slugs.include? key }
32
33
 
33
- if critic.criticism.empty?
34
- puts 'OK'
35
- exit(0)
36
- else
37
- messages = Hash.new { |hash, key| hash[key] = [] }
34
+ def criticize_file(path)
35
+ code = File.read path
36
+ critic = Skeptic::Critic.new CRITIC_OPTS
37
+ critic.criticize code
38
+ critic.criticism
39
+ end
38
40
 
39
- critic.criticism.each do |message, type|
41
+ def criticize_directory(path)
42
+ Dir["#{path}/**/*.rb"].map do |file|
43
+ [file, criticize_file(file)]
44
+ end
45
+ end
46
+
47
+ def display_directory_criticism(criticism)
48
+ has_errors = false
49
+ criticism.each do |filename, file_criticism|
50
+ unless file_criticism.empty?
51
+ puts "#{filename} :\n\n"
52
+ display_file_criticism file_criticism
53
+ has_errors = true
54
+ end
55
+ end
56
+
57
+ puts "#{criticism.count} files checked"
58
+ has_errors
59
+ end
60
+
61
+ def display_file_criticism(criticism)
62
+ messages = Hash.new { |hash, key| hash[key] = [] }
63
+ criticism.each do |message, type|
40
64
  messages[type] << message
41
65
  end
42
66
 
@@ -47,6 +71,21 @@ else
47
71
  end
48
72
  puts ""
49
73
  end
74
+ !criticism.empty?
75
+ end
76
+
77
+ has_errors = if Dir.exist? opts[:path]
78
+ display_directory_criticism criticize_directory opts[:path]
79
+ else
80
+ display_file_criticism criticize_file opts[:path]
81
+ end
50
82
 
51
- exit(1)
83
+ if has_errors
84
+ puts 'Errors found'
85
+ exit 1
86
+ else
87
+ puts 'OK'
88
+ exit 0
52
89
  end
90
+
91
+
@@ -0,0 +1,83 @@
1
+ module Skeptic
2
+ module Rules
3
+ class MaxMethodArity
4
+ DESCRIPTION = 'Limit the arguments count per method'
5
+ MAX_METHOD_ARITY = 3
6
+
7
+ include SexpVisitor
8
+
9
+ def initialize(limit = nil)
10
+ @violations = []
11
+ @limit = limit || MAX_METHOD_ARITY
12
+ end
13
+
14
+ def apply_to(code, tokens, sexp)
15
+ visit sexp
16
+ self
17
+ end
18
+
19
+ def violations
20
+ @violations.map do |method, arity|
21
+ "#{method} has #{arity} arguments (maximum method arity: #{@limit})"
22
+ end
23
+ end
24
+
25
+ def name
26
+ "Maximum method arity (#@limit)"
27
+ end
28
+
29
+ private
30
+
31
+ on :class do |name, parents, body|
32
+ env.push :module => qualified_class_name(name)
33
+ visit body
34
+
35
+ env.pop
36
+ end
37
+
38
+ on :module do |name, body|
39
+ env.push :module => qualified_class_name(name)
40
+ visit body
41
+
42
+ env.pop
43
+ end
44
+
45
+ on :def do |name, params, _|
46
+ qualified_method_name = env[:module] + '#' + extract_name(name)
47
+ env.push :method => qualified_method_name
48
+
49
+ visit params
50
+
51
+ env.pop
52
+ end
53
+
54
+ on :defs do |target, separator, name, params, body|
55
+ method_name = extract_name(name)
56
+ class_name = extract_name(target)
57
+ class_name = env[:module] if class_name == 'self'
58
+
59
+ qualified_method_name = class_name + '.' + method_name
60
+ env.push :method => qualified_method_name
61
+
62
+ visit params
63
+
64
+ env.pop
65
+ end
66
+
67
+ on :params do |*params|
68
+ check_max_arity(params) if params
69
+ end
70
+
71
+ def check_max_arity(params)
72
+ arguments_count = extract_param_idents(params).size
73
+ if arguments_count > @limit
74
+ @violations << [env[:method], arguments_count]
75
+ end
76
+ end
77
+
78
+ def qualified_class_name(name)
79
+ [env[:module], extract_name(name)].compact.join('::')
80
+ end
81
+ end
82
+ end
83
+ end
@@ -106,7 +106,7 @@ module Skeptic
106
106
  end
107
107
 
108
108
  on :case do |testable, alternatives|
109
- visit testable
109
+ visit testable unless testable.nil?
110
110
 
111
111
  with scope.push(:case) do
112
112
  visit alternatives
@@ -6,7 +6,7 @@ module Skeptic
6
6
  include SexpVisitor
7
7
 
8
8
  OPERATORS_WITHOUT_SPACES_AROUND_THEM = ['**', '::', '...', '..']
9
- IGNORED_TOKEN_TYPES = [:on_sp, :on_ignored_nl, :on_nl, :on_lparen, :on_symbeg]
9
+ IGNORED_TOKEN_TYPES = [:on_sp, :on_ignored_nl, :on_nl, :on_lparen, :on_symbeg, :on_lbracket, :on_lbrace]
10
10
 
11
11
  def initialize(data)
12
12
  @violations = []
@@ -94,7 +94,7 @@ module Skeptic
94
94
  end
95
95
 
96
96
  on :block_var do |params|
97
- normal_params = params[1]
97
+ normal_params = params[1] || []
98
98
  unless normal_params.empty?
99
99
  right_param = normal_params.last
100
100
  right_location = [right_param.last[0],
data/lib/skeptic/rules.rb CHANGED
@@ -15,5 +15,6 @@ module Skeptic
15
15
  table.register NoGlobalVariables, :boolean
16
16
  table.register NoTrailingWhitespace, :boolean
17
17
  table.register SpacesAroundOperators, :boolean
18
+ table.register MaxMethodArity, :int
18
19
  end
19
20
  end
@@ -86,6 +86,8 @@ module Skeptic
86
86
  [tree]
87
87
  when Symbol
88
88
  []
89
+ when nil
90
+ []
89
91
  else
90
92
  tree.compact.map { |node| extract_param_idents node }.reduce [], :+
91
93
  end
data/lib/skeptic.rb CHANGED
@@ -15,6 +15,7 @@ require 'skeptic/rules/english_words_for_names'
15
15
  require 'skeptic/rules/naming_conventions'
16
16
  require 'skeptic/rules/no_global_variables'
17
17
  require 'skeptic/rules/spaces_around_operators'
18
+ require 'skeptic/rules/max_method_arity'
18
19
 
19
20
  require 'skeptic/rule_table'
20
21
  require 'skeptic/rules'
data/skeptic.gemspec CHANGED
@@ -2,15 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: skeptic 0.0.7 ruby lib
5
+ # stub: skeptic 0.0.8 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "skeptic"
9
- s.version = "0.0.7"
9
+ s.version = "0.0.8"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
12
13
  s.authors = ["Stefan Kanev"]
13
- s.date = "2013-12-14"
14
+ s.date = "2014-10-12"
14
15
  s.description = "An experimental, half-assed, bug-ridden and highly opinionated code analyzer."
15
16
  s.email = "stefan.kanev@gmail.com"
16
17
  s.executables = ["skeptic"]
@@ -39,6 +40,7 @@ Gem::Specification.new do |s|
39
40
  "lib/skeptic/rules/english_words_for_names.rb",
40
41
  "lib/skeptic/rules/line_length.rb",
41
42
  "lib/skeptic/rules/lines_per_method.rb",
43
+ "lib/skeptic/rules/max_method_arity.rb",
42
44
  "lib/skeptic/rules/max_nesting_depth.rb",
43
45
  "lib/skeptic/rules/methods_per_class.rb",
44
46
  "lib/skeptic/rules/naming_conventions.rb",
@@ -52,8 +54,7 @@ Gem::Specification.new do |s|
52
54
  ]
53
55
  s.homepage = "http://github.com/skanev/skeptic"
54
56
  s.licenses = ["MIT"]
55
- s.require_paths = ["lib"]
56
- s.rubygems_version = "2.1.5"
57
+ s.rubygems_version = "2.2.2"
57
58
  s.summary = "Skeptic points out annoying things in your code"
58
59
 
59
60
  if s.respond_to? :specification_version then
@@ -62,7 +63,7 @@ Gem::Specification.new do |s|
62
63
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
64
  s.add_runtime_dependency(%q<trollop>, [">= 1.16.2"])
64
65
  s.add_runtime_dependency(%q<ffi-aspell>, [">= 0"])
65
- s.add_development_dependency(%q<rspec>, [">= 0"])
66
+ s.add_development_dependency(%q<rspec>, ["= 2.14.1"])
66
67
  s.add_development_dependency(%q<cucumber>, [">= 0"])
67
68
  s.add_development_dependency(%q<aruba>, [">= 0"])
68
69
  s.add_development_dependency(%q<bundler>, [">= 0"])
@@ -71,7 +72,7 @@ Gem::Specification.new do |s|
71
72
  else
72
73
  s.add_dependency(%q<trollop>, [">= 1.16.2"])
73
74
  s.add_dependency(%q<ffi-aspell>, [">= 0"])
74
- s.add_dependency(%q<rspec>, [">= 0"])
75
+ s.add_dependency(%q<rspec>, ["= 2.14.1"])
75
76
  s.add_dependency(%q<cucumber>, [">= 0"])
76
77
  s.add_dependency(%q<aruba>, [">= 0"])
77
78
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -81,7 +82,7 @@ Gem::Specification.new do |s|
81
82
  else
82
83
  s.add_dependency(%q<trollop>, [">= 1.16.2"])
83
84
  s.add_dependency(%q<ffi-aspell>, [">= 0"])
84
- s.add_dependency(%q<rspec>, [">= 0"])
85
+ s.add_dependency(%q<rspec>, ["= 2.14.1"])
85
86
  s.add_dependency(%q<cucumber>, [">= 0"])
86
87
  s.add_dependency(%q<aruba>, [">= 0"])
87
88
  s.add_dependency(%q<bundler>, [">= 0"])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skeptic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kanev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-14 00:00:00.000000000 Z
11
+ date: 2014-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 2.14.1
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 2.14.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: cucumber
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +151,7 @@ files:
151
151
  - lib/skeptic/rules/english_words_for_names.rb
152
152
  - lib/skeptic/rules/line_length.rb
153
153
  - lib/skeptic/rules/lines_per_method.rb
154
+ - lib/skeptic/rules/max_method_arity.rb
154
155
  - lib/skeptic/rules/max_nesting_depth.rb
155
156
  - lib/skeptic/rules/methods_per_class.rb
156
157
  - lib/skeptic/rules/naming_conventions.rb
@@ -181,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
182
  version: '0'
182
183
  requirements: []
183
184
  rubyforge_project:
184
- rubygems_version: 2.1.5
185
+ rubygems_version: 2.2.2
185
186
  signing_key:
186
187
  specification_version: 4
187
188
  summary: Skeptic points out annoying things in your code