cocoapods-swordfish 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +35 -0
  3. data/lib/cocoapods_plugin.rb +86 -0
  4. data/lib/gem_version.rb +11 -0
  5. data/lib/swordfish/command/archive.rb +187 -0
  6. data/lib/swordfish/command/auto.rb +192 -0
  7. data/lib/swordfish/command/config.rb +70 -0
  8. data/lib/swordfish/command/repo/update.rb +42 -0
  9. data/lib/swordfish/command/spec/create.rb +78 -0
  10. data/lib/swordfish/command/spec/push.rb +114 -0
  11. data/lib/swordfish/command/swordfish.rb +41 -0
  12. data/lib/swordfish/command.rb +2 -0
  13. data/lib/swordfish/config/config.rb +137 -0
  14. data/lib/swordfish/config/config_asker.rb +57 -0
  15. data/lib/swordfish/config/config_builder.rb +216 -0
  16. data/lib/swordfish/helpers/build_helper.rb +160 -0
  17. data/lib/swordfish/helpers/build_utils.rb +94 -0
  18. data/lib/swordfish/helpers/framework.rb +85 -0
  19. data/lib/swordfish/helpers/framework_builder.rb +451 -0
  20. data/lib/swordfish/helpers/library.rb +54 -0
  21. data/lib/swordfish/helpers/library_builder.rb +90 -0
  22. data/lib/swordfish/helpers/sources_helper.rb +38 -0
  23. data/lib/swordfish/helpers/spec_creator.rb +167 -0
  24. data/lib/swordfish/helpers/spec_files_helper.rb +76 -0
  25. data/lib/swordfish/helpers/spec_source_creator.rb +266 -0
  26. data/lib/swordfish/helpers/upload_helper.rb +94 -0
  27. data/lib/swordfish/hmap/hmap_generator.rb +59 -0
  28. data/lib/swordfish/hmap/pod_target.rb +92 -0
  29. data/lib/swordfish/hmap/podfile_dsl.rb +36 -0
  30. data/lib/swordfish/hmap/post_install_hook_context.rb +41 -0
  31. data/lib/swordfish/hmap/xcconfig.rb +99 -0
  32. data/lib/swordfish/hmap.rb +4 -0
  33. data/lib/swordfish/native/acknowledgements.rb +27 -0
  34. data/lib/swordfish/native/analyzer.rb +55 -0
  35. data/lib/swordfish/native/file_accessor.rb +28 -0
  36. data/lib/swordfish/native/installation_options.rb +25 -0
  37. data/lib/swordfish/native/installer.rb +135 -0
  38. data/lib/swordfish/native/linter.rb +25 -0
  39. data/lib/swordfish/native/path_source.rb +33 -0
  40. data/lib/swordfish/native/pod_source_installer.rb +19 -0
  41. data/lib/swordfish/native/pod_target_installer.rb +94 -0
  42. data/lib/swordfish/native/podfile.rb +105 -0
  43. data/lib/swordfish/native/podfile_env.rb +36 -0
  44. data/lib/swordfish/native/podfile_generator.rb +195 -0
  45. data/lib/swordfish/native/podspec_finder.rb +24 -0
  46. data/lib/swordfish/native/resolver.rb +223 -0
  47. data/lib/swordfish/native/source.rb +35 -0
  48. data/lib/swordfish/native/sources_manager.rb +19 -0
  49. data/lib/swordfish/native/specification.rb +31 -0
  50. data/lib/swordfish/native/target_architectures.rb +79 -0
  51. data/lib/swordfish/native/target_validator.rb +41 -0
  52. data/lib/swordfish/native/validator.rb +39 -0
  53. data/lib/swordfish/native.rb +16 -0
  54. data/lib/swordfish.rb +2 -0
  55. metadata +167 -0
