iosappaudit 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '020928007442acd4e62981306e047324cd18bbae4639a3abfa989d2451fb68e2'
4
+ data.tar.gz: eae2e1627e5f9e20f74cb99ae865b75fb6919a660545a92313557781aafe2358
5
+ SHA512:
6
+ metadata.gz: 74575f011ea5d86e3d027901e84155d34fcd9cc1b74ffddc1d4ba0ca29bb01efa6cb6cb5e82b1afce0e1fd9e9225b90c7549837ed9c1ecd7569b016e23ddf45c
7
+ data.tar.gz: bf7062f0c587b10604320744d7b81b4ad04a5a56c2ac817b1af0999ed94f835755dc6c3e6bb2ee52ec3d4e1fd00ea4052e3f630c623859c6009ba3617764633b
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in iosappaudit.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "iosappaudit"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ project_url: "" # required
2
+ sources_url: "" # required
3
+ xcodeproj:
4
+ name: "" # first xcodeproj found will be used if empty
5
+ main_target_name: "" # first target will be used if empty
6
+ complexity:
7
+ file_line_count_threshold: 500
8
+ output_format:
9
+ adds_row_padding: true
10
+ size: 0
11
+ csv_output: audit.csv
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require 'iosappaudit'
@@ -0,0 +1,35 @@
1
+ section:
2
+ project:
3
+ title: Project
4
+ row:
5
+ name: Name
6
+ version: Version
7
+ deployment_target: Deployment Target
8
+ localizations: Localizations
9
+ settings:
10
+ title: Settings
11
+ row:
12
+ schemes: Schemes
13
+ targets: Targets
14
+ configurations: Configurations
15
+ complexity:
16
+ title: Code
17
+ row:
18
+ file_count: Files
19
+ file_count_threshold: !!pl
20
+ 1: Files with more than one line
21
+ n: Files with more than %1 lines
22
+ swift_file_count: Swift files
23
+ obj_c_file_count: Objective C files
24
+ code_line_count: Lines of code
25
+ ccn_line_count: Cyclomatic Complexity Number
26
+ resources:
27
+ title: Resources
28
+ row:
29
+ xib_count: Xibs
30
+ storyboards: Storyboards
31
+ tests:
32
+ title: Tests
33
+ row:
34
+ unit_tests: Unit Tests
35
+ ui_tests: UI Tests
@@ -0,0 +1,43 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "iosappaudit/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'iosappaudit'
8
+ s.version = IOSAppAudit::VERSION
9
+ s.date = '2019-01-23'
10
+ s.summary = "Audit"
11
+ s.description = "Audit"
12
+ s.authors = ["Gaétan Zanella"]
13
+ s.email = 'gaetan.zanella@gmail.com'
14
+ # use `git ls-files -coz -x *.gem` for development
15
+
16
+ s.homepage = 'http://rubygems.org/gems/hola'
17
+ s.license = 'MIT'
18
+ s.add_dependency "xcodeproj", "~> 1.4"
19
+ s.add_dependency "r18n-core", "~> 3.2"
20
+ s.add_dependency "colorize", "~> 0.8"
21
+ s.add_development_dependency "byebug", "~> 10.0"
22
+
23
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
24
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
25
+ if s.respond_to?(:metadata)
26
+ s.metadata["allowed_push_host"] = "https://rubygems.org"
27
+ s.metadata["homepage_uri"] = s.homepage
28
+ s.metadata["source_code_uri"] = "https://github.com/faberNovel/iosappaudit"
29
+ s.metadata["changelog_uri"] = "https://github.com/faberNovel/iosappaudit/blob/master/CHANGELOG.md"
30
+ else
31
+ raise "RubyGems 2.0 or newer is required to protect against " \
32
+ "public gem pushes."
33
+ end
34
+
35
+ # Specify which files should be added to the gem when it is released.
36
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
37
+ s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
38
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
39
+ end
40
+ s.bindir = "exe"
41
+ s.executables = ["iosappaudit"]
42
+ s.require_paths = ["lib"]
43
+ end
@@ -0,0 +1,37 @@
1
+ require 'optparse'
2
+ require 'xcodeproj'
3
+ require 'rexml/document'
4
+ require 'r18n-core'
5
+ require 'CSV'
6
+ require 'yaml'
7
+ require 'JSON'
8
+ require 'fileutils'
9
+ require 'colorize'
10
+
11
+ require_relative "iosappaudit/Review/complexity_report.rb"
12
+ require_relative "iosappaudit/Review/complexity_report_parser.rb"
13
+ require_relative "iosappaudit/Review/complexity_reviewer.rb"
14
+ require_relative "iosappaudit/Review/project_report.rb"
15
+ require_relative "iosappaudit/Review/project_reviewer.rb"
16
+ require_relative "iosappaudit/Helper/file_seeker.rb"
17
+ require_relative "iosappaudit/Helper/options_parser.rb"
18
+ require_relative "iosappaudit/Presenter/CSVReportPresenter.rb"
19
+
20
+ options = {}
21
+ OptionParser.new do |parser|
22
+ parser.on("-o", "--option=URL") do |url|
23
+ options[:url] = url
24
+ end
25
+ end.parse!
26
+
27
+ properties_parser = Helper::OptionsParser.new
28
+ properties = properties_parser.parse options
29
+
30
+ complexity_reviewer = Review::ComplexityReviewer.new
31
+ complexity_report = complexity_reviewer.review_folder properties
32
+
33
+ project_reviewer = Review::ProjectReviewer.new
34
+ project_report = project_reviewer.review_folder properties
35
+
36
+ presenter = Presenter::CSVReportPresenter.new properties, project_report, complexity_report
37
+ presenter.generate_review
@@ -0,0 +1,20 @@
1
+ module Helper
2
+ class FileSeeker
3
+
4
+ def initialize()
5
+ end
6
+
7
+
8
+ def find_files(url, name, extension)
9
+ Dir.glob("#{url}/**/#{name}.#{extension}")
10
+ end
11
+
12
+ def find_files_with_extension(url, extension)
13
+ Dir.glob("#{url}/**/*.#{extension}")
14
+ end
15
+
16
+ def find_file_names_with_extension(url, extension)
17
+ find_files_with_extension(url, extension).map { |url| File.basename(url) }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Helper
2
+ class OptionsParser
3
+ def parse(options)
4
+ default_properties = JSON.parse(YAML::load_file(__dir__ + "/../../../default_configuration.yaml").to_json, object_class: Hash)
5
+ properties = JSON.parse(YAML::load_file(options[:url]).to_json, object_class: Hash)
6
+ default_properties.merge! properties
7
+ symbolizeOptions default_properties
8
+ end
9
+
10
+ def symbolizeOptions(options)
11
+ options.inject({}) { |new_hash, key_value|
12
+ key, value = key_value
13
+ value = symbolizeOptions(value) if value.is_a?(Hash)
14
+ new_hash[key.to_sym] = value
15
+ new_hash
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,94 @@
1
+ include R18n::Helpers
2
+
3
+ module Presenter
4
+ class CSVReportPresenter
5
+
6
+ def initialize(options, project_report, complexity_report)
7
+ @project_report = project_report
8
+ @complexity_report = complexity_report
9
+ @options = options
10
+ root = File.expand_path '../../..', File.dirname(__FILE__)
11
+ R18n.default_places = "#{root}/i18n/"
12
+ R18n.set('en')
13
+ end
14
+
15
+ def generate_review
16
+ puts "Generating csv review..."
17
+ url = @options[:csv_output]
18
+ CSV.open(url, "wb") do |csv|
19
+ # Project
20
+ csv << section(t.section.project.title)
21
+ csv << value_row(t.section.project.row.name, @project_report.name)
22
+ csv << value_row(t.section.project.row.version, @project_report.version)
23
+ csv << value_row(t.section.project.row.deployment_target, @project_report.deployment_target.first)
24
+ csv << array_row(t.section.project.row.localizations, @project_report.localizations)
25
+ # Settings
26
+ csv << section(t.section.settings.title)
27
+ csv << array_row(t.section.settings.row.targets, @project_report.target_names)
28
+ csv << array_row(t.section.settings.row.configurations, @project_report.configuration_names)
29
+ # Complexity
30
+ csv << section(t.section.complexity.title)
31
+ csv << array_row(t.section.complexity.row.file_count, @project_report.main_target_files)
32
+ csv << array_row(t.section.complexity.row.swift_file_count, @project_report.main_target_swift_files)
33
+ csv << array_row(t.section.complexity.row.obj_c_file_count, @project_report.main_target_obj_c_files)
34
+ csv << value_row(t.section.complexity.row.code_line_count, @complexity_report.file_measure.sum_ncss)
35
+ file_line_count_threshold = @options[:complexity][:file_line_count_threshold]
36
+ metrics_ncss = @complexity_report.file_metrics_with_more_than_count_lines @options[:complexity][:file_line_count_threshold]
37
+ csv << array_row(t.section.complexity.row.file_count_threshold(file_line_count_threshold), format_ncss(metrics_ncss))
38
+ metrics_ccn = @complexity_report.file_metrics_sorted_by_ccn
39
+ csv << value_row(t.section.complexity.row.ccn_line_count, @complexity_report.file_measure.sum_ccn, format_ccn(metrics_ccn))
40
+ # Resources
41
+ csv << section(t.section.resources.title)
42
+ csv << array_row(t.section.resources.row.xib_count, @project_report.xibs)
43
+ csv << array_row(t.section.resources.row.storyboards, @project_report.storyboards)
44
+ # Tests
45
+ csv << section(t.section.tests.title)
46
+ csv << array_row(t.section.tests.row.unit_tests, @project_report.unit_test_target_files)
47
+ csv << array_row(t.section.tests.row.ui_tests, @project_report.ui_test_target_files)
48
+ end
49
+ puts "Report #{url} created 🎉".colorize(:green)
50
+ end
51
+
52
+ def section(title)
53
+ return [title]
54
+ end
55
+
56
+ def value_row(title, value, detail=[])
57
+ if value.nil?
58
+ return format_row [title, detail]
59
+ end
60
+ format_row [title, value, format_array(detail)]
61
+ end
62
+
63
+ def array_row(title, array)
64
+ if array.nil?
65
+ return [title, 0]
66
+ end
67
+ return format_row [title, array.count, format_array(array)]
68
+ end
69
+
70
+ def format_row(array)
71
+ if @options[:output_format][:adds_row_padding]
72
+ array.unshift("")
73
+ end
74
+ array
75
+ end
76
+
77
+ def format_array(array)
78
+ size = @options[:output_format][:size]
79
+ output = array.first(size).join("\n")
80
+ if array.count > size
81
+ output += "\n..."
82
+ end
83
+ output
84
+ end
85
+
86
+ def format_ncss(metrics)
87
+ metrics.map { |metric| "(#{metric.ncss}) #{metric.file_url}" }
88
+ end
89
+
90
+ def format_ccn(metrics)
91
+ metrics.map { |metric| "(#{metric.ccn}) #{metric.file_url}" }
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,70 @@
1
+ module Review
2
+ class FunctionMetric
3
+
4
+ attr_accessor :file_url, :function_name, :line_number, :ncss, :ccn
5
+
6
+ def initialize(file_url = "", function_name = "", line_number = 0, ncss = 0, ccn = 0)
7
+ @file_url = file_url
8
+ @function_name = function_name
9
+ @line_number = line_number
10
+ @ncss = ncss
11
+ @ccn = ccn
12
+ end
13
+ end
14
+
15
+ class FileMetric
16
+
17
+ attr_accessor :file_url, :ncss, :ccn, :functions
18
+
19
+ def initialize(file_url = "", ncss = 0, ccn = 0, functions = 0)
20
+ @file_url = file_url
21
+ @ncss = ncss
22
+ @ccn = ccn
23
+ @functions = functions
24
+ end
25
+ end
26
+
27
+ class FunctionMeasure
28
+
29
+ attr_accessor :metrics, :average_ncss, :average_ccn
30
+
31
+ def initialize(metrics = [], average_ncss = 0, average_ccn = 0)
32
+ @metrics = metrics
33
+ @average_ncss = average_ncss
34
+ @average_ccn = average_ccn
35
+ end
36
+ end
37
+
38
+ class FileMeasure
39
+
40
+ attr_accessor :metrics, :average_ncss, :average_ccn, :average_functions, :sum_ncss, :sum_ccn, :sum_functions
41
+
42
+ def initialize(metrics = [], average_ncss = 0, average_ccn = 0, average_functions = 0, sum_ncss = 0, sum_ccn = 0, sum_functions = 0)
43
+ @metrics = metrics
44
+ @average_ncss = average_ncss
45
+ @average_ccn = average_ccn
46
+ @average_functions = average_functions
47
+ @sum_ncss = sum_ncss
48
+ @sum_ccn = sum_ccn
49
+ @sum_functions = sum_functions
50
+ end
51
+ end
52
+
53
+ class ComplexityReport
54
+
55
+ attr_accessor :function_measure, :file_measure
56
+
57
+ def initialize(function_measure = [], file_measure = [])
58
+ @function_measure = function_measure
59
+ @file_measure = file_measure
60
+ end
61
+
62
+ def file_metrics_with_more_than_count_lines(count)
63
+ file_measure.metrics.select { |metric| metric.ncss >= count }.sort { |lhs, rhs| (lhs.ncss <=> rhs.ncss) * -1 }
64
+ end
65
+
66
+ def file_metrics_sorted_by_ccn
67
+ file_measure.metrics.sort { |lhs, rhs| (lhs.ccn <=> rhs.ccn) * -1 }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,50 @@
1
+ include REXML
2
+
3
+ module Review
4
+ class ComplexityReportParser
5
+
6
+ def initialize()
7
+ end
8
+
9
+ def parse_file(url)
10
+ file = File.new url
11
+ doc = Document.new file
12
+
13
+ function_measure = FunctionMeasure.new
14
+ file_measure = FileMeasure.new
15
+
16
+ function_xml = doc.root.elements["measure[@type='Function']"]
17
+ function_measure.average_ncss = function_xml.elements["average[@label='NCSS']"]["value"].to_s.to_f
18
+ function_measure.average_ccn = function_xml.elements["average[@label='CCN']"]["value"].to_s.to_f
19
+ function_xml.elements.each("item") do |item|
20
+ values = item.get_elements("value")
21
+ item_name = item.attributes["name"]
22
+ metric = FunctionMetric.new
23
+ metric.file_url = /(?<=( at )).+(?=:)/.match(item_name).to_s
24
+ metric.function_name = /.+(?=\(...\))/.match(item_name).to_s
25
+ metric.line_number = /(?<=:)\d+/.match(item_name).to_s.to_i
26
+ metric.ncss = values[1].text.to_i
27
+ metric.ccn = values[2].text.to_i
28
+ function_measure.metrics.push metric
29
+ end
30
+
31
+ file_xml = doc.root.elements["measure[@type='File']"]
32
+ file_measure.average_ncss = file_xml.elements["average[@label='NCSS']"]["value"].to_s.to_f
33
+ file_measure.average_ccn = file_xml.elements["average[@label='CCN']"]["value"].to_s.to_f
34
+ file_measure.average_functions = file_xml.elements["average[@label='Functions']"]["value"].to_s.to_f
35
+ file_measure.sum_ncss = file_xml.elements["sum[@label='NCSS']"]["value"].to_s.to_i
36
+ file_measure.sum_ccn = file_xml.elements["sum[@label='CCN']"]["value"].to_s.to_i
37
+ file_measure.sum_functions = file_xml.elements["sum[@label='Functions']"]["value"].to_s.to_i
38
+ file_xml.elements.each("item") do |item|
39
+ values = item.get_elements("value")
40
+ metric = FileMetric.new
41
+ metric.file_url = item.attributes["name"].to_s
42
+ metric.ncss = values[1].text.to_i
43
+ metric.ccn = values[2].text.to_i
44
+ metric.functions = values[3].text.to_i
45
+ file_measure.metrics.push metric
46
+ end
47
+ ComplexityReport.new function_measure, file_measure
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,18 @@
1
+ module Review
2
+ class ComplexityReviewer
3
+
4
+ def initialize()
5
+ end
6
+
7
+ def review_folder(options)
8
+ puts "Reviewing source complexity... "
9
+ lizard_report = "lizard-report.xml"
10
+ source = options[:sources_url]
11
+ `lizard -m --xml #{source} > #{lizard_report}`
12
+ parser = ComplexityReportParser.new
13
+ report = parser.parse_file lizard_report
14
+ FileUtils.rm lizard_report
15
+ report
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ module Review
2
+ class ProjectReport
3
+ attr_accessor :name, :version, :deployment_target, :target_names, :configuration_names, :main_target_name, :main_target_files, :main_target_resources, :ui_test_target_name, :unit_test_target_name, :ui_test_target_files, :unit_test_target_files, :localizations
4
+
5
+ def initialize
6
+ @name = ""
7
+ @version = ""
8
+ @deployment_target = ""
9
+ @target_names = ""
10
+ @configuration_names = ""
11
+ @main_target_name = ""
12
+ @main_target_files = []
13
+ @main_target_resources = []
14
+ @ui_test_target_name = ""
15
+ @unit_test_targe_name = ""
16
+ @ui_test_target_files = []
17
+ @unit_test_target_files = []
18
+ @localizations = []
19
+ end
20
+
21
+ def main_target_swift_files
22
+ main_target_files.select { |file| file.include?(".swift") }
23
+ end
24
+
25
+ def main_target_obj_c_files
26
+ main_target_files.select { |file| file.include?(".m") }
27
+ end
28
+
29
+ def has_swift_files?
30
+ main_target_swift_files.empty?
31
+ end
32
+
33
+ def has_obj_c_files?
34
+ main_target_obj_c_files.empty?
35
+ end
36
+
37
+ def xibs
38
+ main_target_resources.select { |file| file.include?(".xib") }
39
+ end
40
+
41
+ def storyboards
42
+ main_target_resources.select { |file| file.include?(".storyboard") }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,61 @@
1
+ module Review
2
+ class ProjectReviewer
3
+
4
+ def initialize()
5
+ end
6
+
7
+ def review_folder(options)
8
+ file_seeker = Helper::FileSeeker.new
9
+ url = options[:project_url]
10
+ project_name = options[:xcodeproj][:name]
11
+ urls = []
12
+ if project_name.empty?
13
+ urls = file_seeker.find_files_with_extension url, "xcodeproj"
14
+ else
15
+ urls = file_seeker.find_files url, project_name, "xcodeproj"
16
+ end
17
+ if urls.empty?
18
+ raise "Xcode project not found"
19
+ end
20
+ report = ProjectReport.new
21
+ project = Xcodeproj::Project.open urls.first
22
+ project_basename = File.basename(urls.first)
23
+ puts "Reviewing #{project_basename}..."
24
+ root_object = project.root_object
25
+ if root_object.targets.empty?
26
+ raise "Xcode project #{root_object.name} has no target"
27
+ end
28
+ report.name = root_object.name
29
+ report.deployment_target = root_object.targets.map { |target| target.deployment_target }.uniq
30
+ report.target_names = root_object.targets.map &:name
31
+ report.configuration_names = root_object.targets.flat_map { |target| target.build_configurations.map(&:name) }.uniq
32
+ report.localizations = findLocalizations project
33
+ main_target_name = options[:xcodeproj][:main_target_name]
34
+ main_target = nil
35
+ if main_target_name.empty?
36
+ main_target = root_object.targets[0]
37
+ else
38
+ main_target = root_object.targets.detect { |target| target.name == main_target_name }
39
+ if main_target.nil?
40
+ raise "Xcode target named #{main_target_name} not found"
41
+ end
42
+ end
43
+ report.version = project.build_configurations.map { |config| config.build_settings["CURRENT_PROJECT_VERSION"] }.uniq.first
44
+ ui_test_target = root_object.targets.detect { |target| target.build_configurations.any? { |config| !config.build_settings["TEST_TARGET_NAME"].nil? } }
45
+ unit_test_target = root_object.targets.detect { |target| target.build_configurations.any? { |config| !config.build_settings["TEST_HOST"].nil? } }
46
+ report.main_target_name = main_target&.name
47
+ report.main_target_files = main_target&.source_build_phase&.files&.map { |file| file.display_name }
48
+ report.main_target_resources = main_target&.resources_build_phase&.files&.map { |file| file.display_name }
49
+ report.ui_test_target_name = ui_test_target&.name
50
+ report.unit_test_target_name = unit_test_target&.name
51
+ report.ui_test_target_files = ui_test_target&.source_build_phase&.files&.map { |file| file.display_name }
52
+ report.unit_test_target_files = unit_test_target&.source_build_phase&.files&.map { |file| file.display_name }
53
+ return report
54
+ end
55
+
56
+ def findLocalizations(project)
57
+ files = project.files.select { |f| f.path.include?("Localizable.strings") }
58
+ files.map { |f| f.name.nil? ? "base" : f.name }.uniq
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module IOSAppAudit
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iosappaudit
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gaétan Zanella
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-01-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xcodeproj
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: r18n-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Audit
70
+ email: gaetan.zanella@gmail.com
71
+ executables:
72
+ - iosappaudit
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - Rakefile
79
+ - bin/console
80
+ - bin/setup
81
+ - default_configuration.yaml
82
+ - exe/iosappaudit
83
+ - i18n/en.yml
84
+ - iosappaudit.gemspec
85
+ - lib/iosappaudit.rb
86
+ - lib/iosappaudit/Helper/file_seeker.rb
87
+ - lib/iosappaudit/Helper/options_parser.rb
88
+ - lib/iosappaudit/Presenter/CSVReportPresenter.rb
89
+ - lib/iosappaudit/Review/complexity_report.rb
90
+ - lib/iosappaudit/Review/complexity_report_parser.rb
91
+ - lib/iosappaudit/Review/complexity_reviewer.rb
92
+ - lib/iosappaudit/Review/project_report.rb
93
+ - lib/iosappaudit/Review/project_reviewer.rb
94
+ - lib/iosappaudit/version.rb
95
+ homepage: http://rubygems.org/gems/hola
96
+ licenses:
97
+ - MIT
98
+ metadata:
99
+ allowed_push_host: https://rubygems.org
100
+ homepage_uri: http://rubygems.org/gems/hola
101
+ source_code_uri: https://github.com/faberNovel/iosappaudit
102
+ changelog_uri: https://github.com/faberNovel/iosappaudit/blob/master/CHANGELOG.md
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubygems_version: 3.0.3
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Audit
122
+ test_files: []