cocoapods-miBin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rakeTasks +7 -0
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +104 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +522 -0
  8. data/Rakefile +13 -0
  9. data/cocoapods-miBin.gemspec +27 -0
  10. data/lib/cocoapods-miBin.rb +4 -0
  11. data/lib/cocoapods-miBin/command.rb +3 -0
  12. data/lib/cocoapods-miBin/command/bin.rb +60 -0
  13. data/lib/cocoapods-miBin/command/bin/archive.rb +134 -0
  14. data/lib/cocoapods-miBin/command/bin/init.rb +71 -0
  15. data/lib/cocoapods-miBin/command/bin/lib.rb +14 -0
  16. data/lib/cocoapods-miBin/command/bin/lib/lint.rb +69 -0
  17. data/lib/cocoapods-miBin/command/bin/list.rb +50 -0
  18. data/lib/cocoapods-miBin/command/bin/open.rb +61 -0
  19. data/lib/cocoapods-miBin/command/bin/repo.rb +15 -0
  20. data/lib/cocoapods-miBin/command/bin/repo/push.rb +116 -0
  21. data/lib/cocoapods-miBin/command/bin/repo/update.rb +42 -0
  22. data/lib/cocoapods-miBin/command/bin/search.rb +69 -0
  23. data/lib/cocoapods-miBin/command/bin/spec.rb +15 -0
  24. data/lib/cocoapods-miBin/command/bin/spec/create.rb +75 -0
  25. data/lib/cocoapods-miBin/command/bin/spec/lint.rb +111 -0
  26. data/lib/cocoapods-miBin/command/bin/umbrella.rb +55 -0
  27. data/lib/cocoapods-miBin/config/config.rb +81 -0
  28. data/lib/cocoapods-miBin/config/config_asker.rb +58 -0
  29. data/lib/cocoapods-miBin/gem_version.rb +11 -0
  30. data/lib/cocoapods-miBin/helpers.rb +5 -0
  31. data/lib/cocoapods-miBin/helpers/framework.rb +64 -0
  32. data/lib/cocoapods-miBin/helpers/framework_builder.rb +227 -0
  33. data/lib/cocoapods-miBin/helpers/sources_helper.rb +33 -0
  34. data/lib/cocoapods-miBin/helpers/spec_creator.rb +159 -0
  35. data/lib/cocoapods-miBin/helpers/spec_files_helper.rb +77 -0
  36. data/lib/cocoapods-miBin/native.rb +21 -0
  37. data/lib/cocoapods-miBin/native/acknowledgements.rb +27 -0
  38. data/lib/cocoapods-miBin/native/analyzer.rb +53 -0
  39. data/lib/cocoapods-miBin/native/installation_options.rb +26 -0
  40. data/lib/cocoapods-miBin/native/installer.rb +116 -0
  41. data/lib/cocoapods-miBin/native/linter.rb +26 -0
  42. data/lib/cocoapods-miBin/native/path_source.rb +33 -0
  43. data/lib/cocoapods-miBin/native/pod_source_installer.rb +19 -0
  44. data/lib/cocoapods-miBin/native/pod_target.rb +8 -0
  45. data/lib/cocoapods-miBin/native/podfile.rb +79 -0
  46. data/lib/cocoapods-miBin/native/podfile_env.rb +36 -0
  47. data/lib/cocoapods-miBin/native/podspec_finder.rb +25 -0
  48. data/lib/cocoapods-miBin/native/resolver.rb +200 -0
  49. data/lib/cocoapods-miBin/native/sandbox_analyzer.rb +34 -0
  50. data/lib/cocoapods-miBin/native/source.rb +35 -0
  51. data/lib/cocoapods-miBin/native/sources_manager.rb +20 -0
  52. data/lib/cocoapods-miBin/native/specification.rb +31 -0
  53. data/lib/cocoapods-miBin/native/validator.rb +16 -0
  54. data/lib/cocoapods-miBin/source_provider_hook.rb +21 -0
  55. data/lib/cocoapods_plugin.rb +5 -0
  56. data/spec/command/bin_spec.rb +12 -0
  57. data/spec/spec_helper.rb +50 -0
  58. metadata +173 -0
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods-miBin/native/specification'
4
+
5
+ module Pod
6
+ class Specification
7
+ class Linter
8
+ # !@group Lint steps
9
+
10
+ # Checks that the spec's root name matches the filename.
11
+ #
12
+ # @return [void]
13
+ #
14
+ def validate_root_name
15
+ if spec.root.name && file
16
+ acceptable_names = Specification::VALID_EXTNAME.map { |extname| "#{spec.root.name}#{extname}" }
17
+ names_match = acceptable_names.include?(file.basename.to_s)
18
+ unless names_match
19
+ results.add_error('name', 'The name of the spec should match the ' \
20
+ 'name of the file.')
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods-miBin/native/specification'
4
+
5
+ module Pod
6
+ module ExternalSources
7
+ # Provides support for fetching a specification file from a path local to
8
+ # the machine running the installation.
9
+ #
10
+ class PathSource < AbstractExternalSource
11
+ def normalized_podspec_path(declared_path)
12
+ extension = File.extname(declared_path)
13
+
14
+ if extension == '.podspec' || extension == '.json'
15
+ path_with_ext = declared_path
16
+ else
17
+ # 默认先从 binary podspec 找起,因为 binary podspec 的 subspec 可能比 code podspec 多
18
+ # 这里可能出现 code subspec 和 binary subspec 对应不上的情况,导致 lint 失败
19
+ # 所以不要在 code podspec 同一目录下保留 binary podspec
20
+ path_with_ext = Specification::VALID_EXTNAME
21
+ .map { |extname| "#{declared_path}/#{name}#{extname}" }
22
+ .find { |file| File.exist?(file) } || "#{declared_path}/#{name}.podspec"
23
+ end
24
+
25
+ UI.message "获取的 podspec 路径为 `#{path_with_ext}`"
26
+
27
+ podfile_dir = File.dirname(podfile_path || '')
28
+
29
+ File.expand_path(path_with_ext, podfile_dir)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods-miBin/native/installation_options'
4
+
5
+ module Pod
6
+ class Installer
7
+ class PodSourceInstaller
8
+ attr_accessor :installation_options
9
+
10
+ alias old_verify_source_is_secure verify_source_is_secure
11
+ def verify_source_is_secure(root_spec)
12
+ # http source 默认不警告
13
+ if installation_options.warn_for_unsecure_source?
14
+ old_verify_source_is_secure(root_spec)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+
2
+ module Pod
3
+ class PodTarget < Target
4
+ def static_framework?
5
+ true
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods'
4
+ require 'cocoapods-miBin/native/podfile_env'
5
+
6
+ module Pod
7
+ class Podfile
8
+ # TREAT_DEVELOPMENTS_AS_NORMAL = 'treat_developments_as_normal'.freeze
9
+
10
+ module DSL
11
+ def allow_prerelease!
12
+ set_internal_hash_value(ALLOW_PRERELEASE, true)
13
+ end
14
+
15
+ def use_binaries!(flag = true)
16
+ set_internal_hash_value(USE_BINARIES, flag)
17
+ end
18
+
19
+ def use_binaries_with_spec_selector!(&block)
20
+ raise Informative, '必须提供选择需要二进制组件的 block !' unless block_given?
21
+
22
+ set_internal_hash_value(USE_BINARIES_SELECTOR, block)
23
+ end
24
+
25
+ def set_use_source_pods(pods)
26
+ hash_pods_use_source = get_internal_hash_value(USE_SOURCE_PODS) || []
27
+ hash_pods_use_source += Array(pods)
28
+ set_internal_hash_value(USE_SOURCE_PODS, hash_pods_use_source)
29
+ end
30
+ end
31
+
32
+ alias old_plugins plugins
33
+ def plugins
34
+ if ENV[USE_PLUGINS]
35
+ env_plugins = ENV[USE_PLUGINS].split(',').each_with_object({}) do |name, result|
36
+ result[name] = {}
37
+ end
38
+ env_plugins.merge!(old_plugins)
39
+ else
40
+ old_plugins
41
+ end
42
+ end
43
+
44
+ def use_binaries_selector
45
+ get_internal_hash_value(USE_BINARIES_SELECTOR, nil)
46
+ end
47
+
48
+ def allow_prerelease?
49
+ get_internal_hash_value(ALLOW_PRERELEASE, false) || ENV[ALLOW_PRERELEASE] == 'true'
50
+ end
51
+
52
+ def use_binaries?
53
+ get_internal_hash_value(USE_BINARIES, false) || ENV[USE_BINARIES] == 'true'
54
+ end
55
+
56
+ def use_source_pods
57
+ get_internal_hash_value(USE_SOURCE_PODS, []) + String(ENV[USE_SOURCE_PODS]).split('|').uniq
58
+ end
59
+
60
+ private
61
+
62
+ def valid_bin_plugin
63
+ unless plugins.keys.include?('cocoapods-miBin')
64
+ raise Pod::Informative, 'You should add `plugin \'cocoapods-miBin\'` before using its DSL'
65
+ end
66
+ end
67
+
68
+ # set_hash_value 有 key 限制
69
+ def set_internal_hash_value(key, value)
70
+ valid_bin_plugin
71
+
72
+ internal_hash[key] = value
73
+ end
74
+
75
+ def get_internal_hash_value(key, default = nil)
76
+ internal_hash.fetch(key, default)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pod
4
+ class Podfile
5
+ USE_BINARIES = 'use_binaries'
6
+ USE_SOURCE_PODS = 'use_source_pods'
7
+ USE_BINARIES_SELECTOR = 'use_binaries_selector'
8
+ ALLOW_PRERELEASE = 'allow_prerelease'
9
+ USE_PLUGINS = 'use_plugins'
10
+
11
+ module ENVExecutor
12
+ def execute_with_bin_plugin(&block)
13
+ execute_with_key(USE_PLUGINS, -> { 'cocoapods-miBin' }, &block)
14
+ end
15
+
16
+ def execute_with_allow_prerelease(allow_prerelease, &block)
17
+ execute_with_key(ALLOW_PRERELEASE, -> { allow_prerelease ? 'true' : 'false' }, &block)
18
+ end
19
+
20
+ def execute_with_use_binaries(use_binaries, &block)
21
+ execute_with_key(USE_BINARIES, -> { use_binaries ? 'true' : 'false' }, &block)
22
+ end
23
+
24
+ def execute_with_key(key, value_returner)
25
+ origin_value = ENV[key]
26
+ ENV[key] = value_returner.call
27
+
28
+ yield if block_given?
29
+
30
+ ENV[key] = origin_value
31
+ end
32
+ end
33
+
34
+ extend ENVExecutor
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods-miBin/native/specification'
4
+
5
+ module Pod
6
+ class Sandbox
7
+ class PodspecFinder
8
+ def podspecs
9
+ return @specs_by_name if @specs_by_name
10
+
11
+ @specs_by_name = {}
12
+ spec_files = Pathname.glob(root + '{,*}.podspec{,.json}')
13
+ # pod 指向分支时,如果目标组件有 subspec ,并且有 template spec ,request 之后使用的 spec 不应该为 template spec
14
+ # 这里做下过滤
15
+ spec_files = spec_files.reject { |p| Specification::DEFAULT_TEMPLATE_EXTNAME.find { |e| p.to_s.end_with?(e) } }
16
+ spec_files.sort_by { |p| -p.to_path.split(File::SEPARATOR).size }.each do |file|
17
+ spec = Specification.from_file(file)
18
+ spec.validate_cocoapods_version
19
+ @specs_by_name[spec.name] = spec
20
+ end
21
+ @specs_by_name
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parallel'
4
+ require 'cocoapods'
5
+ require 'cocoapods-miBin/native/podfile'
6
+ require 'cocoapods-miBin/native/sources_manager'
7
+ require 'cocoapods-miBin/native/installation_options'
8
+ require 'cocoapods-miBin/gem_version'
9
+
10
+ module Pod
11
+ class Resolver
12
+ if Pod.match_version?('~> 1.6')
13
+ # 其实不用到 resolver_specs_by_target 再改 spec
14
+ # 在这个方法里面,通过修改 dependency 的 source 应该也可以
15
+ # 就是有一点,如果改了之后,对应的 source 没有符合 dependency 的版本
16
+ # 分析依赖阶段就会报错了,没法像 resolver_specs_by_target 一样
17
+ # 没有对应的二进制版本时还可以转到源码源码
18
+ #
19
+ def aggregate_for_dependency(dependency)
20
+ sources_manager = Config.instance.sources_manager
21
+ if dependency&.podspec_repo
22
+ sources_manager.aggregate_for_dependency(dependency)
23
+ # 采用 lock 中的 source ,会导致插件对 source 的先后调整失效
24
+ # elsif (locked_vertex = @locked_dependencies.vertex_named(dependency.name)) && (locked_dependency = locked_vertex.payload) && locked_dependency.podspec_repo
25
+ # sources_manager.aggregate_for_dependency(locked_dependency)
26
+ else
27
+ @aggregate ||= Source::Aggregate.new(sources)
28
+ end
29
+ end
30
+ end
31
+
32
+ if Pod.match_version?('~> 1.4')
33
+ def specifications_for_dependency(dependency, additional_requirements_frozen = [])
34
+ additional_requirements = additional_requirements_frozen.dup
35
+ additional_requirements.compact!
36
+ requirement = Requirement.new(dependency.requirement.as_list + additional_requirements.flat_map(&:as_list))
37
+ if podfile.allow_prerelease? && !requirement.prerelease?
38
+ requirement = Requirement.new(dependency.requirement.as_list.map { |r| r + '.a' } + additional_requirements.flat_map(&:as_list))
39
+ end
40
+
41
+ options = if Pod.match_version?('~> 1.7')
42
+ podfile.installation_options
43
+ else
44
+ installation_options
45
+ end
46
+
47
+ if Pod.match_version?('~> 1.8')
48
+ specifications = find_cached_set(dependency)
49
+ .all_specifications(options.warn_for_multiple_pod_sources, requirement)
50
+ else
51
+ specifications = find_cached_set(dependency)
52
+ .all_specifications(options.warn_for_multiple_pod_sources)
53
+ .select { |s| requirement.satisfied_by? s.version }
54
+ end
55
+
56
+ specifications
57
+ .map { |s| s.subspec_by_name(dependency.name, false, true) }
58
+ .compact
59
+ end
60
+ end
61
+
62
+ if Pod.match_version?('~> 1.6')
63
+ alias old_valid_possibility_version_for_root_name? valid_possibility_version_for_root_name?
64
+
65
+ def valid_possibility_version_for_root_name?(requirement, activated, spec)
66
+ return true if podfile.allow_prerelease?
67
+
68
+ old_valid_possibility_version_for_root_name?(requirement, activated, spec)
69
+ end
70
+ elsif Pod.match_version?('~> 1.4')
71
+ def requirement_satisfied_by?(requirement, activated, spec)
72
+ version = spec.version
73
+ return false unless requirement.requirement.satisfied_by?(version)
74
+
75
+ shared_possibility_versions, prerelease_requirement = possibility_versions_for_root_name(requirement, activated)
76
+ if !shared_possibility_versions.empty? && !shared_possibility_versions.include?(version)
77
+ return false
78
+ end
79
+ if !podfile.allow_prerelease? && version.prerelease? && !prerelease_requirement
80
+ return false
81
+ end
82
+ unless spec_is_platform_compatible?(activated, requirement, spec)
83
+ return false
84
+ end
85
+
86
+ true
87
+ end
88
+ end
89
+
90
+ # >= 1.4.0 才有 resolver_specs_by_target 以及 ResolverSpecification
91
+ # >= 1.5.0 ResolverSpecification 才有 source,供 install 或者其他操作时,输入 source 变更
92
+ #
93
+ if Pod.match_version?('~> 1.4')
94
+ old_resolver_specs_by_target = instance_method(:resolver_specs_by_target)
95
+ define_method(:resolver_specs_by_target) do
96
+ specs_by_target = old_resolver_specs_by_target.bind(self).call
97
+
98
+ sources_manager = Config.instance.sources_manager
99
+ use_source_pods = podfile.use_source_pods
100
+
101
+ missing_binary_specs = []
102
+ specs_by_target.each do |target, rspecs|
103
+ # use_binaries 并且 use_source_pods 不包含
104
+ use_binary_rspecs = if podfile.use_binaries? || podfile.use_binaries_selector
105
+ rspecs.select do |rspec|
106
+ ([rspec.name, rspec.root.name] & use_source_pods).empty? &&
107
+ (podfile.use_binaries_selector.nil? || podfile.use_binaries_selector.call(rspec.spec))
108
+ end
109
+ else
110
+ []
111
+ end
112
+
113
+ # Parallel.map(rspecs, in_threads: 8) do |rspec|
114
+ specs_by_target[target] = rspecs.map do |rspec|
115
+ # 含有 subspecs 的组件暂不处理
116
+ # next rspec if rspec.spec.subspec? || rspec.spec.subspecs.any?
117
+
118
+ # developments 组件采用默认输入的 spec (development pods 的 source 为 nil)
119
+ unless rspec.spec.respond_to?(:spec_source) && rspec.spec.spec_source
120
+ next rspec
121
+ end
122
+
123
+ # 采用二进制依赖并且不为开发组件
124
+ use_binary = use_binary_rspecs.include?(rspec)
125
+ source = use_binary ? sources_manager.binary_source : sources_manager.code_source
126
+
127
+ spec_version = rspec.spec.version
128
+
129
+ UI.message "- 开始处理 #{rspec.spec.name} #{spec_version} 组件."
130
+
131
+ begin
132
+ # 从新 source 中获取 spec
133
+ specification = source.specification(rspec.root.name, spec_version)
134
+
135
+ # 组件是 subspec
136
+ if rspec.spec.subspec?
137
+ specification = specification.subspec_by_name(rspec.name, false, true)
138
+ end
139
+ # 这里可能出现分析依赖的 source 和切换后的 source 对应 specification 的 subspec 对应不上
140
+ # 造成 subspec_by_name 返回 nil,这个是正常现象
141
+ next unless specification
142
+
143
+ used_by_only = if Pod.match_version?('~> 1.7')
144
+ rspec.used_by_non_library_targets_only
145
+ else
146
+ rspec.used_by_tests_only
147
+ end
148
+ # used_by_only = rspec.respond_to?(:used_by_tests_only) ? rspec.used_by_tests_only : rspec.used_by_non_library_targets_only
149
+ # 组装新的 rspec ,替换原 rspec
150
+ rspec = if Pod.match_version?('~> 1.4.0')
151
+ ResolverSpecification.new(specification, used_by_only)
152
+ else
153
+ ResolverSpecification.new(specification, used_by_only, source)
154
+ end
155
+ rspec
156
+ rescue Pod::StandardError => e
157
+ # 没有从新的 source 找到对应版本组件,直接返回原 rspec
158
+ missing_binary_specs << rspec.spec if use_binary
159
+ rspec
160
+ end
161
+
162
+ rspec
163
+ end.compact
164
+ end
165
+
166
+ if missing_binary_specs.any?
167
+ missing_binary_specs.uniq.each do |spec|
168
+ UI.message "【#{spec.name} | #{spec.version}】组件无对应二进制版本 , 将采用源码依赖."
169
+ end
170
+ end
171
+
172
+ specs_by_target
173
+ end
174
+ end
175
+ end
176
+
177
+ if Pod.match_version?('~> 1.4.0')
178
+ # 1.4.0 没有 spec_source
179
+ class Specification
180
+ class Set
181
+ class LazySpecification < BasicObject
182
+ attr_reader :spec_source
183
+
184
+ old_initialize = instance_method(:initialize)
185
+ define_method(:initialize) do |name, version, source|
186
+ old_initialize.bind(self).call(name, version, source)
187
+
188
+ @spec_source = source
189
+ end
190
+
191
+ def respond_to?(method, include_all = false)
192
+ return super unless method == :spec_source
193
+
194
+ true
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pod
4
+ class Installer
5
+ class Analyzer
6
+ class SandboxAnalyzer
7
+ # def pod_changed?(pod)
8
+ # spec = root_spec(pod)
9
+ # 有 subspec 的情况下,root spec 对应的 used_files 可能始终为空
10
+ # 要添加为空 && 没有 subspec 的情况
11
+ # file_accessors = spec.available_platforms.map { |platform| Sandbox::FileAccessor.new(sandbox.pod_dir(pod), spec.consumer(platform)) }
12
+ # files = [
13
+ # file_accessors.map(&:vendored_frameworks),
14
+ # file_accessors.map(&:vendored_libraries),
15
+ # file_accessors.map(&:resource_bundle_files),
16
+ # file_accessors.map(&:prefix_header),
17
+ # file_accessors.map(&:resources),
18
+ # file_accessors.map(&:source_files),
19
+ # file_accessors.map(&:module_map),
20
+ # ]
21
+ # used_files = files.flatten.compact.map(&:to_s).uniq
22
+ # p pod if used_files.empty?
23
+
24
+ # return true if spec.version != sandbox_version(pod)
25
+ # return true if spec.checksum != sandbox_checksum(pod)
26
+ # return true if resolved_spec_names(pod) != sandbox_spec_names(pod)
27
+ # return true if sandbox.predownloaded?(pod)
28
+ # return true if folder_empty?(pod)
29
+ # false
30
+ # end
31
+ end
32
+ end
33
+ end
34
+ end