cocoapods-binary-ht 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/cocoapods-binary-cache.rb +2 -0
- data/lib/cocoapods-binary-ht/cache/all.rb +9 -0
- data/lib/cocoapods-binary-ht/cache/validation_result.rb +73 -0
- data/lib/cocoapods-binary-ht/cache/validator.rb +20 -0
- data/lib/cocoapods-binary-ht/cache/validator_accumulated.rb +4 -0
- data/lib/cocoapods-binary-ht/cache/validator_base.rb +112 -0
- data/lib/cocoapods-binary-ht/cache/validator_dependencies_graph.rb +25 -0
- data/lib/cocoapods-binary-ht/cache/validator_dev_pods.rb +30 -0
- data/lib/cocoapods-binary-ht/cache/validator_exclusion.rb +14 -0
- data/lib/cocoapods-binary-ht/cache/validator_non_dev_pods.rb +13 -0
- data/lib/cocoapods-binary-ht/cache/validator_with_podfile.rb +9 -0
- data/lib/cocoapods-binary-ht/dependencies_graph/dependencies_graph.rb +108 -0
- data/lib/cocoapods-binary-ht/dependencies_graph/graph_visualizer.rb +65 -0
- data/lib/cocoapods-binary-ht/diagnosis/base.rb +13 -0
- data/lib/cocoapods-binary-ht/diagnosis/diagnosis.rb +24 -0
- data/lib/cocoapods-binary-ht/diagnosis/integration.rb +23 -0
- data/lib/cocoapods-binary-ht/env.rb +32 -0
- data/lib/cocoapods-binary-ht/helper/benchmark_show.rb +11 -0
- data/lib/cocoapods-binary-ht/helper/checksum.rb +18 -0
- data/lib/cocoapods-binary-ht/helper/json.rb +37 -0
- data/lib/cocoapods-binary-ht/helper/lockfile.rb +90 -0
- data/lib/cocoapods-binary-ht/helper/path_utils.rb +8 -0
- data/lib/cocoapods-binary-ht/helper/podspec.rb +20 -0
- data/lib/cocoapods-binary-ht/hooks/post_install.rb +23 -0
- data/lib/cocoapods-binary-ht/hooks/pre_install.rb +121 -0
- data/lib/cocoapods-binary-ht/main.rb +21 -0
- data/lib/cocoapods-binary-ht/pod-binary/LICENSE.txt +22 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/build.rb +37 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/detected_prebuilt_pods/installer.rb +25 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/detected_prebuilt_pods/target_definition.rb +29 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/names.rb +27 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/podfile_options.rb +2 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/prebuild_sandbox.rb +71 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/sandbox.rb +9 -0
- data/lib/cocoapods-binary-ht/pod-binary/helper/target_checker.rb +42 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/alter_specs.rb +150 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/patch/embed_framework_script.rb +36 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/patch/resolve_dependencies.rb +20 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/patch/sandbox_analyzer_state.rb +29 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/patch/source_installation.rb +55 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/source_installer.rb +114 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration/validation.rb +20 -0
- data/lib/cocoapods-binary-ht/pod-binary/integration.rb +11 -0
- data/lib/cocoapods-binary-ht/pod-binary/prebuild.rb +166 -0
- data/lib/cocoapods-binary-ht/pod-binary/prebuild_dsl.rb +10 -0
- data/lib/cocoapods-binary-ht/pod-binary/prebuild_hook.rb +10 -0
- data/lib/cocoapods-binary-ht/pod-rome/LICENSE.txt +22 -0
- data/lib/cocoapods-binary-ht/pod-rome/xcodebuild_command.rb +266 -0
- data/lib/cocoapods-binary-ht/pod-rome/xcodebuild_raw.rb +68 -0
- data/lib/cocoapods-binary-ht/prebuild_output/metadata.rb +63 -0
- data/lib/cocoapods-binary-ht/prebuild_output/output.rb +44 -0
- data/lib/cocoapods-binary-ht/state_store.rb +21 -0
- data/lib/cocoapods-binary-ht/ui.rb +9 -0
- data/lib/cocoapods_plugin.rb +5 -0
- data/lib/command/binary.rb +37 -0
- data/lib/command/config.rb +215 -0
- data/lib/command/executor/base.rb +37 -0
- data/lib/command/executor/fetcher.rb +67 -0
- data/lib/command/executor/prebuilder.rb +61 -0
- data/lib/command/executor/pusher.rb +35 -0
- data/lib/command/executor/visualizer.rb +23 -0
- data/lib/command/fetch.rb +22 -0
- data/lib/command/helper/zip.rb +20 -0
- data/lib/command/prebuild.rb +47 -0
- data/lib/command/push.rb +22 -0
- data/lib/command/visualize.rb +34 -0
- metadata +209 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
def alter_specs_for_prebuilt_pods
|
4
|
+
cache = []
|
5
|
+
|
6
|
+
@original_specs = analysis_result.specifications
|
7
|
+
.map { |spec| [spec.name, Pod::Specification.from_file(spec.defined_in_file)] }
|
8
|
+
.to_h
|
9
|
+
|
10
|
+
analysis_result.specifications
|
11
|
+
.select { |spec| should_integrate_prebuilt_pod?(spec.root.name) }
|
12
|
+
.group_by(&:root)
|
13
|
+
.each do |_, specs|
|
14
|
+
first_subspec_or_self = specs.find(&:subspec?) || specs[0]
|
15
|
+
specs.each do |spec|
|
16
|
+
alterations = {
|
17
|
+
:source_files => true,
|
18
|
+
:resources => true,
|
19
|
+
:license => true,
|
20
|
+
:vendored_framework => spec == first_subspec_or_self
|
21
|
+
}
|
22
|
+
alter_spec(spec, alterations, cache)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def metadata_of_target(name)
|
30
|
+
@metadata_by_target ||= {}
|
31
|
+
metadata = @metadata_by_target[name]
|
32
|
+
return metadata unless metadata.nil?
|
33
|
+
|
34
|
+
framework_path = sandbox.prebuild_sandbox.framework_folder_path_for_target_name(name)
|
35
|
+
metadata = PodPrebuild::Metadata.in_dir(framework_path)
|
36
|
+
@metadata_by_target[name] = metadata
|
37
|
+
metadata
|
38
|
+
end
|
39
|
+
|
40
|
+
def alter_spec(spec, alterations, cache)
|
41
|
+
metadata = metadata_of_target(spec.root.name)
|
42
|
+
targets = Pod.fast_get_targets_for_pod_name(spec.root.name, pod_targets, cache)
|
43
|
+
platforms = targets.map { |target| target.platform.name.to_s }.uniq
|
44
|
+
|
45
|
+
if alterations[:vendored_framework]
|
46
|
+
targets.each do |target|
|
47
|
+
# Use the prebuilt frameworks as vendered frameworks.
|
48
|
+
# The framework_file_path rule is decided in `install_for_prebuild`,
|
49
|
+
# as to compitable with older version and be less wordy.
|
50
|
+
framework_file_path = target.framework_name
|
51
|
+
framework_file_path = target.name + "/" + framework_file_path if targets.count > 1
|
52
|
+
framework_file_path = PodPrebuild.config.prebuilt_path(path: framework_file_path)
|
53
|
+
add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
empty_source_files(spec, platforms) if alterations[:source_files]
|
58
|
+
if alterations[:resources]
|
59
|
+
if metadata.static_framework?
|
60
|
+
tweak_resources_for_xib(spec, platforms)
|
61
|
+
tweak_resources_for_resource_bundles(spec, platforms)
|
62
|
+
else
|
63
|
+
# For dynamic frameworks, resources & resource bundles are already bundled inside the framework.
|
64
|
+
# We need to empty resources & resource bundles. Otherwise, there will be duplications
|
65
|
+
# (resources locating in both app bundle and framework bundle)
|
66
|
+
empty_resources(spec, platforms)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
empty_liscence(spec) if alterations[:license]
|
70
|
+
end
|
71
|
+
|
72
|
+
def empty_resources(spec, platforms)
|
73
|
+
spec.attributes_hash["resources"] = nil
|
74
|
+
spec.attributes_hash["resource_bundles"] = nil
|
75
|
+
platforms.each do |platform|
|
76
|
+
next if spec.attributes_hash[platform].nil?
|
77
|
+
|
78
|
+
spec.attributes_hash[platform]["resources"] = nil
|
79
|
+
spec.attributes_hash[platform]["resource_bundles"] = nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def tweak_resources_for_xib(spec, platforms)
|
84
|
+
# This is a workaround for prebuilt static framework that has `*.xib` files in the resources
|
85
|
+
# (declared by `spec.resources = ...`)
|
86
|
+
# ---------------------------------------------------------------
|
87
|
+
# In the prebuild stage, a XIB file is compiled as a NIB file in the framework.
|
88
|
+
# In the integration stage, this file is added to the script `Pods-<Target>-resources.sh`:
|
89
|
+
# - If it's a XIB, it's installed to the target bundle by `ibtool`
|
90
|
+
# - If it's a NIB, it's copied directly to the target bundle
|
91
|
+
# Since the one embedded in the prebuilt framework is a NIB (already compiled)
|
92
|
+
# --> We need to alter the spec so that this file will be copied to the target bundle
|
93
|
+
change_xib_to_nib = ->(path) { path.sub(".xib", ".nib") }
|
94
|
+
update_resources = lambda do |resources|
|
95
|
+
if resources.is_a?(String)
|
96
|
+
change_xib_to_nib.call(resources)
|
97
|
+
elsif resources.is_a?(Array)
|
98
|
+
resources.map { |item| change_xib_to_nib.call(item) }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
spec.attributes_hash["resources"] = update_resources.call(spec.attributes_hash["resources"])
|
102
|
+
platforms.each do |platform|
|
103
|
+
next if spec.attributes_hash[platform].nil?
|
104
|
+
|
105
|
+
platform_resources = spec.attributes_hash[platform]["resources"]
|
106
|
+
spec.attributes_hash[platform]["resources"] = update_resources.call(platform_resources)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def tweak_resources_for_resource_bundles(spec, platforms)
|
111
|
+
add_resource_bundles_to_resources = lambda do |attributes|
|
112
|
+
return if attributes.nil?
|
113
|
+
|
114
|
+
resource_bundles = attributes["resource_bundles"] || {}
|
115
|
+
resource_bundle_names = resource_bundles.keys
|
116
|
+
attributes["resource_bundles"] = nil
|
117
|
+
attributes["resources"] ||= []
|
118
|
+
attributes["resources"] = [attributes["resources"]] if attributes["resources"].is_a?(String)
|
119
|
+
attributes["resources"] += resource_bundle_names.map do |name|
|
120
|
+
PodPrebuild.config.prebuilt_path(path: "#{name}.bundle")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
add_resource_bundles_to_resources.call(spec.attributes_hash)
|
125
|
+
platforms.each do |platform|
|
126
|
+
add_resource_bundles_to_resources.call(spec.attributes_hash[platform])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_vendered_framework(spec, platform, added_framework_file_path)
|
131
|
+
spec.attributes_hash[platform] = {} if spec.attributes_hash[platform].nil?
|
132
|
+
vendored_frameworks = spec.attributes_hash[platform]["vendored_frameworks"] || []
|
133
|
+
vendored_frameworks = [vendored_frameworks] if vendored_frameworks.is_a?(String)
|
134
|
+
vendored_frameworks += [added_framework_file_path]
|
135
|
+
spec.attributes_hash[platform]["vendored_frameworks"] = vendored_frameworks
|
136
|
+
end
|
137
|
+
|
138
|
+
def empty_source_files(spec, platforms)
|
139
|
+
spec.attributes_hash["source_files"] = []
|
140
|
+
platforms.each do |platform|
|
141
|
+
spec.attributes_hash[platform]["source_files"] = [] unless spec.attributes_hash[platform].nil?
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def empty_liscence(spec)
|
146
|
+
spec.attributes_hash["license"] = {}
|
147
|
+
spec.root.attributes_hash["license"] = {}
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# A fix in embeded frameworks script.
|
2
|
+
#
|
3
|
+
# The framework file in pod target folder is a symblink. The EmbedFrameworksScript use `readlink`
|
4
|
+
# to read the read path. As the symlink is a relative symlink, readlink cannot handle it well. So
|
5
|
+
# we override the `readlink` to a fixed version.
|
6
|
+
#
|
7
|
+
module Pod
|
8
|
+
module Generator
|
9
|
+
class EmbedFrameworksScript
|
10
|
+
old_method = instance_method(:script)
|
11
|
+
define_method(:script) do
|
12
|
+
script = old_method.bind(self).call
|
13
|
+
patch = <<-SH.strip_heredoc
|
14
|
+
#!/bin/sh
|
15
|
+
# ---- this is added by cocoapods-binary ---
|
16
|
+
# Readlink cannot handle relative symlink well, so we override it to a new one
|
17
|
+
# If the path isn't an absolute path, we add a realtive prefix.
|
18
|
+
old_read_link=`which readlink`
|
19
|
+
readlink () {
|
20
|
+
path=`$old_read_link "$1"`;
|
21
|
+
if [ $(echo "$path" | cut -c 1-1) = '/' ]; then
|
22
|
+
echo $path;
|
23
|
+
else
|
24
|
+
echo "`dirname $1`/$path";
|
25
|
+
fi
|
26
|
+
}
|
27
|
+
# ---
|
28
|
+
SH
|
29
|
+
|
30
|
+
# patch the rsync for copy dSYM symlink
|
31
|
+
script = script.gsub "rsync --delete", "rsync --copy-links --delete"
|
32
|
+
patch + script
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Let cocoapods use the prebuild framework files in install process.
|
2
|
+
#
|
3
|
+
# the code only effect the second pod install process.
|
4
|
+
#
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
# Modify specification to use only the prebuild framework after analyzing
|
8
|
+
original_resolve_dependencies = instance_method(:resolve_dependencies)
|
9
|
+
define_method(:resolve_dependencies) do
|
10
|
+
original_resolve_dependencies.bind(self).call
|
11
|
+
|
12
|
+
# check the pods
|
13
|
+
# Although we have did it in prebuild stage, it's not sufficient.
|
14
|
+
# Same pod may appear in another target in form of source code.
|
15
|
+
# Prebuild.check_one_pod_should_have_only_one_target(prebuilt_pod_targets)
|
16
|
+
validate_every_pod_only_have_one_form
|
17
|
+
alter_specs_for_prebuilt_pods
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Analyzer
|
4
|
+
class SandboxAnalyzer
|
5
|
+
original_analyze = instance_method(:analyze)
|
6
|
+
define_method(:analyze) do
|
7
|
+
state = original_analyze.bind(self).call
|
8
|
+
state = alter_state(state)
|
9
|
+
state
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def alter_state(state)
|
15
|
+
return state if PodPrebuild.config.tracked_prebuilt_pod_names.empty?
|
16
|
+
|
17
|
+
prebuilt = PodPrebuild.config.tracked_prebuilt_pod_names
|
18
|
+
Pod::UI.message "Alter sandbox state: treat prebuilt frameworks as added: #{prebuilt.to_a}"
|
19
|
+
SpecsState.new(
|
20
|
+
:added => (state.added + prebuilt).uniq,
|
21
|
+
:changed => state.changed - prebuilt,
|
22
|
+
:removed => state.deleted - prebuilt,
|
23
|
+
:unchanged => state.unchanged - prebuilt
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative "../source_installer"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
# Override the download step to skip download and prepare file in target folder
|
6
|
+
alias original_create_pod_installer create_pod_installer
|
7
|
+
def create_pod_installer(name)
|
8
|
+
if should_integrate_prebuilt_pod?(name)
|
9
|
+
create_prebuilt_source_installer(name)
|
10
|
+
else
|
11
|
+
create_normal_source_installer(name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def create_normal_source_installer(name)
|
18
|
+
original_create_pod_installer(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def original_specs_by_platform(name)
|
22
|
+
specs_for_pod(name).map do |platform, specs|
|
23
|
+
specs_ = specs.map { |spec| @original_specs[spec.name] }
|
24
|
+
[platform, specs_]
|
25
|
+
end.to_h
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_prebuilt_source_installer(name)
|
29
|
+
# A source installer needs to install with the original spec (instead of the altered spec).
|
30
|
+
# Otherwise, the cache will be corrupted because CocoaPods packs necessary dirs/files from temp dir
|
31
|
+
# to the cache dir based on the spec.
|
32
|
+
source_installer = PodSourceInstaller.new(sandbox, podfile, original_specs_by_platform(name))
|
33
|
+
pod_installer = PrebuiltSourceInstaller.new(
|
34
|
+
sandbox,
|
35
|
+
podfile,
|
36
|
+
specs_for_pod(name),
|
37
|
+
source_installer: source_installer
|
38
|
+
)
|
39
|
+
pod_installers << pod_installer
|
40
|
+
pod_installer
|
41
|
+
end
|
42
|
+
|
43
|
+
def should_integrate_prebuilt_pod?(name)
|
44
|
+
if PodPrebuild.config.prebuild_job? && PodPrebuild.config.targets_to_prebuild_from_cli.empty?
|
45
|
+
# In a prebuild job, at the integration stage, all prebuilt frameworks should be
|
46
|
+
# ready for integration regardless of whether there was any cache miss or not.
|
47
|
+
# Those that are missed were prebuilt in the prebuild stage.
|
48
|
+
PodPrebuild.state.cache_validation.include?(name)
|
49
|
+
else
|
50
|
+
prebuilt = PodPrebuild.state.cache_validation.hit + PodPrebuild.config.targets_to_prebuild_from_cli
|
51
|
+
prebuilt.include?(name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class PrebuiltSourceInstaller < PodSourceInstaller
|
4
|
+
def initialize(*args, **kwargs)
|
5
|
+
@source_installer = kwargs.delete(:source_installer)
|
6
|
+
super(*args, **kwargs)
|
7
|
+
end
|
8
|
+
|
9
|
+
def prebuild_sandbox
|
10
|
+
@prebuild_sandbox ||= Pod::PrebuildSandbox.from_standard_sandbox(sandbox)
|
11
|
+
end
|
12
|
+
|
13
|
+
def install!
|
14
|
+
@source_installer.install!
|
15
|
+
install_prebuilt_framework!
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def install_prebuilt_framework!
|
21
|
+
return if !PodPrebuild.config.dev_pods_enabled? && sandbox.local?(name)
|
22
|
+
|
23
|
+
# make a symlink to target folder
|
24
|
+
# TODO (bang): Unify to 1 sandbox to optimize and avoid inconsistency
|
25
|
+
# if spec used in multiple platforms, it may return multiple paths
|
26
|
+
target_names = prebuild_sandbox.existed_target_names_for_pod_name(name)
|
27
|
+
target_names.each do |name|
|
28
|
+
real_file_folder = prebuild_sandbox.framework_folder_path_for_target_name(name)
|
29
|
+
|
30
|
+
# If have only one platform, just place int the root folder of this pod.
|
31
|
+
# If have multiple paths, we use a sperated folder to store different
|
32
|
+
# platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
|
33
|
+
target_folder = sandbox.pod_dir(self.name)
|
34
|
+
target_folder += real_file_folder.basename if target_names.count > 1
|
35
|
+
target_folder += PodPrebuild.config.prebuilt_path
|
36
|
+
target_folder.rmtree if target_folder.exist?
|
37
|
+
target_folder.mkpath
|
38
|
+
|
39
|
+
walk(real_file_folder) do |child|
|
40
|
+
source = child
|
41
|
+
# only make symlink to file and `.framework` folder
|
42
|
+
if child.directory? && [".framework", ".xcframework", ".dSYM"].include?(child.extname)
|
43
|
+
if [".framework", ".xcframework"].include?(child.extname)
|
44
|
+
mirror_with_symlink(source, real_file_folder, target_folder)
|
45
|
+
end
|
46
|
+
# Ignore dsym here to avoid cocoapods from adding install_dsym to buildphase-script
|
47
|
+
# That can cause duplicated output files error in Xcode 11 (warning in Xcode 10)
|
48
|
+
# We need more setup to support local debuging with prebuilt dSYM
|
49
|
+
next false # Don't go deeper
|
50
|
+
elsif child.file?
|
51
|
+
mirror_with_symlink(source, real_file_folder, target_folder)
|
52
|
+
next true
|
53
|
+
else
|
54
|
+
next true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# symbol link copy resource for static framework
|
59
|
+
metadata = PodPrebuild::Metadata.in_dir(real_file_folder)
|
60
|
+
next unless metadata.static_framework?
|
61
|
+
|
62
|
+
metadata.resources.each do |path|
|
63
|
+
target_file_path = Pathname(path)
|
64
|
+
.sub("${PODS_ROOT}", sandbox.root.to_path)
|
65
|
+
.sub("${PODS_CONFIGURATION_BUILD_DIR}", sandbox.root.to_path)
|
66
|
+
next if target_file_path.exist?
|
67
|
+
|
68
|
+
real_file_path = real_file_folder + metadata.framework_name + File.basename(path)
|
69
|
+
|
70
|
+
# TODO (thuyen): Fix https://github.com/pandaleecn/cocoapods-binary-ht/issues/45
|
71
|
+
|
72
|
+
case File.extname(path)
|
73
|
+
when ".xib"
|
74
|
+
# https://github.com/pandaleecn/cocoapods-binary-ht/issues/7
|
75
|
+
# When ".xib" files are compiled in a framework, it becomes ".nib" files
|
76
|
+
# --> We need to correct the path extension
|
77
|
+
real_file_path = real_file_path.sub_ext(".nib")
|
78
|
+
target_file_path = target_file_path.sub(".xib", ".nib")
|
79
|
+
when ".bundle"
|
80
|
+
next if metadata.resource_bundles.include?(File.basename(path))
|
81
|
+
|
82
|
+
real_file_path = real_file_folder + File.basename(path) unless real_file_path.exist?
|
83
|
+
end
|
84
|
+
make_link(real_file_path, target_file_path)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def walk(path, &action)
|
90
|
+
return unless path.exist?
|
91
|
+
|
92
|
+
path.children.each do |child|
|
93
|
+
result = action.call(child, &action)
|
94
|
+
if child.directory?
|
95
|
+
walk(child, &action) if result
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def make_link(source, target)
|
101
|
+
source = Pathname.new(source)
|
102
|
+
target = Pathname.new(target)
|
103
|
+
target.rmtree if target.exist?
|
104
|
+
target.parent.mkpath unless target.parent.exist?
|
105
|
+
relative_source = source.relative_path_from(target.parent)
|
106
|
+
FileUtils.ln_sf(relative_source, target)
|
107
|
+
end
|
108
|
+
|
109
|
+
def mirror_with_symlink(source, basefolder, target_folder)
|
110
|
+
make_link(source, target_folder + source.relative_path_from(basefolder))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
def validate_every_pod_only_have_one_form
|
4
|
+
multi_targets_pods = pod_targets
|
5
|
+
.group_by(&:pod_name)
|
6
|
+
.select do |_, targets|
|
7
|
+
is_multi_targets = targets.map { |t| t.platform.name }.uniq.count > 1
|
8
|
+
is_multi_forms = targets.map { |t| prebuilt_pod_targets.include?(t) }.uniq.count > 1
|
9
|
+
is_multi_targets && is_multi_forms
|
10
|
+
end
|
11
|
+
return if multi_targets_pods.empty?
|
12
|
+
|
13
|
+
warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
|
14
|
+
warnings += multi_targets_pods
|
15
|
+
.map { |name, targets| " #{name}: #{targets.map { |t| t.platform.name }}" }
|
16
|
+
.join("\n")
|
17
|
+
raise Informative, warnings
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative "helper/podfile_options"
|
2
|
+
require_relative "helper/prebuild_sandbox"
|
3
|
+
require_relative "helper/sandbox"
|
4
|
+
require_relative "helper/names"
|
5
|
+
require_relative "helper/target_checker"
|
6
|
+
require_relative "integration/alter_specs"
|
7
|
+
require_relative "integration/validation"
|
8
|
+
require_relative "integration/patch/embed_framework_script"
|
9
|
+
require_relative "integration/patch/sandbox_analyzer_state"
|
10
|
+
require_relative "integration/patch/resolve_dependencies"
|
11
|
+
require_relative "integration/patch/source_installation"
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require_relative "../prebuild_output/output"
|
3
|
+
require_relative "../helper/lockfile"
|
4
|
+
require_relative "helper/target_checker"
|
5
|
+
require_relative "helper/build"
|
6
|
+
|
7
|
+
module Pod
|
8
|
+
class PrebuildInstaller < Installer # rubocop:disable Metrics/ClassLength
|
9
|
+
attr_reader :lockfile_wrapper
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
super(options[:sandbox], options[:podfile], options[:lockfile])
|
13
|
+
@cache_validation = options[:cache_validation]
|
14
|
+
@lockfile_wrapper = lockfile && PodPrebuild::Lockfile.new(lockfile)
|
15
|
+
end
|
16
|
+
|
17
|
+
def installation_options
|
18
|
+
# Skip integrating user targets for prebuild Pods project.
|
19
|
+
@installation_options ||= Pod::Installer::InstallationOptions.new(
|
20
|
+
super.to_h.merge(:integrate_targets => false)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_code_gen!(targets)
|
25
|
+
return if PodPrebuild.config.prebuild_code_gen.nil?
|
26
|
+
|
27
|
+
Pod::UI.title("Running code generation...") do
|
28
|
+
PodPrebuild.config.prebuild_code_gen.call(self, targets)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def prebuild_output
|
33
|
+
@prebuild_output ||= PodPrebuild::Output.new(sandbox)
|
34
|
+
end
|
35
|
+
|
36
|
+
def targets_to_prebuild
|
37
|
+
to_build = PodPrebuild.config.targets_to_prebuild_from_cli
|
38
|
+
if to_build.empty?
|
39
|
+
to_build = PodPrebuild.config.prebuild_all_pods? ? @cache_validation.all : @cache_validation.missed
|
40
|
+
end
|
41
|
+
pod_targets.select { |target| to_build.include?(target.name) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def prebuild_frameworks!
|
45
|
+
existed_framework_folder = sandbox.generate_framework_path
|
46
|
+
sandbox_path = sandbox.root
|
47
|
+
targets = targets_to_prebuild
|
48
|
+
Pod::UI.puts "Prebuild frameworks (total #{targets.count}): #{targets.map(&:name)}".magenta
|
49
|
+
|
50
|
+
run_code_gen!(targets)
|
51
|
+
|
52
|
+
PodPrebuild.remove_build_dir(sandbox_path)
|
53
|
+
PodPrebuild.build(
|
54
|
+
sandbox: sandbox_path,
|
55
|
+
targets: targets,
|
56
|
+
configuration: PodPrebuild.config.prebuild_config,
|
57
|
+
output_path: sandbox.generate_framework_path,
|
58
|
+
bitcode_enabled: PodPrebuild.config.bitcode_enabled?,
|
59
|
+
device_build_enabled: PodPrebuild.config.device_build_enabled?,
|
60
|
+
disable_dsym: PodPrebuild.config.disable_dsym?,
|
61
|
+
log_path: PodPrebuild.config.xcodebuild_log_path,
|
62
|
+
args: PodPrebuild.config.build_args
|
63
|
+
)
|
64
|
+
PodPrebuild.remove_build_dir(sandbox_path)
|
65
|
+
|
66
|
+
targets.each do |target|
|
67
|
+
collect_metadata(target, sandbox.framework_folder_path_for_target_name(target.name))
|
68
|
+
end
|
69
|
+
|
70
|
+
# copy vendored libraries and frameworks
|
71
|
+
targets.each do |target|
|
72
|
+
root_path = sandbox.pod_dir(target.name)
|
73
|
+
target_folder = sandbox.framework_folder_path_for_target_name(target.name)
|
74
|
+
|
75
|
+
# If target shouldn't build, we copy all the original files
|
76
|
+
# This is for target with only .a and .h files
|
77
|
+
unless target.should_build?
|
78
|
+
FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
|
79
|
+
next
|
80
|
+
end
|
81
|
+
|
82
|
+
target.spec_consumers.each do |consumer|
|
83
|
+
file_accessor = Sandbox::FileAccessor.new(root_path, consumer)
|
84
|
+
lib_paths = file_accessor.vendored_frameworks || []
|
85
|
+
lib_paths += file_accessor.vendored_libraries
|
86
|
+
# @TODO dSYM files
|
87
|
+
lib_paths.each do |lib_path|
|
88
|
+
relative = lib_path.relative_path_from(root_path)
|
89
|
+
destination = target_folder + relative
|
90
|
+
destination.dirname.mkpath unless destination.dirname.exist?
|
91
|
+
FileUtils.cp_r(lib_path, destination, :remove_destination => true)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# save the pod_name for prebuild framwork in sandbox
|
97
|
+
targets.each do |target|
|
98
|
+
sandbox.save_pod_name_for_target target
|
99
|
+
end
|
100
|
+
|
101
|
+
# Remove useless files
|
102
|
+
# remove useless pods
|
103
|
+
all_needed_names = pod_targets.map(&:name).uniq
|
104
|
+
useless_target_names = sandbox.exsited_framework_target_names.reject do |name|
|
105
|
+
all_needed_names.include? name
|
106
|
+
end
|
107
|
+
useless_target_names.each do |name|
|
108
|
+
Pod::UI.message "Remove: #{name}"
|
109
|
+
path = sandbox.framework_folder_path_for_target_name(name)
|
110
|
+
path.rmtree if path.exist?
|
111
|
+
end
|
112
|
+
|
113
|
+
if PodPrebuild.config.dont_remove_source_code?
|
114
|
+
# just remove the tmp files
|
115
|
+
path = sandbox.root + "Manifest.lock.tmp"
|
116
|
+
path.rmtree if path.exist?
|
117
|
+
else
|
118
|
+
# only keep manifest.lock and framework folder in _Prebuild
|
119
|
+
to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
|
120
|
+
to_delete_files = sandbox_path.children.reject { |file| to_remain_files.include?(File.basename(file)) }
|
121
|
+
to_delete_files.each { |file| file.rmtree if file.exist? }
|
122
|
+
end
|
123
|
+
|
124
|
+
prebuild_output.write_delta_file(
|
125
|
+
updated: targets.map { |target| target.label.to_s },
|
126
|
+
deleted: useless_target_names
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def clean_delta_file
|
131
|
+
prebuild_output.clean_delta_file
|
132
|
+
end
|
133
|
+
|
134
|
+
def collect_metadata(target, output_path)
|
135
|
+
metadata = PodPrebuild::Metadata.in_dir(output_path)
|
136
|
+
metadata.framework_name = target.framework_name
|
137
|
+
metadata.static_framework = target.static_framework?
|
138
|
+
resource_paths = target.resource_paths
|
139
|
+
metadata.resources = resource_paths.is_a?(Hash) ? resource_paths.values.flatten : resource_paths
|
140
|
+
metadata.resource_bundles = target
|
141
|
+
.file_accessors
|
142
|
+
.map { |f| f.resource_bundles.keys }
|
143
|
+
.flatten
|
144
|
+
.map { |name| "#{name}.bundle" }
|
145
|
+
metadata.build_settings = pods_project.targets
|
146
|
+
.detect { |native_target| native_target.name == target.name }
|
147
|
+
.build_configurations
|
148
|
+
.detect { |config| config.name == PodPrebuild.config.prebuild_config }
|
149
|
+
.build_settings
|
150
|
+
metadata.source_hash = @lockfile_wrapper && @lockfile_wrapper.dev_pod_hash(target.name)
|
151
|
+
|
152
|
+
# Store root path for code-coverage support later
|
153
|
+
# TODO: update driver code-coverage logic to use path stored here
|
154
|
+
project_root = PathUtils.remove_last_path_component(@sandbox.standard_sanbox_path.to_s)
|
155
|
+
metadata.project_root = project_root
|
156
|
+
metadata.save!
|
157
|
+
end
|
158
|
+
|
159
|
+
# patch the post install hook
|
160
|
+
old_method2 = instance_method(:run_plugins_post_install_hooks)
|
161
|
+
define_method(:run_plugins_post_install_hooks) do
|
162
|
+
old_method2.bind(self).call
|
163
|
+
prebuild_frameworks! if PodPrebuild::Env.prebuild_stage?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative "helper/podfile_options"
|
2
|
+
require_relative "helper/prebuild_sandbox"
|
3
|
+
|
4
|
+
Pod::HooksManager.register("cocoapods-binary-ht", :pre_install) do |installer_context|
|
5
|
+
PodPrebuild::PreInstallHook.new(installer_context).run
|
6
|
+
end
|
7
|
+
|
8
|
+
Pod::HooksManager.register("cocoapods-binary-ht", :post_install) do |installer_context|
|
9
|
+
PodPrebuild::PostInstallHook.new(installer_context).run
|
10
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Boris Bügling <boris@icculus.org>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|