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,90 @@
|
|
1
|
+
require_relative "checksum"
|
2
|
+
|
3
|
+
module PodPrebuild
|
4
|
+
class Lockfile
|
5
|
+
attr_reader :lockfile, :data
|
6
|
+
|
7
|
+
def initialize(lockfile)
|
8
|
+
@lockfile = lockfile
|
9
|
+
@data = lockfile.to_hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def pods
|
13
|
+
@pods ||= (@data["PODS"] || []).map { |v| pod_from(v) }.to_h
|
14
|
+
end
|
15
|
+
|
16
|
+
def external_sources
|
17
|
+
@data["EXTERNAL SOURCES"] || {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def dev_pod_sources
|
21
|
+
@dev_pod_sources ||= external_sources.select { |_, attributes| attributes.key?(:path) } || {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def dev_pod_names
|
25
|
+
# There are 2 types of external sources:
|
26
|
+
# - Development pods: declared with `:path` option in Podfile, corresponding to `:path` in the Lockfile
|
27
|
+
# - External remote pods: declared with `:git` option in Podfile, corresponding to `:git` in the Lockfile
|
28
|
+
# --------------------
|
29
|
+
# EXTERNAL SOURCES:
|
30
|
+
# ADevPod:
|
31
|
+
# :path: path/to/dev_pod
|
32
|
+
# AnExternalRemotePod:
|
33
|
+
# :git: git@remote_url
|
34
|
+
# :commit: abc1234
|
35
|
+
# --------------------
|
36
|
+
@dev_pod_names ||= dev_pod_sources.keys.to_set
|
37
|
+
end
|
38
|
+
|
39
|
+
def dev_pods
|
40
|
+
dev_pod_names_ = dev_pod_names
|
41
|
+
@dev_pods ||= pods.select { |name, _| dev_pod_names_.include?(name) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def non_dev_pods
|
45
|
+
dev_pod_names_ = dev_pod_names
|
46
|
+
@non_dev_pods ||= pods.reject { |name, _| dev_pod_names_.include?(name) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def subspec_vendor_pods
|
50
|
+
dev_pod_names_ = dev_pod_names
|
51
|
+
@subspec_vendor_pods ||= subspec_pods.reject { |name, _| dev_pod_names_.include?(name) }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return content hash (Hash the directory at source path) of a dev_pod
|
55
|
+
# Return nil if it's not a dev_pod
|
56
|
+
def dev_pod_hash(pod_name)
|
57
|
+
dev_pod_hashes_map[pod_name]
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def subspec_pods
|
63
|
+
@subspec_pods ||= pods.keys
|
64
|
+
.select { |k| k.include?("/") }
|
65
|
+
.group_by { |k| k.split("/")[0] }
|
66
|
+
end
|
67
|
+
|
68
|
+
# Generate a map between a dev_pod and it source hash
|
69
|
+
def dev_pod_hashes_map
|
70
|
+
@dev_pod_hashes_map ||=
|
71
|
+
dev_pod_sources.map { |name, attribs| [name, FolderChecksum.git_checksum(attribs[:path])] }.to_h
|
72
|
+
end
|
73
|
+
|
74
|
+
# Parse an item under `PODS` section of a Lockfile
|
75
|
+
# @param hash_or_string: an item under `PODS` section, could be a Hash (if having dependencies) or a String
|
76
|
+
# Examples:
|
77
|
+
# --------------------------
|
78
|
+
# PODS:
|
79
|
+
# - FrameworkA (0.0.1)
|
80
|
+
# - FrameworkB (0.0.2):
|
81
|
+
# - DependencyOfB
|
82
|
+
# -------------------------
|
83
|
+
# @return [framework_name, version] (for ex. ["AFramework", "0.0.1"])
|
84
|
+
def pod_from(hash_or_string)
|
85
|
+
name_with_version = hash_or_string.is_a?(Hash) ? hash_or_string.keys[0] : hash_or_string
|
86
|
+
match = name_with_version.match(/(\S+) \((\S+)\)/)
|
87
|
+
[match[1], match[2]]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Copyright 2019 panda Holdings PTE LTE (panda), All rights reserved.
|
2
|
+
# Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
|
3
|
+
|
4
|
+
class PathUtils
|
5
|
+
def self.remove_last_path_component(path, num_components = 1)
|
6
|
+
path.split("/")[0...-num_components].join("/")
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pod
|
2
|
+
class Specification
|
3
|
+
def empty_source_files?
|
4
|
+
unless subspecs.empty?
|
5
|
+
# return early if there are some files in subpec(s) but process the spec itself
|
6
|
+
return false unless subspecs.all?(&:empty_source_files?)
|
7
|
+
end
|
8
|
+
|
9
|
+
check = lambda do |patterns|
|
10
|
+
patterns = [patterns] if patterns.is_a?(String)
|
11
|
+
patterns.reject(&:empty?).all? do |pattern|
|
12
|
+
Xcodeproj::Constants::HEADER_FILES_EXTENSIONS.any? { |ext| pattern.end_with?(ext) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
available_platforms.all? do |platform|
|
16
|
+
check.call(consumer(platform).source_files)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module PodPrebuild
|
2
|
+
class PostInstallHook
|
3
|
+
def initialize(installer_context)
|
4
|
+
@installer_context = installer_context
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
diagnose if PodPrebuild::Env.integration_stage?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def diagnose
|
14
|
+
Pod::UI.title("Diagnosing cocoapods-binary-ht") do
|
15
|
+
PodPrebuild::Diagnosis.new(
|
16
|
+
cache_validation: PodPrebuild.state.cache_validation,
|
17
|
+
standard_sandbox: @installer_context.sandbox,
|
18
|
+
specs: @installer_context.umbrella_targets.map(&:specs).flatten
|
19
|
+
).run
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module PodPrebuild
|
2
|
+
class PreInstallHook
|
3
|
+
include ObjectSpace
|
4
|
+
|
5
|
+
attr_reader :installer_context, :podfile, :prebuild_sandbox, :standard_sandbox, :cache_validation
|
6
|
+
|
7
|
+
def initialize(installer_context)
|
8
|
+
@installer_context = installer_context
|
9
|
+
@podfile = installer_context.podfile
|
10
|
+
@pod_install_options = {}
|
11
|
+
@prebuild_sandbox = nil
|
12
|
+
@standard_sandbox = installer_context.sandbox
|
13
|
+
@cache_validation = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
return if @installer_context.sandbox.is_a?(Pod::PrebuildSandbox)
|
18
|
+
|
19
|
+
log_section "🚀 Prebuild frameworks"
|
20
|
+
ensure_valid_podfile
|
21
|
+
save_installation_states
|
22
|
+
create_prebuild_sandbox
|
23
|
+
Pod::UI.title("Detect implicit dependencies") { detect_implicit_dependencies }
|
24
|
+
Pod::UI.title("Validate prebuilt cache") { validate_cache }
|
25
|
+
prebuild! if PodPrebuild.config.prebuild_job?
|
26
|
+
|
27
|
+
PodPrebuild::Env.next_stage!
|
28
|
+
prepare_for_integration
|
29
|
+
log_section "🤖 Resume pod installation"
|
30
|
+
require_relative "../pod-binary/integration"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def save_installation_states
|
36
|
+
save_pod_install_options
|
37
|
+
end
|
38
|
+
|
39
|
+
def save_pod_install_options
|
40
|
+
# Fetch original installer (which is running this pre-install hook) options,
|
41
|
+
# then pass them to our installer to perform update if needed
|
42
|
+
# Looks like this is the most appropriate way to figure out that something should be updated
|
43
|
+
@original_installer = ObjectSpace.each_object(Pod::Installer).first
|
44
|
+
@pod_install_options[:update] = @original_installer.update
|
45
|
+
@pod_install_options[:repo_update] = @original_installer.repo_update
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_valid_podfile
|
49
|
+
podfile.target_definition_list.each do |target_definition|
|
50
|
+
next if target_definition.explicit_prebuilt_pod_names.empty?
|
51
|
+
raise "cocoapods-binary-ht requires `use_frameworks!`" unless target_definition.uses_frameworks?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_prebuild_sandbox
|
56
|
+
@prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
|
57
|
+
Pod::UI.message "Create prebuild sandbox at #{@prebuild_sandbox.root}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def detect_implicit_dependencies
|
61
|
+
@original_installer.resolve_dependencies
|
62
|
+
all_specs = @original_installer.analysis_result.specifications
|
63
|
+
pods_with_empty_source_files = all_specs
|
64
|
+
.group_by { |spec| spec.name.split("/")[0] }
|
65
|
+
.select { |_, specs| specs.all?(&:empty_source_files?) }
|
66
|
+
.keys
|
67
|
+
PodPrebuild.config.update_detected_excluded_pods!(pods_with_empty_source_files)
|
68
|
+
PodPrebuild.config.update_detected_prebuilt_pod_names!(@original_installer.prebuilt_pod_names)
|
69
|
+
Pod::UI.puts "Exclude pods with empty source files: #{pods_with_empty_source_files.to_a}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_cache
|
73
|
+
prebuilt_lockfile = Pod::Lockfile.from_file(prebuild_sandbox.root + "Manifest.lock")
|
74
|
+
@cache_validation = PodPrebuild::CacheValidator.new(
|
75
|
+
podfile: podfile,
|
76
|
+
pod_lockfile: installer_context.lockfile,
|
77
|
+
prebuilt_lockfile: prebuilt_lockfile,
|
78
|
+
validate_prebuilt_settings: PodPrebuild.config.validate_prebuilt_settings,
|
79
|
+
generated_framework_path: prebuild_sandbox.generate_framework_path,
|
80
|
+
sandbox_root: prebuild_sandbox.root,
|
81
|
+
ignored_pods: PodPrebuild.config.excluded_pods,
|
82
|
+
prebuilt_pod_names: PodPrebuild.config.prebuilt_pod_names
|
83
|
+
).validate
|
84
|
+
path_to_save_cache_validation = PodPrebuild.config.save_cache_validation_to
|
85
|
+
@cache_validation.update_to(path_to_save_cache_validation) unless path_to_save_cache_validation.nil?
|
86
|
+
cache_validation.print_summary
|
87
|
+
PodPrebuild.state.update(:cache_validation => cache_validation)
|
88
|
+
end
|
89
|
+
|
90
|
+
def prebuild!
|
91
|
+
binary_installer = Pod::PrebuildInstaller.new(
|
92
|
+
sandbox: prebuild_sandbox,
|
93
|
+
podfile: podfile,
|
94
|
+
lockfile: installer_context.lockfile,
|
95
|
+
cache_validation: cache_validation
|
96
|
+
)
|
97
|
+
binary_installer.update = @pod_install_options[:update]
|
98
|
+
binary_installer.repo_update = @pod_install_options[:repo_update]
|
99
|
+
|
100
|
+
Pod::UI.title("Prebuilding...") do
|
101
|
+
binary_installer.clean_delta_file
|
102
|
+
binary_installer.install!
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def prepare_for_integration
|
107
|
+
# Remove local podspec of external sources so that it downloads sources correctly.
|
108
|
+
# Otherwise, with incremental pod installation, CocoaPods downloads the sources
|
109
|
+
# based on the `s.source` declaration in the podspecs which are sometimes incorrect.
|
110
|
+
PodPrebuild.config.prebuilt_pod_names.each do |name|
|
111
|
+
@standard_sandbox.remove_local_podspec(name) if @standard_sandbox.checkout_sources.key?(name)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def log_section(message)
|
116
|
+
Pod::UI.puts "-----------------------------------------"
|
117
|
+
Pod::UI.puts message
|
118
|
+
Pod::UI.puts "-----------------------------------------"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright 2019 panda Holdings PTE LTE (panda), All rights reserved.
|
2
|
+
# Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
|
3
|
+
|
4
|
+
require_relative "ui"
|
5
|
+
require_relative "dependencies_graph/dependencies_graph"
|
6
|
+
require_relative "cache/all"
|
7
|
+
require_relative "helper/benchmark_show"
|
8
|
+
require_relative "helper/json"
|
9
|
+
require_relative "helper/lockfile"
|
10
|
+
require_relative "helper/path_utils"
|
11
|
+
require_relative "helper/podspec"
|
12
|
+
require_relative "env"
|
13
|
+
require_relative "state_store"
|
14
|
+
require_relative "hooks/post_install"
|
15
|
+
require_relative "hooks/pre_install"
|
16
|
+
require_relative "pod-binary/prebuild_dsl"
|
17
|
+
require_relative "pod-binary/prebuild_hook"
|
18
|
+
require_relative "pod-binary/prebuild"
|
19
|
+
require_relative "prebuild_output/metadata"
|
20
|
+
require_relative "prebuild_output/output"
|
21
|
+
require_relative "diagnosis/diagnosis"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2018 leavez <gaojiji@gmail.com>
|
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.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative "../../pod-rome/xcodebuild_raw"
|
2
|
+
require_relative "../../pod-rome/xcodebuild_command"
|
3
|
+
|
4
|
+
module PodPrebuild
|
5
|
+
def self.build(options)
|
6
|
+
targets = options[:targets] || []
|
7
|
+
return if targets.empty?
|
8
|
+
|
9
|
+
options[:sandbox] = Pod::Sandbox.new(Pathname(options[:sandbox])) unless options[:sandbox].is_a?(Pod::Sandbox)
|
10
|
+
options[:build_dir] = build_dir(options[:sandbox].root)
|
11
|
+
|
12
|
+
case targets[0].platform.name
|
13
|
+
when :ios, :tvos, :watchos
|
14
|
+
PodPrebuild::XcodebuildCommand.new(options).run
|
15
|
+
when :osx
|
16
|
+
xcodebuild(
|
17
|
+
sandbox: options[:sandbox],
|
18
|
+
targets: targets,
|
19
|
+
configuration: options[:configuration],
|
20
|
+
sdk: "macosx",
|
21
|
+
args: options[:args]
|
22
|
+
)
|
23
|
+
else
|
24
|
+
raise "Unsupported platform for '#{targets[0].name}': '#{targets[0].platform.name}'"
|
25
|
+
end
|
26
|
+
raise "The build directory was not found in the expected location" unless options[:build_dir].directory?
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.remove_build_dir(sandbox_root)
|
30
|
+
path = build_dir(sandbox_root)
|
31
|
+
path.rmtree if path.exist?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.build_dir(sandbox_root)
|
35
|
+
sandbox_root.parent + "build"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
# Returns the names of pod targets detected as prebuilt, including
|
4
|
+
# those declared in Podfile and their dependencies
|
5
|
+
def prebuilt_pod_names
|
6
|
+
prebuilt_pod_targets.map(&:name).to_set
|
7
|
+
end
|
8
|
+
|
9
|
+
# Returns the pod targets detected as prebuilt, including
|
10
|
+
# those declared in Podfile and their dependencies
|
11
|
+
def prebuilt_pod_targets
|
12
|
+
@prebuilt_pod_targets ||= begin
|
13
|
+
explicit_prebuilt_pod_names = aggregate_targets
|
14
|
+
.flat_map { |target| target.target_definition.explicit_prebuilt_pod_names }
|
15
|
+
.uniq
|
16
|
+
|
17
|
+
targets = pod_targets.select { |target| explicit_prebuilt_pod_names.include?(target.pod_name) }
|
18
|
+
dependencies = targets.flat_map(&:recursive_dependent_targets) # Treat dependencies as prebuilt pods
|
19
|
+
all = (targets + dependencies).uniq
|
20
|
+
all = all.reject { |target| sandbox.local?(target.pod_name) } unless PodPrebuild.config.dev_pods_enabled?
|
21
|
+
all
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pod
|
2
|
+
class Podfile
|
3
|
+
class TargetDefinition
|
4
|
+
def detect_prebuilt_pod(name, requirements)
|
5
|
+
@explicit_prebuilt_pod_names ||= []
|
6
|
+
options = requirements.last || {}
|
7
|
+
@explicit_prebuilt_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:binary]
|
8
|
+
options.delete(:binary) if options.is_a?(Hash)
|
9
|
+
requirements.pop if options.empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the names of pod targets explicitly declared as prebuilt in Podfile using `:binary => true`.
|
13
|
+
def explicit_prebuilt_pod_names
|
14
|
+
names = @explicit_prebuilt_pod_names || []
|
15
|
+
names += parent.explicit_prebuilt_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
16
|
+
names
|
17
|
+
end
|
18
|
+
|
19
|
+
# ---- patch method ----
|
20
|
+
# We want modify `store_pod` method, but it's hard to insert a line in the
|
21
|
+
# implementation. So we patch a method called in `store_pod`.
|
22
|
+
original_parse_inhibit_warnings = instance_method(:parse_inhibit_warnings)
|
23
|
+
define_method(:parse_inhibit_warnings) do |name, requirements|
|
24
|
+
detect_prebuilt_pod(name, requirements)
|
25
|
+
original_parse_inhibit_warnings.bind(self).call(name, requirements)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# ABOUT NAMES
|
2
|
+
#
|
3
|
+
# There are many kinds of name in cocoapods. Two main names are widely used in this plugin.
|
4
|
+
# - root_spec.name (spec.root_name, targe.pod_name):
|
5
|
+
# aka "pod_name"
|
6
|
+
# the name we use in podfile. the concept.
|
7
|
+
#
|
8
|
+
# - target.name:
|
9
|
+
# aka "target_name"
|
10
|
+
# the name of the final target in xcode project. the final real thing.
|
11
|
+
#
|
12
|
+
# One pod may have multiple targets in xcode project, due to one pod can be used in mutiple
|
13
|
+
# platform simultaneously. So one `root_spec.name` may have multiple coresponding `target.name`s.
|
14
|
+
# Therefore, map a spec to/from targets is a little complecated. It's one to many.
|
15
|
+
#
|
16
|
+
|
17
|
+
# Tool to transform Pod_name to target efficiently
|
18
|
+
module Pod
|
19
|
+
def self.fast_get_targets_for_pod_name(pod_name, targets, cache)
|
20
|
+
pod_name = pod_name.split("/")[0] # Look for parent spec instead of subspecs
|
21
|
+
if cache.empty?
|
22
|
+
targets.select { |target| target.name == pod_name }
|
23
|
+
else
|
24
|
+
cache.first[pod_name] || []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative "names"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class PrebuildSandbox < Sandbox
|
5
|
+
# [String] standard_sandbox_path
|
6
|
+
def self.from_standard_sandbox_path(path)
|
7
|
+
prebuild_sandbox_path = Pathname.new(path).realpath + ".." + PodPrebuild.config.prebuild_sandbox_path
|
8
|
+
new(prebuild_sandbox_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_standard_sandbox(sandbox)
|
12
|
+
from_standard_sandbox_path(sandbox.root)
|
13
|
+
end
|
14
|
+
|
15
|
+
def standard_sanbox_path
|
16
|
+
root.parent
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate_framework_path
|
20
|
+
root + "GeneratedFrameworks"
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param name [String] pass the target.name (may containing platform suffix)
|
24
|
+
# @return [Pathname] the folder containing the framework file.
|
25
|
+
def framework_folder_path_for_target_name(name)
|
26
|
+
generate_framework_path + name
|
27
|
+
end
|
28
|
+
|
29
|
+
def exsited_framework_target_names
|
30
|
+
existed_framework_name_pairs.map { |pair| pair[0] }.uniq
|
31
|
+
end
|
32
|
+
|
33
|
+
def exsited_framework_pod_names
|
34
|
+
existed_framework_name_pairs.map { |pair| pair[1] }.uniq
|
35
|
+
end
|
36
|
+
|
37
|
+
def existed_target_names_for_pod_name(pod_name)
|
38
|
+
existed_framework_name_pairs.select { |pair| pair[1] == pod_name }.map { |pair| pair[0] }
|
39
|
+
end
|
40
|
+
|
41
|
+
def save_pod_name_for_target(target)
|
42
|
+
folder = framework_folder_path_for_target_name(target.name)
|
43
|
+
return unless folder.exist?
|
44
|
+
|
45
|
+
flag_file_path = folder + "#{target.pod_name}.pod_name"
|
46
|
+
File.write(flag_file_path.to_s, "")
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def pod_name_for_target_folder(target_folder_path)
|
52
|
+
name = Pathname.new(target_folder_path).children.find do |child|
|
53
|
+
child.to_s.end_with? ".pod_name"
|
54
|
+
end
|
55
|
+
name = name.basename(".pod_name").to_s unless name.nil?
|
56
|
+
name ||= Pathname.new(target_folder_path).basename.to_s # for compatibility with older version
|
57
|
+
name
|
58
|
+
end
|
59
|
+
|
60
|
+
# Array<[target_name, pod_name]>
|
61
|
+
def existed_framework_name_pairs
|
62
|
+
return [] unless generate_framework_path.exist?
|
63
|
+
|
64
|
+
generate_framework_path.children.map do |framework_path|
|
65
|
+
if framework_path.directory? && !framework_path.children.empty?
|
66
|
+
[framework_path.basename.to_s, pod_name_for_target_folder(framework_path)]
|
67
|
+
end
|
68
|
+
end.reject(&:nil?).uniq
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Pod
|
2
|
+
class Prebuild
|
3
|
+
# Check the targets, for the current limitation of the plugin
|
4
|
+
#
|
5
|
+
# @param [Array<PodTarget>] prebuilt_targets
|
6
|
+
def self.check_one_pod_should_have_only_one_target(prebuilt_targets)
|
7
|
+
targets_have_different_platforms = prebuilt_targets.reject { |t| t.pod_name == t.name }
|
8
|
+
return unless targets_have_different_platforms.empty?
|
9
|
+
|
10
|
+
names = targets_have_different_platforms.map(&:pod_name)
|
11
|
+
raw_names = targets_have_different_platforms.map(&:name)
|
12
|
+
message = "Oops, you came across a limitation of cocoapods-binary.
|
13
|
+
|
14
|
+
The plugin requires that one pod should have ONLY ONE target in the 'Pod.xcodeproj'. There are mainly 2 situations \
|
15
|
+
causing this problem:
|
16
|
+
|
17
|
+
1. One pod integrates in 2 or more different platforms' targets. e.g.
|
18
|
+
```
|
19
|
+
target 'iphoneApp' do
|
20
|
+
pod 'A', :binary => true
|
21
|
+
end
|
22
|
+
target 'watchApp' do
|
23
|
+
pod 'A'
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
2. Use different subspecs in multiple targets. e.g.
|
28
|
+
```
|
29
|
+
target 'iphoneApp' do
|
30
|
+
pod 'A/core'
|
31
|
+
pod 'A/network'
|
32
|
+
end
|
33
|
+
target 'iphoneAppTest' do
|
34
|
+
pod 'A/core'
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
Related pods: #{names}, target names: #{raw_names}"
|
39
|
+
raise Informative, message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|