fastlane-plugin-bugsnag 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d3998cc286232a7f3d2ec963ed35420f020015e
4
+ data.tar.gz: 57a410de55d97ed5d19ea6ce08c36ddf7520b2d0
5
+ SHA512:
6
+ metadata.gz: 4d43547635bd11fea2b6cfa290e6aff090f921d920fa831e94f7db8f6d0a2014e8c1c39a1021a0f01e24040179a3ba2482a895c3cd8100d81ef4c30db1951730
7
+ data.tar.gz: cf8084b78c671410580d4a42f5ff5e35c91e658c51cd0edc9dd0df092bd9810871d279a7cbccc6a9da7a9cb320c5083da8309ddd77c1bb1c1cdfdaab679edae5
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 Bugsnag, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Given a directory, uploads any *.dSYM bundles with the directory to
4
+ # Bugsnag. As a pre-upload step, bitcode symbol maps can be combined with
5
+ # dSYM files to ensure symbols are sent for bitcode-enabled binaries.
6
+ #
7
+ # Depends on:
8
+ # * curl
9
+ # * dwarfdump
10
+ # * dsymutil (for --symbol-maps, optional)
11
+ # * unzip (for uploading a .zip file, optional)
12
+
13
+ function print_usage() {
14
+ echo "Usage: $0 [--symbol-maps DIR] dSYMS_PATH"
15
+ echo
16
+ echo "-h, --help Displays this message"
17
+ echo "-v, --verbose Print verbose logging output during execution"
18
+ echo "--symbol-maps DIR Path to a directory of bitcode symbol maps. The"
19
+ echo " dSYM files will be restored with symbols prior to"
20
+ echo " upload. Requires dsymutil."
21
+ echo "--upload-server URL The server receiving dSYM files. Set this value if"
22
+ echo " using an on-premise Bugsnag installation"
23
+ echo
24
+ echo "dSYMS_PATH A directory or .zip file containing *.dSYM bundles to"
25
+ echo " upload"
26
+ }
27
+
28
+ function exit_with_usage() {
29
+ echo $1
30
+ echo
31
+ print_usage
32
+ exit 1
33
+ }
34
+
35
+ function log() {
36
+ if [[ $silent != 1 ]]; then
37
+ echo $@
38
+ fi
39
+ }
40
+
41
+ function log_verbose() {
42
+ if [[ $verbose == 1 ]]; then
43
+ log $@
44
+ fi
45
+ }
46
+
47
+ upload_server=https://upload.bugsnag.com
48
+ unset symbol_maps
49
+ unset dsym_dir
50
+ unset verbose
51
+ unset silent
52
+
53
+ while [[ $# -gt 0 ]]; do
54
+ case $1 in
55
+ -h|--help)
56
+ print_usage
57
+ exit 0;;
58
+ -s|--silent)
59
+ silent=1
60
+ shift;;
61
+ -v|--verbose)
62
+ verbose=1
63
+ shift;;
64
+ --symbol-maps)
65
+ symbol_maps=$2
66
+ shift
67
+ shift;;
68
+ --upload-server)
69
+ upload_server=$2
70
+ shift
71
+ shift;;
72
+ -*)
73
+ exit_with_usage "Invalid parameter provided: $1";;
74
+ *)
75
+ dsym_dir=$1
76
+ break;;
77
+ esac
78
+ done
79
+
80
+ if [[ ! -z $symbol_maps ]]; then
81
+ if [[ ! -d $symbol_maps ]]; then
82
+ exit_with_usage "Bitcode symbol map parameter is not a directory"
83
+ elif [[ ! -x "$(command -v dsymutil 2>/dev/null)" ]]; then
84
+ exit_with_usage "dsymutil command not found."
85
+ fi
86
+ fi
87
+ if [[ -z $dsym_dir ]]; then
88
+ exit_with_usage "No dSYM directory provided"
89
+ fi
90
+ if [[ ! -d $dsym_dir ]]; then
91
+ if [[ $dsym_dir == *".zip" ]]; then
92
+ if [[ ! -x "$(command -v unzip 2>/dev/null)" ]]; then
93
+ exit_with_usage "unzip command not found."
94
+ fi
95
+ temp_dir=$(mktemp -dt "bugsnag-dsym-upload")
96
+ unzip -qq $dsym_dir -d $temp_dir
97
+ dsym_dir=$temp_dir
98
+ else
99
+ exit_with_usage "'$dsym_dir' is not a directory or a zip file"
100
+ fi
101
+ fi
102
+
103
+ # Set IFS to ensure that file paths with spaces in get processed correctly
104
+ IFS=$'\n'
105
+
106
+ log_verbose "Uploading files to $upload_server"
107
+ success_count=0
108
+ fail_count=0
109
+
110
+ for dsym in $dsym_dir/*.dSYM; do
111
+ log_verbose "Preparing to upload $dsym"
112
+
113
+ if [[ -d $symbol_maps ]]; then
114
+ log_verbose "Updating file with bitcode symbol maps in $symbol_maps"
115
+ dsymutil "$dsym" --symbol-map "$symbol_maps"
116
+ fi
117
+
118
+ dwarf_data=$dsym/Contents/Resources/DWARF
119
+ if [[ ! -d $dwarf_data ]]; then
120
+ log_verbose "Skipping file missing DWARF data: $dsym"
121
+ fail_count=$((fail_count+1))
122
+ continue
123
+ fi
124
+ for file in $dwarf_data/*; do
125
+ uuid=$(dwarfdump -u $file 2>/dev/null)
126
+ if [[ $uuid == UUID* ]]; then
127
+ log Uploading $uuid
128
+ output=$(curl --silent --show-error $upload_server -F dsym=@\"$file\")
129
+ if [ $? -eq 0 ]; then
130
+ success_count=$((success_count+1))
131
+ else
132
+ fail_count=$((fail_count+1))
133
+ log_verbose "Failed to upload file: $file"
134
+ fi
135
+ echo $output | grep -v '^OK$'
136
+ log
137
+ else
138
+ log_verbose "Skipping file without UUID: $file"
139
+ fail_count=$((fail_count+1))
140
+ fi
141
+ done
142
+ done
143
+
144
+ if [ $success_count -gt 0 ]; then
145
+ log "$success_count files uploaded successfully"
146
+ fi
147
+
148
+ if [ $fail_count -gt 0 ]; then
149
+ log "$fail_count files failed to upload"
150
+ fi
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/bugsnag/version'
2
+
3
+ module Fastlane
4
+ module Bugsnag
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ # By default we want to import all available actions and helpers
13
+ # A plugin can contain any number of actions and plugins
14
+ Fastlane::Bugsnag.all_classes.each do |current|
15
+ require current
16
+ end
@@ -0,0 +1,104 @@
1
+ module Fastlane
2
+ module Actions
3
+ class UploadSymbolsToBugsnagAction < Action
4
+
5
+ UPLOAD_SCRIPT_PATH = File.expand_path(
6
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', '..', 'bugsnag-dsym-upload'))
7
+
8
+ def self.run(params)
9
+ parse_dsym_paths(params[:dsym_path]).each do |dsym_path|
10
+ if dsym_path.end_with?(".zip") or File.directory?(dsym_path)
11
+ args = upload_args(dsym_path, params[:symbol_maps_path], params[:upload_url])
12
+ success = Kernel.system(UPLOAD_SCRIPT_PATH, *args)
13
+ UI.success("Uploaded dSYMs in #{dsym_path}") if success
14
+ else
15
+ UI.user_error!("The specified symbol file path cannot be used: #{dsym_path}")
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.description
21
+ "Uploads symbol files to Bugsnag"
22
+ end
23
+
24
+ def self.authors
25
+ ["kattrali"]
26
+ end
27
+
28
+ def self.return_value
29
+ nil
30
+ end
31
+
32
+ def self.details
33
+ "Takes debug symbol (dSYM) files from a macOS, iOS, or tvOS project and uploads them to Bugsnag to improve stacktrace quality"
34
+ end
35
+
36
+ def self.is_supported?(platform)
37
+ [:ios, :mac, :tvos].include?(platform)
38
+ end
39
+
40
+ def self.available_options
41
+ validate_dsym_path = proc do |value|
42
+ value = [value] unless value.is_a? Array
43
+ value.each do |path|
44
+ unless File.exist?(path)
45
+ UI.user_error!("Could not find file at path '#{File.expand_path(path)}'")
46
+ end
47
+ unless File.directory?(path) or path.end_with?(".zip", ".dSYM")
48
+ UI.user_error!("Symbolication file needs to be a directory containing dSYMs, a .dSYM file or a .zip file, got #{File.expand_path(path)}")
49
+ end
50
+ end
51
+ end
52
+ validate_symbol_maps = proc do |path|
53
+ return if path.nil?
54
+
55
+ unless File.exist?(path) and File.directory?(path)
56
+ UI.user_error!("Symbol maps file needs to be a directory containing symbol map files")
57
+ end
58
+ end
59
+ [
60
+ FastlaneCore::ConfigItem.new(key: :dsym_path,
61
+ env_name: "BUGSNAG_DSYM_PATH",
62
+ description: "Path to the DSYM directory, file, or zip to upload",
63
+ default_value: default_dsym_path,
64
+ optional: true,
65
+ verify_block: validate_dsym_path),
66
+ FastlaneCore::ConfigItem.new(key: :upload_url,
67
+ env_name: "BUGSNAG_UPLOAD_URL",
68
+ description: "URL of the server receiving uploaded files",
69
+ default_value: nil,
70
+ optional: true),
71
+ FastlaneCore::ConfigItem.new(key: :symbol_maps_path,
72
+ env_name: "BUGSNAG_SYMBOL_MAPS_PATH",
73
+ description: "Path to the BCSymbolMaps directory to build complete dSYM files",
74
+ default_value: nil,
75
+ optional: true,
76
+ verify_block: validate_symbol_maps)
77
+ ]
78
+ end
79
+
80
+ private
81
+
82
+ def self.upload_args dir, symbol_maps_dir, upload_url
83
+ args = ["--silent"]
84
+ args += ["--upload-server", upload_url] unless upload_url.nil?
85
+ args += ["--symbol-maps", symbol_maps_dir] unless symbol_maps_dir.nil?
86
+ args << dir
87
+ args
88
+ end
89
+
90
+ def self.parse_dsym_paths dsym_path
91
+ dsym_paths = dsym_path.is_a?(Array) ? dsym_path : [dsym_path]
92
+ dsym_paths.compact.map do |path|
93
+ path.end_with?(".dSYM") ? File.dirname(path) : path
94
+ end.uniq
95
+ end
96
+
97
+ def self.default_dsym_path
98
+ Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] ||
99
+ Actions.lane_context[SharedValues::DSYM_PATHS] ||
100
+ Dir["./**/*.dSYM.zip"] + Dir["./**/*.dSYM"]
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module Bugsnag
3
+ VERSION = "1.1.0"
4
+ end
5
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ Action = Fastlane::Actions::UploadSymbolsToBugsnagAction
4
+
5
+ FIXTURE_PATH = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
6
+
7
+ describe Action do
8
+
9
+ it 'has an executable upload script' do
10
+ expect(File.exist?(Action::UPLOAD_SCRIPT_PATH)).to be true
11
+ end
12
+
13
+ describe '#run' do
14
+ it 'silences script output by default' do
15
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
16
+ "--silent", FIXTURE_PATH)
17
+ Action.run({dsym_path: FIXTURE_PATH})
18
+ end
19
+
20
+ it 'requires the dSYM file path to exist' do
21
+ expect(Fastlane::UI).to receive(:user_error!)
22
+
23
+ Action.run({dsym_path: 'fake/file/path'})
24
+ end
25
+
26
+ it 'rejects dSYM files which are not a .zip or a directory' do
27
+ expect(Fastlane::UI).to receive(:user_error!)
28
+
29
+ Action.run({dsym_path: File.join(FIXTURE_PATH, 'invalid_file')})
30
+ end
31
+
32
+ it 'uploads a single .dSYM file' do
33
+ directory = File.join(FIXTURE_PATH, 'dSYMs')
34
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
35
+ "--silent", directory)
36
+ Action.run({dsym_path: File.join(FIXTURE_PATH, 'dSYMs/app.dSYM')})
37
+ end
38
+
39
+ it 'uploads a .zip of .dSYM files' do
40
+ path = File.join(FIXTURE_PATH, 'files.zip')
41
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
42
+ "--silent", path)
43
+ Action.run({dsym_path: path})
44
+ end
45
+
46
+ it 'uploads multiple .zip files' do
47
+ zip1 = File.join(FIXTURE_PATH, 'files.zip')
48
+ zip2 = File.join(FIXTURE_PATH, 'more_files.zip')
49
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
50
+ "--silent", zip1)
51
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
52
+ "--silent", zip2)
53
+ Action.run({dsym_path: [zip1, zip2]})
54
+ end
55
+
56
+ it 'uploads multiple .dSYM files multiple directories' do
57
+ dsym1 = File.join(FIXTURE_PATH, 'dSYMs/app.dSYM')
58
+ dsym2 = File.join(FIXTURE_PATH, 'stuff/app.dSYM')
59
+ dsym3 = File.join(FIXTURE_PATH, 'dSYMs/app2.dSYM')
60
+ dsym4 = File.join(FIXTURE_PATH, 'stuff/app2.dSYM')
61
+ directories = [File.join(FIXTURE_PATH, 'dSYMs'), File.join(FIXTURE_PATH, 'stuff')]
62
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
63
+ "--silent", directories[0])
64
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
65
+ "--silent", directories[1])
66
+ Action.run({dsym_path: [dsym1, dsym2, dsym3, dsym4]})
67
+ end
68
+
69
+ it 'uploads multiple .dSYM files in a single directory' do
70
+ dsym1 = File.join(FIXTURE_PATH, 'dSYMs/app.dSYM')
71
+ dsym2 = File.join(FIXTURE_PATH, 'dSYMs/app2.dSYM')
72
+ directory = File.join(FIXTURE_PATH, 'dSYMs')
73
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
74
+ "--silent", directory)
75
+ Action.run({dsym_path: [dsym1, dsym2]})
76
+ end
77
+
78
+ context 'using a private server' do
79
+ it 'uploads to the private server' do
80
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
81
+ "--silent",
82
+ "--upload-server", "http://myserver.example.com",
83
+ FIXTURE_PATH)
84
+ Action.run({dsym_path: FIXTURE_PATH,
85
+ upload_url: "http://myserver.example.com"})
86
+ end
87
+ end
88
+
89
+ context 'using bitcode' do
90
+ it 'combines dSYM files with symbols' do
91
+ path = File.join(FIXTURE_PATH, 'BCSymbolMaps')
92
+ expect(Kernel).to receive(:system).with(Action::UPLOAD_SCRIPT_PATH,
93
+ "--silent",
94
+ "--symbol-maps", path,
95
+ FIXTURE_PATH)
96
+ Action.run({dsym_path: FIXTURE_PATH, symbol_maps_path: path})
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1 @@
1
+ yep, I am a symbol map!
File without changes
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ # This module is only used to check the environment is currently a testing env
4
+ module SpecHelper
5
+ end
6
+
7
+ require 'fastlane' # to import the Action super class
8
+ require 'fastlane/plugin/bugsnag' # import the actual plugin
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-bugsnag
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Delisa Mason
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
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: bundler
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
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
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: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
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: fastlane
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2.28.5
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 2.28.5
97
+ description:
98
+ email: iskanamagus@gmail.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - LICENSE.txt
104
+ - bugsnag-dsym-upload
105
+ - lib/fastlane/plugin/bugsnag.rb
106
+ - lib/fastlane/plugin/bugsnag/actions/upload_symbols_to_bugsnag.rb
107
+ - lib/fastlane/plugin/bugsnag/version.rb
108
+ - spec/bugsnag_upload_dsym_action_spec.rb
109
+ - spec/fixtures/BCSymbolMaps/real.bcsymbolmap
110
+ - spec/fixtures/dSYMs/app.dSYM/Contents/Resources/DWARF/app
111
+ - spec/fixtures/dSYMs/app2.dSYM/Contents/Resources/DWARF/app2
112
+ - spec/fixtures/files.zip
113
+ - spec/fixtures/invalid_file
114
+ - spec/fixtures/more_files.zip
115
+ - spec/fixtures/stuff/app.dSYM/Contents/Resources/DWARF/app
116
+ - spec/fixtures/stuff/app2.dSYM/Contents/Resources/DWARF/app2
117
+ - spec/spec_helper.rb
118
+ homepage: https://github.com/bugsnag/bugsnag-upload
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.4.5
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Uploads dSYM files to Bugsnag
142
+ test_files:
143
+ - spec/bugsnag_upload_dsym_action_spec.rb
144
+ - spec/fixtures/BCSymbolMaps/real.bcsymbolmap
145
+ - spec/fixtures/dSYMs/app.dSYM/Contents/Resources/DWARF/app
146
+ - spec/fixtures/dSYMs/app2.dSYM/Contents/Resources/DWARF/app2
147
+ - spec/fixtures/files.zip
148
+ - spec/fixtures/invalid_file
149
+ - spec/fixtures/more_files.zip
150
+ - spec/fixtures/stuff/app.dSYM/Contents/Resources/DWARF/app
151
+ - spec/fixtures/stuff/app2.dSYM/Contents/Resources/DWARF/app2
152
+ - spec/spec_helper.rb