cocoapods-bugsnag 2.2.2 → 2.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +2 -3
- data/cocoapods-bugsnag.gemspec +5 -3
- data/lib/cocoapods_bugsnag.rb +58 -41
- data/spec/cocoapods_bugsnag_spec.rb +126 -1
- data/spec/spec_helper.rb +42 -0
- metadata +4 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bd7a73528694640aa6a5d4029fcf1cdbef07d71a0da73ab2b859272e491a8ca
|
4
|
+
data.tar.gz: 2c00d5eea8c273f5d30b2683cb04fb0bc446f17bdf2b2f6f3e6a0233bda6bb9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '042861a83266e07106633d6b236fe5e3ac5271d2bacfd73bf2eb43e50388e81b7e371a7df0ee2bce2a3762f139629ef7a37a2beaa77b8cf73af2120dea75466e'
|
7
|
+
data.tar.gz: 9708b8a7b945b3e99c18df3d5768d1369f0353e83d1266fcf92b90dc2626b258140b55c58bde738fb040f1d1f4121d8fbcdbc9b906ca45c97e96d8ad5d4ecf4b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.3.0 (13 Sept 2022)
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
* The Xcode build phase is now compatible with Xcode 14's `ENABLE_USER_SCRIPT_SANDBOXING` build setting.
|
8
|
+
This requires all dSYM files to be specified in the build phase's "Input Files" list.
|
9
|
+
| [#28](https://github.com/bugsnag/cocoapods-bugsnag/pull/28)
|
10
|
+
|
3
11
|
## 2.2.2 (17 May 2022)
|
4
12
|
|
5
13
|
### Enhancements
|
data/README.md
CHANGED
@@ -40,9 +40,8 @@ pod install
|
|
40
40
|
Once added, uploading your dSYM files to Bugsnag will occur automatically.
|
41
41
|
|
42
42
|
By default, your Bugsnag API key will either be read from the `BUGSNAG_API_KEY`
|
43
|
-
environment variable
|
44
|
-
|
45
|
-
phase in Xcode.
|
43
|
+
environment variable (add an Xcode build setting with this name to set it) or
|
44
|
+
from the `:bugsnag:apiKey` (or `BugsnagAPIKey`) value in your `Info.plist`.
|
46
45
|
|
47
46
|
Uploading can be disabled by setting `DISABLE_COCOAPODS_BUGSNAG=YES` in Xcode's
|
48
47
|
Build Settings or an `xcconfig` file, or as an argument to `xcodebuild`.
|
data/cocoapods-bugsnag.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "cocoapods-bugsnag"
|
3
|
-
spec.version = "2.
|
3
|
+
spec.version = "2.3.0"
|
4
4
|
spec.homepage = "https://bugsnag.com"
|
5
5
|
spec.description = "Configures the dSYM upload phase of your project when integrated with bugsnag."
|
6
6
|
spec.summary = "To get meaningful stacktraces from your crashes, the Bugsnag service needs your dSYM file for your build. This plugin adds an upload phase to your project where needed."
|
@@ -12,11 +12,13 @@ Gem::Specification.new do |spec|
|
|
12
12
|
"cocoapods-bugsnag.gemspec"
|
13
13
|
]
|
14
14
|
spec.extra_rdoc_files = [ "README.md", "CHANGELOG.md" ]
|
15
|
-
spec.test_files = [
|
15
|
+
spec.test_files = [
|
16
|
+
"spec/cocoapods_bugsnag_spec.rb",
|
17
|
+
"spec/spec_helper.rb"
|
18
|
+
]
|
16
19
|
spec.require_paths = [ "lib" ]
|
17
20
|
spec.license = "MIT"
|
18
21
|
|
19
22
|
spec.add_dependency "cocoapods", "~> 1.0"
|
20
23
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
21
|
-
spec.add_development_dependency "bacon", "~> 1.0"
|
22
24
|
end
|
data/lib/cocoapods_bugsnag.rb
CHANGED
@@ -9,41 +9,48 @@ module Pod
|
|
9
9
|
BUGSNAG_PHASE_SCRIPT = <<'RUBY'
|
10
10
|
# Set DISABLE_COCOAPODS_BUGSNAG=YES via Xcode's Build Settings, xcconfig or xcodebuild to skip upload
|
11
11
|
if ENV['DISABLE_COCOAPODS_BUGSNAG'] == 'YES'
|
12
|
-
|
12
|
+
puts 'Skipping dSYM upload'
|
13
13
|
return
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
# Attempt to get the API key from an environment variable (or Xcode build setting)
|
17
|
+
api_key = ENV["BUGSNAG_API_KEY"]
|
17
18
|
|
18
|
-
#
|
19
|
+
# If not present, attempt to lookup the value from the Info.plist
|
19
20
|
unless api_key
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
info_plist_path = "#{ENV["BUILT_PRODUCTS_DIR"]}/#{ENV["INFOPLIST_PATH"]}"
|
25
|
-
plist_buddy_response = `/usr/libexec/PlistBuddy -c "print :bugsnag:apiKey" "#{info_plist_path}"`
|
26
|
-
plist_buddy_response = `/usr/libexec/PlistBuddy -c "print :BugsnagAPIKey" "#{info_plist_path}"` if !$?.success?
|
27
|
-
api_key = plist_buddy_response if $?.success?
|
28
|
-
end
|
21
|
+
info_plist_path = "#{ENV["BUILT_PRODUCTS_DIR"]}/#{ENV["INFOPLIST_PATH"]}"
|
22
|
+
plist_buddy_response = `/usr/libexec/PlistBuddy -c "print :bugsnag:apiKey" "#{info_plist_path}"`
|
23
|
+
plist_buddy_response = `/usr/libexec/PlistBuddy -c "print :BugsnagAPIKey" "#{info_plist_path}"` if !$?.success?
|
24
|
+
api_key = plist_buddy_response if $?.success?
|
29
25
|
end
|
30
26
|
|
31
|
-
fail("No Bugsnag API key detected - add your key to your Info.plist
|
32
|
-
|
33
|
-
fork do
|
34
|
-
Process.setsid
|
35
|
-
STDIN.reopen("/dev/null")
|
36
|
-
STDOUT.reopen("/dev/null", "a")
|
37
|
-
STDERR.reopen("/dev/null", "a")
|
27
|
+
fail("No Bugsnag API key detected - add your key to your Info.plist or BUGSNAG_API_KEY environment variable") unless api_key
|
38
28
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
29
|
+
if ENV['ENABLE_USER_SCRIPT_SANDBOXING'] == 'YES'
|
30
|
+
count = ENV['SCRIPT_INPUT_FILE_COUNT'].to_i
|
31
|
+
abort 'error: dSYMs must be specified as build phase "Input Files" because ENABLE_USER_SCRIPT_SANDBOXING is enabled' unless count > 0
|
32
|
+
dsyms = []
|
33
|
+
for i in 0 .. count - 1
|
34
|
+
file = ENV["SCRIPT_INPUT_FILE_#{i}"]
|
35
|
+
next if file.end_with? '.plist'
|
36
|
+
if File.exist? file
|
37
|
+
dsyms.append file
|
38
|
+
else
|
39
|
+
abort "error: cannot read #{file}" unless ENV['DEBUG_INFORMATION_FORMAT'] != 'dwarf-with-dsym'
|
40
|
+
end
|
46
41
|
end
|
42
|
+
else
|
43
|
+
dsyms = Dir["#{ENV['DWARF_DSYM_FOLDER_PATH']}/*/Contents/Resources/DWARF/*"]
|
44
|
+
end
|
45
|
+
|
46
|
+
dsyms.each do |dsym|
|
47
|
+
Process.detach Process.spawn('/usr/bin/curl', '--http1.1',
|
48
|
+
'-F', "apiKey=#{api_key}",
|
49
|
+
'-F', "dsym=@#{dsym}",
|
50
|
+
'-F', "projectRoot=#{ENV['PROJECT_DIR']}",
|
51
|
+
'https://upload.bugsnag.com/',
|
52
|
+
%i[err out] => :close
|
53
|
+
)
|
47
54
|
end
|
48
55
|
RUBY
|
49
56
|
|
@@ -51,44 +58,54 @@ RUBY
|
|
51
58
|
def integrate!
|
52
59
|
integrate_without_bugsnag!
|
53
60
|
return unless should_add_build_phase?
|
54
|
-
|
61
|
+
|
55
62
|
UI.section("Integrating with Bugsnag") do
|
56
63
|
add_bugsnag_upload_script_phase
|
57
64
|
user_project.save
|
58
65
|
end
|
59
|
-
UI.puts "Added 'Upload Bugsnag dSYM' build phase"
|
60
66
|
end
|
61
67
|
|
62
|
-
|
63
68
|
def add_bugsnag_upload_script_phase
|
64
|
-
|
69
|
+
native_targets.each do |native_target|
|
65
70
|
phase = native_target.shell_script_build_phases.select do |bp|
|
66
71
|
bp.name == BUGSNAG_PHASE_NAME
|
67
|
-
end.first || native_target
|
72
|
+
end.first || add_shell_script_build_phase(native_target, BUGSNAG_PHASE_NAME)
|
68
73
|
|
69
|
-
phase.input_paths =
|
74
|
+
phase.input_paths = dsym_phase_input_paths(phase)
|
70
75
|
phase.shell_path = BUGSNAG_PHASE_SHELL_PATH
|
71
76
|
phase.shell_script = BUGSNAG_PHASE_SCRIPT
|
72
77
|
phase.show_env_vars_in_log = '0'
|
73
78
|
end
|
74
79
|
end
|
75
80
|
|
81
|
+
def add_shell_script_build_phase(native_target, name)
|
82
|
+
UI.puts "Adding '#{name}' build phase to '#{native_target.name}'"
|
83
|
+
native_target.new_shell_script_build_phase(name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def dsym_phase_input_paths(phase)
|
87
|
+
(phase.input_paths + BUGSNAG_PHASE_INPUT_PATHS + target.framework_dsym_paths).uniq
|
88
|
+
end
|
89
|
+
|
76
90
|
def should_add_build_phase?
|
77
91
|
has_bugsnag_dep = target.target_definition.dependencies.any? do |dep|
|
78
|
-
dep.name.
|
92
|
+
dep.name.match?(/bugsnag/i)
|
79
93
|
end
|
80
94
|
uses_bugsnag_plugin = target.target_definition.podfile.plugins.key?('cocoapods-bugsnag')
|
81
95
|
return has_bugsnag_dep && uses_bugsnag_plugin
|
82
96
|
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module Pod
|
101
|
+
class AggregateTarget
|
102
|
+
def framework_dsym_paths
|
103
|
+
return [] unless includes_frameworks?
|
83
104
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
bp.name == BUGSNAG_PHASE_NAME && bp.input_paths == BUGSNAG_PHASE_INPUT_PATHS && bp.shell_path == BUGSNAG_PHASE_SHELL_PATH && bp.shell_script == BUGSNAG_PHASE_SCRIPT
|
89
|
-
end
|
90
|
-
end
|
91
|
-
)
|
105
|
+
framework_paths_by_config['Release'].map do |framework|
|
106
|
+
name = File.basename(framework.source_path, '.framework')
|
107
|
+
"#{framework.source_path}.dSYM/Contents/Resources/DWARF/#{name}"
|
108
|
+
end
|
92
109
|
end
|
93
110
|
end
|
94
111
|
end
|
@@ -1,3 +1,128 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'cocoapods'
|
4
|
+
require 'cocoapods_bugsnag'
|
5
|
+
require 'tmpdir'
|
3
6
|
|
7
|
+
# rubocop:disable Lint/MissingCopEnableDirective, Metrics/BlockLength
|
8
|
+
|
9
|
+
RSpec.describe 'cocoapods-bugsnag' do
|
10
|
+
context 'with a user project' do
|
11
|
+
around(:each) do |t|
|
12
|
+
Dir.chdir(Dir.mktmpdir) { t.run }
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:config) { Pod::Config.instance }
|
16
|
+
|
17
|
+
before do
|
18
|
+
user_project = Xcodeproj::Project.new('App.xcodeproj')
|
19
|
+
Pod::Generator::AppTargetHelper.add_app_target(user_project, :osx, '10.11')
|
20
|
+
user_project.save
|
21
|
+
|
22
|
+
CLAide::Command::PluginManager.load_plugins('cocoapods')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'adds a build phase if included in Podfile' do
|
26
|
+
File.write 'Podfile', <<~RUBY
|
27
|
+
use_frameworks!
|
28
|
+
plugin 'cocoapods-bugsnag'
|
29
|
+
target 'App' do
|
30
|
+
pod 'AFNetworking'
|
31
|
+
pod 'Bugsnag'
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
|
35
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
36
|
+
installer.install!
|
37
|
+
|
38
|
+
expect(Pod::UI.output).to include "Adding 'Upload Bugsnag dSYM' build phase to 'App'"
|
39
|
+
|
40
|
+
expect(installer.aggregate_targets.flat_map(&:user_targets)).to all(satisfy do |target|
|
41
|
+
upload_phase = target.shell_script_build_phases.find { |bp| bp.name == 'Upload Bugsnag dSYM' }
|
42
|
+
expect(upload_phase.shell_path).to eq '/usr/bin/env ruby'
|
43
|
+
expect(upload_phase.shell_script).to include 'BUGSNAG_API_KEY'
|
44
|
+
expect(upload_phase.shell_script).to include 'SCRIPT_INPUT_FILE_COUNT'
|
45
|
+
expect(upload_phase.show_env_vars_in_log).to eq '0'
|
46
|
+
expect(upload_phase.input_paths).to eq %w[
|
47
|
+
${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}
|
48
|
+
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}
|
49
|
+
${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework.dSYM/Contents/Resources/DWARF/AFNetworking
|
50
|
+
${BUILT_PRODUCTS_DIR}/Bugsnag/Bugsnag.framework.dSYM/Contents/Resources/DWARF/Bugsnag
|
51
|
+
]
|
52
|
+
end)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not remove existing input phases' do
|
56
|
+
File.write 'Podfile', <<~RUBY
|
57
|
+
use_frameworks!
|
58
|
+
plugin 'cocoapods-bugsnag'
|
59
|
+
target 'App' do
|
60
|
+
pod 'AFNetworking'
|
61
|
+
pod 'Bugsnag'
|
62
|
+
end
|
63
|
+
RUBY
|
64
|
+
|
65
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
66
|
+
installer.install!
|
67
|
+
|
68
|
+
expect(Pod::UI.output).to include "Adding 'Upload Bugsnag dSYM' build phase to 'App'"
|
69
|
+
Pod::UI.output = ''.dup
|
70
|
+
|
71
|
+
File.write 'Podfile', <<~RUBY
|
72
|
+
use_frameworks!
|
73
|
+
plugin 'cocoapods-bugsnag'
|
74
|
+
target 'App' do
|
75
|
+
# AFNetworking now omitted
|
76
|
+
pod 'Bugsnag'
|
77
|
+
end
|
78
|
+
RUBY
|
79
|
+
|
80
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
81
|
+
installer.install!
|
82
|
+
|
83
|
+
expect(Pod::UI.output).not_to include "Adding 'Upload Bugsnag dSYM' build phase to 'App'"
|
84
|
+
|
85
|
+
expect(installer.aggregate_targets.flat_map(&:user_targets)).to all(satisfy do |target|
|
86
|
+
upload_phase = target.shell_script_build_phases.find { |bp| bp.name == 'Upload Bugsnag dSYM' }
|
87
|
+
expect(upload_phase.input_paths).to include(
|
88
|
+
'${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework.dSYM/Contents/Resources/DWARF/AFNetworking'
|
89
|
+
)
|
90
|
+
end)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does nothing if Bugsnag is not a dependency' do
|
94
|
+
File.write 'Podfile', <<~RUBY
|
95
|
+
plugin 'cocoapods-bugsnag'
|
96
|
+
target 'App'
|
97
|
+
RUBY
|
98
|
+
|
99
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
100
|
+
installer.install!
|
101
|
+
|
102
|
+
expect(Pod::UI.output).not_to include "Adding 'Upload Bugsnag dSYM' build phase to 'App'"
|
103
|
+
|
104
|
+
expect(installer.aggregate_targets.flat_map(&:user_targets)).to all(satisfy do |target|
|
105
|
+
upload_phase = target.shell_script_build_phases.find { |bp| bp.name == 'Upload Bugsnag dSYM' }
|
106
|
+
expect(upload_phase).to be_nil
|
107
|
+
end)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'does nothing if not added as a plugin' do
|
111
|
+
File.write 'Podfile', <<~RUBY
|
112
|
+
target 'App' do
|
113
|
+
pod 'Bugsnag'
|
114
|
+
end
|
115
|
+
RUBY
|
116
|
+
|
117
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
118
|
+
installer.install!
|
119
|
+
|
120
|
+
expect(Pod::UI.output).not_to include "Adding 'Upload Bugsnag dSYM' build phase to 'App'"
|
121
|
+
|
122
|
+
expect(installer.aggregate_targets.flat_map(&:user_targets)).to all(satisfy do |target|
|
123
|
+
upload_phase = target.shell_script_build_phases.find { |bp| bp.name == 'Upload Bugsnag dSYM' }
|
124
|
+
expect(upload_phase).to be_nil
|
125
|
+
end)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods'
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
# Disable the wrapping so the output is deterministic in the tests.
|
7
|
+
#
|
8
|
+
UI.disable_wrap = true
|
9
|
+
|
10
|
+
# Redirects the messages to an internal store.
|
11
|
+
#
|
12
|
+
module UI
|
13
|
+
class << self
|
14
|
+
attr_accessor :output, :warnings, :next_input
|
15
|
+
|
16
|
+
def puts(message = '')
|
17
|
+
@output << "#{message}\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
def warn(message = '', _actions = [])
|
21
|
+
@warnings << "#{message}\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
def print(message)
|
25
|
+
@output << message
|
26
|
+
end
|
27
|
+
|
28
|
+
alias gets next_input
|
29
|
+
|
30
|
+
def print_warnings; end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec.configure do |config|
|
36
|
+
config.before(:each) do
|
37
|
+
Pod::UI.output = ''.dup
|
38
|
+
Pod::UI.warnings = ''.dup
|
39
|
+
Pod::UI.next_input = ''.dup
|
40
|
+
Pod::Config.instance = nil
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-bugsnag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delisa Mason
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cocoapods
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 12.3.3
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: bacon
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.0'
|
55
41
|
description: Configures the dSYM upload phase of your project when integrated with
|
56
42
|
bugsnag.
|
57
43
|
email:
|
@@ -68,6 +54,7 @@ files:
|
|
68
54
|
- lib/cocoapods_bugsnag.rb
|
69
55
|
- lib/cocoapods_plugin.rb
|
70
56
|
- spec/cocoapods_bugsnag_spec.rb
|
57
|
+
- spec/spec_helper.rb
|
71
58
|
homepage: https://bugsnag.com
|
72
59
|
licenses:
|
73
60
|
- MIT
|
@@ -95,3 +82,4 @@ summary: To get meaningful stacktraces from your crashes, the Bugsnag service ne
|
|
95
82
|
where needed.
|
96
83
|
test_files:
|
97
84
|
- spec/cocoapods_bugsnag_spec.rb
|
85
|
+
- spec/spec_helper.rb
|