xcode-archive-cache 0.0.9 → 0.0.10.pre.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f444a19221b84c55a31be3d82277eef653239bdec9299d65b1252c1874dae15
4
- data.tar.gz: 9f1927ba1c9bf360d83a3b4febf128b069b8d846eca236a8d8f9bd848de9af24
3
+ metadata.gz: ea58d5804a6b809038af9c443a49426935c3f1b82673ce4029cadcd5dcdb21a2
4
+ data.tar.gz: edae37d1c99f73465be2486e910e32bb4b445811d4ef8dd4db91e45853f34a6e
5
5
  SHA512:
6
- metadata.gz: a0b85c53b4127976dfee59597aade6e6e7d0064841b8ea240446f9f7482bf3bd438a482cc3d75bd86caa917c040fe5e9f89f3c35e07291fdb8cd08d3f5b6b9e6
7
- data.tar.gz: c52f972d48a54b9331985d0b7a39f8e131a77a0e46c3cb8c0501422f313deb279b4ed9d0974fb99be7cd83f40a40feb374ae3d6f0feb73b5376089d7d574324a
6
+ metadata.gz: a753ce67b8129209b5da8e0afbdbd542da9660651ae47559fcfacbcf25ed9d35bedc45dbc05d23f13b33b1e4d05885f54bb43aaea2d3e2b4085f3fc1e960be63
7
+ data.tar.gz: c90dee530d492db4c3986c0e0ca6d651e0099a8f0348cdb4f5fa0110a32d143932809bdfce295ab4dc36e8180456320a208ff9f927cc2478f9b8d086cc016c32
@@ -9,7 +9,8 @@ module XcodeArchiveCache
9
9
  #
10
10
  def archive(path, destination)
11
11
  if File.exists?(destination)
12
- raise ArgumentError.new, "Artifact cache path #{destination} is already taken"
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
- raise ArgumentError.new, "State file already exists: #{state_file_path}"
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
@@ -35,7 +35,7 @@ module XcodeArchiveCache
35
35
  # @param [XcodeArchiveCache::BuildGraph::Graph] graph
36
36
  #
37
37
  def should_rebuild?(graph)
38
- graph.nodes.reduce(false) {|rebuild, node| rebuild || node.waiting_for_rebuild}
38
+ graph.root_node.state != :unpacked
39
39
  end
40
40
 
41
41
  private
@@ -17,7 +17,7 @@ module XcodeArchiveCache
17
17
  #
18
18
  def list_product_contents(built_node)
19
19
  file_paths = list_products(built_node)
20
- file_paths.select {|path| File.exist?(path)}.map {|path| File.realpath(path)}
20
+ file_paths.select { |path| File.exist?(path) }.map { |path| File.realpath(path) }
21
21
  end
22
22
 
23
23
  private
@@ -78,7 +78,15 @@ module XcodeArchiveCache
78
78
  raise Informative, "Product of type #{built_node.native_target.product_type} not found for #{built_node.name}"
79
79
  end
80
80
 
81
- [product_path]
81
+ paths = [product_path]
82
+
83
+ # this one is generated during Swift compilation
84
+ # so we need to cache it as well
85
+ #
86
+ swift_objc_interface_header_path = built_node.swift_objc_interface_header_path
87
+ paths << swift_objc_interface_header_path if swift_objc_interface_header_path
88
+
89
+ paths
82
90
  end
83
91
 
84
92
  # @param [XcodeArchiveCache::BuildGraph::Node] built_node
@@ -106,7 +114,7 @@ module XcodeArchiveCache
106
114
  end
107
115
 
108
116
  uuids = list_bc_symbolmap_uuids(executable_path)
109
- uuids.map {|uuid| find_bc_symbolmap(uuid)}.flatten
117
+ uuids.map { |uuid| find_bc_symbolmap(uuid) }.flatten
110
118
  end
111
119
 
112
120
  # @param [String] executable_path
@@ -114,7 +122,11 @@ module XcodeArchiveCache
114
122
  # @return [Array<String>]
115
123
  #
116
124
  def list_bc_symbolmap_uuids(executable_path)
