mago 0.0.5 → 0.1.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.
- checksums.yaml +4 -4
- data/README.markdown +44 -4
- data/lib/mago/cli/command.rb +10 -3
- data/lib/mago/cli/formatter.rb +17 -16
- data/lib/mago/cli/source_formatter.rb +4 -1
- data/lib/mago/detector.rb +24 -3
- data/lib/mago/version.rb +1 -1
- data/spec/integration/cli_spec.rb +31 -17
- data/spec/spec_helper.rb +2 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c74fb610902c60e56bb26d0b64eafa820c65fff
|
4
|
+
data.tar.gz: ff885d004ea58452cae383bb4f5a71d8bb15c0b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd48970c17f3d583d8a07b43a68efbe8595786d3c2ab5f58813c9d5c8761cdc3d75faab3bd3667674c7b0c47ad46c9d56ad7d3ff3d084a56584d666bae1de5ef
|
7
|
+
data.tar.gz: c9bc80c552d2b09d507613ea4c10f6fa22388b2d8193034cd896d86cb094baef6f3d6313170b2aad2b6f14b6095c11c8f25e05a3765f1646b73e7c858f9628e2
|
data/README.markdown
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
# Mago
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/greyblake/mago)
|
4
4
|
|
5
|
+
Magic numbers detector for Ruby source code.
|
6
|
+
|
7
|
+

