cocoapods-bin 0.0.1
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/.gitignore +4 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +100 -0
- data/LICENSE.txt +22 -0
- data/README.md +15 -0
- data/Rakefile +13 -0
- data/cocoapods-bin.gemspec +26 -0
- data/lib/cocoapods-bin/command/bin/init.rb +66 -0
- data/lib/cocoapods-bin/command/bin/lib/lint.rb +94 -0
- data/lib/cocoapods-bin/command/bin/lib.rb +12 -0
- data/lib/cocoapods-bin/command/bin/open.rb +60 -0
- data/lib/cocoapods-bin/command/bin/repo/push.rb +98 -0
- data/lib/cocoapods-bin/command/bin/repo.rb +12 -0
- data/lib/cocoapods-bin/command/bin/spec/create.rb +68 -0
- data/lib/cocoapods-bin/command/bin/spec/lint.rb +52 -0
- data/lib/cocoapods-bin/command/bin/spec.rb +13 -0
- data/lib/cocoapods-bin/command/bin.rb +52 -0
- data/lib/cocoapods-bin/command.rb +1 -0
- data/lib/cocoapods-bin/config/config.rb +52 -0
- data/lib/cocoapods-bin/config/config_asker.rb +50 -0
- data/lib/cocoapods-bin/gem_version.rb +9 -0
- data/lib/cocoapods-bin/helpers/sources_helper.rb +31 -0
- data/lib/cocoapods-bin/helpers/spec_files_helper.rb +17 -0
- data/lib/cocoapods-bin/helpers/spec_generator.rb +86 -0
- data/lib/cocoapods-bin/helpers.rb +3 -0
- data/lib/cocoapods-bin/native/analyzer.rb +28 -0
- data/lib/cocoapods-bin/native/installation_options.rb +24 -0
- data/lib/cocoapods-bin/native/installer.rb +73 -0
- data/lib/cocoapods-bin/native/linter.rb +29 -0
- data/lib/cocoapods-bin/native/pod_source_installer.rb +15 -0
- data/lib/cocoapods-bin/native/podfile.rb +67 -0
- data/lib/cocoapods-bin/native/resolver.rb +103 -0
- data/lib/cocoapods-bin/native/source.rb +35 -0
- data/lib/cocoapods-bin/native/source_provider_hook.rb +11 -0
- data/lib/cocoapods-bin/native/sources_manager.rb +18 -0
- data/lib/cocoapods-bin/native/validator.rb +16 -0
- data/lib/cocoapods-bin/native.rb +13 -0
- data/lib/cocoapods-bin.rb +1 -0
- data/lib/cocoapods_plugin.rb +3 -0
- data/spec/command/bin_spec.rb +12 -0
- data/spec/spec_helper.rb +50 -0
- metadata +143 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'cocoapods-bin/command/bin/spec/create'
|
2
|
+
require 'cocoapods-bin/command/bin/spec/lint'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Command
|
6
|
+
class Bin < Command
|
7
|
+
class Spec < Bin
|
8
|
+
self.abstract_command = true
|
9
|
+
self.summary = '管理二进制 spec.'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'cocoapods-bin/command/bin/init'
|
2
|
+
require 'cocoapods-bin/command/bin/spec'
|
3
|
+
require 'cocoapods-bin/command/bin/lib'
|
4
|
+
require 'cocoapods-bin/command/bin/repo'
|
5
|
+
require 'cocoapods-bin/command/bin/open'
|
6
|
+
require 'cocoapods-bin/helpers'
|
7
|
+
|
8
|
+
module Pod
|
9
|
+
class Command
|
10
|
+
# This is an example of a cocoapods plugin adding a top-level subcommand
|
11
|
+
# to the 'pod' command.
|
12
|
+
#
|
13
|
+
# You can also create subcommands of existing or new commands. Say you
|
14
|
+
# wanted to add a subcommand to `list` to show newly deprecated pods,
|
15
|
+
# (e.g. `pod list deprecated`), there are a few things that would need
|
16
|
+
# to change.
|
17
|
+
#
|
18
|
+
# - move this file to `lib/pod/command/list/deprecated.rb` and update
|
19
|
+
# the class to exist in the the Pod::Command::List namespace
|
20
|
+
# - change this class to extend from `List` instead of `Command`. This
|
21
|
+
# tells the plugin system that it is a subcommand of `list`.
|
22
|
+
# - edit `lib/cocoapods_plugins.rb` to require this file
|
23
|
+
#
|
24
|
+
# @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
|
25
|
+
# in the `plugins.json` file, once your plugin is released.
|
26
|
+
#
|
27
|
+
class Bin < Command
|
28
|
+
include CBin::SourcesHelper
|
29
|
+
include CBin::SpecFilesHelper
|
30
|
+
|
31
|
+
self.abstract_command = true
|
32
|
+
|
33
|
+
self.default_subcommand = 'open'
|
34
|
+
self.summary = '组件二进制化插件.'
|
35
|
+
self.description = <<-DESC
|
36
|
+
组件二进制化插件。利用源码私有源与二进制私有源实现对组件依赖类型的切换。
|
37
|
+
DESC
|
38
|
+
|
39
|
+
def initialize(argv)
|
40
|
+
@help = argv.flag?('help')
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate!
|
45
|
+
super
|
46
|
+
# 这里由于 --help 是在 validate! 方法中提取的,会导致 --help 失效
|
47
|
+
# pod lib create 也有这个问题
|
48
|
+
banner! if @help
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cocoapods-bin/command/bin'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module CBin
|
4
|
+
class Config
|
5
|
+
def config_file
|
6
|
+
File.expand_path("#{Pod::Config.instance.home_dir}/bin.yml")
|
7
|
+
end
|
8
|
+
|
9
|
+
def template_hash
|
10
|
+
{
|
11
|
+
'code_repo_url' => '源码私有源 Git 地址,如> git@git.2dfire.net:ios/cocoapods-spec.git',
|
12
|
+
'binary_repo_url' => '二进制私有源 Git 地址,如> git@git.2dfire.net:ios/cocoapods-spec-binary.git',
|
13
|
+
'binary_download_url' => '二进制下载地址,内部会依次传入组件名称与版本,替换字符串中的 %s ,如> http://iosframeworkserver-shopkeeperclient.app.2dfire.com/download/%s/%s.zip'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def sync_config(config)
|
18
|
+
File.open(config_file, 'w+') do |f|
|
19
|
+
f.write(config.to_yaml)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def load_config
|
26
|
+
if File.exists?(config_file)
|
27
|
+
YAML.load_file(config_file)
|
28
|
+
else
|
29
|
+
Hash[template_hash.map { |k, v| [k, v.split('>', 2).last.strip] }]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to_missing?(method, include_private = false)
|
34
|
+
@config.respond_to?(method) || super
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(method, *args, &block)
|
38
|
+
@config ||= OpenStruct.new load_config
|
39
|
+
if @config.respond_to?(method)
|
40
|
+
@config.send(method, *args)
|
41
|
+
elsif template_hash.keys.include?(method.to_s)
|
42
|
+
raise Pod::Informative, "#{method} 字段必须在配置文件 #{config_file} 中设置, 请执行 init 命令配置或手动修改配置文件".red
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.config
|
50
|
+
@config ||= Config.new
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'cocoapods-bin/config/config'
|
3
|
+
|
4
|
+
module CBin
|
5
|
+
class Config
|
6
|
+
class Asker
|
7
|
+
def show_prompt
|
8
|
+
print ' > '.green
|
9
|
+
end
|
10
|
+
|
11
|
+
def ask_with_answer(question, pre_answer)
|
12
|
+
print "\n#{question}\n"
|
13
|
+
|
14
|
+
print "旧值:#{pre_answer}\n" unless pre_answer.nil?
|
15
|
+
|
16
|
+
answer = ''
|
17
|
+
loop do
|
18
|
+
show_prompt
|
19
|
+
answer = STDIN.gets.chomp
|
20
|
+
|
21
|
+
if answer == '' && !pre_answer.nil?
|
22
|
+
answer = pre_answer
|
23
|
+
print answer.yellow
|
24
|
+
print "\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
break unless answer.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
answer
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def wellcome_message
|
35
|
+
print <<-EOF
|
36
|
+
|
37
|
+
开始设置二进制化初始信息.
|
38
|
+
所有的信息都会保存在 #{CBin.config.config_file} 文件中.
|
39
|
+
你可以在对应目录下手动添加编辑该文件. 文件包含的配置信息如下:
|
40
|
+
|
41
|
+
#{CBin.config.template_hash.to_yaml}
|
42
|
+
EOF
|
43
|
+
end
|
44
|
+
|
45
|
+
def done_message
|
46
|
+
print "\n设置完成.\n".green
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'cocoapods-bin/native'
|
2
|
+
|
3
|
+
module CBin
|
4
|
+
module SourcesHelper
|
5
|
+
def sources_manager
|
6
|
+
Pod::Config.instance.sources_manager
|
7
|
+
end
|
8
|
+
|
9
|
+
def binary_source
|
10
|
+
sources_manager.binary_source
|
11
|
+
end
|
12
|
+
|
13
|
+
def code_source
|
14
|
+
sources_manager.code_source
|
15
|
+
end
|
16
|
+
|
17
|
+
# 优先采用对应依赖的 source
|
18
|
+
# cocoapods 内部会先匹配前面符合的 specification
|
19
|
+
# 只允许二进制的 specification subspec 比源码的 specification subspec 多
|
20
|
+
#
|
21
|
+
def valid_sources(code_dependencies = false)
|
22
|
+
sources = [binary_source, code_source]
|
23
|
+
sources.reverse! if code_dependencies
|
24
|
+
sources
|
25
|
+
end
|
26
|
+
|
27
|
+
def sources_option(code_dependencies, additional_sources)
|
28
|
+
(valid_sources(code_dependencies).map(&:name) + additional_sources).join(',')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'cocoapods-bin/native'
|
2
|
+
|
3
|
+
module CBin
|
4
|
+
module SpecFilesHelper
|
5
|
+
def spec_files
|
6
|
+
@spec_files ||= Pathname.glob('*.podspec{,.json}')
|
7
|
+
end
|
8
|
+
|
9
|
+
def binary_spec_files
|
10
|
+
@binary_spec_files ||= Pathname.glob('*.binary.podspec{,.json}')
|
11
|
+
end
|
12
|
+
|
13
|
+
def code_spec_files
|
14
|
+
@code_spec_files ||= spec_files - binary_spec_files
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
require 'cocoapods-bin/config/config'
|
3
|
+
|
4
|
+
module CBin
|
5
|
+
class SpecGenerator
|
6
|
+
attr_reader :ref_spec
|
7
|
+
attr_reader :spec
|
8
|
+
|
9
|
+
def initialize(ref_spec, platforms = 'ios')
|
10
|
+
@ref_spec = ref_spec
|
11
|
+
@platforms = Array(platforms)
|
12
|
+
validate!
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate!
|
16
|
+
raise StandardError, '不支持自动生成存在 subspec 的二进制 podspec .' if ref_spec.subspecs.any?
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate
|
20
|
+
@spec = @ref_spec.dup
|
21
|
+
# vendored_frameworks | resources | source | source_files | public_header_files
|
22
|
+
# license | resource_bundles
|
23
|
+
|
24
|
+
# Project Linkin
|
25
|
+
@spec.vendored_frameworks = "#{ref_spec.root.name}.framework"
|
26
|
+
|
27
|
+
# Resources
|
28
|
+
extnames = []
|
29
|
+
extnames << '*.bundle' if ref_spec_consumer.resource_bundles.any?
|
30
|
+
extnames += ref_spec_consumer.resources.map { |r| File.basename(r) } if ref_spec_consumer.resources.any?
|
31
|
+
@spec.resources = framework_contents('Resources').flat_map { |r| extnames.map { |e| "#{r}/#{e}" } } if extnames.any?
|
32
|
+
|
33
|
+
# Source Location
|
34
|
+
@spec.source = { http: CBin.config.binary_download_url % [ref_spec.root.name, ref_spec.version] }
|
35
|
+
|
36
|
+
# Source Code
|
37
|
+
@spec.source_files = framework_contents('Headers/*')
|
38
|
+
@spec.public_header_files = framework_contents('Headers/*')
|
39
|
+
|
40
|
+
# Unused for binary
|
41
|
+
spec_hash = @spec.to_hash
|
42
|
+
# spec_hash.delete('license')
|
43
|
+
spec_hash.delete('resource_bundles')
|
44
|
+
|
45
|
+
# Filter platforms
|
46
|
+
platforms = spec_hash['platforms']
|
47
|
+
selected_platforms = platforms.select { |k, v| @platforms.include?(k) }
|
48
|
+
spec_hash['platforms'] = selected_platforms.empty? ? platforms : selected_platforms
|
49
|
+
|
50
|
+
@spec = Pod::Specification.from_hash(spec_hash)
|
51
|
+
|
52
|
+
Pod::UI.message "生成二进制 podspec 内容: "
|
53
|
+
@spec.to_pretty_json.split("\n").each do |text|
|
54
|
+
Pod::UI.message text
|
55
|
+
end
|
56
|
+
|
57
|
+
@spec
|
58
|
+
end
|
59
|
+
|
60
|
+
def write_to_spec_file(file = filename)
|
61
|
+
File.open(file, 'w+') do |f|
|
62
|
+
f.write(spec.to_pretty_json)
|
63
|
+
end
|
64
|
+
|
65
|
+
@filename = file
|
66
|
+
end
|
67
|
+
|
68
|
+
def clear_spec_file
|
69
|
+
File.delete(@filename) if File.exist?(@filename)
|
70
|
+
end
|
71
|
+
|
72
|
+
def filename
|
73
|
+
@filename ||= "#{spec.name}.binary.podspec.json"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def ref_spec_consumer(platform = :ios)
|
79
|
+
ref_spec.consumer(:ios)
|
80
|
+
end
|
81
|
+
|
82
|
+
def framework_contents(name)
|
83
|
+
["#{ref_spec.root.name}.framework", "#{ref_spec.root.name}.framework/Versions/A"].map { |path| "#{path}/#{name}" }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'parallel'
|
2
|
+
require 'cocoapods'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Installer
|
6
|
+
class Analyzer
|
7
|
+
# > 1.5.3 版本
|
8
|
+
# rewrite update_repositories
|
9
|
+
#
|
10
|
+
alias_method :old_update_repositories, :update_repositories
|
11
|
+
def update_repositories
|
12
|
+
if installation_options.update_source_with_multi_processes
|
13
|
+
# 并发更新私有源
|
14
|
+
Parallel.each(sources, in_threads: 4) do |source|
|
15
|
+
if source.git?
|
16
|
+
config.sources_manager.update(source.name, true)
|
17
|
+
else
|
18
|
+
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@specs_updated = true
|
22
|
+
else
|
23
|
+
old_update_repositories
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
class InstallationOptions
|
6
|
+
def self.env_option(key, default = true)
|
7
|
+
option key, ENV[key.to_s].nil? ? default : ENV[key.to_s] == 'true'
|
8
|
+
end
|
9
|
+
|
10
|
+
# 不同 source 存在相同 spec 名时,默认不警告
|
11
|
+
defaults.delete('warn_for_multiple_pod_sources')
|
12
|
+
env_option :warn_for_multiple_pod_sources, false
|
13
|
+
|
14
|
+
# 是否警告不安全 source (如 http )
|
15
|
+
env_option :warn_for_unsecure_source, false
|
16
|
+
|
17
|
+
# 是否多进程执行 install_pod_sources
|
18
|
+
env_option :install_with_multi_processes, true
|
19
|
+
|
20
|
+
# 是否多进程执行 update_repositories
|
21
|
+
env_option :update_source_with_multi_processes, true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'parallel'
|
2
|
+
require 'cocoapods'
|
3
|
+
require 'cocoapods-bin/native/pod_source_installer'
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
alias_method :old_create_pod_installer, :create_pod_installer
|
8
|
+
def create_pod_installer(pod_name)
|
9
|
+
installer = old_create_pod_installer(pod_name)
|
10
|
+
installer.installation_options = installation_options
|
11
|
+
installer
|
12
|
+
end
|
13
|
+
|
14
|
+
# rewrite install_pod_sources
|
15
|
+
alias_method :old_install_pod_sources, :install_pod_sources
|
16
|
+
def install_pod_sources
|
17
|
+
if installation_options.install_with_multi_processes
|
18
|
+
@installed_specs = []
|
19
|
+
pods_to_install = sandbox_state.added | sandbox_state.changed
|
20
|
+
title_options = { :verbose_prefix => '-> '.green }
|
21
|
+
# 多进程下载,多线程时 log 会显著交叉,多进程好点,但是多进程需要利用文件锁对 cache 进行保护
|
22
|
+
# in_processes: 10
|
23
|
+
Parallel.each(root_specs.sort_by(&:name), in_threads: 10) do |spec|
|
24
|
+
if pods_to_install.include?(spec.name)
|
25
|
+
if sandbox_state.changed.include?(spec.name) && sandbox.manifest
|
26
|
+
current_version = spec.version
|
27
|
+
previous_version = sandbox.manifest.version(spec.name)
|
28
|
+
has_changed_version = current_version != previous_version
|
29
|
+
current_repo = analysis_result.specs_by_source.detect { |key, values| break key if values.map(&:name).include?(spec.name) }
|
30
|
+
current_repo &&= current_repo.url || current_repo.name
|
31
|
+
previous_spec_repo = sandbox.manifest.spec_repo(spec.name)
|
32
|
+
has_changed_repo = !previous_spec_repo.nil? && current_repo && (current_repo != previous_spec_repo)
|
33
|
+
title = "Installing #{spec.name} #{spec.version}"
|
34
|
+
title << " (was #{previous_version} and source changed to `#{current_repo}` from `#{previous_spec_repo}`)" if has_changed_version && has_changed_repo
|
35
|
+
title << " (was #{previous_version})" if has_changed_version && !has_changed_repo
|
36
|
+
title << " (source changed to `#{current_repo}` from `#{previous_spec_repo}`)" if !has_changed_version && has_changed_repo
|
37
|
+
else
|
38
|
+
title = "Installing #{spec}"
|
39
|
+
end
|
40
|
+
UI.titled_section(title.green, title_options) do
|
41
|
+
install_source_of_pod(spec.name)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
UI.titled_section("Using #{spec}", title_options) do
|
45
|
+
create_pod_installer(spec.name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
old_install_pod_sources
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Downloader
|
56
|
+
class Cache
|
57
|
+
# 多线程锁
|
58
|
+
@@lock = Mutex.new
|
59
|
+
|
60
|
+
# 后面如果要切到进程的话,可以在 cache root 里面新建一个文件
|
61
|
+
# 利用这个文件 lock
|
62
|
+
# https://stackoverflow.com/questions/23748648/using-fileflock-as-ruby-global-lock-mutex-for-processes
|
63
|
+
|
64
|
+
# rmtree 在多进程情况下可能 Directory not empty @ dir_s_rmdir 错误
|
65
|
+
# old_ensure_matching_version 会移除不是同一个 CocoaPods 版本的组件缓存
|
66
|
+
alias_method :old_ensure_matching_version, :ensure_matching_version
|
67
|
+
def ensure_matching_version
|
68
|
+
@@lock.synchronize { old_ensure_matching_version }
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module Pod
|
3
|
+
class Specification
|
4
|
+
class Linter
|
5
|
+
# !@group Lint steps
|
6
|
+
|
7
|
+
# Checks that the spec's root name matches the filename.
|
8
|
+
#
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
def validate_root_name
|
12
|
+
if spec.root.name && file
|
13
|
+
acceptable_names = [
|
14
|
+
spec.root.name + '.podspec',
|
15
|
+
spec.root.name + '.podspec.json',
|
16
|
+
# 支持 binary 后缀
|
17
|
+
spec.root.name + '.binary.podspec',
|
18
|
+
spec.root.name + '.binary.podspec.json'
|
19
|
+
]
|
20
|
+
names_match = acceptable_names.include?(file.basename.to_s)
|
21
|
+
unless names_match
|
22
|
+
results.add_error('name', 'The name of the spec should match the ' \
|
23
|
+
'name of the file.')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cocoapods-bin/native/installation_options'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
class PodSourceInstaller
|
6
|
+
attr_accessor :installation_options
|
7
|
+
|
8
|
+
alias_method :old_verify_source_is_secure, :verify_source_is_secure
|
9
|
+
def verify_source_is_secure(root_spec)
|
10
|
+
# http source 默认不警告
|
11
|
+
old_verify_source_is_secure(root_spec) if installation_options.warn_for_unsecure_source?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Podfile
|
5
|
+
USE_BINARIES = 'use_binaries'.freeze
|
6
|
+
USE_SOURCE_PODS = 'use_source_pods'.freeze
|
7
|
+
USE_BINARIES_SELECTOR = 'use_binaries_selector'.freeze
|
8
|
+
# TREAT_DEVELOPMENTS_AS_NORMAL = 'treat_developments_as_normal'.freeze
|
9
|
+
|
10
|
+
module DSL
|
11
|
+
def use_binaries!(flag = true)
|
12
|
+
set_internal_hash_value(USE_BINARIES, flag)
|
13
|
+
end
|
14
|
+
|
15
|
+
def use_binaries_with_spec_selector!(&block)
|
16
|
+
raise Informative, '必须提供选择需要二进制组件的 block !' unless block_given?
|
17
|
+
|
18
|
+
set_internal_hash_value(USE_BINARIES_SELECTOR, block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_use_source_pods(pods)
|
22
|
+
hash_pods_use_source = get_internal_hash_value(USE_SOURCE_PODS) || []
|
23
|
+
hash_pods_use_source += Array(pods)
|
24
|
+
set_internal_hash_value(USE_SOURCE_PODS, hash_pods_use_source)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ENVExecutor
|
29
|
+
def execute_with_use_binaries(use_binaries, &block)
|
30
|
+
execute_with_key(USE_BINARIES, -> { use_binaries ? 'true' : 'false' }, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute_with_key(key, value_returner, &block)
|
34
|
+
origin_value = ENV[key]
|
35
|
+
ENV[key] = value_returner.call
|
36
|
+
|
37
|
+
yield if block_given?
|
38
|
+
|
39
|
+
ENV[key] = origin_value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
extend ENVExecutor
|
44
|
+
|
45
|
+
def use_binaries_selector
|
46
|
+
get_internal_hash_value(USE_BINARIES_SELECTOR, nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
def use_binaries?
|
50
|
+
get_internal_hash_value(USE_BINARIES, false) || ENV[USE_BINARIES] == 'true'
|
51
|
+
end
|
52
|
+
|
53
|
+
def use_source_pods
|
54
|
+
get_internal_hash_value(USE_SOURCE_PODS, []) + String(ENV[USE_SOURCE_PODS]).split('|').uniq
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
# set_hash_value 有 key 限制
|
59
|
+
def set_internal_hash_value(key, value)
|
60
|
+
internal_hash[key] = value
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_internal_hash_value(key, default = nil)
|
64
|
+
internal_hash.fetch(key, default)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'parallel'
|
2
|
+
require 'cocoapods'
|
3
|
+
require 'cocoapods-bin/native/podfile'
|
4
|
+
require 'cocoapods-bin/native/sources_manager'
|
5
|
+
require 'cocoapods-bin/native/installation_options'
|
6
|
+
require 'cocoapods-bin/gem_version'
|
7
|
+
|
8
|
+
module Pod
|
9
|
+
class Resolver
|
10
|
+
# >= 1.4.0 才有 resolver_specs_by_target 以及 ResolverSpecification
|
11
|
+
# >= 1.5.0 ResolverSpecification 才有 source,供 install 或者其他操作时,输入 source 变更
|
12
|
+
#
|
13
|
+
if Pod.match_version?('~> 1.4')
|
14
|
+
old_resolver_specs_by_target = instance_method(:resolver_specs_by_target)
|
15
|
+
define_method(:resolver_specs_by_target) do
|
16
|
+
resolver_specs_by_target = old_resolver_specs_by_target.bind(self).call()
|
17
|
+
|
18
|
+
# 过滤出用户工程
|
19
|
+
user_specs_by_target = resolver_specs_by_target.reject { |st| st.name.end_with?('_Tests') || st.name == 'Pods' }
|
20
|
+
|
21
|
+
sources_manager = Config.instance.sources_manager
|
22
|
+
use_source_pods = podfile.use_source_pods
|
23
|
+
|
24
|
+
user_specs_by_target.each do |target, rspecs|
|
25
|
+
# use_binaries 并且 use_source_pods 不包含
|
26
|
+
use_binary_rspecs = if podfile.use_binaries? || podfile.use_binaries_selector
|
27
|
+
rspecs.select do |rspec|
|
28
|
+
([rspec.name, rspec.root.name] & use_source_pods).empty? &&
|
29
|
+
(podfile.use_binaries_selector.nil? || podfile.use_binaries_selector.call(rspec.spec))
|
30
|
+
end
|
31
|
+
else
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Parallel.map(rspecs, in_threads: 8) do |rspec|
|
36
|
+
resolver_specs_by_target[target] = rspecs.map do |rspec|
|
37
|
+
# 含有 subspecs 的组件暂不处理
|
38
|
+
# next rspec if rspec.spec.subspec? || rspec.spec.subspecs.any?
|
39
|
+
|
40
|
+
# developments 组件采用默认输入的 spec (development pods 的 source 为 nil)
|
41
|
+
next rspec unless rspec.spec.respond_to?(:spec_source) && rspec.spec.spec_source
|
42
|
+
|
43
|
+
# 采用二进制依赖并且不为开发组件
|
44
|
+
use_binary = use_binary_rspecs.include?(rspec)
|
45
|
+
source = use_binary ? sources_manager.binary_source : sources_manager.code_source
|
46
|
+
|
47
|
+
spec_version = rspec.spec.version
|
48
|
+
begin
|
49
|
+
# 从新 source 中获取 spec
|
50
|
+
specification = source.specification(rspec.root.name, spec_version)
|
51
|
+
|
52
|
+
# 组件是 subspec
|
53
|
+
specification = specification.subspec_by_name(rspec.name, false, true) if rspec.spec.subspec?
|
54
|
+
# 这里可能出现分析依赖的 source 和切换后的 source 对应 specification 的 subspec 对应不上
|
55
|
+
# 造成 subspec_by_name 返回 nil,这个是正常现象
|
56
|
+
next unless specification
|
57
|
+
|
58
|
+
# 组装新的 rspec ,替换原 rspec
|
59
|
+
rspec = if Pod.match_version?('~> 1.4.0')
|
60
|
+
ResolverSpecification.new(specification, rspec.used_by_tests_only)
|
61
|
+
else
|
62
|
+
ResolverSpecification.new(specification, rspec.used_by_tests_only, source)
|
63
|
+
end
|
64
|
+
rspec
|
65
|
+
rescue Pod::StandardError => error
|
66
|
+
# 没有从新的 source 找到对应版本组件,直接返回原 rspec
|
67
|
+
UI.message "【#{rspec.spec.name} | #{spec_version}】组件无对应二进制版本 , 将采用源码依赖." if use_binary#.yellow
|
68
|
+
rspec
|
69
|
+
end
|
70
|
+
|
71
|
+
rspec
|
72
|
+
end.compact
|
73
|
+
end
|
74
|
+
|
75
|
+
resolver_specs_by_target
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
if Pod.match_version?('~> 1.4.0')
|
81
|
+
# 1.4.0 没有 spec_source
|
82
|
+
class Specification
|
83
|
+
class Set
|
84
|
+
class LazySpecification < BasicObject
|
85
|
+
attr_reader :spec_source
|
86
|
+
|
87
|
+
old_initialize = instance_method(:initialize)
|
88
|
+
define_method(:initialize) do |name, version, source|
|
89
|
+
old_initialize.bind(self).call(name, version, source)
|
90
|
+
|
91
|
+
@spec_source = source
|
92
|
+
end
|
93
|
+
|
94
|
+
def respond_to?(method, include_all = false)
|
95
|
+
return super unless method == :spec_source
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|