117
- shell_executor.execute_for_output("otool -l #{executable_path} | grep uuid | awk {'print $2'}").split("\n")
125
+ begin
126
+ shell_executor.execute_for_output("otool -l #{executable_path} | grep uuid | awk {'print $2'}").split("\n")
127
+ rescue
128
+ []
129
+ end
118
130
  end
119
131
 
120
132
  # @param [String] uuid
@@ -86,9 +86,45 @@ module XcodeArchiveCache
86
86
  # @return [String]
87
87
  #
88
88
  def dsym_file_name
89
- return nil unless build_settings
89
+ build_settings ? build_settings[XcodeArchiveCache::BuildSettings::DWARF_DSYM_FILE_NAME_KEY] : nil
90
+ end
91
+
92
+ # @return [String]
93
+ #
94
+ def modulemap_file_path
95
+ modulemap_file = build_settings[XcodeArchiveCache::BuildSettings::MODULEMAP_FILE_KEY]
96
+ return unless modulemap_file
90
97
 
91
- build_settings[XcodeArchiveCache::BuildSettings::DWARF_DSYM_FILE_NAME_KEY]
98
+ Pathname.new(modulemap_file).absolute? ? modulemap_file : File.join(File.dirname(native_target.project.path), modulemap_file)
99
+ end
100
+
101
+ # @return [String]
102
+ #
103
+ def swift_objc_interface_header_path
104
+ header_file = swift_objc_interface_header_file
105
+ return if header_file == nil
106
+
107
+ File.join(build_settings[XcodeArchiveCache::BuildSettings::DERIVED_SOURCES_DIR_KEY], header_file)
108
+ end
109
+
110
+ # @return [String]
111
+ #
112
+ def swift_objc_interface_header_file
113
+ header_file = build_settings[XcodeArchiveCache::BuildSettings::SWIFT_OBJC_INTERFACE_HEADER_NAME_KEY]
114
+ if header_file == nil
115
+ our_module_name = module_name
116
+ return if our_module_name == nil
117
+
118
+ header_file = our_module_name + "-Swift.h"
119
+ end
120
+
121
+ header_file
122
+ end
123
+
124
+ # @return [String]
125
+ #
126
+ def module_name
127
+ build_settings[XcodeArchiveCache::BuildSettings::PRODUCT_MODULE_NAME_KEY]
92
128
  end
93
129
 
94
130
  # @return [Array<Node>]
@@ -8,24 +8,50 @@ module XcodeArchiveCache
8
8
  @cache_storage = cache_storage
9
9
  end
10
10
 
11
+ # @param [XcodeArchiveCache::BuildGraph::Graph] graph
12
+ #
13
+ def evaluate_build_graph(graph)
14
+ return if graph.root_node.state != :unknown
15
+
16
+ # DFS over graph, evaluating dependencies first
17
+ #
18
+ stack = [graph.root_node]
19
+
20
+ while stack.length > 0
21
+ last_node = stack.last
22
+
23
+ if last_node.state == :evaluating_dependencies
24
+ # dependencies were evaluated, we're good to go
25
+ evaluate(last_node)
26
+ stack.delete_at(stack.length - 1)
27
+ elsif last_node.state == :unknown
28
+ last_node.state = :evaluating_dependencies
29
+ stack += last_node.dependencies.select { |dependency| dependency.state == :unknown }
30
+ else
31
+ stack.delete_at(stack.length - 1)
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
11
38
  # @param [XcodeArchiveCache::BuildGraph::Node] node
12
39
  #
13
40
  def evaluate(node)
14
- return if node.state != :unknown
41
+ has_dependencies_waiting_for_rebuild = node.dependencies
42
+ .reduce(false) { |rebuild, dependency| rebuild || dependency.waiting_for_rebuild }
15
43
 
16
44
  # we include dependency shas in every node sha calculation,
17
45
  # so if some dependency changes, that change propagates
18
46
  # all the way to the top level
19
47
  #
20
- if cache_storage.cached_artifact_path(node) == nil
48
+ if has_dependencies_waiting_for_rebuild || cache_storage.cached_artifact_path(node) == nil
21
49
  node.state = :waiting_for_rebuild
22
50
  else
23
51
  node.state = :exists_in_cache
24
52
  end
25
53
  end
26
54
 
