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 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