xcode-archive-cache 0.0.10.pre.1 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/build/product_extractor.rb +84 -11
- data/lib/build_graph/builder.rb +10 -10
- data/lib/build_graph/native_target_finder.rb +123 -13
- data/lib/build_graph/node.rb +19 -7
- data/lib/build_graph/sha_calculator.rb +20 -2
- data/lib/build_settings/extractor.rb +2 -0
- data/lib/build_settings/loader.rb +2 -0
- data/lib/build_settings/parser.rb +28 -5
- 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 +149 -46
- data/lib/injection/dependency_remover.rb +22 -1
- data/lib/injection/headers_mover.rb +13 -2
- data/lib/injection/injector.rb +53 -34
- data/lib/injection/pods_script_fixer.rb +18 -33
- data/lib/injection/pods_xcframework_fixer.rb +126 -0
- data/lib/injection/storage.rb +16 -16
- 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 -20
- data/lib/shell/executor.rb +13 -1
- data/lib/xcode-archive-cache.rb +8 -1
- data/lib/xcodebuild/executor.rb +1 -1
- metadata +20 -15
- data/lib/injection/modulemap_fixer.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2121ee4ca94b2acfa38e1071a6f30209381464a7da5239e919d4b70cafd1d84
|
4
|
+
data.tar.gz: 9874700c995c65ee3ecaa4772a1aa6deba6868591b96da6d271b9ee1f32588df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 528092da4900b8232d71a9583ec0752c92ff2ee851bc13db3609c91c1a9aec3db4278abb777a3c574728d35b409b59ede6fc1481c0dafed49b93a396b994b114
|
7
|
+
data.tar.gz: c16c9ff1c2623437b5e29c0fea3cd1bc10cfe631c4df1772197595392b5a05286a8223294c20f9dc306b5ed47089f7c7c85c7eeb4138a940d2a37861c6266bdc
|
@@ -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,7 +79,7 @@ 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}"
|
79
83
|
end
|
80
84
|
|
81
85
|
paths = [product_path]
|
@@ -83,8 +87,32 @@ module XcodeArchiveCache
|
|
83
87
|
# this one is generated during Swift compilation
|
84
88
|
# so we need to cache it as well
|
85
89
|
#
|
86
|
-
|
87
|
-
|
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
|
115
|
+
end
|
88
116
|
|
89
117
|
paths
|
90
118
|
end
|
@@ -94,12 +122,57 @@ module XcodeArchiveCache
|
|
94
122
|
# @return [String]
|
95
123
|
#
|
96
124
|
def get_main_product_glob(built_node)
|
97
|
-
|
98
|
-
|
99
|
-
|
125
|
+
product_names = [File.basename(built_node.native_target.product_reference.path)]
|
126
|
+
if built_node.native_target.product_reference.name
|
127
|
+
product_names.push(File.basename(built_node.native_target.product_reference.name))
|
128
|
+
end
|
129
|
+
|
130
|
+
get_product_glob(product_names.select { |name| File.extname(name).length > 0 })
|
131
|
+
end
|
132
|
+
|
133
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
134
|
+
#
|
135
|
+
# @return [String]
|
136
|
+
#
|
137
|
+
def get_swift_objc_interface_header_glob(built_node)
|
138
|
+
get_product_glob([File.basename(built_node.swift_objc_interface_header_file)])
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
142
|
+
#
|
143
|
+
# @return [String]
|
144
|
+
#
|
145
|
+
def get_swiftmodule_glob(built_node)
|
146
|
+
if built_node.module_name
|
147
|
+
get_product_glob([built_node.module_name + ".swiftmodule"])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
152
|
+
#
|
153
|
+
# @return [String]
|
154
|
+
#
|
155
|
+
def get_modulemap_glob(built_node)
|
156
|
+
resulting_modulemap_file_name = built_node.resulting_modulemap_file_name
|
157
|
+
if resulting_modulemap_file_name
|
158
|
+
get_product_glob([resulting_modulemap_file_name])
|
159
|
+
else
|
160
|
+
modulemap_file_path = built_node.original_modulemap_file_path
|
161
|
+
if modulemap_file_path && File.exist?(modulemap_file_path)
|
162
|
+
modulemap_file_name = File.basename(modulemap_file_path)
|
163
|
+
get_product_glob([modulemap_file_name])
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# @param [Array<String>] file_names
|
169
|
+
#
|
170
|
+
# @return [String]
|
171
|
+
#
|
172
|
+
def get_product_glob(file_names)
|
100
173
|
File.join(derived_data_path,
|
101
174
|
"**",
|
102
|
-
|
175
|
+
"{#{file_names.join(",")}}")
|
103
176
|
end
|
104
177
|
|
105
178
|
# @param [String] framework_path
|
@@ -110,7 +183,7 @@ module XcodeArchiveCache
|
|
110
183
|
executable_name = File.basename(framework_path, File.extname(framework_path))
|
111
184
|
executable_path = File.join(framework_path, executable_name)
|
112
185
|
unless File.exist?(executable_path)
|
113
|
-
raise Informative, "Failed to find executable inside framework: #{framework_path}"
|
186
|
+
raise XcodeArchiveCache::Informative, "Failed to find executable inside framework: #{framework_path}"
|
114
187
|
end
|
115
188
|
|
116
189
|
uuids = list_bc_symbolmap_uuids(executable_path)
|
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 || native_target.product_reference.path == 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
|
data/lib/build_graph/node.rb
CHANGED
@@ -34,6 +34,10 @@ module XcodeArchiveCache
|
|
34
34
|
#
|
35
35
|
attr_accessor :build_settings
|
36
36
|
|
37
|
+
# @return [Array<Xcodeproj::Project::Object::PBXNativeTarget>]
|
38
|
+
#
|
39
|
+
attr_reader :targets_injected_to
|
40
|
+
|
37
41
|
# @param [String] name
|
38
42
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] native_target
|
39
43
|
# @param [Boolean] is_root
|
@@ -44,6 +48,7 @@ module XcodeArchiveCache
|
|
44
48
|
@is_root = is_root
|
45
49
|
@dependent = []
|
46
50
|
@dependencies = []
|
51
|
+
@targets_injected_to = []
|
47
52
|
@state = :unknown
|
48
53
|
end
|
49
54
|
|
@@ -91,8 +96,8 @@ module XcodeArchiveCache
|
|
91
96
|
|
92
97
|
# @return [String]
|
93
98
|
#
|
94
|
-
def
|
95
|
-
modulemap_file =
|
99
|
+
def original_modulemap_file_path
|
100
|
+
modulemap_file = modulemap_file_name
|
96
101
|
return unless modulemap_file
|
97
102
|
|
98
103
|
Pathname.new(modulemap_file).absolute? ? modulemap_file : File.join(File.dirname(native_target.project.path), modulemap_file)
|
@@ -100,11 +105,12 @@ module XcodeArchiveCache
|
|
100
105
|
|
101
106
|
# @return [String]
|
102
107
|
#
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
def resulting_modulemap_file_name
|
109
|
+
if module_name
|
110
|
+
module_name + ".modulemap"
|
111
|
+
else
|
112
|
+
File.basename(modulemap_file_name)
|
113
|
+
end
|
108
114
|
end
|
109
115
|
|
110
116
|
# @return [String]
|
@@ -127,6 +133,12 @@ module XcodeArchiveCache
|
|
127
133
|
build_settings[XcodeArchiveCache::BuildSettings::PRODUCT_MODULE_NAME_KEY]
|
128
134
|
end
|
129
135
|
|
136
|
+
# @return [String]
|
137
|
+
#
|
138
|
+
def modulemap_file_name
|
139
|
+
build_settings[XcodeArchiveCache::BuildSettings::MODULEMAP_FILE_KEY]
|
140
|
+
end
|
141
|
+
|
130
142
|
# @return [Array<Node>]
|
131
143
|
# Direct + transitive dependents
|
132
144
|
#
|
@@ -2,6 +2,10 @@ module XcodeArchiveCache
|
|
2
2
|
module BuildGraph
|
3
3
|
class NodeShaCalculator
|
4
4
|
|
5
|
+
def initialize
|
6
|
+
@own_sha = calculate_own_sources_sha
|
7
|
+
end
|
8
|
+
|
5
9
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
6
10
|
#
|
7
11
|
def calculate(node)
|
@@ -24,6 +28,20 @@ module XcodeArchiveCache
|
|
24
28
|
|
25
29
|
private
|
26
30
|
|
31
|
+
# @return [String]
|
32
|
+
#
|
33
|
+
attr_reader :own_sha
|
34
|
+
|
35
|
+
# @return [String]
|
36
|
+
#
|
37
|
+
def calculate_own_sources_sha
|
38
|
+
root = Pathname.new(File.expand_path('../', File.dirname(__FILE__)))
|
39
|
+
source_file_glob = File.join(root.realpath.to_s, "**", "*.rb")
|
40
|
+
source_file_paths = Dir.glob(source_file_glob)
|
41
|
+
|
42
|
+
calculate_sha(source_file_paths)
|
43
|
+
end
|
44
|
+
|
27
45
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
28
46
|
#
|
29
47
|
# @return [Array<String>]
|
@@ -36,7 +54,7 @@ module XcodeArchiveCache
|
|
36
54
|
inputs << list_build_phase_inputs(build_phase)
|
37
55
|
end
|
38
56
|
|
39
|
-
modulemap_file_path = node.
|
57
|
+
modulemap_file_path = node.original_modulemap_file_path
|
40
58
|
inputs << modulemap_file_path if modulemap_file_path
|
41
59
|
|
42
60
|
# file path order should not affect evaluation result
|
@@ -74,7 +92,7 @@ module XcodeArchiveCache
|
|
74
92
|
# @param [Array<String>] dependency_shas
|
75
93
|
#
|
76
94
|
def save_auxiliary_data(build_settings, dependency_shas, tempfile)
|
77
|
-
file_contents = build_settings + dependency_shas.join("\n")
|
95
|
+
file_contents = build_settings + dependency_shas.join("\n") + "\nXCODE-ARCHIVE-CACHE: #{own_sha}\n"
|
78
96
|
tempfile << file_contents
|
79
97
|
tempfile.flush
|
80
98
|
end
|
@@ -73,6 +73,7 @@ module XcodeArchiveCache
|
|
73
73
|
original_platform = settings[EFFECTIVE_PLATFORM_NAME_KEY]
|
74
74
|
simulator_platform = settings[CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY]
|
75
75
|
settings[EFFECTIVE_PLATFORM_NAME_KEY] = "-#{simulator_platform}"
|
76
|
+
settings[PLATFORM_NAME_KEY] = simulator_platform
|
76
77
|
|
77
78
|
configuration = settings[CONFIGURATION_KEY]
|
78
79
|
path_regexp = Regexp.new("#{configuration}#{original_platform}")
|
@@ -82,6 +83,7 @@ module XcodeArchiveCache
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
86
|
+
PLATFORM_NAME_KEY = "PLATFORM_NAME".freeze
|
85
87
|
EFFECTIVE_PLATFORM_NAME_KEY = "EFFECTIVE_PLATFORM_NAME".freeze
|
86
88
|
CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY = "CORRESPONDING_SIMULATOR_PLATFORM_NAME".freeze
|
87
89
|
CONFIGURATION_KEY = "CONFIGURATION".freeze
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module XcodeArchiveCache
|
2
2
|
module BuildSettings
|
3
3
|
|
4
|
+
PRODUCT_NAME_KEY = "PRODUCT_NAME".freeze
|
5
|
+
TARGET_NAME_KEY = "TARGET_NAME".freeze
|
4
6
|
FULL_PRODUCT_NAME_KEY = "FULL_PRODUCT_NAME".freeze
|
5
7
|
DWARF_DSYM_FILE_NAME_KEY = "DWARF_DSYM_FILE_NAME".freeze
|
6
8
|
MODULEMAP_FILE_KEY = "MODULEMAP_FILE".freeze
|
@@ -1,11 +1,24 @@
|
|
1
1
|
module XcodeArchiveCache
|
2
2
|
module BuildSettings
|
3
|
+
class SettingEntry
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :modifiers
|
6
|
+
attr_reader :full_string
|
7
|
+
|
8
|
+
def initialize(name, modifiers, full_string)
|
9
|
+
@name = name
|
10
|
+
@modifiers = modifiers
|
11
|
+
@full_string = full_string
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
class Parser
|
4
16
|
|
5
17
|
def initialize
|
6
18
|
@setting_name_regex = Regexp.new("^(?<#{SETTING_NAME_GROUP}>#{SETTING_NAME_CHARACTERS})\s=")
|
7
19
|
@setting_value_regex = Regexp.new("^#{SETTING_NAME_CHARACTERS}\s=\s(?<#{SETTING_VALUE_GROUP}>.+)$")
|
8
20
|
@setting_entry_regex = create_entry_regex
|
21
|
+
@setting_entry_part_regex = Regexp.new("#{SETTING_ENTRY_PART_CHARACTERS}")
|
9
22
|
@setting_entry_name_regex = Regexp.new(SETTING_NAME_CHARACTERS)
|
10
23
|
end
|
11
24
|
|
@@ -13,12 +26,18 @@ module XcodeArchiveCache
|
|
13
26
|
#
|
14
27
|
# @return [Array<String>]
|
15
28
|
#
|
16
|
-
def
|
29
|
+
def find_all_entries(string)
|
30
|
+
return nil if string == nil
|
31
|
+
|
17
32
|
string.scan(setting_entry_regex)
|
18
|
-
.map {|entry|
|
19
|
-
.
|
33
|
+
.map {|entry|
|
34
|
+
parts = entry.scan(setting_entry_part_regex)
|
35
|
+
name = parts.first
|
36
|
+
modifiers = parts.drop(1)
|
37
|
+
|
38
|
+
name != nil ? SettingEntry.new(name, modifiers, entry) : nil
|
39
|
+
}
|
20
40
|
.compact
|
21
|
-
.uniq
|
22
41
|
end
|
23
42
|
|
24
43
|
# @param [String] string
|
@@ -47,7 +66,7 @@ module XcodeArchiveCache
|
|
47
66
|
#
|
48
67
|
# @return [Regexp]
|
49
68
|
#
|
50
|
-
def create_entry_regex(characters =
|
69
|
+
def create_entry_regex(characters = SETTING_ALL_CHARACTERS)
|
51
70
|
Regexp.new("\\$[({]#{characters}[)}]")
|
52
71
|
end
|
53
72
|
|
@@ -65,10 +84,14 @@ module XcodeArchiveCache
|
|
65
84
|
#
|
66
85
|
attr_reader :setting_entry_regex
|
67
86
|
|
87
|
+
attr_reader :setting_entry_part_regex
|
88
|
+
|
68
89
|
# @return [Regexp]
|
69
90
|
#
|
70
91
|
attr_reader :setting_entry_name_regex
|
71
92
|
|
93
|
+
SETTING_ALL_CHARACTERS = "[A-Za-z0-9_:]+".freeze
|
94
|
+
SETTING_ENTRY_PART_CHARACTERS = "[A-Za-z0-9_]+".freeze
|
72
95
|
SETTING_NAME_CHARACTERS = "[A-Z0-9_]+".freeze
|
73
96
|
SETTING_NAME_GROUP = "name".freeze
|
74
97
|
SETTING_VALUE_GROUP = "value".freeze
|
@@ -12,15 +12,17 @@ module XcodeArchiveCache
|
|
12
12
|
# @return [String]
|
13
13
|
#
|
14
14
|
def interpolate(string, build_settings)
|
15
|
-
|
15
|
+
return nil if string == nil
|
16
|
+
|
17
|
+
entries = parser.find_all_entries(string)
|
16
18
|
result = string
|
17
19
|
|
18
|
-
|
19
|
-
value = build_settings[name]
|
20
|
+
entries.each do |entry|
|
21
|
+
value = build_settings[entry.name]
|
20
22
|
next unless value
|
21
23
|
|
22
|
-
|
23
|
-
result = result.gsub(
|
24
|
+
modified_value = modify_setting_value(value, entry.modifiers)
|
25
|
+
result = result.gsub(entry.full_string, modified_value)
|
24
26
|
end
|
25
27
|
|
26
28
|
result
|
@@ -31,6 +33,20 @@ module XcodeArchiveCache
|
|
31
33
|
# @return [Parser]
|
32
34
|
#
|
33
35
|
attr_accessor :parser
|
36
|
+
|
37
|
+
def modify_setting_value(value, modifiers)
|
38
|
+
modified_value = value
|
39
|
+
|
40
|
+
modifiers.each do |modifier|
|
41
|
+
case modifier
|
42
|
+
when "c99extidentifier"
|
43
|
+
modified_value = modified_value.gsub(/[-\s]/, "_")
|
44
|
+
else
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
modified_value
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
36
52
|
end
|