27
- private
28
-
29
55
  # @return [XcodeArchiveCache::ArtifactCache::AbstractStorage]
30
56
  #
31
57
  attr_reader :cache_storage
@@ -36,6 +36,9 @@ module XcodeArchiveCache
36
36
  inputs << list_build_phase_inputs(build_phase)
37
37
  end
38
38
 
39
+ modulemap_file_path = node.modulemap_file_path
40
+ inputs << modulemap_file_path if modulemap_file_path
41
+
39
42
  # file path order should not affect evaluation result
40
43
  inputs.flatten.compact.sort
41
44
  end
@@ -13,7 +13,7 @@ module XcodeArchiveCache
13
13
  # @return [Hash{String => Container}]
14
14
  # Target build settings keyed by target name
15
15
  #
16
- def extract_per_target(build_settings)
16
+ def extract_per_target(build_settings, fix_simulator)
17
17
  per_target_settings = build_settings.split("Build settings for action")
18
18
  result = Hash.new
19
19
 
@@ -22,6 +22,7 @@ module XcodeArchiveCache
22
22
  target_name = get_target_name(parsed_settings)
23
23
  next unless target_name
24
24
 
25
+ replace_platform_with_simulator(parsed_settings) if fix_simulator
25
26
  filtered_settings = filter.filter(parsed_settings)
26
27
  result[target_name] = Container.new(parsed_settings, filtered_settings)
27
28
  end
@@ -65,6 +66,25 @@ module XcodeArchiveCache
65
66
  result
66
67
  end
67
68
 
69
+
70
+ # @param [Hash{String => String}] settings
71
+ #
72
+ def replace_platform_with_simulator(settings)
73
+ original_platform = settings[EFFECTIVE_PLATFORM_NAME_KEY]
74
+ simulator_platform = settings[CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY]
75
+ settings[EFFECTIVE_PLATFORM_NAME_KEY] = "-#{simulator_platform}"
76
+
77
+ configuration = settings[CONFIGURATION_KEY]
78
+ path_regexp = Regexp.new("#{configuration}#{original_platform}")
79
+ simulator_path = "#{configuration}-#{simulator_platform}"
80
+ settings.each do |key, value|
81
+ settings[key] = value.gsub(path_regexp, simulator_path)
82
+ end
83
+ end
84
+
85
+ EFFECTIVE_PLATFORM_NAME_KEY = "EFFECTIVE_PLATFORM_NAME".freeze
86
+ CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY = "CORRESPONDING_SIMULATOR_PLATFORM_NAME".freeze
87
+ CONFIGURATION_KEY = "CONFIGURATION".freeze
68
88
  TARGET_NAME_KEY = "TARGETNAME".freeze
69
89
 
70
90
  # @param [Hash{String => String}] parsed_settings
@@ -10,7 +10,7 @@ module XcodeArchiveCache
10
10
  # Machine-dependent settings i.e. paths, user names, group names are rejected
11
11
  #
12
12
  def filter(settings, settings_to_keep = SETTINGS_TO_KEEP)
13
- filtered_settings = settings.select {|name, _| settings_to_keep.include?(name)}
13
+ filtered_settings = settings.select { |name, _| settings_to_keep.include?(name) }
14
14
  SETTINGS_TO_STRIP.each do |name|
15
15
  value = filtered_settings[name]
16
16
  next if value == nil
@@ -44,7 +44,9 @@ module XcodeArchiveCache
44
44
  # splitting will be broken, but probability of
45
45
  # someone using such path is quite low (or it isn't ?)
46
46
  #
47
- value_components = value_without_quotes.split(/\s-/)
47
+ value_components = value_without_quotes
48
+ .split(/^-|\s-/)
49
+ .select { |component| component.length > 0 }
48
50
 
49
51
  index = 0
50
52
  indices_to_remove = []
@@ -66,7 +68,8 @@ module XcodeArchiveCache
66
68
  kept_components.push(component) unless indices_to_remove.include?(component_index)
67
69
  end
68
70
 
69
- kept_components.join(" -")
71
+ result = kept_components.join(" -")
72
+ result.length > 0 ? "-#{result}" : ""
70
73
  end
71
74
 
