alcove 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3a24347defb0bd648d7c15cd13d754590615977
4
+ data.tar.gz: a7530953e48cfc71bde431f94a235b3a17407293
5
+ SHA512:
6
+ metadata.gz: e74cccadf0a4dcd053843c3d5271c27e11c1823d91499d855c86981ea76b9c90c55490fd358522866b5c8c39ba54ca3a0f9542ee9827d71234e3be664da9f1a6
7
+ data.tar.gz: a95b48ef3a9ccd19fabda7e85c88fb3f47c2a2602bf34b5483ca6bef751b9859f9d7e36060a826bbe6bca5d3d9ea045bc0382845ac72f3664566c2c8869106c8
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Isaac Overacker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,26 @@
1
+ # Alcove [![Build Status](https://travis-ci.org/ioveracker/Alcove.svg?branch=master)](https://travis-ci.org/ioveracker/Alcove)
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
+
4
+ ## Installation
5
+
6
+ $ sudo gem install alcove
7
+
8
+ If you don't have it already, you'll also need to install lcov.
9
+
10
+ *Homebrew*
11
+
12
+ $ brew install lcov
13
+
14
+ *MacPorts*
15
+
16
+ $ sudo port install lcov
17
+
18
+ ## Xcode Project Configuration
19
+ If you haven't already, open your project in Xcode and update your main target to Generate Test Coverage Files and Instrument Program Flow *for Debug configuration only*).
20
+
21
+ ## Generating Reports
22
+ Now that you have the prerequisites out of the way, you can generate a report. Make sure you've recently executed your tests, then:
23
+
24
+ alcove --product-name <your-product-name>
25
+
26
+ Be sure to check out the --help for additional options for fine-tuning your report.
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/ruby
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+ require 'alcove'
4
+ require 'alcove/version'
5
+ require 'ostruct'
6
+ require 'optparse'
7
+
8
+ options = OpenStruct.new
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: alcove --product-name <product-name> [options]"
11
+
12
+ opts.on('-h', '--help', 'Displays the help screen') do
13
+ puts opts
14
+ exit
15
+ end
16
+
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
+
22
+ options.product_name = ''
23
+ opts.on('-p', '--product-name NAME', 'The name of your product') do |p|
24
+ options.product_name = p
25
+ end
26
+
27
+ options.remove_filter = []
28
+ opts.on('-r', '--remove-filter X,Y,Z...', ::Array, 'A list of filters (e.g. *.h,main.m)') do |r|
29
+ options.remove_filter = r
30
+ end
31
+
32
+ opts.on('-s', '--search-directory DIR', 'Search in DIR for coverage files') do |s|
33
+ options.search_directory = s
34
+ end
35
+
36
+ options.verbose = false
37
+ opts.on('-v', '--verbose', 'Output additional information') do
38
+ options.verbose = true
39
+ end
40
+
41
+ opts.on_tail('--version', 'Show version') do
42
+ puts Alcove::VERSION
43
+ exit
44
+ end
45
+
46
+ begin
47
+ opts.parse!(ARGV)
48
+ if options.product_name.length == 0
49
+ puts '--product-name is required'.yellow
50
+ puts opts
51
+ exit(1)
52
+ end
53
+ rescue OptionParser::InvalidOption => e
54
+ puts e
55
+ puts opts
56
+ exit(1)
57
+ end
58
+ end
59
+
60
+ 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
+ alcoveOptions.verbose = options.verbose
66
+
67
+ alcove = Alcove.new(alcoveOptions)
68
+ alcove.generate_report
@@ -0,0 +1,113 @@
1
+ require 'colored'
2
+ require 'etc'
3
+ require 'find'
4
+ require 'fileutils'
5
+ require 'ostruct'
6
+ require 'optparse'
7
+
8
+ class Alcove
9
+ def initialize(options)
10
+ @output_directory = options.output_directory
11
+ @product_name = options.product_name
12
+ @remove_filter = options.remove_filter
13
+ @verbose = options.verbose
14
+ @search_directory = options.search_directory
15
+ end
16
+
17
+ def generate_report
18
+ temp_dir = 'alcove-temp'
19
+ # geninfo parameters
20
+ gi_filename = 'alcove-info.temp'
21
+ gi_filename_absolute = File.join(temp_dir, gi_filename)
22
+ # lcov parameters
23
+ lcov_filename = 'alcove-lcov.info'
24
+ lcov_filename_absolute = File.join(temp_dir, lcov_filename)
25
+ lcov_system_removals = ['*iPhoneSimulator*']
26
+
27
+ puts ' 🔍 Generating report...'
28
+
29
+ FileUtils.rm_rf(temp_dir)
30
+ FileUtils.mkdir(temp_dir)
31
+
32
+ puts ' 📦 Gathering .gcno and .gcda files...' if @verbose
33
+ copy_input_files(@product_name, temp_dir)
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
112
+ end
113
+ end
@@ -0,0 +1,3 @@
1
+ class Alcove
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alcove
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Isaac Overacker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colored
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Painless code coverage reporting for Xcode projects written in Objective-C.
56
+ email: isaac@overacker.me
57
+ executables:
58
+ - alcove
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/alcove/version.rb
63
+ - lib/alcove.rb
64
+ - bin/alcove
65
+ - README.md
66
+ - LICENSE
67
+ homepage: https://github.com/ioveracker/alcove
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.0.14
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Painless code coverage reporting for Objective-C.
91
+ test_files: []