alcove 0.1.0 → 0.2.0.pre.alpha.pre.36
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +21 -3
- data/bin/alcove +107 -44
- data/lib/alcove.rb +90 -102
- data/lib/alcove/version.rb +1 -1
- metadata +27 -13
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZmM2NTQyZDc5OGEyNGY5YjQ5YTFkMWRjODc1OTdlODg2MWJjOWMxZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NmMyYzI1NTM1ZmE0NDFkZDg1YjQ5M2QwMmRmMWYxNjI5NTJlY2U1OA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDM3YjY3Yjg1MzNlNTllYzMwMTY5N2Q0YTc4NGEyM2VhYjk4Yzg0NmFkNGVm
|
10
|
+
ZWEzMmMzNDY4YTJjZDEzZWQ2M2E2ZjAzMWU2MTc2MGJhNjk5ZjEyYjY2NzZl
|
11
|
+
NGM1ZmRhZWU3NGEyYmI4N2NmZDYzOGYwMjMxMjI5NThjNzgyNDc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZjVmOTRiN2JmOTE5M2ExMjY1NWM2ZjZlZmI1NTA1YzdhY2I3MWY0YTQyYTll
|
14
|
+
NTE1YTA4M2NmMmE5NjI2YmQ4OWVhNDI4MDUwMWE2ZmFjYzFhMDgyNmEwYTEw
|
15
|
+
MzVkNWJjYzQ5ZWIzYTE0ODk3MWZhNzM4MGVjMzExMmMxZDk5Y2Q=
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Alcove [![Build Status](https://travis-ci.org/ioveracker/Alcove.svg?branch=master)](https://travis-ci.org/ioveracker/Alcove)
|
1
|
+
# Alcove [![Gem Version](https://badge.fury.io/rb/alcove.svg)](http://badge.fury.io/rb/alcove) [![Build Status](https://travis-ci.org/ioveracker/Alcove.svg?branch=master)](https://travis-ci.org/ioveracker/Alcove) [![Code Climate](https://codeclimate.com/github/ioveracker/Alcove/badges/gpa.svg)](https://codeclimate.com/github/ioveracker/Alcove)
|
2
2
|
Painless code coverage reporting for Objective-C projects. Most of the heavy lifting is done by the venerable lcov. Alcove simply searches the nooks and crannies to collect the data needed to generate the report and ties everything together for you. Best of all, it's a gem with minimal depedencies, so installation is quick and painless.
|
3
3
|
|
4
4
|
## Installation
|
5
5
|
|
6
|
-
$
|
6
|
+
$ gem install alcove
|
7
7
|
|
8
8
|
If you don't have it already, you'll also need to install lcov.
|
9
9
|
|
@@ -16,7 +16,8 @@ If you don't have it already, you'll also need to install lcov.
|
|
16
16
|
$ sudo port install lcov
|
17
17
|
|
18
18
|
## Xcode Project Configuration
|
19
|
-
If you haven't already, open your project in Xcode and update your
|
19
|
+
If you haven't already, open your project in Xcode and update your non-test targets to Generate Test Coverage Files and Instrument Program Flow (*for Debug configuration only*).
|
20
|
+
![Xcode](http://i.imgur.com/xdcg4er.png?1)
|
20
21
|
|
21
22
|
## Generating Reports
|
22
23
|
Now that you have the prerequisites out of the way, you can generate a report. Make sure you've recently executed your tests, then:
|
@@ -24,3 +25,20 @@ Now that you have the prerequisites out of the way, you can generate a report.
|
|
24
25
|
alcove --product-name <your-product-name>
|
25
26
|
|
26
27
|
Be sure to check out the --help for additional options for fine-tuning your report.
|
28
|
+
|
29
|
+
## Options
|
30
|
+
|
31
|
+
### --output-directory
|
32
|
+
Specify this option to change the output directory for the report. Any intermediate paths will be created.
|
33
|
+
|
34
|
+
### --product-name
|
35
|
+
The product name specified in your Xcode project.
|
36
|
+
|
37
|
+
### --remove-filter
|
38
|
+
A list of filters to use when gathering files for the report. Use this if you want to exclude certain files from the report. For example: `alcove --product-name SampleProduct --remove-filter *.h,main.m` will exclude header files and the main.m file from the report.
|
39
|
+
|
40
|
+
### --search-directory
|
41
|
+
Use this option to specify the directory to be searched for your product. Alcove plays nicely with the the structure on your development machine, as well as on an Xcode Server, but if you have some funky output directory for your build, you can specify its parent here.
|
42
|
+
|
43
|
+
## Attribution
|
44
|
+
Shoutout to [@NateBank](https://github.com/NateBank) for the [name suggestion](https://www.youtube.com/watch?v=j1Q-a5zCmhc).
|
data/bin/alcove
CHANGED
@@ -7,62 +7,125 @@ require 'optparse'
|
|
7
7
|
|
8
8
|
options = OpenStruct.new
|
9
9
|
OptionParser.new do |opts|
|
10
|
-
|
10
|
+
opts.banner = "Usage: alcove --product-name <product-name> [options]"
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
opts.on("-h", "--help", "Displays the help screen") do
|
13
|
+
puts opts
|
14
|
+
exit
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
options.output_directory = "alcove-report"
|
18
|
+
opts.on("-o", "--output-directory DIR", "Place report in DIR instead of default") do |o|
|
19
|
+
options.output_directory = o
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
22
|
+
opts.on("--percent-file", "Generate a file containing coverage percent") do |p|
|
23
|
+
options.generate_percent_file = true
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
options.product_name = ""
|
27
|
+
opts.on("-p", "--product-name NAME", "The name of your product") do |p|
|
28
|
+
options.product_name = p
|
29
|
+
end
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
options.remove_filter = []
|
32
|
+
opts.on("-r", "--remove-filter X,Y,Z...", ::Array, "A list of filters (e.g. *.h,main.m)") do |r|
|
33
|
+
options.remove_filter = r
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
36
|
+
opts.on("-s", "--search-directory DIR", "Search in DIR for coverage files") do |s|
|
37
|
+
options.search_directory = s
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
options.verbose = false
|
41
|
+
opts.on("-v", "--verbose", "Output additional information") do
|
42
|
+
options.verbose = true
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
opts.on_tail("--version", "Show version") do
|
46
|
+
puts Alcove::VERSION
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
opts.parse!(ARGV)
|
52
|
+
if options.product_name.length == 0
|
53
|
+
STDERR.puts "--product-name is required".yellow
|
54
|
+
puts opts
|
55
|
+
exit(1)
|
57
56
|
end
|
57
|
+
rescue OptionParser::InvalidOption => e
|
58
|
+
puts e
|
59
|
+
puts opts
|
60
|
+
exit(1)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def exit_with_code(code)
|
65
|
+
FileUtils.rm_rf(Alcove::TEMP_DIR)
|
66
|
+
exit(code)
|
58
67
|
end
|
59
68
|
|
60
69
|
alcoveOptions = OpenStruct.new
|
61
|
-
alcoveOptions.output_directory = options.output_directory
|
62
|
-
alcoveOptions.product_name = options.product_name
|
63
|
-
alcoveOptions.remove_filter = options.remove_filter
|
64
|
-
alcoveOptions.search_directory = options.search_directory
|
65
70
|
alcoveOptions.verbose = options.verbose
|
66
71
|
|
67
72
|
alcove = Alcove.new(alcoveOptions)
|
68
|
-
|
73
|
+
puts " 🔍 Generating report..."
|
74
|
+
|
75
|
+
FileUtils.rm_rf(Alcove::TEMP_DIR)
|
76
|
+
FileUtils.mkdir(Alcove::TEMP_DIR)
|
77
|
+
|
78
|
+
if options.search_directory
|
79
|
+
search_directory = options.search_directory
|
80
|
+
else
|
81
|
+
search_directory = alcove.get_search_directory
|
82
|
+
end
|
83
|
+
alcove.copy_input_files_to_temp(search_directory, options.product_name)
|
84
|
+
|
85
|
+
gi_filename_absolute = File.join(Alcove::TEMP_DIR, "alcove-info.temp")
|
86
|
+
gen_success = alcove.gen_info_files(gi_filename_absolute)
|
87
|
+
if gen_success
|
88
|
+
puts " ✅ geninfo successful".green if options.verbose
|
89
|
+
else
|
90
|
+
STDERR.puts " 🚫 geninfo failed!".red
|
91
|
+
exit_with_code(1)
|
92
|
+
end
|
93
|
+
|
94
|
+
lcov_filename_absolute = File.join(Alcove::TEMP_DIR, "alcove-lcov.info")
|
95
|
+
lcov_success = alcove.lcov(gi_filename_absolute, options.remove_filter, lcov_filename_absolute)
|
96
|
+
if lcov_success
|
97
|
+
puts " ✅ lcov successful".green if options.verbose
|
98
|
+
else
|
99
|
+
STDERR.puts " 🚫 lcov failed!".red
|
100
|
+
exit_with_code(1)
|
101
|
+
end
|
102
|
+
|
103
|
+
genhtml_success, coverage_percent = alcove.genhtml(lcov_filename_absolute, options.output_directory)
|
104
|
+
if genhtml_success
|
105
|
+
puts "" if options.verbose
|
106
|
+
puts " ✅ Successfully generated report".green
|
107
|
+
|
108
|
+
coverage_string = " 📊 Line coverage: #{coverage_percent}%"
|
109
|
+
if coverage_percent < 50
|
110
|
+
puts coverage_string.red
|
111
|
+
elsif coverage_percent < 85
|
112
|
+
puts coverage_string.yellow
|
113
|
+
else
|
114
|
+
puts coverage_string.green
|
115
|
+
end
|
116
|
+
|
117
|
+
puts " 🍻 Open #{options.output_directory}/index.html to view the report"
|
118
|
+
|
119
|
+
else
|
120
|
+
STDERR.puts " 🚫 genhtml failed!".red
|
121
|
+
exit_with_code(1)
|
122
|
+
end
|
123
|
+
|
124
|
+
if options.generate_percent_file
|
125
|
+
File.open("#{options.output_directory}/alcove-percent.txt", 'w') {|f|
|
126
|
+
f.write(coverage_percent)
|
127
|
+
}
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
exit_with_code(0)
|
data/lib/alcove.rb
CHANGED
@@ -4,110 +4,98 @@ require 'find'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'ostruct'
|
6
6
|
require 'optparse'
|
7
|
+
require 'open3'
|
7
8
|
|
8
9
|
class Alcove
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
TEMP_DIR = "alcove-temp"
|
11
|
+
# Public: Initializes a new instance.
|
12
|
+
def initialize(options)
|
13
|
+
@verbose = options.verbose
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: Determines the directory to use when searching for .gcno and .gcda
|
17
|
+
# files.
|
18
|
+
#
|
19
|
+
# Returns the directory to search.
|
20
|
+
def get_search_directory
|
21
|
+
if ENV["XCS_SOURCE_DIR"]
|
22
|
+
puts " Xcode Server found." if @verbose
|
23
|
+
ENV["XCS_SOURCE_DIR"].sub("Source", "DerivedData")
|
24
|
+
else
|
25
|
+
puts " Development machine found." if @verbose
|
26
|
+
File.join(Etc.getpwuid.dir, "/Library/Developer/Xcode/DerivedData")
|
15
27
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
puts
|
33
|
-
|
34
|
-
|
35
|
-
gen_success = gen_info_files(gi_filename_absolute, temp_dir)
|
36
|
-
if gen_success
|
37
|
-
puts ' ✅ geninfo successful'.green if @verbose
|
38
|
-
else
|
39
|
-
puts ' 🚫 geninfo failed!'.red
|
40
|
-
FileUtils.rm_rf(temp_dir)
|
41
|
-
exit(1)
|
42
|
-
end
|
43
|
-
|
44
|
-
lcov_removals = lcov_system_removals + @remove_filter
|
45
|
-
lcov_success = lcov(gi_filename_absolute, lcov_removals, lcov_filename_absolute)
|
46
|
-
if lcov_success
|
47
|
-
puts ' ✅ lcov successful'.green if @verbose
|
48
|
-
else
|
49
|
-
puts ' 🚫 lcov failed!'.red
|
50
|
-
FileUtils.rm_rf(temp_dir)
|
51
|
-
exit(1)
|
52
|
-
end
|
53
|
-
|
54
|
-
genhtml_success = genhtml(@output_directory, lcov_filename_absolute)
|
55
|
-
if genhtml_success
|
56
|
-
puts '' if @verbose
|
57
|
-
puts ' ✅ Successfully generated report'.green
|
58
|
-
puts " 🍻 Open #{@output_directory}/index.html to view the report"
|
59
|
-
else
|
60
|
-
puts ' 🚫 genhtml failed!'.red
|
61
|
-
FileUtils.rm_rf(temp_dir)
|
62
|
-
exit(1)
|
63
|
-
end
|
64
|
-
|
65
|
-
FileUtils.rm_rf(temp_dir)
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def copy_input_files(product_name, temp_dir)
|
71
|
-
derived_data = ''
|
72
|
-
if @search_directory
|
73
|
-
puts " Search directory provided." if @verbose
|
74
|
-
derived_data = @search_directory
|
75
|
-
elsif ENV['XCS_SOURCE_DIR']
|
76
|
-
puts " Xcode Server found." if @verbose
|
77
|
-
derived_data = ENV['XCS_SOURCE_DIR'].sub('Source', 'DerivedData')
|
78
|
-
else
|
79
|
-
puts " Development machine found." if @verbose
|
80
|
-
derived_data = File.join(Etc.getpwuid.dir, "/Library/Developer/Xcode/DerivedData")
|
81
|
-
end
|
82
|
-
|
83
|
-
puts " Searching in #{derived_data}..." if @verbose
|
84
|
-
Find.find(derived_data) do |path|
|
85
|
-
if path.match(/#{product_name}.*\.gcda\Z/) || path.match(/#{product_name}.*\.gcno\Z/)
|
86
|
-
puts " 👍 .#{path.sub(derived_data, "")}".green if @verbose
|
87
|
-
FileUtils.cp(path, "#{temp_dir}/")
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def gen_info_files(filename, temp_dir)
|
93
|
-
absolute_temp_dir = File.join(Dir.pwd, temp_dir)
|
94
|
-
gen_info_cmd = "geninfo #{absolute_temp_dir}/*.gcno --output-filename #{filename}"
|
95
|
-
gen_info_cmd += ' --quiet' unless @verbose
|
96
|
-
return system gen_info_cmd
|
97
|
-
end
|
98
|
-
|
99
|
-
def lcov(info_filename, filenames_to_remove, lcov_file)
|
100
|
-
all_removals = filenames_to_remove.map { |i| '"' + i.to_s + '"' }.join(" ")
|
101
|
-
lcov_cmd = "lcov --remove #{info_filename} #{all_removals} > #{lcov_file}"
|
102
|
-
lcov_cmd += ' --quiet' unless @verbose
|
103
|
-
return system lcov_cmd
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
def genhtml(output_directory, lcov_filename)
|
108
|
-
FileUtils.mkpath(output_directory)
|
109
|
-
genhtml_cmd = "genhtml --no-function-coverage --no-branch-coverage --output-directory #{output_directory} #{lcov_filename}"
|
110
|
-
genhtml_cmd += ' --quiet' unless @verbose
|
111
|
-
return system genhtml_cmd
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Searches for the .gcno and .gcda files required to generate the
|
31
|
+
# report and copies them into the temp directory.
|
32
|
+
#
|
33
|
+
# search_directory - The directory to search for .gcno and .gcda files.
|
34
|
+
# product_name - The product name (${PRODUCT_NAME}) from the Xcode
|
35
|
+
# project, which will be used to determine what .gcno and
|
36
|
+
# .gcda files to copy.
|
37
|
+
#
|
38
|
+
# Returns nothing.
|
39
|
+
def copy_input_files_to_temp(search_directory, product_name)
|
40
|
+
puts " 📦 Gathering .gcno and .gcda files..." if @verbose
|
41
|
+
puts " Searching in #{search_directory}..." if @verbose
|
42
|
+
Find.find(search_directory) do |path|
|
43
|
+
if path.match(/#{product_name}.*\.gcda\Z/) || path.match(/#{product_name}.*\.gcno\Z/)
|
44
|
+
puts " 👍 .#{path.sub(search_directory, "")}".green if @verbose
|
45
|
+
FileUtils.cp(path, "#{Alcove::TEMP_DIR}/")
|
46
|
+
end
|
112
47
|
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Calls the geninfo command to generate information files for
|
51
|
+
# lcov to process.
|
52
|
+
#
|
53
|
+
# filename - The name of the file to be created by geninfo.
|
54
|
+
#
|
55
|
+
# Returns the result of the geninfo command.
|
56
|
+
def gen_info_files(filename)
|
57
|
+
absolute_temp_dir = File.join(Dir.pwd, Alcove::TEMP_DIR)
|
58
|
+
gen_info_cmd = "geninfo #{absolute_temp_dir}/*.gcno --output-filename #{filename}"
|
59
|
+
gen_info_cmd << " --quiet" unless @verbose
|
60
|
+
system gen_info_cmd
|
61
|
+
end
|
62
|
+
|
63
|
+
# Public: Calls the lcov command to generate coverage information files.
|
64
|
+
#
|
65
|
+
# info_filename - The name of the file generated by geninfo
|
66
|
+
# filenames_to_remove - An array of filters to remove from the report.
|
67
|
+
# lcov_file - The file in which lcov will place the generated info.
|
68
|
+
#
|
69
|
+
# Returns the result of the lcov command.
|
70
|
+
def lcov(info_filename, filenames_to_remove, lcov_file)
|
71
|
+
all_removals = filenames_to_remove.map { |i| "\"#{i.to_s}\"" }.join(" ")
|
72
|
+
lcov_cmd = "lcov --remove #{info_filename} #{all_removals} > #{lcov_file}"
|
73
|
+
lcov_cmd << " --quiet" unless @verbose
|
74
|
+
system lcov_cmd
|
75
|
+
end
|
76
|
+
|
77
|
+
# Public: Calls the genhtml command to generate an HTML report from the
|
78
|
+
# lcov information file.
|
79
|
+
#
|
80
|
+
# lcov_file_path - The path to the file generated by lcov.
|
81
|
+
# output_directory - The directory where output files should be placed.
|
82
|
+
#
|
83
|
+
# Returns the result of the genhtml command.
|
84
|
+
def genhtml(lcov_file_path, output_directory)
|
85
|
+
FileUtils.mkpath(output_directory)
|
86
|
+
genhtml_cmd = "genhtml --no-function-coverage --no-branch-coverage --output-directory #{output_directory} #{lcov_file_path}"
|
87
|
+
|
88
|
+
stdout, stderr, exit_status = Open3.capture3(genhtml_cmd)
|
89
|
+
puts stdout if @verbose
|
90
|
+
summary_string = extract_percent_from_summary(stdout)
|
91
|
+
|
92
|
+
return exit_status.success?, summary_string
|
93
|
+
end
|
94
|
+
|
95
|
+
# Public: Extracts the percentage from the lcov summary string.
|
96
|
+
#
|
97
|
+
# summary - The summary string output by lcov or genhtml
|
98
|
+
def extract_percent_from_summary(summary)
|
99
|
+
summary[/lines.*: (.*)%/, 1].to_f
|
100
|
+
end
|
113
101
|
end
|
data/lib/alcove/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alcove
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0.pre.alpha.pre.36
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Isaac Overacker
|
@@ -28,30 +28,44 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - '>='
|
45
|
+
- - ! '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - '>='
|
52
|
+
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.5'
|
55
69
|
description: Painless code coverage reporting for Xcode projects written in Objective-C.
|
56
70
|
email: isaac@overacker.me
|
57
71
|
executables:
|
@@ -59,11 +73,11 @@ executables:
|
|
59
73
|
extensions: []
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
|
-
- lib/alcove/version.rb
|
63
|
-
- lib/alcove.rb
|
64
|
-
- bin/alcove
|
65
|
-
- README.md
|
66
76
|
- LICENSE
|
77
|
+
- README.md
|
78
|
+
- bin/alcove
|
79
|
+
- lib/alcove.rb
|
80
|
+
- lib/alcove/version.rb
|
67
81
|
homepage: https://github.com/ioveracker/alcove
|
68
82
|
licenses:
|
69
83
|
- MIT
|
@@ -74,17 +88,17 @@ require_paths:
|
|
74
88
|
- lib
|
75
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
90
|
requirements:
|
77
|
-
- - '>='
|
91
|
+
- - ! '>='
|
78
92
|
- !ruby/object:Gem::Version
|
79
93
|
version: '0'
|
80
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
95
|
requirements:
|
82
|
-
- - '
|
96
|
+
- - ! '>'
|
83
97
|
- !ruby/object:Gem::Version
|
84
|
-
version:
|
98
|
+
version: 1.3.1
|
85
99
|
requirements: []
|
86
100
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.
|
101
|
+
rubygems_version: 2.4.5
|
88
102
|
signing_key:
|
89
103
|
specification_version: 4
|
90
104
|
summary: Painless code coverage reporting for Objective-C.
|