72
75
  # TODO: extend
@@ -283,6 +286,7 @@ module XcodeArchiveCache
283
286
  output-file-map
284
287
  save-optimization-record-path
285
288
  working-directory
289
+ fmodule-map-file
286
290
  )
287
291
  end
288
292
  end
@@ -3,6 +3,11 @@ module XcodeArchiveCache
3
3
 
4
4
  FULL_PRODUCT_NAME_KEY = "FULL_PRODUCT_NAME".freeze
5
5
  DWARF_DSYM_FILE_NAME_KEY = "DWARF_DSYM_FILE_NAME".freeze
6
+ MODULEMAP_FILE_KEY = "MODULEMAP_FILE".freeze
7
+ SWIFT_OBJC_INTERFACE_HEADER_NAME_KEY = "SWIFT_OBJC_INTERFACE_HEADER_NAME".freeze
8
+ SWIFT_MODULE_NAME_KEY = "SWIFT_MODULE_NAME".freeze
9
+ PRODUCT_MODULE_NAME_KEY = "PRODUCT_MODULE_NAME".freeze
10
+ DERIVED_SOURCES_DIR_KEY = "DERIVED_SOURCES_DIR".freeze
6
11
 
7
12
  class Container
8
13
 
@@ -58,9 +63,11 @@ module XcodeArchiveCache
58
63
  end
59
64
  end
60
65
 
66
+ should_fix_settings = executor.set_up_for_simulator?
67
+
61
68
  threads.each do |thread|
62
69
  project_path, all_targets_settings = thread.value
63
- per_target_settings = extractor.extract_per_target(all_targets_settings)
70
+ per_target_settings = extractor.extract_per_target(all_targets_settings, should_fix_settings)
64
71
  set_project_settings(project_path, per_target_settings)
65
72
  end
66
73
  end
@@ -45,7 +45,7 @@ module XcodeArchiveCache
45
45
 
46
46
  # @param [String] characters
47
47
  #
48
- # @return [String]
48
+ # @return [Regexp]
49
49
  #
50
50
  def create_entry_regex(characters = SETTING_NAME_CHARACTERS)
51
51
  Regexp.new("\\$[({]#{characters}[)}]")
@@ -64,13 +64,36 @@ module XcodeArchiveCache
64
64
  add_cflag(build_configuration, path_to_capital_i(path))
65
65
  end
66
66
 
67
+ # @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
68
+ # @param [String] path
69
+ #
70
+ def fix_module_map_path(build_configuration, old_modulemap_names, path)
71
+ replace_module_map_flag(build_configuration.build_settings, OTHER_CFLAGS_KEY, old_modulemap_names, path)
72
+ replace_module_map_flag(build_configuration.build_settings, OTHER_CPLUSPLUSFLAGS_KEY, old_modulemap_names, path)
73
+ replace_module_map_flag(build_configuration.build_settings, OTHER_SWIFT_FLAGS_KEY, old_modulemap_names, path)
74
+
75
+ if build_configuration.base_configuration_reference
76
+ xcconfig_path = build_configuration.base_configuration_reference.real_path
77
+ return unless File.exist?(xcconfig_path)
78
+ xcconfig = Xcodeproj::Config.new(xcconfig_path)
79
+
80
+ replace_module_map_flag(xcconfig.attributes, OTHER_CFLAGS_KEY, old_modulemap_names, path)
81
+ replace_module_map_flag(xcconfig.attributes, OTHER_CPLUSPLUSFLAGS_KEY, old_modulemap_names, path)
82
+ replace_module_map_flag(xcconfig.attributes, OTHER_SWIFT_FLAGS_KEY, old_modulemap_names, path)
83
+
84
+ xcconfig.save_as(Pathname.new(xcconfig_path))
85
+ end
86
+ end
87
+
67
88
  private
68
89
 
69
90
  FRAMEWORK_SEARCH_PATHS_KEY = "FRAMEWORK_SEARCH_PATHS"
70
91
  LIBRARY_SEARCH_PATHS_KEY = "LIBRARY_SEARCH_PATHS"
71
92
  HEADER_SEARCH_PATHS_KEY = "HEADER_SEARCH_PATHS"
