xcode-archive-cache 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/xcode-archive-cache +11 -0
- data/lib/artifact_cache/abstract_storage.rb +18 -0
- data/lib/artifact_cache/archiver.rb +110 -0
- data/lib/artifact_cache/artifact_extractor.rb +31 -0
- data/lib/artifact_cache/local_storage.rb +46 -0
- data/lib/build/performer.rb +48 -0
- data/lib/build/product_extractor.rb +129 -0
- data/lib/build_graph/builder.rb +154 -0
- data/lib/build_graph/graph.rb +37 -0
- data/lib/build_graph/native_target_finder.rb +101 -0
- data/lib/build_graph/node.rb +104 -0
- data/lib/build_graph/rebuild_evaluator.rb +30 -0
- data/lib/build_graph/sha_calculator.rb +102 -0
- data/lib/build_settings/extractor.rb +80 -0
- data/lib/build_settings/filter.rb +289 -0
- data/lib/build_settings/loader.rb +80 -0
- data/lib/build_settings/parser.rb +77 -0
- data/lib/build_settings/string_interpolator.rb +36 -0
- data/lib/command/command.rb +45 -0
- data/lib/command/inject.rb +52 -0
- data/lib/config/config.rb +211 -0
- data/lib/config/dsl.rb +69 -0
- data/lib/injection/build_flags_changer.rb +172 -0
- data/lib/injection/dependency_remover.rb +146 -0
- data/lib/injection/framework_embedder.rb +47 -0
- data/lib/injection/headers_mover.rb +65 -0
- data/lib/injection/injector.rb +220 -0
- data/lib/injection/pods_script_fixer.rb +52 -0
- data/lib/injection/storage.rb +122 -0
- data/lib/logs/logs.rb +47 -0
- data/lib/runner/runner.rb +139 -0
- data/lib/shell/executor.rb +69 -0
- data/lib/xcode-archive-cache.rb +59 -0
- data/lib/xcodebuild/executor.rb +146 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 49b93ea668f7de9a3723feec1518e934f0b46755afaf941866cf028ed0cc7f0b
|
4
|
+
data.tar.gz: 16c0538e9665fe7f7c95c747d34f8ae48a3d8c2c5ed7adb1cc865dbbcbe0c43f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07424e1f9f50852d8d3a2fb873454d6e441860d33d220a6b37aeb11bb5dd6e90a872bbd37f8c749bb3b0e6a0693fe9aab8fb6c344f7294127861f7ddd9321e8f
|
7
|
+
data.tar.gz: 670815a9f5e0bf971f5f0868e42bdeb0b2d0f12b745572688c0022914f57d6d0ba3016cddd54b5aca92203101df21c52b84d6c01de9c080bfa6eb3be1e9b0273
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module ArtifactCache
|
3
|
+
class AbstractStorage
|
4
|
+
|
5
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
6
|
+
#
|
7
|
+
# @return [String] cached artifact path, nil if no cached artifact found
|
8
|
+
#
|
9
|
+
def cached_artifact_path(node)
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def store(node, path)
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module ArtifactCache
|
3
|
+
class Archiver
|
4
|
+
|
5
|
+
include XcodeArchiveCache::Logs
|
6
|
+
|
7
|
+
# @param [String] path
|
8
|
+
# @param [String] destination
|
9
|
+
#
|
10
|
+
def archive(path, destination)
|
11
|
+
if File.exists?(destination)
|
12
|
+
raise ArgumentError.new, "Artifact cache path #{destination} is already taken"
|
13
|
+
end
|
14
|
+
|
15
|
+
if File.file?(path)
|
16
|
+
archive_single_file(path, destination)
|
17
|
+
elsif File.directory?(path)
|
18
|
+
archive_directory(path, destination)
|
19
|
+
else
|
20
|
+
raise ArgumentError.new, "No artifact found at path #{path}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [String] path
|
25
|
+
# @param [String] destination
|
26
|
+
#
|
27
|
+
def unarchive(path, destination)
|
28
|
+
unless File.file?(path)
|
29
|
+
raise ArgumentError.new, "Artifact archive not found: #{path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
unless File.directory?(destination)
|
33
|
+
FileUtils.mkdir_p(destination)
|
34
|
+
end
|
35
|
+
|
36
|
+
Zip::File.open(path) do |archive|
|
37
|
+
archive.each do |archive_entry|
|
38
|
+
destination_file_path = File.join(destination, archive_entry.name)
|
39
|
+
destination_dir_path = File.dirname(destination_file_path)
|
40
|
+
unless File.exists?(destination_dir_path) && File.directory?(destination_dir_path)
|
41
|
+
FileUtils.mkdir_p(destination_dir_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
archive_entry.extract(destination_file_path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @param [String] path
|
52
|
+
# @param [String] destination
|
53
|
+
#
|
54
|
+
def archive_single_file(path, destination)
|
55
|
+
info("archiving #{path}")
|
56
|
+
|
57
|
+
Zip::File.open(destination, Zip::File::CREATE) do |archive|
|
58
|
+
archive.add(File.basename(path), path)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param [String] path
|
63
|
+
# @param [String] destination
|
64
|
+
#
|
65
|
+
def archive_directory(path, destination)
|
66
|
+
info("archiving #{path}")
|
67
|
+
|
68
|
+
Zip::File.open(destination, Zip::File::CREATE) do |archive|
|
69
|
+
add_entries(list_entries_in_directory(path), path, archive)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Array<String>] entries
|
74
|
+
# @param [String] root_dir
|
75
|
+
# @param [Zip::File] archive
|
76
|
+
#
|
77
|
+
def add_entries(entries, root_dir, archive)
|
78
|
+
entries.each do |entry|
|
79
|
+
if File.directory?(entry)
|
80
|
+
add_entries(list_entries_in_directory(entry), root_dir, archive)
|
81
|
+
elsif File.file?(entry)
|
82
|
+
add_single_file_entry(entry, root_dir, archive)
|
83
|
+
else
|
84
|
+
raise ArgumentError.new, "No file found at path #{entry}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [String] path
|
90
|
+
#
|
91
|
+
def list_entries_in_directory(path)
|
92
|
+
(Dir.entries(path) - %w(. ..)).map {|entry| File.join(path, entry)}
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param [String] path_on_disk
|
96
|
+
# @param [String] root_dir
|
97
|
+
# @param [Zip::File] archive
|
98
|
+
#
|
99
|
+
def add_single_file_entry(path_on_disk, root_dir, archive)
|
100
|
+
file_path = Pathname.new(path_on_disk)
|
101
|
+
root_dir_path = Pathname.new(root_dir)
|
102
|
+
path_in_archive = file_path.relative_path_from(root_dir_path).to_s
|
103
|
+
|
104
|
+
archive.get_output_stream(path_in_archive) do |stream|
|
105
|
+
stream.write(File.open(path_on_disk, 'rb').read)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module ArtifactCache
|
3
|
+
class ArtifactExtractor
|
4
|
+
|
5
|
+
# @param [XcodeArchiveCache::ArtifactCache::AbstractStorage] storage
|
6
|
+
#
|
7
|
+
def initialize(storage)
|
8
|
+
@storage = storage
|
9
|
+
@archiver = Archiver.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
13
|
+
# @param [String] destination
|
14
|
+
#
|
15
|
+
def unpack(node, destination)
|
16
|
+
cached_artifact_path = storage.cached_artifact_path(node)
|
17
|
+
archiver.unarchive(cached_artifact_path, destination)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# @return [XcodeArchiveCache::ArtifactCache::AbstractStorage]
|
23
|
+
#
|
24
|
+
attr_reader :storage
|
25
|
+
|
26
|
+
# @return [XcodeArchiveCache::ArtifactCache::Archiver]
|
27
|
+
#
|
28
|
+
attr_reader :archiver
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module ArtifactCache
|
3
|
+
class LocalStorage < AbstractStorage
|
4
|
+
|
5
|
+
# @param [String] cache_dir_path
|
6
|
+
#
|
7
|
+
def initialize(cache_dir_path)
|
8
|
+
@cache_dir_path = cache_dir_path
|
9
|
+
@archiver = Archiver.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
13
|
+
#
|
14
|
+
# @return [String] cached artifact path, nil if no artifact found in cache dir
|
15
|
+
#
|
16
|
+
def cached_artifact_path(node)
|
17
|
+
path = path_inside_cache_dir(node)
|
18
|
+
File.exist?(path) ? path : nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def store(node, path)
|
22
|
+
archive_path = path_inside_cache_dir(node)
|
23
|
+
archive_directory = File.expand_path("..", archive_path)
|
24
|
+
unless File.exist?(archive_directory)
|
25
|
+
FileUtils.mkdir_p(archive_directory)
|
26
|
+
end
|
27
|
+
|
28
|
+
archiver.archive(path, archive_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
#
|
35
|
+
attr_reader :cache_dir_path
|
36
|
+
|
37
|
+
# @return [XcodeArchiveCache::ArtifactCache::Archiver]
|
38
|
+
#
|
39
|
+
attr_reader :archiver
|
40
|
+
|
41
|
+
def path_inside_cache_dir(node)
|
42
|
+
File.join(cache_dir_path, node.name, node.sha)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module Build
|
3
|
+
class Performer
|
4
|
+
|
5
|
+
include XcodeArchiveCache::Logs
|
6
|
+
|
7
|
+
# @param [String] derived_data_path
|
8
|
+
#
|
9
|
+
def initialize(xcodebuild_executor, derived_data_path)
|
10
|
+
@xcodebuild_executor = xcodebuild_executor
|
11
|
+
@derived_data_path = derived_data_path
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [String] configuration
|
15
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
16
|
+
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
17
|
+
#
|
18
|
+
def rebuild_missing(target, graph)
|
19
|
+
should_rebuild_anything = should_rebuild?(graph)
|
20
|
+
if should_rebuild_anything
|
21
|
+
rebuild_list = graph.nodes.select(&:rebuild).map(&:name).join(", ")
|
22
|
+
info("going to rebuild:\n#{rebuild_list}")
|
23
|
+
|
24
|
+
build_result = xcodebuild_executor.build(target.project.path, target.name, derived_data_path)
|
25
|
+
unless build_result
|
26
|
+
raise StandardError.new, "Failed to perform rebuild"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
info("no need to rebuild anything")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
34
|
+
#
|
35
|
+
def should_rebuild?(graph)
|
36
|
+
graph.nodes.reduce(false) {|rebuild, node| rebuild || node.rebuild}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [String]
|
42
|
+
#
|
43
|
+
attr_reader :derived_data_path
|
44
|
+
|
45
|
+
attr_reader :xcodebuild_executor
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module Build
|
3
|
+
class ProductExtractor
|
4
|
+
|
5
|
+
# @param [String] configuration
|
6
|
+
# @param [String] derived_data_path
|
7
|
+
#
|
8
|
+
def initialize(configuration, derived_data_path)
|
9
|
+
@configuration = configuration
|
10
|
+
@derived_data_path = derived_data_path
|
11
|
+
@shell_executor = XcodeArchiveCache::Shell::Executor.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def list_product_contents(root_target_name, built_node)
|
15
|
+
file_paths = list_products(root_target_name, built_node)
|
16
|
+
file_paths.select {|path| File.exist?(path)}.map {|path| File.realpath(path) }
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
attr_reader :configuration
|
24
|
+
|
25
|
+
# @return [String]
|
26
|
+
#
|
27
|
+
attr_reader :derived_data_path
|
28
|
+
|
29
|
+
# @return [XcodeArchiveCache::Shell::Executor]
|
30
|
+
#
|
31
|
+
attr_reader :shell_executor
|
32
|
+
|
33
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
34
|
+
#
|
35
|
+
def list_products(root_target_name, built_node)
|
36
|
+
if built_node.has_framework_product?
|
37
|
+
list_framework_products(root_target_name, built_node)
|
38
|
+
elsif built_node.has_static_library_product?
|
39
|
+
list_static_lib_products(root_target_name, built_node)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
44
|
+
#
|
45
|
+
# @return [Array<String>]
|
46
|
+
#
|
47
|
+
def list_framework_products(root_target_name, built_node)
|
48
|
+
framework_glob = get_main_product_glob(root_target_name, built_node)
|
49
|
+
framework_path = Dir.glob(framework_glob).first
|
50
|
+
unless framework_path
|
51
|
+
raise Informative, "Framework product not found for #{built_node.name}"
|
52
|
+
end
|
53
|
+
|
54
|
+
framework_dsym_glob = File.join(File.dirname(framework_glob), built_node.dsym_file_name)
|
55
|
+
framework_dsym_path = Dir.glob(framework_dsym_glob).first
|
56
|
+
|
57
|
+
bc_symbolmap_paths = list_framework_bc_symbolmaps(framework_path)
|
58
|
+
|
59
|
+
([framework_path, framework_dsym_path] + bc_symbolmap_paths).flatten.compact
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
63
|
+
#
|
64
|
+
# @return [Array<String>]
|
65
|
+
#
|
66
|
+
def list_static_lib_products(root_target_name, built_node)
|
67
|
+
static_lib_glob = get_main_product_glob(root_target_name, built_node)
|
68
|
+
static_lib_path = Dir.glob(static_lib_glob).first
|
69
|
+
unless static_lib_path
|
70
|
+
raise Informative, "Static library product not found for #{built_node.name}"
|
71
|
+
end
|
72
|
+
|
73
|
+
[static_lib_path]
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
77
|
+
#
|
78
|
+
# @return [String]
|
79
|
+
#
|
80
|
+
def get_main_product_glob(root_target_name, built_node)
|
81
|
+
product_name = built_node.native_target.product_reference.name ?
|
82
|
+
built_node.native_target.product_reference.name :
|
83
|
+
built_node.native_target.product_reference.path
|
84
|
+
File.join(derived_data_path,
|
85
|
+
"**",
|
86
|
+
File.basename(product_name))
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
90
|
+
#
|
91
|
+
# @return [String]
|
92
|
+
#
|
93
|
+
def configuration_dir(built_node)
|
94
|
+
"#{configuration}-#{built_node.native_target.sdk}"
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [String] framework_path
|
98
|
+
#
|
99
|
+
# @return [Array<String>]
|
100
|
+
#
|
101
|
+
def list_framework_bc_symbolmaps(framework_path)
|
102
|
+
executable_name = File.basename(framework_path, File.extname(framework_path))
|
103
|
+
executable_path = File.join(framework_path, executable_name)
|
104
|
+
unless File.exist?(executable_path)
|
105
|
+
raise Informative, "Failed to find executable inside framework: #{framework_path}"
|
106
|
+
end
|
107
|
+
|
108
|
+
uuids = list_bc_symbolmap_uuids(executable_path)
|
109
|
+
uuids.map {|uuid| find_bc_symbolmap(uuid)}.flatten
|
110
|
+
end
|
111
|
+
|
112
|
+
# @param [String] executable_path
|
113
|
+
#
|
114
|
+
# @return [Array<String>]
|
115
|
+
#
|
116
|
+
def list_bc_symbolmap_uuids(executable_path)
|
117
|
+
shell_executor.execute_for_output("otool -l #{executable_path} | grep uuid | awk {'print $2'}").split("\n")
|
118
|
+
end
|
119
|
+
|
120
|
+
# @param [String] uuid
|
121
|
+
#
|
122
|
+
# @return [String]
|
123
|
+
#
|
124
|
+
def find_bc_symbolmap(uuid)
|
125
|
+
Dir.glob(File.join(derived_data_path, "**", "#{uuid}.bcsymbolmap")).first
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module BuildGraph
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
include XcodeArchiveCache::Logs
|
6
|
+
|
7
|
+
# @param [XcodeArchiveCache::Xcodebuild::Executor] xcodebuild_executor
|
8
|
+
#
|
9
|
+
def initialize(native_target_finder, xcodebuild_executor)
|
10
|
+
@build_settings_loader = XcodeArchiveCache::BuildSettings::Loader.new(xcodebuild_executor)
|
11
|
+
@native_target_finder = native_target_finder
|
12
|
+
@sha_calculator = NodeShaCalculator.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] dependency_target
|
16
|
+
#
|
17
|
+
# @return [Graph]
|
18
|
+
#
|
19
|
+
def build_graph(dependent_target, dependency_target)
|
20
|
+
native_target_finder.set_platform_name_filter(dependency_target.platform_name)
|
21
|
+
|
22
|
+
build_settings = load_setting_for_target(dependent_target)
|
23
|
+
graph = Graph.new(dependency_target.project, build_settings)
|
24
|
+
|
25
|
+
add_to_graph(dependency_target, graph, true)
|
26
|
+
load_settings(graph)
|
27
|
+
calculate_shas(graph)
|
28
|
+
|
29
|
+
graph
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @return [XcodeArchiveCache::BuildSettings::Loader]
|
35
|
+
#
|
36
|
+
attr_accessor :build_settings_loader
|
37
|
+
|
38
|
+
# @return [XcodeArchive::BuildGraph::NativeTargetFinder]
|
39
|
+
#
|
40
|
+
attr_accessor :native_target_finder
|
41
|
+
|
42
|
+
# @return [XcodeArchiveCache::BuildGraph::NodeShaCalculator]
|
43
|
+
#
|
44
|
+
attr_accessor :sha_calculator
|
45
|
+
|
46
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
47
|
+
# @param [Graph] graph
|
48
|
+
# @param [Boolean] is_root
|
49
|
+
# @param [Array<String>] target_stack
|
50
|
+
# Stack of native target display names at this level of traverse
|
51
|
+
#
|
52
|
+
# @return [Node] new or existing node
|
53
|
+
#
|
54
|
+
def add_to_graph(target, graph, is_root, target_stack = [])
|
55
|
+
debug("traversing #{target.display_name}")
|
56
|
+
|
57
|
+
unless target
|
58
|
+
raise ArgumentError.new, "Target is required"
|
59
|
+
end
|
60
|
+
|
61
|
+
display_name = target.display_name
|
62
|
+
existing_node = graph.node_by_name(display_name)
|
63
|
+
if existing_node
|
64
|
+
debug("already added this one")
|
65
|
+
return existing_node
|
66
|
+
end
|
67
|
+
|
68
|
+
if target_stack.include?(display_name)
|
69
|
+
target_stack.push(display_name)
|
70
|
+
raise Informative, "Circular dependency detected: #{target_stack.join(" -> ")}"
|
71
|
+
end
|
72
|
+
|
73
|
+
node = graph.node_by_name(display_name)
|
74
|
+
if node
|
75
|
+
debug("already traversed this one")
|
76
|
+
return node
|
77
|
+
else
|
78
|
+
debug("adding new node")
|
79
|
+
node = Node.new(display_name, target, is_root)
|
80
|
+
graph.nodes.push(node)
|
81
|
+
end
|
82
|
+
|
83
|
+
dependencies = []
|
84
|
+
target_stack.push(display_name)
|
85
|
+
|
86
|
+
dependency_targets = target.dependencies.map {|dependency| native_target_finder.find_for_dependency(dependency)} +
|
87
|
+
target.frameworks_build_phase.files.map {|file| native_target_finder.find_for_file(file)}
|
88
|
+
|
89
|
+
# PBXNativeTarget has no custom equality check
|
90
|
+
deduplicated_targets = dependency_targets.compact.uniq {|dependency_target| dependency_target.uuid + dependency_target.display_name}
|
91
|
+
debug("dependency targets: #{deduplicated_targets.map(&:display_name)}")
|
92
|
+
|
93
|
+
deduplicated_targets.each do |dependency_target|
|
94
|
+
dependency_node = add_to_graph(dependency_target, graph, false, target_stack)
|
95
|
+
|
96
|
+
unless dependency_node.dependent.include?(node)
|
97
|
+
debug("adding #{node.name} as dependent to #{dependency_node.name}")
|
98
|
+
dependency_node.dependent.push(node)
|
99
|
+
end
|
100
|
+
|
101
|
+
unless dependencies.include?(dependency_node)
|
102
|
+
debug("adding #{dependency_node.name} as dependency to #{node.name}")
|
103
|
+
dependencies.push(dependency_node)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
target_stack.pop
|
108
|
+
node.dependencies.push(*dependencies)
|
109
|
+
|
110
|
+
debug("done with #{target.display_name}")
|
111
|
+
node
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
115
|
+
#
|
116
|
+
def calculate_shas(graph)
|
117
|
+
graph.nodes.each do |node|
|
118
|
+
debug("calculating sha for #{node.name}")
|
119
|
+
sha_calculator.calculate(node)
|
120
|
+
debug("sha calculated for #{node.name}: #{node.sha}")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
125
|
+
#
|
126
|
+
def load_settings(graph)
|
127
|
+
counter = 1
|
128
|
+
|
129
|
+
graph.nodes.each do |node|
|
130
|
+
node_settings = load_setting_for_target(node.native_target)
|
131
|
+
unless node_settings
|
132
|
+
raise Informative, "No build settings loaded for #{node.name}"
|
133
|
+
end
|
134
|
+
|
135
|
+
node.build_settings = node_settings
|
136
|
+
|
137
|
+
debug("settings loaded for #{node.name} (#{counter} / #{graph.nodes.length})")
|
138
|
+
counter += 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
144
|
+
#
|
145
|
+
def load_setting_for_target(target)
|
146
|
+
info("loading settings for #{target.display_name}")
|
147
|
+
|
148
|
+
project_path = target.project.path
|
149
|
+
build_settings_loader.load_settings(project_path)
|
150
|
+
build_settings_loader.get_settings(project_path, target.display_name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|