cocoapods-miBin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rakeTasks +7 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +104 -0
- data/LICENSE.txt +22 -0
- data/README.md +522 -0
- data/Rakefile +13 -0
- data/cocoapods-miBin.gemspec +27 -0
- data/lib/cocoapods-miBin.rb +4 -0
- data/lib/cocoapods-miBin/command.rb +3 -0
- data/lib/cocoapods-miBin/command/bin.rb +60 -0
- data/lib/cocoapods-miBin/command/bin/archive.rb +134 -0
- data/lib/cocoapods-miBin/command/bin/init.rb +71 -0
- data/lib/cocoapods-miBin/command/bin/lib.rb +14 -0
- data/lib/cocoapods-miBin/command/bin/lib/lint.rb +69 -0
- data/lib/cocoapods-miBin/command/bin/list.rb +50 -0
- data/lib/cocoapods-miBin/command/bin/open.rb +61 -0
- data/lib/cocoapods-miBin/command/bin/repo.rb +15 -0
- data/lib/cocoapods-miBin/command/bin/repo/push.rb +116 -0
- data/lib/cocoapods-miBin/command/bin/repo/update.rb +42 -0
- data/lib/cocoapods-miBin/command/bin/search.rb +69 -0
- data/lib/cocoapods-miBin/command/bin/spec.rb +15 -0
- data/lib/cocoapods-miBin/command/bin/spec/create.rb +75 -0
- data/lib/cocoapods-miBin/command/bin/spec/lint.rb +111 -0
- data/lib/cocoapods-miBin/command/bin/umbrella.rb +55 -0
- data/lib/cocoapods-miBin/config/config.rb +81 -0
- data/lib/cocoapods-miBin/config/config_asker.rb +58 -0
- data/lib/cocoapods-miBin/gem_version.rb +11 -0
- data/lib/cocoapods-miBin/helpers.rb +5 -0
- data/lib/cocoapods-miBin/helpers/framework.rb +64 -0
- data/lib/cocoapods-miBin/helpers/framework_builder.rb +227 -0
- data/lib/cocoapods-miBin/helpers/sources_helper.rb +33 -0
- data/lib/cocoapods-miBin/helpers/spec_creator.rb +159 -0
- data/lib/cocoapods-miBin/helpers/spec_files_helper.rb +77 -0
- data/lib/cocoapods-miBin/native.rb +21 -0
- data/lib/cocoapods-miBin/native/acknowledgements.rb +27 -0
- data/lib/cocoapods-miBin/native/analyzer.rb +53 -0
- data/lib/cocoapods-miBin/native/installation_options.rb +26 -0
- data/lib/cocoapods-miBin/native/installer.rb +116 -0
- data/lib/cocoapods-miBin/native/linter.rb +26 -0
- data/lib/cocoapods-miBin/native/path_source.rb +33 -0
- data/lib/cocoapods-miBin/native/pod_source_installer.rb +19 -0
- data/lib/cocoapods-miBin/native/pod_target.rb +8 -0
- data/lib/cocoapods-miBin/native/podfile.rb +79 -0
- data/lib/cocoapods-miBin/native/podfile_env.rb +36 -0
- data/lib/cocoapods-miBin/native/podspec_finder.rb +25 -0
- data/lib/cocoapods-miBin/native/resolver.rb +200 -0
- data/lib/cocoapods-miBin/native/sandbox_analyzer.rb +34 -0
- data/lib/cocoapods-miBin/native/source.rb +35 -0
- data/lib/cocoapods-miBin/native/sources_manager.rb +20 -0
- data/lib/cocoapods-miBin/native/specification.rb +31 -0
- data/lib/cocoapods-miBin/native/validator.rb +16 -0
- data/lib/cocoapods-miBin/source_provider_hook.rb +21 -0
- data/lib/cocoapods_plugin.rb +5 -0
- data/spec/command/bin_spec.rb +12 -0
- data/spec/spec_helper.rb +50 -0
- metadata +173 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods-miBin/native/sources_manager.rb'
|
4
|
+
|
5
|
+
module CBin
|
6
|
+
module SourcesHelper
|
7
|
+
def sources_manager
|
8
|
+
Pod::Config.instance.sources_manager
|
9
|
+
end
|
10
|
+
|
11
|
+
def binary_source
|
12
|
+
sources_manager.binary_source
|
13
|
+
end
|
14
|
+
|
15
|
+
def code_source
|
16
|
+
sources_manager.code_source
|
17
|
+
end
|
18
|
+
|
19
|
+
# 优先采用对应依赖的 source
|
20
|
+
# cocoapods 内部会先匹配前面符合的 specification
|
21
|
+
# 只允许二进制的 specification subspec 比源码的 specification subspec 多
|
22
|
+
#
|
23
|
+
def valid_sources(code_dependencies = false)
|
24
|
+
sources = [binary_source, code_source]
|
25
|
+
sources.reverse! if code_dependencies
|
26
|
+
sources
|
27
|
+
end
|
28
|
+
|
29
|
+
def sources_option(code_dependencies, additional_sources)
|
30
|
+
(valid_sources(code_dependencies).map(&:url) + Array(additional_sources)).join(',')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods'
|
4
|
+
require 'cocoapods-miBin/config/config'
|
5
|
+
|
6
|
+
module CBin
|
7
|
+
class Specification
|
8
|
+
class Creator
|
9
|
+
attr_reader :code_spec
|
10
|
+
attr_reader :template_spec
|
11
|
+
attr_reader :spec
|
12
|
+
|
13
|
+
def initialize(code_spec, template_spec, platforms = 'ios')
|
14
|
+
@code_spec = code_spec
|
15
|
+
@template_spec = template_spec
|
16
|
+
@platforms = Array(platforms)
|
17
|
+
validate!
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate!
|
21
|
+
raise Pod::Informative, '源码 podspec 不能为空 .' unless code_spec
|
22
|
+
if code_spec.subspecs.any? && template_spec.nil?
|
23
|
+
raise Pod::Informative, "不支持自动生成存在 subspec 的二进制 podspec , 需要提供模版文件 #{code_spec.name}.binary.podspec.template ."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def create
|
28
|
+
spec = template_spec ? create_from_code_spec_and_template_spec : create_from_code_spec
|
29
|
+
|
30
|
+
Pod::UI.message '生成二进制 podspec 内容: '
|
31
|
+
spec.to_pretty_json.split("\n").each do |text|
|
32
|
+
Pod::UI.message text
|
33
|
+
end
|
34
|
+
|
35
|
+
spec
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_spec_file(file = filename)
|
39
|
+
create unless spec
|
40
|
+
|
41
|
+
File.open(file, 'w+') do |f|
|
42
|
+
f.write(spec.to_pretty_json)
|
43
|
+
end
|
44
|
+
|
45
|
+
@filename = file
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear_spec_file
|
49
|
+
File.delete(filename) if File.exist?(filename)
|
50
|
+
end
|
51
|
+
|
52
|
+
def filename
|
53
|
+
@filename ||= "#{spec.name}.binary.podspec.json"
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def create_from_code_spec
|
59
|
+
@spec = code_spec.dup
|
60
|
+
# vendored_frameworks | resources | source | source_files | public_header_files
|
61
|
+
# license | resource_bundles | vendored_libraries
|
62
|
+
#
|
63
|
+
#vi = @spec.vendored_libraries
|
64
|
+
file_accessor = Pod::Sandbox::FileAccessor.new(Pathname.new('.').expand_path, code_spec_consumer)
|
65
|
+
vendored_static_libraries = file_accessor.vendored_static_libraries
|
66
|
+
vendored_static_frameworks = file_accessor.vendored_static_frameworks
|
67
|
+
#puts Pathname.new('.').expand_path
|
68
|
+
#puts code_spec_consumer
|
69
|
+
#puts vi
|
70
|
+
|
71
|
+
# Project Linkin
|
72
|
+
base_framework = ["#{spec.name}_binary/#{code_spec.root.name}.framework"]
|
73
|
+
vendored_static_frameworks.each do |framework|
|
74
|
+
#puts framework.class
|
75
|
+
base_framework.append("#{spec.name}_binary/"+File.basename(framework))
|
76
|
+
end
|
77
|
+
@spec.vendored_frameworks = base_framework
|
78
|
+
# Resources
|
79
|
+
extnames = []
|
80
|
+
extnames << '*.bundle' if code_spec_consumer.resource_bundles.any?
|
81
|
+
if code_spec_consumer.resources.any?
|
82
|
+
extnames += code_spec_consumer.resources.map { |r| File.basename(r) }
|
83
|
+
end
|
84
|
+
if extnames.any?
|
85
|
+
#@spec.resources = framework_contents('Resources').flat_map { |r| extnames.map { |e| "#{r}/#{e}" } }
|
86
|
+
@spec.resources = framework_resources.flat_map { |r| extnames.map { |e| "#{r}/#{e}" } }
|
87
|
+
end
|
88
|
+
|
89
|
+
base_libs = []
|
90
|
+
vendored_static_libraries.each do |lib|
|
91
|
+
#puts framework.class
|
92
|
+
base_libs.append("#{spec.name}_binary/"+File.basename(lib))
|
93
|
+
end
|
94
|
+
if base_libs.count > 0
|
95
|
+
@spec.vendored_libraries = base_libs
|
96
|
+
end
|
97
|
+
|
98
|
+
# Source Location
|
99
|
+
@spec.source = binary_source
|
100
|
+
|
101
|
+
# Source Code
|
102
|
+
@spec.source_files = framework_contents('Headers/*')
|
103
|
+
@spec.public_header_files = framework_contents('Headers/*')
|
104
|
+
|
105
|
+
# Unused for binary
|
106
|
+
spec_hash = @spec.to_hash
|
107
|
+
# spec_hash.delete('license')
|
108
|
+
spec_hash.delete('resource_bundles')
|
109
|
+
spec_hash.delete('exclude_files')
|
110
|
+
spec_hash.delete('preserve_paths')
|
111
|
+
spec_hash.delete('source_files')
|
112
|
+
spec_hash.delete('public_header_files')
|
113
|
+
# 这里不确定 vendored_libraries 指定的时动态/静态库
|
114
|
+
# 如果是静态库的话,需要移除,否则就不移除
|
115
|
+
# 最好是静态库都独立成 Pod ,cocoapods-package 打静态库去 collect 目标文件时好做过滤
|
116
|
+
# 这里统一只对命名后缀 .a 文件做处理
|
117
|
+
# spec_hash.delete('vendored_libraries')
|
118
|
+
# libraries 只能假设为动态库不做处理了,如果有例外,需要开发者自行处理
|
119
|
+
|
120
|
+
#vendored_libraries = spec_hash.delete('vendored_libraries')
|
121
|
+
#vendored_libraries = Array(vendored_libraries).reject { |l| l.end_with?('.a') }
|
122
|
+
#if vendored_libraries.any?
|
123
|
+
# spec_hash['vendored_libraries'] = vendored_libraries
|
124
|
+
#end
|
125
|
+
|
126
|
+
# Filter platforms
|
127
|
+
platforms = spec_hash['platforms']
|
128
|
+
selected_platforms = platforms.select { |k, _v| @platforms.include?(k) }
|
129
|
+
spec_hash['platforms'] = selected_platforms.empty? ? platforms : selected_platforms
|
130
|
+
|
131
|
+
@spec = Pod::Specification.from_hash(spec_hash)
|
132
|
+
@spec
|
133
|
+
end
|
134
|
+
|
135
|
+
def create_from_code_spec_and_template_spec
|
136
|
+
@spec = template_spec.dup
|
137
|
+
|
138
|
+
@spec.version = code_spec.version
|
139
|
+
@spec.source = binary_source
|
140
|
+
@spec
|
141
|
+
end
|
142
|
+
|
143
|
+
def binary_source
|
144
|
+
{ http: format(CBin.config.binary_download_url, code_spec.root.name, code_spec.version, code_spec.root.name ), type: CBin.config.download_file_type }
|
145
|
+
end
|
146
|
+
|
147
|
+
def code_spec_consumer(_platform = :ios)
|
148
|
+
code_spec.consumer(:ios)
|
149
|
+
end
|
150
|
+
|
151
|
+
def framework_contents(name)
|
152
|
+
["#{code_spec.root.name}.framework", "#{code_spec.root.name}.framework/Versions/A"].map { |path| "#{path}/#{name}" }
|
153
|
+
end
|
154
|
+
def framework_resources()
|
155
|
+
["#{spec.name}_binary/#{code_spec.root.name}.framework", "#{spec.name}_binary/#{code_spec.root.name}.framework/Versions/A"].map { |path| "#{path}" }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods-miBin/native/sources_manager.rb'
|
4
|
+
require 'cocoapods-miBin/helpers/spec_creator'
|
5
|
+
|
6
|
+
module CBin
|
7
|
+
module SpecFilesHelper
|
8
|
+
def spec_files
|
9
|
+
@spec_files ||= Pathname.glob('*.podspec{,.json}')
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary_spec_files
|
13
|
+
@binary_spec_files ||= Pathname.glob('*.binary.podspec{,.json}')
|
14
|
+
end
|
15
|
+
|
16
|
+
def binary_template_spec_files
|
17
|
+
@binary_spec_template_files ||= Pathname.glob('*.binary-template.podspec{,.json}')
|
18
|
+
end
|
19
|
+
|
20
|
+
def binary_template_spec_file
|
21
|
+
@binary_spec_template_file ||= binary_template_spec_files.first
|
22
|
+
end
|
23
|
+
|
24
|
+
def code_spec_files
|
25
|
+
@code_spec_files ||= spec_files - binary_spec_files - binary_template_spec_files
|
26
|
+
end
|
27
|
+
|
28
|
+
def code_spec
|
29
|
+
if code_spec_files.first
|
30
|
+
Pod::Specification.from_file(code_spec_files.first)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def binary_spec
|
35
|
+
if binary_spec_files.first
|
36
|
+
Pod::Specification.from_file(binary_spec_files.first)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def binary_template_spec
|
41
|
+
if binary_template_spec_file
|
42
|
+
Pod::Specification.from_file(binary_template_spec_file)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_spec_file(podspec)
|
47
|
+
path = Pathname(podspec)
|
48
|
+
raise Pod::Informative, "无法找到 #{podspec}" unless path.exist?
|
49
|
+
|
50
|
+
path
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_binary_spec_file(code_spec, template_spec)
|
54
|
+
# 1. code spec 是否有 subpsec
|
55
|
+
# 1.1 有,查找 template spec,并生成
|
56
|
+
# 1.2 没有,是否有 template spec
|
57
|
+
# 1.2.1 有,根据 template spec 生成
|
58
|
+
# 1.2.2 没有,根据 code spec 生成
|
59
|
+
|
60
|
+
unless code_spec
|
61
|
+
raise Pod::Informative, '没有二进制 podspec 的情况下,必须要提供源码 podspec.'
|
62
|
+
end
|
63
|
+
if code_spec.subspecs.any? && template_spec.nil?
|
64
|
+
raise Pod::Informative, '拥有 subspec 的组件,在生成二进制 podspec 时,必须要提供模版 podspec.'
|
65
|
+
end
|
66
|
+
|
67
|
+
@spec_creator = CBin::Specification::Creator.new(code_spec, template_spec)
|
68
|
+
@spec_creator.create
|
69
|
+
@spec_creator.write_spec_file
|
70
|
+
@spec_creator.filename
|
71
|
+
end
|
72
|
+
|
73
|
+
def clear_binary_spec_file_if_needed
|
74
|
+
@spec_creator&.clear_spec_file
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods'
|
4
|
+
|
5
|
+
if Pod.match_version?('~> 1.4')
|
6
|
+
require 'cocoapods-miBin/native/podfile'
|
7
|
+
require 'cocoapods-miBin/native/installation_options'
|
8
|
+
require 'cocoapods-miBin/native/specification'
|
9
|
+
require 'cocoapods-miBin/native/path_source'
|
10
|
+
require 'cocoapods-miBin/native/analyzer'
|
11
|
+
require 'cocoapods-miBin/native/installer'
|
12
|
+
require 'cocoapods-miBin/native/pod_source_installer'
|
13
|
+
require 'cocoapods-miBin/native/linter'
|
14
|
+
require 'cocoapods-miBin/native/resolver'
|
15
|
+
require 'cocoapods-miBin/native/pod_target'
|
16
|
+
require 'cocoapods-miBin/native/source'
|
17
|
+
require 'cocoapods-miBin/native/validator'
|
18
|
+
require 'cocoapods-miBin/native/acknowledgements'
|
19
|
+
require 'cocoapods-miBin/native/sandbox_analyzer'
|
20
|
+
require 'cocoapods-miBin/native/podspec_finder'
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Generator
|
5
|
+
class Acknowledgements
|
6
|
+
def license_text(spec)
|
7
|
+
return nil unless spec.license
|
8
|
+
|
9
|
+
text = spec.license[:text]
|
10
|
+
unless text
|
11
|
+
if license_file = spec.license[:file]
|
12
|
+
license_path = file_accessor(spec).root + license_file
|
13
|
+
if File.exist?(license_path)
|
14
|
+
text = IO.read(license_path)
|
15
|
+
else
|
16
|
+
# UI.warn "Unable to read the license file `#{license_file}` " \
|
17
|
+
# "for the spec `#{spec}`"
|
18
|
+
end
|
19
|
+
elsif license_file = file_accessor(spec).license
|
20
|
+
text = IO.read(license_file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
text
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parallel'
|
4
|
+
require 'cocoapods'
|
5
|
+
|
6
|
+
module Pod
|
7
|
+
class Installer
|
8
|
+
class Analyzer
|
9
|
+
# > 1.6.0
|
10
|
+
# all_specs[dep.name] 为 nil 会崩溃
|
11
|
+
# 主要原因是 all_specs 分析错误
|
12
|
+
# 查看 source 是否正确
|
13
|
+
#
|
14
|
+
# def dependencies_for_specs(specs, platform, all_specs)
|
15
|
+
# return [] if specs.empty? || all_specs.empty?
|
16
|
+
|
17
|
+
# dependent_specs = Set.new
|
18
|
+
|
19
|
+
# specs.each do |s|
|
20
|
+
# s.dependencies(platform).each do |dep|
|
21
|
+
# all_specs[dep.name].each do |spec|
|
22
|
+
# dependent_specs << spec
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
|
27
|
+
# dependent_specs - specs
|
28
|
+
# end
|
29
|
+
|
30
|
+
# > 1.5.3 版本
|
31
|
+
# rewrite update_repositories
|
32
|
+
#
|
33
|
+
alias old_update_repositories update_repositories
|
34
|
+
def update_repositories
|
35
|
+
if installation_options.update_source_with_multi_processes
|
36
|
+
# 并发更新私有源
|
37
|
+
# 这里多线程会导致 pod update 额外输出 --verbose 的内容
|
38
|
+
# 不知道为什么?
|
39
|
+
Parallel.each(sources.uniq(&:url), in_processes: 4) do |source|
|
40
|
+
if source.git?
|
41
|
+
config.sources_manager.update(source.name, true)
|
42
|
+
else
|
43
|
+
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@specs_updated = true
|
47
|
+
else
|
48
|
+
old_update_repositories
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cocoapods'
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
class InstallationOptions
|
8
|
+
def self.env_option(key, default = true)
|
9
|
+
option key, ENV[key.to_s].nil? ? default : ENV[key.to_s] == 'true'
|
10
|
+
end
|
11
|
+
|
12
|
+
# 不同 source 存在相同 spec 名时,默认不警告
|
13
|
+
defaults.delete('warn_for_multiple_pod_sources')
|
14
|
+
env_option :warn_for_multiple_pod_sources, false
|
15
|
+
|
16
|
+
# 是否警告不安全 source (如 http )
|
17
|
+
env_option :warn_for_unsecure_source, false
|
18
|
+
|
19
|
+
# 是否多线程执行 install_pod_sources
|
20
|
+
env_option :install_with_multi_threads, true
|
21
|
+
|
22
|
+
# 是否多进程执行 update_repositories
|
23
|
+
env_option :update_source_with_multi_processes, true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parallel'
|
4
|
+
require 'cocoapods'
|
5
|
+
require 'cocoapods-miBin/native/pod_source_installer'
|
6
|
+
|
7
|
+
module Pod
|
8
|
+
class Installer
|
9
|
+
alias old_create_pod_installer create_pod_installer
|
10
|
+
def create_pod_installer(pod_name)
|
11
|
+
installer = old_create_pod_installer(pod_name)
|
12
|
+
installer.installation_options = installation_options
|
13
|
+
installer
|
14
|
+
end
|
15
|
+
|
16
|
+
alias old_install_pod_sources install_pod_sources
|
17
|
+
def install_pod_sources
|
18
|
+
if installation_options.install_with_multi_threads
|
19
|
+
if Pod.match_version?('~> 1.4.0')
|
20
|
+
install_pod_sources_for_version_in_1_4_0
|
21
|
+
elsif Pod.match_version?('~> 1.5')
|
22
|
+
install_pod_sources_for_version_above_1_5_0
|
23
|
+
else
|
24
|
+
old_install_pod_sources
|
25
|
+
end
|
26
|
+
else
|
27
|
+
old_install_pod_sources
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# rewrite install_pod_sources
|
32
|
+
def install_pod_sources_for_version_in_1_4_0
|
33
|
+
@installed_specs = []
|
34
|
+
pods_to_install = sandbox_state.added | sandbox_state.changed
|
35
|
+
title_options = { verbose_prefix: '-> '.green }
|
36
|
+
Parallel.each(root_specs.sort_by(&:name), in_threads: 4) do |spec|
|
37
|
+
if pods_to_install.include?(spec.name)
|
38
|
+
if sandbox_state.changed.include?(spec.name) && sandbox.manifest
|
39
|
+
previous = sandbox.manifest.version(spec.name)
|
40
|
+
title = "Installing #{spec.name} #{spec.version} (was #{previous})"
|
41
|
+
else
|
42
|
+
title = "Installing #{spec}"
|
43
|
+
end
|
44
|
+
UI.titled_section(title.green, title_options) do
|
45
|
+
install_source_of_pod(spec.name)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
UI.titled_section("Using #{spec}", title_options) do
|
49
|
+
create_pod_installer(spec.name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def install_pod_sources_for_version_above_1_5_0
|
56
|
+
@installed_specs = []
|
57
|
+
pods_to_install = sandbox_state.added | sandbox_state.changed
|
58
|
+
title_options = { verbose_prefix: '-> '.green }
|
59
|
+
# 多进程下载,多线程时 log 会显著交叉,多进程好点,但是多进程需要利用文件锁对 cache 进行保护
|
60
|
+
# in_processes: 10
|
61
|
+
Parallel.each(root_specs.sort_by(&:name), in_threads: 4) do |spec|
|
62
|
+
if pods_to_install.include?(spec.name)
|
63
|
+
if sandbox_state.changed.include?(spec.name) && sandbox.manifest
|
64
|
+
current_version = spec.version
|
65
|
+
previous_version = sandbox.manifest.version(spec.name)
|
66
|
+
has_changed_version = current_version != previous_version
|
67
|
+
current_repo = analysis_result.specs_by_source.detect do |key, values|
|
68
|
+
break key if values.map(&:name).include?(spec.name)
|
69
|
+
end
|
70
|
+
current_repo &&= current_repo.url || current_repo.name
|
71
|
+
previous_spec_repo = sandbox.manifest.spec_repo(spec.name)
|
72
|
+
has_changed_repo = !previous_spec_repo.nil? && current_repo && (current_repo != previous_spec_repo)
|
73
|
+
title = "Installing #{spec.name} #{spec.version}".dup
|
74
|
+
#puts title.frozen?
|
75
|
+
if has_changed_version && has_changed_repo
|
76
|
+
title << " (was #{previous_version} and source changed to `#{current_repo}` from `#{previous_spec_repo}`)"
|
77
|
+
end
|
78
|
+
if has_changed_version && !has_changed_repo
|
79
|
+
title << " (was #{previous_version})"
|
80
|
+
end
|
81
|
+
if !has_changed_version && has_changed_repo
|
82
|
+
title << " (source changed to `#{current_repo}` from `#{previous_spec_repo}`)"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
title = "Installing #{spec}"
|
86
|
+
end
|
87
|
+
UI.titled_section(title.green, title_options) do
|
88
|
+
install_source_of_pod(spec.name)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
UI.titled_section("Using #{spec}", title_options) do
|
92
|
+
create_pod_installer(spec.name)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
module Downloader
|
100
|
+
class Cache
|
101
|
+
# 多线程锁
|
102
|
+
@@lock = Mutex.new
|
103
|
+
|
104
|
+
# 后面如果要切到进程的话,可以在 cache root 里面新建一个文件
|
105
|
+
# 利用这个文件 lock
|
106
|
+
# https://stackoverflow.com/questions/23748648/using-fileflock-as-ruby-global-lock-mutex-for-processes
|
107
|
+
|
108
|
+
# rmtree 在多进程情况下可能 Directory not empty @ dir_s_rmdir 错误
|
109
|
+
# old_ensure_matching_version 会移除不是同一个 CocoaPods 版本的组件缓存
|
110
|
+
alias old_ensure_matching_version ensure_matching_version
|
111
|
+
def ensure_matching_version
|
112
|
+
@@lock.synchronize { old_ensure_matching_version }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|