72
93
  OTHER_CFLAGS_KEY = "OTHER_CFLAGS"
94
+ OTHER_CPLUSPLUSFLAGS_KEY = "OTHER_CPLUSPLUSFLAGS"
73
95
  OTHER_LDFLAGS_KEY = "OTHER_LDFLAGS"
96
+ OTHER_SWIFT_FLAGS_KEY = "OTHER_SWIFT_FLAGS"
74
97
  INHERITED_SETTINGS_VALUE = "$(inherited)"
75
98
 
76
99
  # @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
@@ -167,6 +190,52 @@ module XcodeArchiveCache
167
190
 
168
191
  "-framework \"#{framework_name}\""
169
192
  end
193
+
194
+ # @param [Hash] build_settings
195
+ # @param [String] flags_key
196
+ # @param [Array<String>] old_modulemap_names
197
+ # @param [String] path
198
+ #
199
+ def replace_module_map_flag(build_settings, flags_key, old_modulemap_names, path)
200
+ flags = build_settings[flags_key]
201
+ if flags
202
+ build_settings[flags_key] = replace_module_map_path(flags, old_modulemap_names, path)
203
+ end
204
+ end
205
+
206
+ MODULE_MAP_FLAG = "-fmodule-map-file="
207
+
208
+ # @param [String] flags
209
+ # @param [Array<String>] old_modulemap_names
210
+ # @param [String] path
211
+ #
212
+ # @return [String]
213
+ #
214
+ def replace_module_map_path(flags, old_modulemap_names, path)
215
+ return if flags == nil
216
+
217
+ is_flags_string = flags.is_a?(String)
218
+ flags = flags.split(" ") if is_flags_string
219
+ updated_flags = flags
220
+ .map { |flags_line| flags_line.split(" ") }
221
+ .flatten
222
+ .map do |line|
223
+ updated_line = line
224
+
225
+ if line.include?(MODULE_MAP_FLAG)
226
+ old_modulemap_names.each do |name|
227
+ if line.include?(name)
228
+ updated_line = "#{MODULE_MAP_FLAG}\"#{path}\""
229
+ break
230
+ end
231
+ end
232
+ end
233
+
234
+ updated_line
235
+ end
236
+
237
+ is_flags_string ? updated_flags.join(" ") : updated_flags
238
+ end
170
239
  end
171
240
  end
172
241
  end
@@ -19,16 +19,29 @@ module XcodeArchiveCache
19
19
 
20
20
  node.native_target.copy_files_build_phases.each do |build_phase|
21
21
  file_paths = build_phase.files
22
- .map {|build_file| get_real_path(build_file)}
22
+ .map { |build_file| get_real_path(build_file) }
23
23
  .compact
24
24
  .uniq
25
- .select {|path| File.extname(path) == ".h"}
25
+ .select { |path| File.extname(path) == ".h" }
26
26
  destination_path = get_destination_dir_path(node, build_phase)
27
27
  storage.store_headers(node, destination_path, file_paths)
28
28
 
29
29
  header_count += file_paths.length
30
30
  end
31
31
 
32
+ if node.has_static_library_product?
33
+ headers_file_paths = node.native_target
34
+ .headers_build_phase
35
+ .files
36
+ .map { |header| get_real_path(header) }
37
+ .uniq
38
+ storage.store_default_headers(node, headers_file_paths)
39
+
40
+ header_count += headers_file_paths.length
41
+
42
+ storage.store_modulemap(node)
43
+ end
44
+
32
45
  debug("found #{header_count} headers")
33
46
  end
34
47
 
@@ -14,6 +14,7 @@ module XcodeArchiveCache
14
14
  @dependency_remover = DependencyRemover.new
15
15
  @build_flags_changer = BuildFlagsChanger.new
16
16
  @pods_fixer = PodsScriptFixer.new
17
+ @modulemap_fixer = ModulemapFixer.new(storage)
17
18
  @framework_embedder = FrameworkEmbedder.new
18
19
  end
19
20
 
@@ -34,8 +35,14 @@ module XcodeArchiveCache
34
35
  return
35
36
  end
36
37
 
38
+ no_rebuild_performed = root_node.state == :unpacked
39
+
37
40
  graph.nodes.each do |node|