|
8
|
+
|
9
|
+
## Magic numbers
|
10
|
+
|
11
|
+
Magic numbers (unnamed constants) are considered as a bad programming practice. Extracting them into constants or explaining variables usually provides the following advantages:
|
12
|
+
* It is easier to read and understand.
|
13
|
+
* It is easier to alter the value of the number, as it is not duplicated.
|
14
|
+
* It may facilitate parameterization.
|
15
|
+
* It helps to detect typos.
|
5
16
|
|
6
17
|
## Installation
|
7
18
|
|
@@ -49,11 +60,40 @@ mago -s ./square.rb
|
|
49
60
|
|
50
61
|
Use `--color` or `-c` option to colorize output.
|
51
62
|
|
52
|
-
## TODO
|
53
63
|
|
54
|
-
|
55
|
-
|
64
|
+
## Using API
|
65
|
+
|
56
66
|
|
67
|
+
See [complete documentation](http://rubydoc.info/gems/mago/) at rubydoc.
|
68
|
+
Here is a simple example:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
require 'mago'
|
72
|
+
|
73
|
+
# Initialize detector with ruby files and options
|
74
|
+
detector = Mago::Detector.new(['./square.rb', './math/fibonacci.rb'], :ignore => [1,2,3])
|
75
|
+
|
76
|
+
# Run detector it to build a report
|
77
|
+
report = detector.run # => #<Mago::Report ...>
|
78
|
+
|
79
|
+
# Use report as you want. The following code provides an output like this:
|
80
|
+
# ./square.rb
|
81
|
+
# Line 3: 5
|
82
|
+
# Line 6: 0
|
83
|
+
# ./math/fibonacci.rb
|
84
|
+
# Line 1: 0.0
|
85
|
+
# Line 6: 5.0
|
86
|
+
report.files.each do |file|
|
87
|
+
puts file.path
|
88
|
+
file.magic_numbers.each do |number|
|
89
|
+
puts " Line #{number.line}: #{number.value}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
report.errors.each do |error|
|
94
|
+
puts "ERROR: #{error}"
|
95
|
+
end
|
96
|
+
```
|
57
97
|
## Copyright
|
58
98
|
|
59
99
|
Copyright (c) 2013 Sergey Potapov. See LICENSE.txt for
|
data/lib/mago/cli/command.rb
CHANGED
@@ -75,12 +75,19 @@ module Mago
|
|
75
75
|
def run
|
76
76
|
ruby_files = Mago::Cli::FileFinder.new(@config.files).find
|
77
77
|
detector = Mago::Detector.new(ruby_files, :ignore => @config.ignore)
|
78
|
-
report = detector.run
|
79
78
|
|
80
79
|
formatter_class = @config.source ? SourceFormatter : Formatter
|
81
|
-
formatter = formatter_class.new(
|
80
|
+
formatter = formatter_class.new(:color => @config.color)
|
82
81
|
|
83
|
-
|
82
|
+
detector.on_file do |file|
|
83
|
+
print formatter.format_file(file)
|
84
|
+
end
|
85
|
+
|
86
|
+
detector.on_error do |error|
|
87
|
+
warn formatter.format_error(error)
|
88
|
+
end
|
89
|
+
|
90
|
+
detector.run
|
84
91
|
end
|
85
92
|
|
86
93
|
# Show help message.
|
data/lib/mago/cli/formatter.rb
CHANGED
@@ -4,42 +4,41 @@ module Mago
|
|
4
4
|
class Formatter
|
5
5
|
include Colorize
|
6
6
|
|
7
|
-
# @param report [Mago::Report]
|
8
7
|
# @param opts [Hash]
|
9
8
|
#
|
10
9
|
# @option opts :color [Boolean] whether colorize output or no
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
@color = opts[:color]
|
10
|
+
def initialize(opts = {})
|
11
|
+
@color = opts[:color]
|
14
12
|
end
|
15
13
|
|
16
14
|
# Format report.
|
17
15
|
#
|
16
|
+
# @param report [Mago::Report]
|
17
|
+
#
|
18
18
|
# @return [String] formated report
|
19
|
-
def format
|
19
|
+
def format(report)
|
20
20
|
out = ''
|
21
21
|
|
22
|
-
|
23
|
-
format_file(file, out)
|
22
|
+
report.files.each do |file|
|
23
|
+
out << format_file(file, out)
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
format_error(error
|
26
|
+
report.errors.each do |error|
|
27
|
+
out << format_error(error)
|
28
28
|
end
|
29
29
|
|
30
30
|
out
|
31
31
|
end
|
32
32
|
|
33
33
|
|
34
|
-
private
|
35
|
-
|
36
34
|
# Format file with magic numbers.
|
37
35
|
#
|
38
36
|
# @param file [Mago::File]
|
39
|
-
# @param out [String] string to write result
|
40
37
|
#
|
41
38
|
# @return [void]
|
42
|
-
def format_file(file
|
39
|
+
def format_file(file)
|
40
|
+
out = ''
|
41
|
+
|
43
42
|
file.magic_numbers.each do |num|
|
44
43
|
if @color
|
45
44
|
val = red(num.value)
|
@@ -53,16 +52,18 @@ module Mago
|
|
53
52
|
|
54
53
|
out << "#{path}:#{line} detected magic number #{val}\n"
|
55
54
|
end
|
55
|
+
|
56
|
+
out
|
56
57
|
end
|
57
58
|
|
58
59
|
# Format error.
|
59
60
|
#
|
60
61
|
# @param error [String] error message
|
61
|
-
# @param out [String] string to write result
|
62
62
|
#
|
63
63
|
# @return [void]
|
64
|
-
def format_error(error
|
65
|
-
out
|
64
|
+
def format_error(error)
|
65
|
+
out = "ERROR: #{error}"
|
66
|
+
@color ? red(out) : out
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
@@ -3,7 +3,8 @@ module Mago
|
|
3
3
|
# Formats report showing lines of source code where magic number was detected.
|
4
4
|
class SourceFormatter < Formatter
|
5
5
|
# :nodoc:
|
6
|
-
def format_file(file
|
6
|
+
def format_file(file)
|
7
|
+
out = ''
|
7
8
|
source_lines = File.readlines(file.path)
|
8
9
|
|
9
10
|
file.magic_numbers.each do |num|
|
@@ -19,6 +20,8 @@ module Mago
|
|
19
20
|
|
20
21
|
out << "#{path}:#{line}| #{source_line}"
|
21
22
|
end
|
23
|
+
|
24
|
+
out
|
22
25
|
end
|
23
26
|
|
24
27
|
# Find a substing in a string and make it red.
|
data/lib/mago/detector.rb
CHANGED
@@ -28,6 +28,16 @@ module Mago
|
|
28
28
|
@report
|
29
29
|
end
|
30
30
|
|
31
|
+
# Set callback to be called when file processing is finished.
|
32
|
+
def on_file(&block)
|
33
|
+
@on_file = block
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set callback to be called when error occurs.
|
37
|
+
def on_error(&block)
|
38
|
+
@on_error = block
|
39
|
+
end
|
40
|
+
|
31
41
|
|
32
42
|
private
|
33
43
|
|
@@ -45,11 +55,22 @@ module Mago
|
|
45
55
|
sexp_processor.process(sexp_node)
|
46
56
|
|
47
57
|
@report.files << file
|
58
|
+
@on_file.call(file) if @on_file
|
48
59
|
rescue Errno::ENOENT => err
|
49
|
-
|
50
|
-
rescue Racc::ParseError => err
|
60
|
+
handle_error(err.message)
|
61
|
+
rescue Racc::ParseError, Encoding::CompatibilityError => err
|
51
62
|
msg = "#{path} has invalid ruby code. " << err.message
|
52
|
-
|
63
|
+
handle_error(msg)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add error to report and call on_error callback if it's set.
|
67
|
+
#
|
68
|
+
# @param error [String]
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
def handle_error(error)
|
72
|
+
@on_error.call(error) if @on_error
|
73
|
+
@report.errors << error
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
data/lib/mago/version.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'mago command' do
|
4
|
+
# Run mago command. Return stdout and stderr.
|
4
5
|
def mago(args = '')
|
5
6
|
cmd = "cd #{FIXTURES_PATH} && #{MAGO_BIN} #{args}"
|
6
|
-
|
7
|
+
|
8
|
+
stdin, stdout, stderr, thread = Open3.popen3(cmd)
|
9
|
+
thread.join
|
10
|
+
|
11
|
+
[stdout.read, stderr.read]
|
7
12
|
end
|
8
13
|
|
14
|
+
|
15
|
+
|
9
16
|
describe 'arguments' do
|
10
17
|
it 'without arguments should look through ruby files in the current directory' do
|
11
|
-
|
18
|
+
stdout, stderr = mago('')
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
stdout.should include('./square.rb')
|
21
|
+
stdout.should include('./math/fibonacci.rb')
|
22
|
+
stderr.should include('./invalid.rb')
|
16
23
|
end
|
17
24
|
|
18
25
|
it 'when directory passed should inspect all ruby files inside' do
|
19
|
-
|
26
|
+
stdout, stderr = mago('./math/')
|
20
27
|
|
21
|
-
|
22
|
-
|
28
|
+
stdout.should include('./math/fibonacci.rb')
|
29
|
+
stdout.should_not include('square')
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
26
33
|
context 'ruby file with invalid syntax' do
|
27
34
|
it 'should report files with syntax errors' do
|
28
|
-
|
29
|
-
|
35
|
+
stdout, stderr = mago('./invalid.rb')
|
36
|
+
stderr.should include('ERROR: ./invalid.rb has invalid ruby code')
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
@@ -34,9 +41,10 @@ describe 'mago command' do
|
|
34
41
|
describe 'options' do
|
35
42
|
context 'without options' do
|
36
43
|
it 'should detect magic number except 0 and 1' do
|
37
|
-
mago('./square.rb')
|
38
|
-
|
39
|
-
|
44
|
+
stdout, stderr = mago('./square.rb')
|
45
|
+
|
46
|
+
stdout.should include("./square.rb:3 detected magic number 5\n")
|
47
|
+
stdout.should include("./square.rb:4 detected magic number 2\n")
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
@@ -45,8 +53,11 @@ describe 'mago command' do
|
|
45
53
|
expected = "./square.rb:3 detected magic number 5\n"\
|
46
54
|
"./square.rb:3 detected magic number 1\n"
|
47
55
|
|
48
|
-
mago('--ignore 0,2 ./square.rb')
|
49
|
-
|
56
|
+
stdout, stderr = mago('--ignore 0,2 ./square.rb')
|
57
|
+
stdout.should == expected
|
58
|
+
|
59
|
+
stdout, stderr = mago('-i 0,2 ./square.rb')
|
60
|
+
stdout.should == expected
|
50
61
|
end
|
51
62
|
end
|
52
63
|
end
|
@@ -56,8 +67,11 @@ describe 'mago command' do
|
|
56
67
|
expected = "./square.rb:3| radius = 5 - 1\n" \
|
57
68
|
"./square.rb:4| square = P * radius ** 2\n"
|
58
69
|
|
59
|
-
mago('--source ./square.rb')
|
60
|
-
|
70
|
+
stdout, stderr = mago('--source ./square.rb')
|
71
|
+
stdout.should == expected
|
72
|
+
|
73
|
+
stdout, stderr = mago('-s ./square.rb')
|
74
|
+
stdout.should == expected
|
61
75
|
end
|
62
76
|
end
|
63
77
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,8 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
3
|
require 'rspec'
|
4
4
|
require 'mago'
|
5
5
|
|
6
|
+
require 'open3'
|
7
|
+
|
6
8
|
# Requires supporting files with custom matchers and macros, etc,
|
7
9
|
# in ./support/ and its subdirectories.
|
8
10
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|