fukuzatsu 0.9.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9049fb6f92f869e6d799c87e622079d696eb8f7b
4
+ data.tar.gz: 7e75d3585e1b60d3d557dec69d74afa14393b8f4
5
+ SHA512:
6
+ metadata.gz: f3f8382ccb36cc0acbf279213e59d38b3838279d66427a78be19ececa27ccb8b328e966c0990f43fd28bed8adeec8e418343661eb723c69a85e7c3fe85fc797b
7
+ data.tar.gz: 5c98337d7d5654c973fe0281802fd53f96569625bc8015bbb1ac904d0c3e3eb2c242023f466625b6181943a9cef7fedd8d3ec5a552053493d51401f540e886fc
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .console_history
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fukuzatsu.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bantik
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Fukuzatsu
2
+
3
+ Fukuzatsu ("complexity") is a tool for measuring code complexity. Its analysis is based on a cycomatic complexity algorithm.
4
+
5
+ You can learn more about cyclomatic complexity at http://en.wikipedia.org/wiki/Cyclomatic_complexity
6
+
7
+ Why should you care about this kind of complexity? More complex code tends to attract bugs and to increase the friction around extending features or refactoring code.
8
+
9
+ Fukuzatsu was inspired by Saikuro, written by Zev Blut.
10
+
11
+ ## Installation
12
+
13
+ Install the gem:
14
+
15
+ $ gem install fukuzatsu
16
+
17
+ This installs the CLI tool.
18
+
19
+ ## Usage
20
+
21
+ fuku parse path/to/file/my_file.rb
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/fuku ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fukuzatsu/cli'
3
+ Fukuzatsu::CLI.start
data/fukuzatsu.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fukuzatsu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fukuzatsu"
8
+ spec.version = Fukuzatsu::VERSION
9
+ spec.authors = ["Bantik"]
10
+ spec.email = ["coraline@idolhands.com"]
11
+ spec.summary = "A simple code complexity analyzer."
12
+ spec.description = "Calculates the cyclomatic complexity of methods within a given file."
13
+ spec.homepage = "https://gitlab.com/coraline/fukuzatsu"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "require_all"
22
+ spec.add_dependency "ephemeral"
23
+ spec.add_dependency "poro_plus"
24
+ spec.add_dependency "haml"
25
+ spec.add_dependency "parser"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.6"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "rspec"
30
+ spec.add_development_dependency "thor"
31
+
32
+ end
data/lib/fukuzatsu.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'require_all'
2
+ require 'ephemeral'
3
+ require 'poro_plus'
4
+ require 'fileutils'
5
+ require 'haml'
6
+
7
+ require_all './lib/fukuzatsu/'
8
+
9
+ module Fukuzatsu
10
+ end
@@ -0,0 +1,82 @@
1
+ require 'parser/current'
2
+
3
+ class Analyzer
4
+
5
+ CONDITIONALS = [:if]
6
+
7
+ attr_accessor :content, :class_name, :edges, :nodes, :exits
8
+
9
+ def initialize(content)
10
+ self.content = content
11
+ self.edges = 0
12
+ self.nodes = 1
13
+ self.exits = 1
14
+ end
15
+
16
+ def complexity
17
+ return unless traverse(parsed)
18
+ self.edges - self.nodes + exits
19
+ end
20
+
21
+ def extract_methods
22
+ @methods ||= methods_from(parsed)
23
+ end
24
+
25
+ def extract_class_name
26
+ return self.class_name if self.class_name
27
+ name = parsed.children.select{|node| node.type == :class}.first.loc.name
28
+ self.class_name = self.content[name.begin_pos..(name.end_pos - 1)]
29
+ end
30
+
31
+ private
32
+
33
+ def extend_graph
34
+ self.edges += 2
35
+ self.nodes += 2
36
+ self.exits += 1
37
+ end
38
+
39
+ def methods_from(node, methods=[])
40
+ if node.type == :def || node.type == :defs
41
+ name = node.loc.name
42
+ expression = node.loc.expression
43
+ methods << ParsedMethod.new(
44
+ name: content[name.begin_pos..name.end_pos - 1],
45
+ content: content[expression.begin_pos..expression.end_pos - 1],
46
+ type: node.type == :defs ? :class : :instance
47
+ )
48
+ end
49
+ node.children.each do |child|
50
+ if parent_node?(child)
51
+ methods_from(child, methods)
52
+ end
53
+ end
54
+ methods
55
+ end
56
+
57
+ def parent_node?(node)
58
+ node.respond_to?(:type) || node.respond_to?(:children)
59
+ end
60
+
61
+ def parse!
62
+ traverse(parsed) && complexity
63
+ end
64
+
65
+ def parsed
66
+ @parsed ||= Parser::CurrentRuby.parse(content)
67
+ end
68
+
69
+ def traverse(node, accumulator=[], extract_methods=false)
70
+ accumulator << node.type
71
+ extend_graph if CONDITIONALS.include?(node.type)
72
+ node.children.each do |child|
73
+ if parent_node?(child)
74
+ accumulator << child.type
75
+ traverse(child, accumulator)
76
+ end
77
+ end
78
+ accumulator
79
+ end
80
+
81
+ end
82
+
@@ -0,0 +1,24 @@
1
+ require 'thor'
2
+ require 'fukuzatsu'
3
+
4
+ module Fukuzatsu
5
+
6
+ class CLI < Thor
7
+
8
+ desc "parse PATH_TO_FILE -f FORMAT", "Formats are text (default, to STDOUT), html, and csv. Ex: parse foo.rb -f html"
9
+ method_option :format, :type => :string, :default => 'text', :aliases => "-f"
10
+ def parse(file)
11
+ file = ParsedFile.new(path_to_file: file)
12
+ case options['format']
13
+ when 'html'
14
+ Formatters::Html.new(file).export
15
+ when 'csv'
16
+ Formatters::Csv.new(file).export
17
+ else
18
+ Formatters::Text.new(file).export
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,44 @@
1
+ module Formatters
2
+
3
+ module Base
4
+
5
+ def self.included(klass)
6
+ klass.send(:attr_accessor, :file)
7
+ end
8
+
9
+ def initialize(file)
10
+ self.file = file
11
+ end
12
+
13
+ def content
14
+ [header, rows, footer].flatten.join("\r\n")
15
+ end
16
+
17
+ def columns
18
+ ["class", "method", "complexity"]
19
+ end
20
+
21
+ def output_path
22
+ output_path = "doc/fukuzatsu/#{self.file.path_to_file.split('/')[0..-2].join("/")}"
23
+ FileUtils.mkpath(output_path)
24
+ output_path
25
+ end
26
+
27
+ def filename
28
+ self.file.path_to_file.split('/')[-1] + file_extension
29
+ end
30
+
31
+ def export
32
+ begin
33
+ outfile = File.open("#{output_path}/#{filename}", 'w')
34
+ outfile.write(content)
35
+ rescue Exception => e
36
+ puts "Unable to write output: #{e} #{e.backtrace}"
37
+ ensure
38
+ outfile && outfile.close
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,27 @@
1
+ module Formatters
2
+
3
+ class Csv
4
+
5
+ include Formatters::Base
6
+
7
+ def header
8
+ columns.join(',')
9
+ end
10
+
11
+ def rows
12
+ file.methods.inject([]) do |a, method|
13
+ a << "#{file.class_name},#{method.prefix}#{method.name},#{method.complexity}"
14
+ a
15
+ end.join("\r\n")
16
+ end
17
+
18
+ def footer
19
+ end
20
+
21
+ def file_extension
22
+ ".csv"
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,50 @@
1
+ module Formatters
2
+
3
+ class Html
4
+
5
+ include Formatters::Base
6
+
7
+ def header
8
+ columns.map{|col| "<th>#{col.titleize}</th>"}.join("\r\n")
9
+ end
10
+
11
+ def content
12
+ Haml::Engine.new(template).render(Object.new, {
13
+ header: header,
14
+ rows: rows,
15
+ class_name: file.class_name,
16
+ path_to_file: file.path_to_file,
17
+ date: Time.now.strftime("%Y/%m/%d"),
18
+ time: Time.now.strftime("%l:%M %P")
19
+ }
20
+ )
21
+ end
22
+
23
+ def template
24
+ File.read(File.dirname(__FILE__) + "/templates/output.html.haml")
25
+ end
26
+
27
+ def rows
28
+ i = 0
29
+ file.methods.inject([]) do |a, method|
30
+ i += 1
31
+ a << "<tr class='#{i % 2 == 1 ? 'even' : 'odd'}'>"
32
+ a << " <td>#{file.class_name}</td>"
33
+ a << " <td>#{method.prefix}#{method.name}</td>"
34
+ a << " <td>#{method.complexity}</td>"
35
+ a << "</tr>"
36
+ a
37
+ end.join("\r\n")
38
+ end
39
+
40
+ def footer
41
+ end
42
+
43
+ def file_extension
44
+ ".htm"
45
+ end
46
+
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,44 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title
5
+ Fukuzatsu:
6
+ = class_name
7
+ %style{media: "screen", type: "text/css"}
8
+ body { background: #593232; color: #fff; font-family: arial, sans-serif; padding: 2em; }
9
+ table { border: 10px solid #000; border-collapse: collapse; min-width: 50%; }
10
+ tr { border-top: 1px solid #000; }
11
+ tr.header { background: rgba(255, 255, 255, 0.75)}
12
+ tr.even { background: rgba(128, 128, 128, 0.5);}
13
+ tr.odd { background: rgba(128, 128, 128, 0.25);}
14
+ th { background: #000; text-align: left; padding: .5em; text-transform: uppercase; font-size: .8em}
15
+ td { text-align: left; padding: .5em;}
16
+ td.center { text-align: center; }
17
+ tfoot { background: #000; border-top: 10px solid #000; font-family: courier; margin-top: 4em; font-size: .75em; }
18
+ a:link, a:visited { color: #aaa }
19
+ h1 { color:#593232; font-size: 1.25em; }
20
+ h2 { color:#593232; font-size: .75em; margin-top: -1em}
21
+ %body
22
+ %table
23
+ %thead
24
+ %tr.header
25
+ %td{colspan: 3}
26
+ %h1
27
+ = class_name
28
+ %h2
29
+ = path_to_file
30
+ %tr
31
+ = header
32
+ %tbody
33
+ = rows
34
+ %tfoot
35
+ %tr
36
+ %td.center{colspan: 3}
37
+ %em
38
+ Analyzed on
39
+ = date
40
+ at
41
+ = time
42
+ by
43
+ %a{href: "https://gitlab.com/coraline/fukuzatsu", target: "_new"}
44
+ Fukuzatsu
@@ -0,0 +1,27 @@
1
+ module Formatters
2
+
3
+ class Text
4
+
5
+ include Formatters::Base
6
+
7
+ def header
8
+ "#{file.class_name}\t\t#{file.complexity}"
9
+ end
10
+
11
+ def export
12
+ puts content
13
+ end
14
+
15
+ def rows
16
+ file.methods.map do |method|
17
+ "#{file.class_name}\t#{method.prefix}#{method.name}\t#{method.complexity}"
18
+ end
19
+ end
20
+
21
+ def footer
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,28 @@
1
+ class ParsedFile
2
+
3
+ include PoroPlus
4
+ include Ephemeral::Base
5
+
6
+ attr_accessor :path_to_file, :class_name
7
+
8
+ def class_name
9
+ @class_name ||= analyzer.extract_class_name
10
+ end
11
+
12
+ def content
13
+ @content ||= File.open(path_to_file, "r").read
14
+ end
15
+
16
+ def analyzer
17
+ Analyzer.new(content)
18
+ end
19
+
20
+ def complexity
21
+ @complexity ||= analyzer.complexity
22
+ end
23
+
24
+ def methods
25
+ @methods ||= analyzer.extract_methods
26
+ end
27
+
28
+ end
@@ -0,0 +1,17 @@
1
+ require 'parser/current'
2
+
3
+ class ParsedMethod
4
+
5
+ include PoroPlus
6
+
7
+ attr_accessor :name, :content, :type
8
+
9
+ def complexity
10
+ @complexity ||= Analyzer.new(content).complexity
11
+ end
12
+
13
+ def prefix
14
+ self.type == :class ? "." : "#"
15
+ end
16
+
17
+ end
@@ -0,0 +1,3 @@
1
+ module Fukuzatsu
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Analyzer do
4
+
5
+ let(:content_1) { File.read("spec/fixtures/program_1.rb") }
6
+ let(:content_2) { File.read("spec/fixtures/program_2.rb") }
7
+
8
+ context "program_1" do
9
+
10
+ let(:analyzer) { Analyzer.new(content_1) }
11
+
12
+ it "matches the manual calculation of complexity of 4" do
13
+ expect(analyzer.complexity).to eq(4)
14
+ end
15
+
16
+ end
17
+
18
+ context "program_2" do
19
+
20
+ let(:analyzer) { Analyzer.new(content_2) }
21
+
22
+ it "matches the manual calculation of complexity of 5" do
23
+ expect(analyzer.complexity).to eq(5)
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,19 @@
1
+ def spaghetti
2
+ if 1 < 5
3
+ p 'hi'
4
+ else
5
+ if 4 ==5
6
+ if 2 > 0
7
+ p 'bye'
8
+ else
9
+ p 'see ya'
10
+ end
11
+ else
12
+ if 2 > 0
13
+ p 'bye'
14
+ else
15
+ p 'see ya'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ def toppings
2
+
3
+ if rand(10) < 5
4
+ return "meatball"
5
+ end
6
+
7
+ if 1 < 5
8
+ return 'tomato'
9
+ else
10
+ if 4 ==5
11
+ if 2 > 0
12
+ return "parmesan"
13
+ else
14
+ return "romano"
15
+ end
16
+ else
17
+ if 2 > 0
18
+ return "alfredo"
19
+ else
20
+ return "gravy"
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,66 @@
1
+ require 'fukuzatsu'
2
+
3
+ class Breathalizer
4
+
5
+ INDICATORS = [
6
+ :if,
7
+ :def,
8
+ ]
9
+
10
+ attr_accessor :path_to_file, :edges, :nodes, :exits, :accumulator
11
+
12
+ def self.parse!(path_to_file)
13
+ new(path_to_file).parse
14
+ end
15
+
16
+ def initialize(path_to_file)
17
+ self.accumulator = []
18
+ self.edges = 0
19
+ self.nodes = 1
20
+ self.exits = 1
21
+ self.path_to_file = path_to_file
22
+ end
23
+
24
+ def file_contents
25
+ File.open(path_to_file, "r").read
26
+ end
27
+
28
+ def parsed
29
+ @parsed ||= Parser::CurrentRuby.parse(file_contents)
30
+ end
31
+
32
+ def parse!
33
+ traverse(parsed)
34
+ complexity
35
+ end
36
+
37
+ def traverse(node)#, accumulator=[])
38
+
39
+ accumulator << node.type
40
+
41
+ if node.type == :if || node.type == :begin
42
+ self.edges += 2
43
+ self.nodes += 2
44
+ self.exits += 1
45
+ elsif node.type == :def
46
+ self.edges += 1
47
+ self.nodes += 1
48
+ self.exits += 1
49
+ end
50
+
51
+ node.children.each do |child|
52
+ if child.respond_to?(:type) || child.respond_to?(:children)
53
+ accumulator << child.type
54
+ traverse(child, accumulator)
55
+ else
56
+ end
57
+ end
58
+ end
59
+
60
+ def complexity
61
+ p "edges = #{self.edges}, nodes = #{self.nodes}, exits = #{self.exits}"
62
+ self.edges - self.nodes + exits
63
+ end
64
+
65
+ end
66
+
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formatters::Csv do
4
+
5
+ let(:formatter) { Formatters::Csv.new }
6
+
7
+ describe "#header" do
8
+ it "outputs a header row" do
9
+ expect(formatter.header).to eq("class,method,complexity,lines")
10
+ end
11
+ end
12
+
13
+ describe "#rows" do
14
+
15
+ let(:expected) {
16
+ [
17
+ "Foo,baz,5,10",
18
+ "Foo,bat,15,100",
19
+ "Bar,gum,51,110",
20
+ "Bar,bun,55,101"
21
+ ]
22
+ }
23
+
24
+ let(:file_1) { ParsedFile.new(class_name: "Foo") }
25
+ let(:file_2) { ParsedFile.new(class_name: "Bar") }
26
+ let(:method_1) { ParsedMethod.new(method_name: "baz", complexity: 5, loc: 10)}
27
+ let(:method_2) { ParsedMethod.new(method_name: "bat", complexity: 15, loc: 100)}
28
+ let(:method_3) { ParsedMethod.new(method_name: "gum", complexity: 51, loc: 110)}
29
+ let(:method_4) { ParsedMethod.new(method_name: "bun", complexity: 55, loc: 101)}
30
+
31
+ before do
32
+ file_1.parsed_methods = [method_1, method_2]
33
+ file_2.parsed_methods = [method_3, method_4]
34
+ formatter.parsed_files = [file_1, file_2]
35
+ end
36
+
37
+ it "builds an array" do
38
+ expect(formatter.rows).to eq(expected)
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'fukuzatsu'
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fukuzatsu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Bantik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: require_all
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ephemeral
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: poro_plus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: haml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: parser
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: thor
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Calculates the cyclomatic complexity of methods within a given file.
140
+ email:
141
+ - coraline@idolhands.com
142
+ executables:
143
+ - fuku
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - bin/fuku
154
+ - fukuzatsu.gemspec
155
+ - lib/fukuzatsu.rb
156
+ - lib/fukuzatsu/analyzer.rb
157
+ - lib/fukuzatsu/cli.rb
158
+ - lib/fukuzatsu/formatters/base.rb
159
+ - lib/fukuzatsu/formatters/csv.rb
160
+ - lib/fukuzatsu/formatters/html.rb
161
+ - lib/fukuzatsu/formatters/templates/output.html.haml
162
+ - lib/fukuzatsu/formatters/text.rb
163
+ - lib/fukuzatsu/parsed_file.rb
164
+ - lib/fukuzatsu/parsed_method.rb
165
+ - lib/fukuzatsu/version.rb
166
+ - spec/analyzer_spec.rb
167
+ - spec/fixtures/program_1.rb
168
+ - spec/fixtures/program_2.rb
169
+ - spec/fixtures/program_3.rb
170
+ - spec/formatters/csv_spec.rb
171
+ - spec/spec_helper.rb
172
+ homepage: https://gitlab.com/coraline/fukuzatsu
173
+ licenses:
174
+ - MIT
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.2.2
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: A simple code complexity analyzer.
196
+ test_files:
197
+ - spec/analyzer_spec.rb
198
+ - spec/fixtures/program_1.rb
199
+ - spec/fixtures/program_2.rb
200
+ - spec/fixtures/program_3.rb
201
+ - spec/formatters/csv_spec.rb
202
+ - spec/spec_helper.rb