38
- headers_mover.prepare_headers_for_injection(node)
41
+ if no_rebuild_performed || node.state == :rebuilt_and_cached
42
+ headers_mover.prepare_headers_for_injection(node)
43
+ modulemap_fixer.fix_modulemap(node)
44
+ end
45
+
39
46
  add_as_prebuilt_dependency(node, target, node.is_root)
40
47
  remove_native_target_from_project(node)
41
48
  end
@@ -51,8 +58,8 @@ module XcodeArchiveCache
51
58
  pods_fixer.fix_embed_frameworks_script(target, graph, storage.container_dir_path)
52
59
  pods_fixer.fix_copy_resources_script(target, graph, storage.container_dir_path)
53
60
  else
54
- framework_nodes = graph.nodes.select {|node| node.has_framework_product?}
55
- framework_file_paths = framework_nodes.map {|node| File.join(storage.get_storage_path(node), node.product_file_name)}
61
+ framework_nodes = graph.nodes.select { |node| node.has_framework_product? }
62
+ framework_file_paths = framework_nodes.map { |node| File.join(storage.get_storage_path(node), node.product_file_name) }
56
63
  framework_embedder.embed(framework_file_paths, target)
57
64
  end
58
65
 
@@ -86,6 +93,10 @@ module XcodeArchiveCache
86
93
  #
87
94
  attr_reader :pods_fixer
88
95
 
96
+ # @return [ModulemapFixer]
97
+ #
98
+ attr_reader :modulemap_fixer
99
+
89
100
  # @return [FrameworkEmbedder]
90
101
  #
91
102
  attr_reader :framework_embedder
@@ -93,9 +104,10 @@ module XcodeArchiveCache
93
104
  # @param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
94
105
  #
95
106
  def inject_unpacked(nodes)
96
- cached_nodes = nodes.select {|node| node.state == :unpacked}
107
+ cached_nodes = nodes.select { |node| node.state == :unpacked }
97
108
  cached_nodes.each do |node|
98
109
  headers_mover.prepare_headers_for_injection(node)
110
+ modulemap_fixer.fix_modulemap(node)
99
111
  add_as_prebuilt_to_dependents(node)
100
112
  end
101
113
  end
@@ -108,7 +120,7 @@ module XcodeArchiveCache
108
120
 
109
121
  nodes
110
122
  .select(&:waiting_for_rebuild)
111
- .each {|node| add_header_paths_to_target(node.native_target, header_storage_paths)}
123
+ .each { |node| add_header_paths_to_target(node.native_target, header_storage_paths) }
112
124
  end
113
125
 
114
126
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
@@ -146,7 +158,7 @@ module XcodeArchiveCache
146
158
  def save_graph_projects(graph)
147
159
  projects = graph.nodes.map(&:native_target).map(&:project).uniq
148
160
  debug("updating #{projects.length} projects")
149
- projects.each {|project| project.save}
161
+ projects.each { |project| project.save }
150
162
  end
151
163
 
152
164
  # @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
@@ -188,10 +200,16 @@ module XcodeArchiveCache
188
200
  def add_as_prebuilt_static_lib(prebuilt_node, dependent_target, should_link)
189
201
  build_configuration = find_build_configuration(dependent_target)
190
202
 
191
- if should_link
203
+ injected_modulemap_file_path = storage.get_modulemap_path(prebuilt_node)
204
+ if injected_modulemap_file_path
205
+ modulemap_file_names = ["#{prebuilt_node.module_name}.modulemap", File.basename(prebuilt_node.modulemap_file_path)]
206
+ build_flags_changer.fix_module_map_path(build_configuration, modulemap_file_names, injected_modulemap_file_path)
207
+ end
208
+
209
+ # if should_link
192
210
  artifact_location = storage.get_storage_path(prebuilt_node)
193
211
  build_flags_changer.add_library_search_path(build_configuration, artifact_location)
194
- end
212
+ # end
195
213
 
196
214
  dependency_remover.remove_dependency(prebuilt_node, dependent_target)
197
215
  end
@@ -199,7 +217,7 @@ module XcodeArchiveCache
199
217
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
200
218
  #
201
219
  def find_build_configuration(target)
