slather 1.8.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +21 -1
  5. data/README.md +15 -10
  6. data/README_Images/test_scheme.png +0 -0
  7. data/Rakefile +6 -0
  8. data/bin/slather +45 -6
  9. data/lib/slather/coverage_file.rb +37 -90
  10. data/lib/slather/coverage_info.rb +84 -0
  11. data/lib/slather/coverage_service/cobertura_xml_output.rb +10 -6
  12. data/lib/slather/coverage_service/coveralls.rb +5 -1
  13. data/lib/slather/coverage_service/gutter_json_output.rb +12 -8
  14. data/lib/slather/coverage_service/hardcover.rb +5 -1
  15. data/lib/slather/coverage_service/html_output.rb +32 -19
  16. data/lib/slather/coverage_service/simple_output.rb +5 -1
  17. data/lib/slather/{coveralls_coverage_file.rb → coveralls_coverage.rb} +1 -1
  18. data/lib/slather/profdata_coverage_file.rb +130 -0
  19. data/lib/slather/project.rb +191 -27
  20. data/lib/slather/version.rb +1 -1
  21. data/lib/slather.rb +9 -1
  22. data/slather.gemspec +4 -4
  23. data/spec/fixtures/cobertura.xml +56 -79
  24. data/spec/fixtures/fixtures/Fixtures.swift +15 -0
  25. data/spec/fixtures/fixtures/other_fixtures.m +23 -0
  26. data/spec/fixtures/fixtures_html/Branches.m.html +244 -258
  27. data/spec/fixtures/fixtures_html/BranchesTests.m.html +209 -225
  28. data/spec/fixtures/fixtures_html/fixtures.m.html +134 -148
  29. data/spec/fixtures/fixtures_html/fixturesTests.m.html +199 -213
  30. data/spec/fixtures/fixtures_html/index.html +68 -131
  31. data/spec/fixtures/fixtures_html/peekaviewTests.m.html +189 -203
  32. data/spec/fixtures/gutter.json +1 -1
  33. data/spec/slather/coverage_file_spec.rb +20 -12
  34. data/spec/slather/coverage_service/cobertura_xml_spec.rb +7 -3
  35. data/spec/slather/coverage_service/coveralls_spec.rb +61 -20
  36. data/spec/slather/coverage_service/gutter_json_spec.rb +6 -2
  37. data/spec/slather/coverage_service/hardcover_spec.rb +33 -3
  38. data/spec/slather/coverage_service/html_output_spec.rb +48 -7
  39. data/spec/slather/coverage_service/simple_output_spec.rb +12 -13
  40. data/spec/slather/profdata_coverage_spec.rb +128 -0
  41. data/spec/slather/project_spec.rb +222 -49
  42. data/spec/spec_helper.rb +28 -2
  43. metadata +58 -46
  44. data/spec/fixtures/fixtures_html/Empty.m.html +0 -30
  45. data/spec/fixtures/fixtures_html/fixtures_cpp.cpp.html +0 -30
  46. data/spec/fixtures/fixtures_html/fixtures_m.m.html +0 -30
  47. data/spec/fixtures/fixtures_html/fixtures_mm.mm.html +0 -30
  48. data/spec/fixtures/fixtures_html/peekaview.m.html +0 -190
@@ -5,7 +5,11 @@ module Slather
5
5
  module HtmlOutput
6
6
 
7
7
  def coverage_file_class
8
- Slather::CoverageFile
8
+ if input_format == "profdata"
9
+ Slather::ProfdataCoverageFile
10
+ else
11
+ Slather::CoverageFile
12
+ end
9
13
  end
10
14
  private :coverage_file_class
11
15
 
@@ -46,6 +50,11 @@ module Slather
46
50
  FileUtils.rm_rf(directory_path) if Dir.exist?(directory_path)
47
51
  FileUtils.mkdir_p(directory_path)
48
52
 
53
+ FileUtils.cp(File.join(gem_root_path, "docs/logo.jpg"), directory_path)
54
+ FileUtils.cp(File.join(gem_root_path, "assets/slather.css"), directory_path)
55
+ FileUtils.cp(File.join(gem_root_path, "assets/highlight.pack.js"), directory_path)
56
+ FileUtils.cp(File.join(gem_root_path, "assets/list.min.js"), directory_path)
57
+
49
58
  reports.each do |name, doc|
50
59
  html_file = File.join(directory_path, "#{name}.html")
51
60
  File.write(html_file, doc.to_html)
@@ -141,18 +150,20 @@ module Slather
141
150
  next
142
151
  end
143
152
 
153
+ line_number_separator = coverage_file.line_number_separator
154
+
144
155
  cov.table(:class => "source_code") {
145
156
  cleaned_gcov_lines.each do |line|
146
- data = line.split(':', 3)
157
+ data = line.split(line_number_separator, 3)
147
158
 
148
159
  line_number = data[1].to_i
149
160
  next unless line_number > 0
150
161
 
151
162
  coverage_data = data[0].strip
152
- line_data = [line_number, data[2], hits_for_coverage_data(coverage_data)]
163
+ line_data = [line_number, data[2], hits_for_coverage_line(coverage_file, line)]
153
164
  classes = ["num", "src", "coverage"]
154
165
 
155
- cov.tr(:class => class_for_coverage_data(coverage_data)) {
166
+ cov.tr(:class => class_for_coverage_line(coverage_file,line)) {
156
167
  line_data.each_with_index { |line, idx|
157
168
  if idx != 1
158
169
  cov.td(line, :class => classes[idx])
@@ -171,10 +182,10 @@ module Slather
171
182
  end
172
183
 
173
184
  def generate_html_template(title, is_index, is_file_empty)
174
- logo_path = File.join(gem_root_path, "docs/logo.jpg")
175
- css_path = File.join(gem_root_path, "assets/slather.css")
176
- highlight_js_path = File.join(gem_root_path, "assets/highlight.pack.js")
177
- list_js_path = File.join(gem_root_path, "assets/list.min.js")
185
+ logo_path = "logo.jpg"
186
+ css_path = "slather.css"
187
+ highlight_js_path = "highlight.pack.js"
188
+ list_js_path = "list.min.js"
178
189
 
179
190
  builder = Nokogiri::HTML::Builder.new do |doc|
180
191
  doc.html {
@@ -191,7 +202,7 @@ module Slather
191
202
  doc.div(:class => "row") { doc.div(:id => "reports") }
192
203
  doc.footer {
193
204
  doc.div(:class => "row") {
194
- doc.p { doc.a("Fork me on Github", :href => "https://github.com/venmo/slather") }
205
+ doc.p { doc.a("Fork me on Github", :href => "https://github.com/SlatherOrg/slather") }
195
206
  doc.p("© #{Date.today.year} Slather")
196
207
  }
197
208
  }
@@ -215,19 +226,21 @@ module Slather
215
226
  File.expand_path File.join(File.dirname(__dir__), "../..")
216
227
  end
217
228
 
218
- def class_for_coverage_data(coverage_data)
219
- case coverage_data
220
- when /\d/ then "covered"
221
- when /#/ then "missed"
222
- else "never"
229
+ def class_for_coverage_line(coverage_file, coverage_line)
230
+ hits = coverage_file.coverage_for_line(coverage_line)
231
+ case
232
+ when hits == nil then "never"
233
+ when hits > 0 then "covered"
234
+ else "missed"
223
235
  end
224
236
  end
225
237
 
226
- def hits_for_coverage_data(coverage_data)
227
- case coverage_data
228
- when /\d/ then (coverage_data.to_i > 0) ? "#{coverage_data}x" : ""
229
- when /#/ then "!"
230
- else ""
238
+ def hits_for_coverage_line(coverage_file, coverage_line)
239
+ hits = coverage_file.coverage_for_line(coverage_line)
240
+ case
241
+ when hits == nil then ""
242
+ when hits > 0 then "#{hits}x"
243
+ else "!"
231
244
  end
232
245
  end
233
246
 
@@ -3,7 +3,11 @@ module Slather
3
3
  module SimpleOutput
4
4
 
5
5
  def coverage_file_class
6
- Slather::CoverageFile
6
+ if input_format == "profdata"
7
+ Slather::ProfdataCoverageFile
8
+ else
9
+ Slather::CoverageFile
10
+ end
7
11
  end
8
12
  private :coverage_file_class
9
13
 
@@ -1,5 +1,5 @@
1
1
  module Slather
2
- class CoverallsCoverageFile < CoverageFile
2
+ module CoverallsCoverage
3
3
 
4
4
  def as_json
5
5
  {
@@ -0,0 +1,130 @@
1
+ require 'slather/coverage_info'
2
+ require 'slather/coveralls_coverage'
3
+
4
+ module Slather
5
+ class ProfdataCoverageFile
6
+
7
+ include CoverageInfo
8
+ include CoverallsCoverage
9
+
10
+ attr_accessor :project, :source, :line_data
11
+
12
+ def initialize(project, source)
13
+ self.project = project
14
+ self.source = source
15
+ create_line_data
16
+ end
17
+
18
+ def create_line_data
19
+ all_lines = self.source.split("\n")[1..-1]
20
+ line_data = Hash.new
21
+ all_lines.each { |line| line_data[line_number_in_line(line)] = line }
22
+ self.line_data = line_data
23
+ end
24
+ private :create_line_data
25
+
26
+ def source_file_pathname
27
+ @source_file_pathname ||= begin
28
+ path = self.source.split("\n")[0].sub ":", ""
29
+ path &&= Pathname(path)
30
+ end
31
+ end
32
+
33
+ def source_file
34
+ File.new(source_file_pathname)
35
+ end
36
+
37
+ def source_data
38
+ all_lines.join("\n")
39
+ end
40
+
41
+ def all_lines
42
+ if @all_lines == nil
43
+ @all_lines = self.source.split("\n")[1..-1]
44
+ end
45
+ @all_lines
46
+ end
47
+
48
+ def cleaned_gcov_data
49
+ source_data
50
+ end
51
+
52
+ def raw_data
53
+ self.source
54
+ end
55
+
56
+ def line_number_in_line(line)
57
+ line =~ /^(\s*)(\d*)\|(\s*)(\d+)\|/
58
+ if $4 != nil
59
+ match = $4.strip
60
+ case match
61
+ when /[0-9]+/
62
+ return match.to_i
63
+ end
64
+ end
65
+ 0
66
+ end
67
+
68
+ def line_coverage_data
69
+ self.source.split("\n")[1..-1].map do |line|
70
+ coverage_for_line(line)
71
+ end
72
+ end
73
+
74
+ def coverage_for_line(line)
75
+ line = line.gsub(":", "|")
76
+ line =~ /^(\s*)(\d*)\|/
77
+
78
+ if $2 == nil
79
+ return nil
80
+ end
81
+
82
+ match = $2.strip
83
+ case match
84
+ when /[0-9]+/
85
+ match.to_i
86
+ when /#+/
87
+ 0
88
+ when "-"
89
+ nil
90
+ end
91
+ end
92
+
93
+ def branch_coverage_data
94
+ @branch_coverage_data ||= begin
95
+ Hash.new
96
+ end
97
+ end
98
+
99
+ def source_file_basename
100
+ File.basename(source_file_pathname, '.swift')
101
+ end
102
+
103
+ def line_number_separator
104
+ "|"
105
+ end
106
+
107
+ def supported_file_extensions
108
+ ["swift"]
109
+ end
110
+ private :supported_file_extensions
111
+
112
+ def ignored?
113
+ ignore = false
114
+ platform_ignore_list.map do |ignore_suffix|
115
+ ignore = source_file_pathname.to_s.end_with? ignore_suffix
116
+ if ignore
117
+ break
118
+ end
119
+ end
120
+ ignore ? ignore : super
121
+ end
122
+
123
+ def platform_ignore_list
124
+ ["MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Headers/XCTestAssertionsImpl.h",
125
+ "MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/objc/objc.h",
126
+ "MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Headers/XCTestAssertions.h"]
127
+ end
128
+ private :platform_ignore_list
129
+ end
130
+ end
@@ -2,14 +2,45 @@ require 'fileutils'
2
2
  require 'xcodeproj'
3
3
  require 'json'
4
4
  require 'yaml'
5
+ require 'shellwords'
5
6
 
6
7
  module Xcodeproj
8
+
7
9
  class Project
8
10
 
9
- def slather_setup_for_coverage
11
+ def slather_setup_for_coverage(format = :auto)
12
+ unless [:gcov, :clang, :auto].include?(format)
13
+ raise StandardError, "Only supported formats for setup are gcov, clang or auto"
14
+ end
15
+ if format == :auto
16
+ format = Slather.xcode_version[0] < 7 ? :gcov : :clang
17
+ end
18
+
10
19
  build_configurations.each do |build_configuration|
11
- build_configuration.build_settings["GCC_INSTRUMENT_PROGRAM_FLOW_ARCS"] = "YES"
12
- build_configuration.build_settings["GCC_GENERATE_TEST_COVERAGE_FILES"] = "YES"
20
+ if format == :clang
21
+ build_configuration.build_settings["CLANG_ENABLE_CODE_COVERAGE"] = "YES"
22
+ else
23
+ build_configuration.build_settings["GCC_INSTRUMENT_PROGRAM_FLOW_ARCS"] = "YES"
24
+ build_configuration.build_settings["GCC_GENERATE_TEST_COVERAGE_FILES"] = "YES"
25
+ end
26
+ end
27
+
28
+ # Patch xcschemes too
29
+ if format == :clang
30
+ if Gem::Requirement.new('~> 0.27') =~ Gem::Version.new(Xcodeproj::VERSION)
31
+ # @todo This will require to bump the xcodeproj dependency to ~> 0.27
32
+ # (which would require to bump cocoapods too)
33
+ schemes_path = Xcodeproj::XCScheme.shared_data_dir(self.path)
34
+ Xcodeproj::Project.schemes(self.path).each do |scheme_name|
35
+ xcscheme_path = "#{schemes_path + scheme_name}.xcscheme"
36
+ xcscheme = Xcodeproj::XCScheme.new(xcscheme_path)
37
+ xcscheme.test_action.xml_element.attributes['codeCoverageEnabled'] = 'YES'
38
+ xcscheme.save_as(self.path, scheme_name)
39
+ end
40
+ else
41
+ # @todo In the meantime, simply inform the user to do it manually
42
+ puts %Q(Ensure you enabled "Gather coverage data" in each of your scheme's Test action)
43
+ end
13
44
  end
14
45
  end
15
46
 
@@ -19,27 +50,32 @@ end
19
50
  module Slather
20
51
  class Project < Xcodeproj::Project
21
52
 
22
- attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :coverage_access_token, :source_directory, :output_directory, :xcodeproj, :show_html
53
+ attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :coverage_access_token, :source_directory,
54
+ :output_directory, :xcodeproj, :show_html, :verbose_mode, :input_format, :scheme, :binary_file, :binary_basename
23
55
 
24
56
  alias_method :setup_for_coverage, :slather_setup_for_coverage
25
57
 
26
58
  def self.open(xcodeproj)
27
59
  proj = super
28
- proj.configure_from_yml
29
60
  proj.xcodeproj = xcodeproj
30
61
  proj
31
62
  end
32
63
 
33
- def derived_data_dir
64
+ def derived_data_path
34
65
  File.expand_path('~') + "/Library/Developer/Xcode/DerivedData/"
35
66
  end
36
- private :derived_data_dir
67
+ private :derived_data_path
37
68
 
38
- def build_directory
39
- @build_directory || derived_data_dir
69
+ def coverage_files
70
+ if self.input_format == "profdata"
71
+ profdata_coverage_files
72
+ else
73
+ gcov_coverage_files
74
+ end
40
75
  end
76
+ private :coverage_files
41
77
 
42
- def coverage_files
78
+ def gcov_coverage_files
43
79
  coverage_files = Dir["#{build_directory}/**/*.gcno"].map do |file|
44
80
  coverage_file = coverage_file_class.new(self, file)
45
81
  # If there's no source file for this gcno, it probably belongs to another project.
@@ -52,7 +88,79 @@ module Slather
52
88
  dedupe(coverage_files)
53
89
  end
54
90
  end
55
- private :coverage_files
91
+ private :gcov_coverage_files
92
+
93
+ def profdata_coverage_files
94
+ files = profdata_llvm_cov_output.split("\n\n")
95
+
96
+ files.map do |source|
97
+ coverage_file = coverage_file_class.new(self, source)
98
+ !coverage_file.ignored? ? coverage_file : nil
99
+ end.compact
100
+ end
101
+ private :profdata_coverage_files
102
+
103
+ def profdata_coverage_dir
104
+ raise StandardError, "The specified build directory (#{self.build_directory}) does not exist" unless File.exists?(self.build_directory)
105
+ dir = nil
106
+ if self.scheme
107
+ dir = Dir["#{build_directory}/**/CodeCoverage/#{self.scheme}"].first
108
+ else
109
+ dir = Dir["#{build_directory}/**/#{self.products.first.name}"].first
110
+ end
111
+
112
+ raise StandardError, "No coverage directory found. Are you sure your project is setup for generating coverage files? Try `slather setup your/project.xcodeproj`" unless dir != nil
113
+ dir
114
+ end
115
+
116
+ def profdata_file
117
+ profdata_coverage_dir = self.profdata_coverage_dir
118
+ if profdata_coverage_dir == nil
119
+ raise StandardError, "No coverage directory found. Please make sure the \"Code Coverage\" checkbox is enabled in your scheme's Test action or the build_directory property is set."
120
+ end
121
+
122
+ file = Dir["#{profdata_coverage_dir}/**/Coverage.profdata"].first
123
+ unless file != nil
124
+ return nil
125
+ end
126
+ return File.expand_path(file)
127
+ end
128
+ private :profdata_file
129
+
130
+ def find_binary_file_for_app(app_bundle_file)
131
+ app_bundle_file_name_noext = Pathname.new(app_bundle_file).basename.to_s.gsub(".app", "")
132
+ Dir["#{app_bundle_file}/**/#{app_bundle_file_name_noext}"].first
133
+ end
134
+
135
+ def find_binary_file_for_dynamic_lib(framework_bundle_file)
136
+ framework_bundle_file_name_noext = Pathname.new(framework_bundle_file).basename.to_s.gsub(".framework", "")
137
+ "#{framework_bundle_file}/#{framework_bundle_file_name_noext}"
138
+ end
139
+
140
+ def find_binary_file_for_static_lib(xctest_bundle_file)
141
+ xctest_bundle_file_name_noext = Pathname.new(xctest_bundle_file).basename.to_s.gsub(".xctest", "")
142
+ Dir["#{xctest_bundle_file}/**/#{xctest_bundle_file_name_noext}"].first
143
+ end
144
+
145
+ def unsafe_profdata_llvm_cov_output
146
+ profdata_file_arg = profdata_file
147
+ if profdata_file_arg == nil
148
+ raise StandardError, "No Coverage.profdata files found. Please make sure the \"Code Coverage\" checkbox is enabled in your scheme's Test action or the build_directory property is set."
149
+ end
150
+
151
+ if self.binary_file == nil
152
+ raise StandardError, "No binary file found."
153
+ end
154
+
155
+ llvm_cov_args = %W(show -instr-profile #{profdata_file_arg} #{self.binary_file})
156
+ `xcrun llvm-cov #{llvm_cov_args.shelljoin}`
157
+ end
158
+ private :unsafe_profdata_llvm_cov_output
159
+
160
+ def profdata_llvm_cov_output
161
+ unsafe_profdata_llvm_cov_output.encode!('UTF-8', 'binary', :invalid => :replace, undef: :replace)
162
+ end
163
+ private :profdata_llvm_cov_output
56
164
 
57
165
  def dedupe(coverage_files)
58
166
  coverage_files.group_by(&:source_file_pathname).values.map { |cf_array| cf_array.max_by(&:percentage_lines_tested) }
@@ -67,45 +175,73 @@ module Slather
67
175
  @yml ||= File.exist?(yml_filename) ? YAML.load_file(yml_filename) : {}
68
176
  end
69
177
 
70
- def configure_from_yml
71
- configure_build_directory_from_yml
72
- configure_ignore_list_from_yml
73
- configure_ci_service_from_yml
74
- configure_coverage_access_token_from_yml
75
- configure_coverage_service_from_yml
76
- configure_source_directory_from_yml
77
- configure_output_directory_from_yml
178
+ def configure
179
+ configure_build_directory
180
+ configure_ignore_list
181
+ configure_ci_service
182
+ configure_coverage_access_token
183
+ configure_coverage_service
184
+ configure_source_directory
185
+ configure_output_directory
186
+ configure_input_format
187
+ configure_scheme
188
+ configure_binary_file
189
+
190
+ if self.verbose_mode
191
+ puts "\nProcessing coverage file: #{profdata_file}"
192
+ puts "Against binary file: #{self.binary_file}\n\n"
193
+ end
78
194
  end
79
195
 
80
- def configure_build_directory_from_yml
81
- self.build_directory = self.class.yml["build_directory"] if self.class.yml["build_directory"] && !@build_directory
196
+ def configure_build_directory
197
+ self.build_directory ||= self.class.yml["build_directory"] || derived_data_path
82
198
  end
83
199
 
84
- def configure_source_directory_from_yml
200
+ def configure_source_directory
85
201
  self.source_directory ||= self.class.yml["source_directory"] if self.class.yml["source_directory"]
86
202
  end
87
203
 
88
- def configure_output_directory_from_yml
204
+ def configure_output_directory
89
205
  self.output_directory ||= self.class.yml["output_directory"] if self.class.yml["output_directory"]
90
206
  end
91
207
 
92
- def configure_ignore_list_from_yml
208
+ def configure_ignore_list
93
209
  self.ignore_list ||= [(self.class.yml["ignore"] || [])].flatten
94
210
  end
95
211
 
96
- def configure_ci_service_from_yml
212
+ def configure_ci_service
97
213
  self.ci_service ||= (self.class.yml["ci_service"] || :travis_ci)
98
214
  end
99
215
 
216
+ def configure_input_format
217
+ self.input_format ||= self.class.yml["input_format"] || input_format
218
+ end
219
+
220
+ def input_format=(format)
221
+ format ||= "auto"
222
+ unless %w(gcov profdata auto).include?(format)
223
+ raise StandardError, "Only supported input formats are gcov, profdata or auto"
224
+ end
225
+ if format == "auto"
226
+ @input_format = Slather.xcode_version[0] < 7 ? "gcov" : "profdata"
227
+ else
228
+ @input_format = format
229
+ end
230
+ end
231
+
232
+ def configure_scheme
233
+ self.scheme ||= self.class.yml["scheme"] if self.class.yml["scheme"]
234
+ end
235
+
100
236
  def ci_service=(service)
101
237
  @ci_service = service && service.to_sym
102
238
  end
103
239
 
104
- def configure_coverage_service_from_yml
240
+ def configure_coverage_service
105
241
  self.coverage_service ||= (self.class.yml["coverage_service"] || :terminal)
106
242
  end
107
243
 
108
- def configure_coverage_access_token_from_yml
244
+ def configure_coverage_access_token
109
245
  self.coverage_access_token ||= (ENV["COVERAGE_ACCESS_TOKEN"] || self.class.yml["coverage_access_token"] || "")
110
246
  end
111
247
 
@@ -128,5 +264,33 @@ module Slather
128
264
  end
129
265
  @coverage_service = service
130
266
  end
267
+
268
+ def configure_binary_file
269
+ if self.input_format == "profdata"
270
+ self.binary_file ||= self.class.yml["binary_file"] || File.expand_path(find_binary_file)
271
+ end
272
+ end
273
+
274
+ def find_binary_file
275
+ xctest_bundle = Dir["#{profdata_coverage_dir}/**/*.xctest"].reject { |bundle|
276
+ bundle.include? "-Runner.app/PlugIns/"
277
+ }.first
278
+ raise StandardError, "No product binary found in #{profdata_coverage_dir}. Are you sure your project is setup for generating coverage files? Try `slather setup your/project.xcodeproj`" unless xctest_bundle != nil
279
+
280
+ # Find the matching binary file
281
+ search_for = self.binary_basename || self.class.yml["binary_basename"] || '*'
282
+ xctest_bundle_file_directory = Pathname.new(xctest_bundle).dirname
283
+ app_bundle = Dir["#{xctest_bundle_file_directory}/#{search_for}.app"].first
284
+ dynamic_lib_bundle = Dir["#{xctest_bundle_file_directory}/#{search_for}.framework"].first
285
+
286
+ if app_bundle != nil
287
+ find_binary_file_for_app(app_bundle)
288
+ elsif dynamic_lib_bundle != nil
289
+ find_binary_file_for_dynamic_lib(dynamic_lib_bundle)
290
+ else
291
+ find_binary_file_for_static_lib(xctest_bundle)
292
+ end
293
+ end
294
+
131
295
  end
132
296
  end
@@ -1,3 +1,3 @@
1
1
  module Slather
2
- VERSION = "1.8.3"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/slather.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'slather/version'
2
2
  require 'slather/project'
3
+ require 'slather/coverage_info'
3
4
  require 'slather/coverage_file'
4
- require 'slather/coveralls_coverage_file'
5
+ require 'slather/coveralls_coverage'
6
+ require 'slather/profdata_coverage_file'
5
7
  require 'slather/coverage_service/cobertura_xml_output'
6
8
  require 'slather/coverage_service/coveralls'
7
9
  require 'slather/coverage_service/hardcover'
@@ -17,4 +19,10 @@ module Slather
17
19
  Pod::UI.warn("[Slather] prepare_pods is now deprecated. The call to prepare_pods in your Podfile can simply be ommitted.")
18
20
  end
19
21
 
22
+ def self.xcode_version
23
+ xcode_path = `xcode-select -p`.strip
24
+ xcode_version = `mdls -name kMDItemVersion -raw #{xcode_path.shellescape}/../..`.strip
25
+ xcode_version.split('.').map(&:to_i)
26
+ end
27
+
20
28
  end
data/slather.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Mark Larsen"]
10
10
  spec.email = ["mark@venmo.com"]
11
11
  spec.summary = %q{Test coverage reports for Xcode projects}
12
- spec.homepage = "https://github.com/venmo/slather"
12
+ spec.homepage = "https://github.com/SlatherOrg/slather"
13
13
  spec.license = "MIT"
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
@@ -20,13 +20,13 @@ Gem::Specification.new do |spec|
20
20
  spec.add_development_dependency "bundler", "~> 1.6"
21
21
  spec.add_development_dependency "coveralls"
22
22
  spec.add_development_dependency "rake", "~> 10.3"
23
- spec.add_development_dependency "rspec", "~> 2.14"
23
+ spec.add_development_dependency "rspec", "~> 3.3"
24
24
  spec.add_development_dependency "pry", "~> 0.9"
25
- spec.add_development_dependency "cocoapods", "~> 0.39.0"
25
+ spec.add_development_dependency "cocoapods", ">= 0.39.0", "< 1.1.0"
26
26
  spec.add_development_dependency "json_spec", "~> 1.1.4"
27
27
  spec.add_development_dependency "equivalent-xml", "~> 0.5.1"
28
28
 
29
29
  spec.add_dependency "clamp", "~> 0.6"
30
- spec.add_dependency "xcodeproj", "~> 0.28.0"
30
+ spec.add_dependency "xcodeproj", ">= 0.28.2", "< 1.1.0"
31
31
  spec.add_dependency "nokogiri", "~> 1.6.3"
32
32
  end