@@ -0,0 +1,94 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Creates the target for the Pods libraries in the Pods project and the
6
+ # relative support files.
7
+ #
8
+ class PodTargetInstaller < TargetInstaller
9
+ require 'cocoapods/installer/xcode/pods_project_generator/app_host_installer'
10
+
11
+ # Adds a shell script phase, intended only for library targets that contain swift,
12
+ # to copy the ObjC compatibility header (the -Swift.h file that the swift compiler generates)
13
+ # to the built products directory. Additionally, the script phase copies the module map, appending a `.Swift`
14
+ # submodule that references the (moved) compatibility header. Since the module map has been moved, the umbrella header
15
+ # is _also_ copied, so that it is sitting next to the module map. This is necessary for a successful archive build.
16
+ #
17
+ # @param [PBXNativeTarget] native_target
18
+ # the native target to add the Swift static library script phase into.
19
+ #
20
+ # @return [Void]
21
+ #
22
+ alias old_add_swift_library_compatibility_header_phase add_swift_library_compatibility_header_phase
23
+
24
+ def add_swift_library_compatibility_header_phase(native_target)
25
+ # UI.warn("========= swift add_swift_library_compatibility_header_phase")
26
+ if $ARGV[1] == "auto"
27
+ UI.warn("========= auto swift add_swift_library_compatibility_header_phase")
28
+
29
+ if custom_module_map
30
+ raise Informative, 'Using Swift static libraries with custom module maps is currently not supported. ' \
31
+ "Please build `#{target.label}` as a framework or remove the custom module map."
32
+ end
33
+
34
+ build_phase = native_target.new_shell_script_build_phase('Copy generated compatibility header')
35
+
36
+ relative_module_map_path = target.module_map_path.relative_path_from(target.sandbox.root)
37
+ relative_umbrella_header_path = target.umbrella_header_path.relative_path_from(target.sandbox.root)
38
+
39
+ build_phase.shell_script = <<-SH.strip_heredoc
40
+ COMPATIBILITY_HEADER_PATH="${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h"
41
+ MODULE_MAP_PATH="${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap"
42
+
43
+ ditto "${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h" "${COMPATIBILITY_HEADER_PATH}"
44
+ ditto "${PODS_ROOT}/#{relative_module_map_path}" "${MODULE_MAP_PATH}"
45
+ ditto "${PODS_ROOT}/#{relative_umbrella_header_path}" "${BUILT_PRODUCTS_DIR}"
46
+
47
+ COPY_PATH="${PODS_CONFIGURATION_BUILD_DIR}/${PRODUCT_MODULE_NAME}"
48
+ UMBRELLA_PATH="${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}-umbrella.h"
49
+ SWIFTMODULE_PATH="${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.swiftmodule"
50
+
51
+ ditto "${MODULE_MAP_PATH}" "${PODS_CONFIGURATION_BUILD_DIR}/${PRODUCT_MODULE_NAME}/${PRODUCT_MODULE_NAME}.modulemap"
52
+ ditto "${COMPATIBILITY_HEADER_PATH}" "${COPY_PATH}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h"
53
+ ditto "${COMPATIBILITY_HEADER_PATH}" "${COPY_PATH}"
54
+ ditto "${UMBRELLA_PATH}" "${COPY_PATH}"
55
+ ditto "${SWIFTMODULE_PATH}" "${COPY_PATH}/${PRODUCT_MODULE_NAME}.swiftmodule"
56
+ ditto "${SWIFTMODULE_PATH}" "${COPY_PATH}/${PRODUCT_MODULE_NAME}.swiftmodule"
57
+
58
+ if [ ${PRODUCT_MODULE_NAME} != ${PRODUCT_NAME} ] ; then
59
+ ditto "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}-umbrella.h" "${COPY_PATH}"
60
+ ditto "${COPY_PATH}" "${PODS_CONFIGURATION_BUILD_DIR}/${PRODUCT_NAME}"
61
+ fi
62
+
63
+ MODULE_MAP_SEARCH_PATH = "${PODS_CONFIGURATION_BUILD_DIR}/${PRODUCT_MODULE_NAME}/${PRODUCT_MODULE_NAME}.modulemap"
64
+
65
+ if [${MODULE_MAP_PATH} != ${MODULE_MAP_SEARCH_PATH}] ; then
66
+ printf "\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\"${COPY_PATH}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\\"\\n requires objc\\n}\\n" >> "${MODULE_MAP_SEARCH_PATH}"
67
+ fi
68
+
69
+ printf "\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\"${COMPATIBILITY_HEADER_PATH}\\"\\n requires objc\\n}\\n" >> "${MODULE_MAP_PATH}"
70
+
71
+ SH
72
+ build_phase.input_paths = %W(
73
+ ${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h
74
+ ${PODS_ROOT}/#{relative_module_map_path}
75
+ ${PODS_ROOT}/#{relative_umbrella_header_path}
76
+ )
77
+ build_phase.output_paths = %W(
78
+ ${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap
79
+ ${BUILT_PRODUCTS_DIR}/#{relative_umbrella_header_path.basename}
80
+ ${BUILT_PRODUCTS_DIR}/Swift\ Compatibility\ Header/${PRODUCT_MODULE_NAME}-Swift.h
81
+ )
82
+ else
83
+ # UI.warn("========= null swift add_swift_library_compatibility_header_phase")
84
+ old_add_swift_library_compatibility_header_phase(native_target)
85
+ end
86
+
87
+ end
88
+
89
+ #-----------------------------------------------------------------------#
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,105 @@
1
+
2
+ require 'cocoapods'
3
+ require 'swordfish/native/podfile_env'
4
+
5
+ $archs_only_arm64 = false
6
+ $excluded_archs_simulator = false
7
+
8
+ module Pod
9
+ class Podfile
10
+ # TREAT_DEVELOPMENTS_AS_NORMAL = 'treat_developments_as_normal'.freeze
11
+
12
+ module DSL
13
+ def set_archs_only_arm64
14
+ $archs_only_arm64 = true
15
+ end
16
+
17
+ def set_excluded_archs_simulator
18
+ $excluded_archs_simulator = true
19
+ end
20
+
21
+ def allow_prerelease
22
+ set_internal_hash_value(ALLOW_PRERELEASE, true)
23
+ end
24
+
25
+ def use_binaries(flag = true)
26
+ set_internal_hash_value(USE_BINARIES, flag)
27
+ end
28
+
29
+ def use_binaries_with_spec_selector!(&block)
30
+ raise Informative, '必须提供选择需要二进制组件的 block !' unless block_given?
31
+
32
+ set_internal_hash_value(USE_BINARIES_SELECTOR, block)
33
+ end
34
+
35
+ def set_use_source_pods(pods)
36
+ hash_pods_use_source = get_internal_hash_value(USE_SOURCE_PODS) || []
37
+ hash_pods_use_source += Array(pods)
38
+ set_internal_hash_value(USE_SOURCE_PODS, hash_pods_use_source)
39
+ end
40
+
41
+ # 0 dev
42
+ # 1 debug_iphoneos
43
+ # 2 release_iphoneos
44
+ # 需要在podfile_env 先定义 CONFIGURATION_ENV
45
+ def set_configuration_env(env = "dev")
46
+ set_internal_hash_value(CONFIGURATION_ENV, env)
47
+ end
48
+ end
49
+
50
+ alias old_plugins plugins
51
+ def plugins
52
+ if ENV[USE_PLUGINS]
53
+ env_plugins = ENV[USE_PLUGINS].split(',').each_with_object({}) do |name, result|
54
+ result[name] = {}
55
+ end
56
+ env_plugins.merge!(old_plugins)
57
+ else
58
+ old_plugins
59
+ end
60
+ end
61
+
62
+ def use_binaries_selector
63
+ get_internal_hash_value(USE_BINARIES_SELECTOR, nil)
64
+ end
65
+
66
+ def allow_prerelease?
67
+ get_internal_hash_value(ALLOW_PRERELEASE, false) || ENV[ALLOW_PRERELEASE] == 'true'
68
+ end
69
+
70
+ def use_binaries?
71
+ get_internal_hash_value(USE_BINARIES, false) || ENV[USE_BINARIES] == 'true'
72
+ end
73
+
74
+ def use_source_pods
75
+ get_internal_hash_value(USE_SOURCE_PODS, []) + String(ENV[USE_SOURCE_PODS]).split('|').uniq
76
+ end
77
+
78
+ def configuration_env
79
+ get_internal_hash_value(CONFIGURATION_ENV, "dev") || ENV[CONFIGURATION_ENV] == "dev"
80
+ end
81
+
82
+ def use_swordfish_plugin
83
+ plugins.keys.include?('cocoapods-swordfish')
84
+ end
85
+
86
+ private
87
+
88
+ def valid_swordfish_plugin
89
+ unless plugins.keys.include?('cocoapods-swordfish')
90
+ raise Pod::Informative, 'You should add `plugin \'cocoapods-swordfish\'` before using its DSL'
91
+ end
92
+ end
93
+
94
+ # set_hash_value 有 key 限制
95
+ def set_internal_hash_value(key, value)
96
+ valid_swordfish_plugin
97
+
98
+ internal_hash[key] = value
99
+ end
100
+
101
+ def get_internal_hash_value(key, default = nil)
102
+ internal_hash.fetch(key, default)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,36 @@
1
+
2
+ module Pod
3
+ class Podfile
4
+ USE_BINARIES = 'use_binaries'
5
+ USE_SOURCE_PODS = 'use_source_pods'
6
+ USE_BINARIES_SELECTOR = 'use_binaries_selector'
7
+ ALLOW_PRERELEASE = 'allow_prerelease'
8
+ USE_PLUGINS = 'use_plugins'
9
+ CONFIGURATION_ENV = 'configuration_env'
10
+
11
+ module ENVExecutor
12
+ def execute_with_bin_plugin(&block)
13
+ execute_with_key(USE_PLUGINS, -> { 'cocoapods-swordfish' }, &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,195 @@
1
+
2
+
3
+ require 'parallel'
4
+ require 'cocoapods'
5
+ require 'swordfish/native/pod_source_installer'
6
+
7
+ module Pod
8
+ module Generate
9
+ # Generates podfiles for pod specifications given a configuration.
10
+ #
11
+ class PodfileGenerator
12
+ # @return [Podfile] a podfile suitable for installing the given spec
13
+ #
14
+ # @param [Specification] spec
15
+ #
16
+ alias old_podfile_for_spec podfile_for_spec
17
+
18
+ def podfile_for_spec(spec)
19
+ generator = self
20
+ dir = configuration.gen_dir_for_pod(spec.name)
21
+
22
+ Pod::Podfile.new do
23
+ project "#{spec.name}.xcodeproj"
24
+ workspace "#{spec.name}.xcworkspace"
25
+
26
+ plugin 'cocoapods-generate'
27
+
28
+ install! 'cocoapods', generator.installation_options
29
+
30
+ generator.podfile_plugins.each do |name, options|
31
+ plugin(*[name, options].compact)
32
+ end
33
+
34
+ use_frameworks!(generator.use_frameworks_value)
35
+
36
+ if (supported_swift_versions = generator.supported_swift_versions)
37
+ supports_swift_versions(supported_swift_versions)
38
+ end
39
+
40
+ # Explicitly set sources
41
+ generator.configuration.sources.each do |source_url|
42
+ source(source_url)
43
+ end
44
+
45
+ self.defined_in_file = dir.join('CocoaPods.podfile.yaml')
46
+
47
+ test_specs = spec.recursive_subspecs.select(&:test_specification?)
48
+ app_specs = if spec.respond_to?(:app_specification?)
49
+ spec.recursive_subspecs.select(&:app_specification?)
50
+ else
51
+ []
52
+ end
53
+
54
+ # Stick all of the transitive dependencies in an abstract target.
55
+ # This allows us to force CocoaPods to use the versions / sources / external sources
56
+ # that we want.
57
+ # By using an abstract target,
58
+
59
+ # 会导致多个dependencies出现, 注释by slj
60
+ # abstract_target 'Transitive Dependencies' do
61
+ # pods_for_transitive_dependencies = [spec.name]
62
+ # .concat(test_specs.map(&:name))
63
+ # .concat(test_specs.flat_map { |ts| ts.dependencies.flat_map(&:name) })
64
+ # .concat(app_specs.map(&:name))
65
+ # .concat(app_specs.flat_map { |as| as.dependencies.flat_map(&:name) })
66
+ #
67
+ # dependencies = generator
68
+ # .transitive_dependencies_by_pod
69
+ # .values_at(*pods_for_transitive_dependencies)
70
+ # .compact
71
+ # .flatten(1)
72
+ # .uniq
73
+ # .sort_by(&:name)
74
+ # .reject { |d| d.root_name == spec.root.name }
75
+ #
76
+ # dependencies.each do |dependency|
77
+ # pod_args = generator.pod_args_for_dependency(self, dependency)
78
+ # pod(*pod_args)
79
+ # end
80
+ # end
81
+
82
+ # Add platform-specific concrete targets that inherit the
83
+ # `pod` declaration for the local pod.
84
+ spec_platform_names = spec.available_platforms.map(&:string_name).flatten.each.reject do |platform_name|
85
+ !generator.configuration.platforms.nil? && !generator.configuration.platforms.include?(platform_name.downcase)
86
+ end
87
+
88
+ spec_platform_names.sort.each do |platform_name|
89
+ target "App-#{platform_name}" do
90
+ current_target_definition.swift_version = generator.swift_version if generator.swift_version
91
+ end
92
+ end
93
+
94
+ # this block has to come _before_ inhibit_all_warnings! / use_modular_headers!,
95
+ # and the local `pod` declaration
96
+ # 会导致多个dependencies出现, 注释by slj
97
+
98
+
99
+ inhibit_all_warnings! if generator.inhibit_all_warnings?
100
+ use_modular_headers! if generator.use_modular_headers?
101
+
102
+ # This is the pod declaration for the local pod,
103
+ # it will be inherited by the concrete target definitions below
104
+
105
+ pod_options = generator.dependency_compilation_kwargs(spec.name)
106
+ pod_options[:path] = spec.defined_in_file.relative_path_from(dir).to_s
107
+ # generator.configuration.podfile.dependencies[0].external_source
108
+
109
+
110
+ { testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
111
+ pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
112
+ end
113
+
114
+ pod spec.name, **pod_options
115
+
116
+ if Pod::Config.instance.podfile
117
+ target_definitions['Pods'].instance_exec do
118
+ target_definition = nil
119
+ Pod::Config.instance.podfile.target_definition_list.each do |target|
120
+ if target.label == "Pods-#{spec.name}"
121
+ target_definition = target
122
+ break
123
+ end
124
+ end
125
+ # setting modular_headers_for
126
+ if(target_definition && target_definition.use_modular_headers_hash.values.any?)
127
+ target_definition.use_modular_headers_hash.values.each do |f|
128
+ f.each { | pod_name| self.set_use_modular_headers_for_pod(pod_name, true) }
129
+ end
130
+ end
131
+
132
+
133
+ if target_definition
134
+ value = target_definition.to_hash['dependencies']
135
+ next if value.blank?
136
+ #删除 本地库中的 spec.name,因为本地的./spec.name地址是错的
137
+ value.each do |f|
138
+ if f.is_a?(Hash) && f.keys.first == spec.name
139
+ value.delete f
140
+ break
141
+ end
142
+ end
143
+ old_value = self.to_hash['dependencies'].first
144
+ value << old_value unless (old_value == nil || value.include?(old_value))
145
+
146
+ set_hash_value(%w(dependencies).first, value)
147
+
148
+ value = target_definition.to_hash['configuration_pod_whitelist']
149
+ next if value.blank?
150
+ set_hash_value(%w(configuration_pod_whitelist).first, value)
151
+
152
+
153
+ end
154
+
155
+
156
+ end
157
+
158
+ end
159
+
160
+ # if generator.configuration && generator.configuration.podfile
161
+ # #变量本地podfile下的dependencies 写入新的验证文件中,指定依赖源
162
+ # generator.configuration.podfile.dependencies.each { |dependencies|
163
+ # #如果不存在dependencies.external_source,就不变量
164
+ # next unless dependencies.external_source
165
+ #
166
+ # dependencies.external_source.each { |key_d, value|
167
+ # pod_options = generator.dependency_compilation_kwargs(dependencies.name)
168
+ # pod_options[key_d] = value.to_s
169
+ # { testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
170
+ # pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
171
+ # end
172
+ # # 过滤 dependencies.name == spec.name
173
+ # pod(dependencies.name, **pod_options) unless dependencies.name == spec.name
174
+ # }
175
+ # }
176
+ # end
177
+
178
+
179
+ # Implement local-sources option to set up dependencies to podspecs in the local filesystem.
180
+ next if generator.configuration.local_sources.empty?
181
+ generator.transitive_local_dependencies(spec, generator.configuration.local_sources).each do |dependency, podspec_file|
182
+ pod_options = generator.dependency_compilation_kwargs(dependency.name)
183
+ pod_options[:path] = if podspec_file[0] == '/' # absolute path
184
+ podspec_file
185
+ else
186
+ '../../' + podspec_file
187
+ end
188
+ pod dependency.name, **pod_options
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+
@@ -0,0 +1,24 @@
1
+
2
+ require 'swordfish/native/specification'
3
+
4
+ module Pod
5
+ class Sandbox
6
+ class PodspecFinder
7
+ def podspecs
8
+ return @specs_by_name if @specs_by_name
9
+
10
+ @specs_by_name = {}
11
+ spec_files = Pathname.glob(root + '{,*}.podspec{,.json}')
12
+ # pod 指向分支时,如果目标组件有 subspec ,并且有 template spec ,request 之后使用的 spec 不应该为 template spec
13
+ # 这里做下过滤
14
+ spec_files = spec_files.reject { |p| Specification::DEFAULT_TEMPLATE_EXTNAME.find { |e| p.to_s.end_with?(e) } }
15
+ spec_files.sort_by { |p| -p.to_path.split(File::SEPARATOR).size }.each do |file|
16
+ spec = Specification.from_file(file)
17
+ spec.validate_cocoapods_version
18
+ @specs_by_name[spec.name] = spec
19
+ end
20
+ @specs_by_name
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,223 @@
1
+
2
+ require 'parallel'
3
+ require 'cocoapods'
4
+
5
+ require 'swordfish/native/podfile'
6
+ require 'swordfish/native/sources_manager'
7
+ require 'swordfish/native/installation_options'
8
+ require 'gem_version'
9
+ require 'swordfish/command/archive'
10
+
11
+ module Pod
12
+ class Resolver
13
+ if Pod.match_version?('~> 1.6')
14
+ # 其实不用到 resolver_specs_by_target 再改 spec
15
+ # 在这个方法里面,通过修改 dependency 的 source 应该也可以
16
+ # 就是有一点,如果改了之后,对应的 source 没有符合 dependency 的版本
17
+ # 分析依赖阶段就会报错了,没法像 resolver_specs_by_target 一样
18
+ # 没有对应的二进制版本时还可以转到源码源码
19
+ #
20
+ def aggregate_for_dependency(dependency)
21
+ sources_manager = Config.instance.sources_manager
22
+ if dependency&.podspec_repo
23
+ sources_manager.aggregate_for_dependency(dependency)
24
+ # 采用 lock 中的 source ,会导致插件对 source 的先后调整失效
25
+ # elsif (locked_vertex = @locked_dependencies.vertex_named(dependency.name)) && (locked_dependency = locked_vertex.payload) && locked_dependency.podspec_repo
26
+ # sources_manager.aggregate_for_dependency(locked_dependency)
27
+ else
28
+ @aggregate ||= Source::Aggregate.new(sources)
29
+ end
30
+ end
31
+ end
32
+
33
+ if Pod.match_version?('~> 1.4')
34
+ def specifications_for_dependency(dependency, additional_requirements_frozen = [])
35
+ additional_requirements = additional_requirements_frozen.dup.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
+
97
+ specs_by_target = old_resolver_specs_by_target.bind(self).call
98
+
99
+ if !podfile.use_swordfish_plugin
100
+ return specs_by_target
101
+ end
102
+
103
+ sources_manager = Config.instance.sources_manager
104
+ use_source_pods = podfile.use_source_pods
105
+
106
+ missing_binary_specs = []
107
+ specs_by_target.each do |target, rspecs|
108
+ # use_binaries 并且 use_source_pods 不包含 本地可过滤
109
+ use_binary_rspecs = if podfile.use_binaries? || podfile.use_binaries_selector
110
+ rspecs.select do |rspec|
111
+ ([rspec.name, rspec.root.name] & use_source_pods).empty? &&
112
+ (podfile.use_binaries_selector.nil? || podfile.use_binaries_selector.call(rspec.spec))
113
+ end
114
+ else
115
+ []
116
+ end
117
+
118
+ # Parallel.map(rspecs, in_threads: 8) do |rspec|
119
+ specs_by_target[target] = rspecs.map do |rspec|
120
+ # 含有 subspecs 的组件暂不处理
121
+ # next rspec if rspec.spec.subspec? || rspec.spec.subspecs.any?
122
+
123
+ # developments 组件采用默认输入的 spec (development pods 的 source 为 nil)
124
+ # 可以使 :podspec => "htts://IMYFoundation.podspec"可以走下去,by slj
125
+ # unless rspec.spec.respond_to?(:spec_source) && rspec.spec.spec_source
126
+ # next rspec
127
+ # end
128
+ #
129
+ #
130
+
131
+ spec_version = rspec.spec.version
132
+ UI.message 'cocoapods-swordfish 插件'
133
+ UI.message "- 开始处理 #{rspec.spec.name} #{spec_version} 组件."
134
+
135
+ # 采用二进制依赖并且不为开发组件
136
+ use_binary = use_binary_rspecs.include?(rspec)
137
+
138
+ # source = sources_manager.binary_source
139
+ # # 采用非二进制
140
+ # unless use_binary
141
+ # # missing_binary_specs << rspec.spec
142
+ # # next rspec
143
+ # source = @aggregate.sources.select { |s|
144
+ # logger.info ""
145
+ # }
146
+ # end
147
+
148
+ # 只实现二进制效果
149
+ # source = use_binary ? sources_manager.binary_source : sources_manager.code_source
150
+ source = sources_manager.binary_source
151
+
152
+ begin
153
+ # 从新 source 中获取 spec,在bin archive中会异常,因为找不到
154
+ specification = source.specification(rspec.root.name, spec_version)
155
+ UI.message "#{rspec.root.name} #{spec_version} \r\n specification =#{specification} "
156
+ # 组件是 subspec
157
+ if rspec.spec.subspec?
158
+ specification = specification.subspec_by_name(rspec.name, false, true)
159
+ end
160
+ # 这里可能出现分析依赖的 source 和切换后的 source 对应 specification 的 subspec 对应不上
161
+ # 造成 subspec_by_name 返回 nil,这个是正常现象
162
+ next unless specification
163
+
164
+ used_by_only = if Pod.match_version?('~> 1.7')
165
+ rspec.used_by_non_library_targets_only
166
+ else
167
+ rspec.used_by_tests_only
168
+ end
169
+ # used_by_only = rspec.respond_to?(:used_by_tests_only) ? rspec.used_by_tests_only : rspec.used_by_non_library_targets_only
170
+ # 组装新的 rspec ,替换原 rspec
171
+ if use_binary
172
+ rspec = ResolverSpecification.new(specification, used_by_only, source)
173
+ UI.message "组装新的 rspec ,替换原 rspec #{rspec.root.name} #{spec_version} \r\n specification =#{specification} \r\n #{rspec} "
174
+
175
+ end
176
+
177
+ rescue Pod::StandardError => e
178
+ # 没有从新的 source 找到对应版本组件,直接返回原 rspec
179
+
180
+ # missing_binary_specs << rspec.spec if use_binary
181
+ missing_binary_specs << rspec.spec
182
+ rspec
183
+ end
184
+
185
+ rspec
186
+ end.compact
187
+ end
188
+
189
+ if missing_binary_specs.any?
190
+ missing_binary_specs.uniq.each do |spec|
191
+ UI.message "【#{spec.name} | #{spec.version}】组件无对应二进制版本 , 将采用源码依赖."
192
+ end
193
+ Pod::Command::Swordfish::Archive.missing_binary_specs(missing_binary_specs)
194
+
195
+ #缓存没有二进制组件到spec文件,local_psec_dir 目录
196
+ sources_sepc = []
197
+ des_dir = Ocean::Config::Builder.instance.local_psec_dir
198
+ FileUtils.rm_f(des_dir) if File.exist?des_dir
199
+ Dir.mkdir des_dir unless File.exist?des_dir
200
+ missing_binary_specs.uniq.each do |spec|
201
+ next if spec.name.include?('/')
202
+
203
+ # spec_git_res = false
204
+ # Ocean::Config::Builder.instance.ignore_git_list.each do |ignore_git|
205
+ # spec_git_res = spec.source[:git] && spec.source[:git].include?(ignore_git)
206
+ # break if spec_git_res
207
+ # end
208
+ # next if spec_git_res
209
+
210
+ #获取没有制作二进制版本的spec集合
211
+ sources_sepc << spec
212
+ unless spec.defined_in_file.nil?
213
+ FileUtils.cp("#{spec.defined_in_file}", "#{des_dir}")
214
+ end
215
+ end
216
+ end
217
+
218
+ specs_by_target
219
+ end
220
+ end
221
+ end
222
+
223
+ end