202
- build_configuration = target.build_configurations.select {|configuration| configuration.name == configuration_name}.first
220
+ build_configuration = target.build_configurations.select { |configuration| configuration.name == configuration_name }.first
203
221
  unless build_configuration
204
222
  raise Informative, "#{configuration_name} build configuration not found on target #{node.name}"
205
223
  end
@@ -0,0 +1,47 @@
1
+ module XcodeArchiveCache
2
+ module Injection
3
+
4
+ class ModulemapFixer
5
+
6
+ # @param [Storage] storage
7
+ #
8
+ def initialize(storage)
9
+ @storage = storage
10
+ end
11
+
12
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
13
+ #
14
+ def fix_modulemap(node)
15
+ return unless node.has_static_library_product?
16
+
17
+ modulemap_file_path = node.modulemap_file_path
18
+ return if modulemap_file_path == nil
19
+
20
+ injected_modulemap_file_path = storage.get_modulemap_path(node)
21
+ return if injected_modulemap_file_path == nil
22
+
23
+ swift_objc_interface_header_file_name = node.swift_objc_interface_header_file
24
+ return if swift_objc_interface_header_file_name == nil
25
+
26
+ # add generated header to modulemap to make Swift stuff available module users
27
+ #
28
+ storage_path = storage.get_storage_path(node)
29
+ header_path = File.join(storage_path, swift_objc_interface_header_file_name)
30
+ return unless File.exist?(header_path)
31
+
32
+ File.open(injected_modulemap_file_path, "a") do |modulemap_file|
33
+ modulemap_file.puts "\nmodule #{node.module_name}.Swift {\n"
34
+ modulemap_file.puts " header \"#{header_path}\"\n"
35
+ modulemap_file.puts " requires objc\n"
36
+ modulemap_file.puts "}\n"
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # @return [Storage]
43
+ #
44
+ attr_accessor :storage
45
+ end
46
+ end
47
+ end
@@ -31,12 +31,41 @@ module XcodeArchiveCache
31
31
  end
32
32
 
33
33
  file_paths.each do |file_path|
34
- FileUtils.cp(file_path, File.join(storage_path, File.basename(file_path)))
34
+ FileUtils.cp(file_path, get_stored_file_path(storage_path, file_path))
35
35
  end
36
36
 
37
37
  save_header_storage_path(storage_path, node)
38
38
  end
39
39
 
40
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
41
+ # @param [Array<String>] file_paths
42
+ #
43
+ def store_default_headers(node, file_paths)
44
+ store_headers(node, get_default_headers_storage_path(node), file_paths)
45
+ end
46
+
47
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
48
+ #
49
+ def store_modulemap(node)
50
+ modulemap_file_path = node.modulemap_file_path
51
+ if modulemap_file_path && File.exist?(modulemap_file_path)
52
+ store_headers(node, get_default_headers_storage_path(node), [modulemap_file_path])
53
+ end
54
+ end
55
+
56
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
57
+ #
58
+ # @return [String]
59
+ #
60
+ def get_modulemap_path(node)
61
+ modulemap_file_path = node.modulemap_file_path
62
+ return if modulemap_file_path == nil
63
+
64
+ storage_path = get_full_header_storage_path(get_default_headers_storage_path(node))
65
+ stored_modulemap_file_path = get_stored_file_path(storage_path, modulemap_file_path)
66
+ File.exist?(stored_modulemap_file_path) ? stored_modulemap_file_path : nil
67
+ end
68
+
40
69
  # @param [XcodeArchiveCache::BuildGraph::Node] node
41
70
  # @param [Array<String>] file_paths
42
71
  #
@@ -70,7 +99,7 @@ module XcodeArchiveCache
70
99
 
71
100
  # @param [XcodeArchiveCache::BuildGraph::Node] node
72
101
  #
73
- # @return [Array<String>]
102
+ # @return [String]
74
103
  #
75
104
  def get_headers_storage_paths(node)
76
105
  headers_storage_dir_paths[node.name]
@@ -78,11 +107,19 @@ module XcodeArchiveCache
78
107
 
79
108
  def get_all_headers_storage_paths
80
109
  headers_storage_dir_paths
