xcode-archive-cache 0.0.9 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/artifact_cache/archiver.rb +2 -1
- data/lib/artifact_cache/local_storage.rb +2 -1
- data/lib/build/performer.rb +1 -1
- data/lib/build/product_extractor.rb +92 -9
- data/lib/build_graph/builder.rb +10 -10
- data/lib/build_graph/native_target_finder.rb +123 -13
- data/lib/build_graph/node.rb +50 -2
- data/lib/build_graph/rebuild_evaluator.rb +30 -4
- data/lib/build_graph/sha_calculator.rb +22 -1
- data/lib/build_settings/extractor.rb +23 -1
- data/lib/build_settings/filter.rb +7 -3
- data/lib/build_settings/loader.rb +10 -1
- data/lib/build_settings/parser.rb +29 -6
- data/lib/build_settings/string_interpolator.rb +21 -5
- data/lib/config/config.rb +2 -2
- data/lib/extensions/build_configuration.rb +26 -0
- data/lib/extensions/target.rb +58 -0
- data/lib/injection/build_flags_changer.rb +176 -4
- data/lib/injection/dependency_remover.rb +22 -1
- data/lib/injection/headers_mover.rb +27 -3
- data/lib/injection/injector.rb +70 -33
- data/lib/injection/pods_script_fixer.rb +2 -20
- data/lib/injection/pods_xcframework_fixer.rb +126 -0
- data/lib/injection/storage.rb +47 -6
- data/lib/modulemap/file_handler.rb +20 -0
- data/lib/modulemap/header_path_extractor.rb +67 -0
- data/lib/modulemap/header_path_fixer.rb +65 -0
- data/lib/runner/runner.rb +39 -28
- data/lib/shell/executor.rb +15 -3
- data/lib/xcode-archive-cache.rb +8 -0
- data/lib/xcodebuild/executor.rb +5 -1
- metadata +18 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c3de4b956fe76ce673329ecf9977a911d3c6bb3055c00e59c3e6903cb16e6b2
|
4
|
+
data.tar.gz: 92253d7316a2a716b71a053f182483e7af54aeb1662111175f3e071909d79998
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88b0a7e44eecbdc426755761dd5df10fb0e1cff4a00c44f915df1f65515685ce3f2527d8d9b1173ea439bff032d49f4875f32a859291a702f829d378103c8234
|
7
|
+
data.tar.gz: c63650b58e921da5e38bb8648d0e6e3cfeddb55165e72f8984511c769a139b6ab3108350c0e684ed27ed9dbf9e02ef46135cc315a182ebc00586bb33c3fdae1f
|
@@ -9,7 +9,8 @@ module XcodeArchiveCache
|
|
9
9
|
#
|
10
10
|
def archive(path, destination)
|
11
11
|
if File.exists?(destination)
|
12
|
-
|
12
|
+
warn "Replacing artifact archive at path #{destination}"
|
13
|
+
FileUtils.rm_rf(destination)
|
13
14
|
end
|
14
15
|
|
15
16
|
if File.file?(path)
|
@@ -60,7 +60,8 @@ module XcodeArchiveCache
|
|
60
60
|
state_file_path = archive_path + ".state"
|
61
61
|
|
62
62
|
if File.exist?(state_file_path)
|
63
|
-
|
63
|
+
warn "Replacing state file #{state_file_path}"
|
64
|
+
FileUtils.rm_f(state_file_path)
|
64
65
|
end
|
65
66
|
|
66
67
|
dependency_shas = node.dependencies
|
data/lib/build/performer.rb
CHANGED
@@ -2,6 +2,8 @@ module XcodeArchiveCache
|
|
2
2
|
module Build
|
3
3
|
class ProductExtractor
|
4
4
|
|
5
|
+
include XcodeArchiveCache::Logs
|
6
|
+
|
5
7
|
# @param [String] configuration
|
6
8
|
# @param [String] derived_data_path
|
7
9
|
#
|
@@ -17,7 +19,9 @@ module XcodeArchiveCache
|
|
17
19
|
#
|
18
20
|
def list_product_contents(built_node)
|
19
21
|
file_paths = list_products(built_node)
|
20
|
-
file_paths
|
22
|
+
file_paths
|
23
|
+
.select { |path| File.exist?(path) }
|
24
|
+
.map { |path| File.realpath(path) }
|
21
25
|
end
|
22
26
|
|
23
27
|
private
|
@@ -44,7 +48,7 @@ module XcodeArchiveCache
|
|
44
48
|
elsif built_node.has_acceptable_product?
|
45
49
|
list_single_product(built_node)
|
46
50
|
else
|
47
|
-
raise Informative, "#{built_node.name} has unsupported product type: #{built_node.native_target.product_type}"
|
51
|
+
raise XcodeArchiveCache::Informative, "#{built_node.name} has unsupported product type: #{built_node.native_target.product_type}"
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -56,7 +60,7 @@ module XcodeArchiveCache
|
|
56
60
|
framework_glob = get_main_product_glob(built_node)
|
57
61
|
framework_path = Dir.glob(framework_glob).first
|
58
62
|
unless framework_path
|
59
|
-
raise Informative, "Framework product not found for #{built_node.name}"
|
63
|
+
raise XcodeArchiveCache::Informative, "Framework product not found for #{built_node.name}"
|
60
64
|
end
|
61
65
|
|
62
66
|
framework_dsym_glob = File.join(File.dirname(framework_glob), built_node.dsym_file_name)
|
@@ -75,10 +79,42 @@ module XcodeArchiveCache
|
|
75
79
|
product_glob = get_main_product_glob(built_node)
|
76
80
|
product_path = Dir.glob(product_glob).first
|
77
81
|
unless product_path
|
78
|
-
raise Informative, "Product of type #{built_node.native_target.product_type} not found for #{built_node.name}"
|
82
|
+
raise XcodeArchiveCache::Informative, "Product of type #{built_node.native_target.product_type} not found for #{built_node.name}"
|
83
|
+
end
|
84
|
+
|
85
|
+
paths = [product_path]
|
86
|
+
|
87
|
+
# this one is generated during Swift compilation
|
88
|
+
# so we need to cache it as well
|
89
|
+
#
|
90
|
+
swift_objc_interface_header_glob = get_swift_objc_interface_header_glob(built_node)
|
91
|
+
swift_objc_interface_header_path = Dir.glob(swift_objc_interface_header_glob).first
|
92
|
+
if swift_objc_interface_header_path
|
93
|
+
debug("using Swift-ObjC interface header #{swift_objc_interface_header_path}")
|
94
|
+
paths << swift_objc_interface_header_path
|
95
|
+
end
|
96
|
+
|
97
|
+
swiftmodule_glob = get_swiftmodule_glob(built_node)
|
98
|
+
if swiftmodule_glob
|
99
|
+
swiftmodule_path = Dir.glob(swiftmodule_glob).first
|
100
|
+
|
101
|
+
if swiftmodule_path
|
102
|
+
debug("using swiftmodule #{swiftmodule_path}")
|
103
|
+
paths << swiftmodule_path
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
modulemap_glob = get_modulemap_glob(built_node)
|
108
|
+
if modulemap_glob
|
109
|
+
modulemap_path = Dir.glob(modulemap_glob).first
|
110
|
+
|
111
|
+
if modulemap_path
|
112
|
+
debug("using modulemap #{modulemap_path}")
|
113
|
+
paths << modulemap_path
|
114
|
+
end
|
79
115
|
end
|
80
116
|
|
81
|
-
|
117
|
+
paths
|
82
118
|
end
|
83
119
|
|
84
120
|
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
@@ -89,9 +125,52 @@ module XcodeArchiveCache
|
|
89
125
|
product_name = built_node.native_target.product_reference.name ?
|
90
126
|
built_node.native_target.product_reference.name :
|
91
127
|
built_node.native_target.product_reference.path
|
128
|
+
get_product_glob(File.basename(product_name))
|
129
|
+
end
|
130
|
+
|
131
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
132
|
+
#
|
133
|
+
# @return [String]
|
134
|
+
#
|
135
|
+
def get_swift_objc_interface_header_glob(built_node)
|
136
|
+
get_product_glob(File.basename(built_node.swift_objc_interface_header_file))
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
140
|
+
#
|
141
|
+
# @return [String]
|
142
|
+
#
|
143
|
+
def get_swiftmodule_glob(built_node)
|
144
|
+
if built_node.module_name
|
145
|
+
get_product_glob(built_node.module_name + ".swiftmodule")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
150
|
+
#
|
151
|
+
# @return [String]
|
152
|
+
#
|
153
|
+
def get_modulemap_glob(built_node)
|
154
|
+
resulting_modulemap_file_name = built_node.resulting_modulemap_file_name
|
155
|
+
if resulting_modulemap_file_name
|
156
|
+
get_product_glob(resulting_modulemap_file_name)
|
157
|
+
else
|
158
|
+
modulemap_file_path = built_node.original_modulemap_file_path
|
159
|
+
if modulemap_file_path && File.exist?(modulemap_file_path)
|
160
|
+
modulemap_file_name = File.basename(modulemap_file_path)
|
161
|
+
get_product_glob(modulemap_file_name)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# @param [String] file_name
|
167
|
+
#
|
168
|
+
# @return [String]
|
169
|
+
#
|
170
|
+
def get_product_glob(file_name)
|
92
171
|
File.join(derived_data_path,
|
93
172
|
"**",
|
94
|
-
|
173
|
+
file_name)
|
95
174
|
end
|
96
175
|
|
97
176
|
# @param [String] framework_path
|
@@ -102,11 +181,11 @@ module XcodeArchiveCache
|
|
102
181
|
executable_name = File.basename(framework_path, File.extname(framework_path))
|
103
182
|
executable_path = File.join(framework_path, executable_name)
|
104
183
|
unless File.exist?(executable_path)
|
105
|
-
raise Informative, "Failed to find executable inside framework: #{framework_path}"
|
184
|
+
raise XcodeArchiveCache::Informative, "Failed to find executable inside framework: #{framework_path}"
|
106
185
|
end
|
107
186
|
|
108
187
|
uuids = list_bc_symbolmap_uuids(executable_path)
|
109
|
-
uuids.map {|uuid| find_bc_symbolmap(uuid)}.flatten
|
188
|
+
uuids.map { |uuid| find_bc_symbolmap(uuid) }.flatten
|
110
189
|
end
|
111
190
|
|
112
191
|
# @param [String] executable_path
|
@@ -114,7 +193,11 @@ module XcodeArchiveCache
|
|
114
193
|
# @return [Array<String>]
|
115
194
|
#
|
116
195
|
def list_bc_symbolmap_uuids(executable_path)
|
117
|
-
|
196
|
+
begin
|
197
|
+
shell_executor.execute_for_output("otool -l #{executable_path} | grep uuid | awk {'print $2'}").split("\n")
|
198
|
+
rescue
|
199
|
+
[]
|
200
|
+
end
|
118
201
|
end
|
119
202
|
|
120
203
|
# @param [String] uuid
|
data/lib/build_graph/builder.rb
CHANGED
@@ -6,8 +6,8 @@ module XcodeArchiveCache
|
|
6
6
|
|
7
7
|
# @param [XcodeArchiveCache::Xcodebuild::Executor] xcodebuild_executor
|
8
8
|
#
|
9
|
-
def initialize(native_target_finder,
|
10
|
-
@build_settings_loader =
|
9
|
+
def initialize(native_target_finder, build_settings_loader)
|
10
|
+
@build_settings_loader = build_settings_loader
|
11
11
|
@native_target_finder = native_target_finder
|
12
12
|
@sha_calculator = NodeShaCalculator.new
|
13
13
|
end
|
@@ -61,13 +61,17 @@ module XcodeArchiveCache
|
|
61
61
|
display_name = target.display_name
|
62
62
|
if target_stack.include?(display_name)
|
63
63
|
target_stack.push(display_name)
|
64
|
-
raise Informative, "Circular dependency detected: #{target_stack.join(" -> ")}"
|
64
|
+
raise XcodeArchiveCache::Informative, "Circular dependency detected: #{target_stack.join(" -> ")}"
|
65
65
|
end
|
66
66
|
|
67
67
|
node = ALL_NODES.select {|node| node.native_target.uuid == target.uuid && node.native_target.project == target.project}.first
|
68
68
|
if node
|
69
69
|
debug("already traversed this one")
|
70
|
-
|
70
|
+
unless graph.nodes.include?(node)
|
71
|
+
nodes_to_add = node.subgraph.select {|subgraph_node| !graph.nodes.include?(subgraph_node)}
|
72
|
+
graph.add_multiple_nodes(nodes_to_add)
|
73
|
+
end
|
74
|
+
|
71
75
|
return node
|
72
76
|
else
|
73
77
|
debug("adding new node")
|
@@ -79,11 +83,7 @@ module XcodeArchiveCache
|
|
79
83
|
dependencies = []
|
80
84
|
target_stack.push(display_name)
|
81
85
|
|
82
|
-
|
83
|
-
target.frameworks_build_phase.files.map {|file| native_target_finder.find_for_file(file)}
|
84
|
-
|
85
|
-
# PBXNativeTarget has no custom equality check
|
86
|
-
deduplicated_targets = dependency_targets.compact.uniq {|dependency_target| dependency_target.uuid + dependency_target.display_name}
|
86
|
+
deduplicated_targets = native_target_finder.find_native_dependencies(target)
|
87
87
|
debug("dependency targets: #{deduplicated_targets.map(&:display_name)}")
|
88
88
|
|
89
89
|
deduplicated_targets.each do |dependency_target|
|
@@ -141,7 +141,7 @@ module XcodeArchiveCache
|
|
141
141
|
info("getting settings for #{target.display_name}")
|
142
142
|
build_settings = build_settings_loader.get_settings(target.project.path, target.display_name)
|
143
143
|
unless build_settings
|
144
|
-
raise Informative, "No build settings loaded for #{target.display_name}"
|
144
|
+
raise XcodeArchiveCache::Informative, "No build settings loaded for #{target.display_name}"
|
145
145
|
end
|
146
146
|
|
147
147
|
build_settings
|
@@ -3,9 +3,14 @@ module XcodeArchiveCache
|
|
3
3
|
class NativeTargetFinder
|
4
4
|
|
5
5
|
# @param [Array<Xcodeproj::Project>] projects
|
6
|
+
# @param [String] build_configuration_name
|
6
7
|
#
|
7
|
-
def initialize(projects)
|
8
|
+
def initialize(projects, build_configuration_name)
|
8
9
|
@all_targets = extract_targets(projects)
|
10
|
+
@build_configuration_name = build_configuration_name
|
11
|
+
@interpolator = XcodeArchiveCache::BuildSettings::StringInterpolator.new
|
12
|
+
|
13
|
+
setup_product_name_to_target_mapping
|
9
14
|
end
|
10
15
|
|
11
16
|
# @param [Array<Xcodeproj::Project>] projects
|
@@ -14,30 +19,67 @@ module XcodeArchiveCache
|
|
14
19
|
#
|
15
20
|
def extract_targets(projects)
|
16
21
|
projects
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
.map {|project| unnest(project)}
|
23
|
+
.flatten
|
24
|
+
.sort_by(&:path)
|
25
|
+
.inject([]) {|unique, current| unique.last && unique.last.path == current.path ? unique : unique + [current]}
|
26
|
+
.map(&:native_targets)
|
27
|
+
.flatten
|
28
|
+
.select {|target| !target.test_target_type?}
|
23
29
|
end
|
24
30
|
|
25
31
|
# @param [String] platform_name
|
26
32
|
#
|
33
|
+
# @return [Array<Xcodeproj::Project::Object::PBXNativeTarget>]
|
34
|
+
#
|
27
35
|
def set_platform_name_filter(platform_name)
|
28
36
|
@platform_name = platform_name
|
29
37
|
end
|
30
38
|
|
39
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
40
|
+
#
|
41
|
+
# @return [Array<Xcodeproj::Project::Object::PBXNativeTarget>]
|
42
|
+
#
|
43
|
+
def find_native_dependencies(target)
|
44
|
+
direct_dependencies = target
|
45
|
+
.dependencies
|
46
|
+
.map {|dependency| find_for_dependency(dependency)}
|
47
|
+
linked_dependencies = find_linked_dependencies(target)
|
48
|
+
join(direct_dependencies, linked_dependencies)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param [Xcodeproj::Project::Object::PBXAbstractTarget] target
|
52
|
+
#
|
53
|
+
# @return [Array<Xcodeproj::Project::Object::PBXAbstractTarget>]
|
54
|
+
#
|
55
|
+
def find_all_dependencies(target)
|
56
|
+
direct_dependencies = target
|
57
|
+
.dependencies
|
58
|
+
.map {|dependency| find_any_for_dependency(dependency)}
|
59
|
+
linked_dependencies = []
|
60
|
+
|
61
|
+
if target.is_a?(Xcodeproj::Project::Object::PBXNativeTarget)
|
62
|
+
linked_dependencies = find_linked_dependencies(target)
|
63
|
+
end
|
64
|
+
|
65
|
+
join(direct_dependencies, linked_dependencies)
|
66
|
+
end
|
67
|
+
|
31
68
|
# @param [Xcodeproj::Project::Object::PBXTargetDependency] dependency
|
32
69
|
#
|
33
70
|
# @return [Xcodeproj::Project::Object::PBXNativeTarget]
|
34
71
|
#
|
35
72
|
def find_for_dependency(dependency)
|
36
73
|
# targets from embedded projects are proxied
|
37
|
-
target = dependency
|
74
|
+
target = find_any_for_dependency(dependency)
|
38
75
|
target.is_a?(Xcodeproj::Project::Object::PBXNativeTarget) ? target : nil
|
39
76
|
end
|
40
77
|
|
78
|
+
def find_any_for_dependency(dependency)
|
79
|
+
target = dependency.target ? dependency.target : dependency.target_proxy.proxied_object
|
80
|
+
target && target.platform_name == platform_name ? target : nil
|
81
|
+
end
|
82
|
+
|
41
83
|
# @param [Xcodeproj::Project::Object::PBXBuildFile] file
|
42
84
|
#
|
43
85
|
# @return [Xcodeproj::Project::Object::PBXNativeTarget]
|
@@ -60,7 +102,7 @@ module XcodeArchiveCache
|
|
60
102
|
end
|
61
103
|
|
62
104
|
if target == nil
|
63
|
-
raise Informative, "Target for #{file.file_ref.path} not found"
|
105
|
+
raise XcodeArchiveCache::Informative, "Target for #{file.file_ref.path} not found"
|
64
106
|
end
|
65
107
|
|
66
108
|
target
|
@@ -68,7 +110,7 @@ module XcodeArchiveCache
|
|
68
110
|
# products of sibling project targets are added as PBXFileReferences
|
69
111
|
targets = find_with_product_path(file.file_ref.path)
|
70
112
|
if targets.length > 1
|
71
|
-
raise Informative, "Found more than one target with product #{File.basename(file.file_ref.path)} in:\n#{targets.map(&:project)}"
|
113
|
+
raise XcodeArchiveCache::Informative, "Found more than one target with product #{File.basename(file.file_ref.path)} in:\n#{targets.map(&:project)}"
|
72
114
|
end
|
73
115
|
|
74
116
|
targets.first
|
@@ -77,9 +119,16 @@ module XcodeArchiveCache
|
|
77
119
|
|
78
120
|
# @param [String] product_name
|
79
121
|
#
|
122
|
+
# @return [Xcodeproj::Project::Object::PBXNativeTarget]
|
123
|
+
#
|
80
124
|
def find_for_product_name(product_name)
|
81
|
-
|
82
|
-
|
125
|
+
canonical = all_targets
|
126
|
+
.select {|native_target| native_target.name == product_name || native_target.product_reference.display_name == product_name}
|
127
|
+
.first
|
128
|
+
|
129
|
+
parsed = @product_name_to_target[product_name]
|
130
|
+
|
131
|
+
canonical ? canonical : parsed
|
83
132
|
end
|
84
133
|
|
85
134
|
private
|
@@ -92,6 +141,36 @@ module XcodeArchiveCache
|
|
92
141
|
#
|
93
142
|
attr_accessor :platform_name
|
94
143
|
|
144
|
+
# @return [String]
|
145
|
+
#
|
146
|
+
attr_reader :build_configuration_name
|
147
|
+
|
148
|
+
def setup_product_name_to_target_mapping
|
149
|
+
@product_name_to_target = Hash.new
|
150
|
+
|
151
|
+
@all_targets.each do |target|
|
152
|
+
build_settings = target.find_build_configuration(build_configuration_name, raise_if_not_found: false)&.build_settings
|
153
|
+
next unless build_settings
|
154
|
+
|
155
|
+
full_settings = build_settings
|
156
|
+
full_settings[XcodeArchiveCache::BuildSettings::TARGET_NAME_KEY] = target.name
|
157
|
+
product_name = @interpolator.interpolate(build_settings[XcodeArchiveCache::BuildSettings::PRODUCT_NAME_KEY], full_settings)
|
158
|
+
|
159
|
+
next if product_name == nil
|
160
|
+
|
161
|
+
product_name_extension = ""
|
162
|
+
case target.product_type
|
163
|
+
when Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]
|
164
|
+
product_name_extension = ".framework"
|
165
|
+
when Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]
|
166
|
+
product_name_extension = ".a"
|
167
|
+
end
|
168
|
+
|
169
|
+
full_product_name = "#{product_name}#{product_name_extension}"
|
170
|
+
@product_name_to_target[full_product_name] = target
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
95
174
|
# @param [Xcodeproj::Project] project
|
96
175
|
#
|
97
176
|
# @return [Array<Xcodeproj::Project>]
|
@@ -106,6 +185,28 @@ module XcodeArchiveCache
|
|
106
185
|
[project] + nested_projects + subnested_projects
|
107
186
|
end
|
108
187
|
|
188
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
189
|
+
#
|
190
|
+
# @return [Array<Xcodeproj::Project::Object::PBXNativeTarget>]
|
191
|
+
#
|
192
|
+
def find_linked_dependencies(target)
|
193
|
+
target
|
194
|
+
.frameworks_build_phase
|
195
|
+
.files
|
196
|
+
.map {|file| find_for_file(file)}
|
197
|
+
end
|
198
|
+
|
199
|
+
# @param [Array<Xcodeproj::Project::Object::PBXAbstractTarget>] direct_dependencies
|
200
|
+
# @params [Array<Xcodeproj::Project::Object::PBXNativeTarget>] linked_dependencies
|
201
|
+
#
|
202
|
+
# @return [Array<Xcodeproj::Project::Object::PBXAbstractTarget>]
|
203
|
+
#
|
204
|
+
def join(direct_dependencies, linked_dependencies)
|
205
|
+
(direct_dependencies + linked_dependencies)
|
206
|
+
.compact
|
207
|
+
.uniq(&:equatable_identifier)
|
208
|
+
end
|
209
|
+
|
109
210
|
# @param [String] uuid
|
110
211
|
#
|
111
212
|
# @return [Xcodeproj::Project::Object::PBXNativeTarget]
|
@@ -128,7 +229,16 @@ module XcodeArchiveCache
|
|
128
229
|
# @return [Array<Xcodeproj::Project::Object::PBXNativeTarget>]
|
129
230
|
#
|
130
231
|
def find_with_product_path(path)
|
131
|
-
all_targets.select {|target| target.platform_name == platform_name && target.product_reference.path == path}
|
232
|
+
canonical = all_targets.select {|target| target.platform_name == platform_name && target.product_reference.path == path }
|
233
|
+
parsed = @product_name_to_target[File.basename(path)]
|
234
|
+
|
235
|
+
if canonical.length > 0
|
236
|
+
canonical
|
237
|
+
elsif parsed
|
238
|
+
[parsed]
|
239
|
+
else
|
240
|
+
[]
|
241
|
+
end
|
132
242
|
end
|
133
243
|
end
|
134
244
|
end
|