mago 0.0.5 → 0.1.0

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: d37b226405e663e2097987a53497f9be0203feb6
4
- data.tar.gz: 3fa69b1d2749e3d9cf2f86574a85f11318ddc255
3
+ metadata.gz: 4c74fb610902c60e56bb26d0b64eafa820c65fff
4
+ data.tar.gz: ff885d004ea58452cae383bb4f5a71d8bb15c0b9
5
5
  SHA512:
6
- metadata.gz: ef14e1c8a0a321b2b70ba99e29883e58850d5edb208bcb8f3921b83910e3259d2577714c18de06eb6724785f940f008f0d9d9800a58660654d78cb48799a578d
7
- data.tar.gz: 882f0ca028c606039c71e5893a570be4fdc2bc1d147f1fa0a60989564a833a9bf9f36ce07e4ea1c93252e002e68c59d9da7628b3dda05bf22cdb2019715bb2bc
6
+ metadata.gz: cd48970c17f3d583d8a07b43a68efbe8595786d3c2ab5f58813c9d5c8761cdc3d75faab3bd3667674c7b0c47ad46c9d56ad7d3ff3d084a56584d666bae1de5ef
7
+ data.tar.gz: c9bc80c552d2b09d507613ea4c10f6fa22388b2d8193034cd896d86cb094baef6f3d6313170b2aad2b6f14b6095c11c8f25e05a3765f1646b73e7c858f9628e2
@@ -1,7 +1,18 @@
1
1
  # Mago
2
2
 
3
- Tool to detect magic numbers in ruby code.
3
+ [![Build Status](https://travis-ci.org/greyblake/mago.png?branch=master)](https://travis-ci.org/greyblake/mago)
4
4
 
5
+ Magic numbers detector for Ruby source code.
6
+
7
+ ![Mago - magic numbers detector for Ruby](http://i1078.photobucket.com/albums/w484/greyblake/ruby-mago.png)
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
- * Add intro about magic numbers to README.
55
- * Create GIF with some famous probject to show how it works.
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
@@ -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(report, :color => @config.color)
80
+ formatter = formatter_class.new(:color => @config.color)
82
81
 
83
- puts formatter.format
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.
@@ -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(report, opts = {})
12
- @report = report
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
- @report.files.each do |file|
23
- format_file(file, out)
22
+ report.files.each do |file|
23
+ out << format_file(file, out)
24
24
  end
25
25
 
26
- @report.errors.each do |error|
27
- format_error(error, out)
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, out)
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, out)
65
- out << "ERROR: %s\n" % [error]
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, out)
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.
@@ -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
- @report.errors << err.message
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
- @report.errors << msg
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
@@ -1,4 +1,4 @@
1
1
  module Mago
2
2
  # :nodoc:
3
- VERSION = '0.0.5'
3
+ VERSION = '0.1.0'
4
4
  end
@@ -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
- %x"#{cmd}"
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
- output = mago('')
18
+ stdout, stderr = mago('')
12
19
 
13
- output.should include('./square.rb')
14
- output.should include('./math/fibonacci.rb')
15
- output.should include('./invalid.rb')
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
- output = mago('./math/')
26
+ stdout, stderr = mago('./math/')
20
27
 
21
- output.should include('./math/fibonacci.rb')
22
- output.should_not include('square')
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
- output = mago('./invalid.rb')
29
- output.should include('ERROR: ./invalid.rb has invalid ruby code')
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').should ==
38
- "./square.rb:3 detected magic number 5\n" \
39
- "./square.rb:4 detected magic number 2\n"
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').should == expected
49
- mago('-i 0,2 ./square.rb').should == expected
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').should == expected
60
- mago('-s ./square.rb').should == expected
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
@@ -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}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mago
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Potapov