81
- .map {|_, path| path}
110
+ .map { |_, path| path }
82
111
  .flatten
83
112
  .uniq
84
113
  end
85
114
 
115
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
116
+ #
117
+ # @return [String]
118
+ #
119
+ def get_default_headers_storage_path(node)
120
+ "include/#{node.name}"
121
+ end
122
+
86
123
  private
87
124
 
88
125
  def prepare_container_dir
@@ -99,6 +136,15 @@ module XcodeArchiveCache
99
136
  File.absolute_path(path, container_dir_path)
100
137
  end
101
138
 
139
+ # @param [String] storage_path
140
+ # @param [String] file_path
141
+ #
142
+ # @return [String]
143
+ #
144
+ def get_stored_file_path(storage_path, file_path)
145
+ File.join(storage_path, File.basename(file_path))
146
+ end
147
+
102
148
  # @param [String] path
103
149
  # @param [XcodeArchiveCache::BuildGraph::Node] node
104
150
  #
data/lib/runner/runner.rb CHANGED
@@ -92,20 +92,12 @@ module XcodeArchiveCache
92
92
  graph_builder = XcodeArchiveCache::BuildGraph::Builder.new(@native_target_finder, xcodebuild_executor)
93
93
  graph = graph_builder.build_graph(target, dependency_target)
94
94
 
95
- evaluate_for_rebuild(graph)
95
+ @rebuild_evaluator.evaluate_build_graph(graph)
96
96
  unpack_cached_artifacts(graph)
97
97
  rebuild_if_needed(xcodebuild_executor, dependency_target, graph)
98
98
  @injector.perform_outgoing_injection(graph, target)
99
99
  end
100
100
 
101
- # @param [XcodeArchiveCache::BuildGraph::Graph] graph
102
- #
103
- def evaluate_for_rebuild(graph)
104
- graph.nodes.each do |node|
105
- @rebuild_evaluator.evaluate(node)
106
- end
107
- end
108
-
109
101
  # @param [XcodeArchiveCache::BuildGraph::Graph] graph
110
102
  #
111
103
  def unpack_cached_artifacts(graph)
@@ -57,12 +57,12 @@ module XcodeArchiveCache
57
57
  # @return [String]
58
58
  #
59
59
  def pipefail_flags(print_command)
60
- flags = %w(e o)
60
+ flags = ["e", "o pipefail"]
61
61
  if print_command
62
62
  flags.insert(1, "x")
63
63
  end
64
64
 
65
- "-" + flags.join("")
65
+ "-" + flags.join(" -")
66
66
  end
67
67
  end
68
68
  end
@@ -40,6 +40,7 @@ require 'build_settings/parser'
40
40
 
41
41
  require 'injection/injector'
42
42
  require 'injection/pods_script_fixer'
43
+ require 'injection/modulemap_fixer'
43
44
  require 'injection/build_flags_changer'
44
45
  require 'injection/dependency_remover'
45
46
  require 'injection/headers_mover'
@@ -55,6 +55,10 @@ module XcodeArchiveCache
55
55
  shell_executor.execute(command, true)
56
56
  end
57
57
 
58
+ def set_up_for_simulator?
59
+ destination_flag.include?("Simulator")
60
+ end
61
+
58
62
  private
59
63
 
60
64
  # @return [String]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcode-archive-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Dyakonov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-13 00:00:00.000000000 Z
11
+ date: 2020-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xcodeproj
@@ -112,6 +112,7 @@ files:
112
112
  - lib/injection/framework_embedder.rb
113
113
  - lib/injection/headers_mover.rb
114
114
  - lib/injection/injector.rb
115
+ - lib/injection/modulemap_fixer.rb
115
116
  - lib/injection/pods_script_fixer.rb
116
117
  - lib/injection/storage.rb
117
118
  - lib/logs/logs.rb
@@ -134,9 +135,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
135
  version: 2.0.0
135
136
  required_rubygems_version: !ruby/object:Gem::Requirement
136
137
  requirements:
137
- - - ">="
138
+ - - ">"
138
139
  - !ruby/object:Gem::Version
139
- version: '0'
140
+ version: 1.3.1
140
141
  requirements: []
141
142
  rubygems_version: 3.0.4
142
143
  signing_key: