cocoapods-swordfish 0.1.6

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.
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,92 @@
1
+ # !/usr/bin/env ruby
2
+ require 'swordfish/hmap/xcconfig'
3
+ require 'swordfish/hmap/hmap_generator'
4
+ require 'swordfish/hmap/podfile_dsl'
5
+
6
+ SAVED_HMAP_DIR='prebuilt-hmaps'
7
+
8
+ module Pod
9
+ class Target
10
+ attr_accessor :prebuilt_hmap_target_names
11
+ def save_hmap(hmap)
12
+ if hmap.empty? == false
13
+ target_hmap_name="#{name}.hmap"
14
+ relative_hmap_path = "#{SAVED_HMAP_DIR}/#{target_hmap_name}"
15
+ target_hmap_path = sandbox.root.to_s + "/#{relative_hmap_path}"
16
+ hmaps_dir = sandbox.root.to_s + "/#{SAVED_HMAP_DIR}"
17
+ unless File.exist?(hmaps_dir)
18
+ Dir.mkdir(hmaps_dir)
19
+ end
20
+ if hmap.save_to(target_hmap_path)
21
+ reset_header_search_with_relative_hmap_path(relative_hmap_path)
22
+ end
23
+ end
24
+ end
25
+ def add_prebuilt_hmap_target(name)
26
+ @prebuilt_hmap_target_names = Array.new if @prebuilt_hmap_target_names == nil
27
+ @prebuilt_hmap_target_names << name
28
+ end
29
+ def concat_prebuilt_hmap_targets(names)
30
+ @prebuilt_hmap_target_names = Array.new if @prebuilt_hmap_target_names == nil
31
+ @prebuilt_hmap_target_names.concat(names) if names
32
+ end
33
+ end
34
+
35
+ class PodTarget
36
+ def reset_header_search_with_relative_hmap_path(hmap_path)
37
+ if build_settings.instance_of?(Hash)
38
+ build_settings.each do |config_name, setting|
39
+ config_file = setting.xcconfig
40
+ config_file.reset_header_search_with_relative_hmap_path(hmap_path, @prebuilt_hmap_target_names.uniq)
41
+ # https://github.com/CocoaPods/CocoaPods/issues/1216
42
+ # just turn off private xcconfig's USE_HEADERMAP flag
43
+ config_file.set_use_hmap(false)
44
+ config_path = xcconfig_path(config_name)
45
+ config_file.save_as(config_path)
46
+ end
47
+ elsif build_settings.instance_of?(BuildSettings::PodTargetSettings)
48
+ config_file = build_settings.xcconfig
49
+ config_file.reset_header_search_with_relative_hmap_path(hmap_path, @prebuilt_hmap_target_names.uniq)
50
+ # https://github.com/CocoaPods/CocoaPods/issues/1216
51
+ # just turn off private xcconfig's USE_HEADERMAP flag
52
+ config_file.set_use_hmap(false)
53
+ config_path = xcconfig_path
54
+ config_file.save_as(config_path)
55
+ else
56
+ Pod::UI.notice 'Unknown build settings'
57
+ end
58
+ end
59
+ def recursively_add_dependent_headers_to_hmap(hmap, generate_type)
60
+ dependent_targets.each do |depend_target|
61
+ # set public header for dependent target
62
+ depend_target.generate_hmap(hmap, generate_type, true, true) if depend_target.respond_to?(:generate_hmap)
63
+ concat_prebuilt_hmap_targets(depend_target.prebuilt_hmap_target_names) if depend_target.prebuilt_hmap_target_names
64
+ end
65
+ end
66
+
67
+ def generate_hmap(hmap, generate_type, only_public_headers=true, add_dependency=false)
68
+ # There is no need to add headers of target defines module to hmap.
69
+ unless defines_module?
70
+ unless $hmap_black_pod_list.include?(name)
71
+ add_prebuilt_hmap_target(name)
72
+ # Create hmap for current target if not in black list.
73
+ hmap.add_hmap_with_header_mapping(only_public_headers ? public_header_mappings_by_file_accessor : header_mappings_by_file_accessor, generate_type, name, product_module_name)
74
+ # Recursively add dependent targets if needed.
75
+ recursively_add_dependent_headers_to_hmap(hmap, generate_type) if add_dependency
76
+ else
77
+ Pod::UI.message "- skip target in black list :#{name}"
78
+ end
79
+ end
80
+ end
81
+ end
82
+ class AggregateTarget
83
+ def reset_header_search_with_relative_hmap_path(hmap_path)
84
+ # override xcconfig
85
+ xcconfigs.each do |config_name, config_file|
86
+ config_file.reset_header_search_with_relative_hmap_path(hmap_path, @prebuilt_hmap_target_names.uniq)
87
+ config_path = xcconfig_path(config_name)
88
+ config_file.save_as(config_path)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,36 @@
1
+ # !/usr/bin/env ruby
2
+ # built-in black list pods
3
+ # you can use hmap_black_pod_list to add other pods
4
+ #
5
+ $hmap_enable = false
6
+ $hmap_black_pod_list = []
7
+ $strict_mode = false
8
+ $prebuilt_hmap_for_pod_targets = true
9
+
10
+ module Pod
11
+ class Podfile
12
+ module DSL
13
+
14
+ def set_hmap_enable()
15
+ $hmap_enable = true
16
+ end
17
+
18
+ def set_hmap_black_pod_list(pods)
19
+ if pods != nil && pods.size() > 0
20
+ $hmap_black_pod_list.concat(pods)
21
+ end
22
+ end
23
+ # if use strict mode, main project can only use `#import <PodTargetName/SomeHeader.h>`
24
+ # `#import <SomeHeader.h>` will get 'file not found' error
25
+ # as well as PodTarget dependent on other PodTarget
26
+ def set_hmap_use_strict_mode
27
+ $strict_mode = true
28
+ end
29
+ # turn off prebuilt hmap for targets in pod project except the `main` target
30
+ def turn_prebuilt_hmap_off_for_pod_targets
31
+ $prebuilt_hmap_for_pod_targets = false
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ # !/usr/bin/env ruby
2
+
3
+ module Pod
4
+ class Installer
5
+ class PostInstallHooksContext
6
+ attr_accessor :aggregate_targets
7
+ version = Gem::Version.new(Pod::VERSION)
8
+ if version < Gem::Version.new('1.7.0')
9
+ # Method `generate` has two args
10
+ class << self
11
+ alias old_generate generate
12
+ def generate(sandbox, aggregate_targets)
13
+ context = old_generate(sandbox, aggregate_targets)
14
+ UI.info "- generate method of post install hook context hooked"
15
+ context.aggregate_targets = aggregate_targets
16
+ context
17
+ end
18
+ end
19
+ elsif version < Gem::Version.new('1.10.0')
20
+ # Method `generate` has three args
21
+ class << self
22
+ alias old_generate generate
23
+ def generate(sandbox, pods_project, aggregate_targets)
24
+ context = old_generate(sandbox, pods_project, aggregate_targets)
25
+ UI.info "- generate method of post install hook context hooked"
26
+ context.aggregate_targets = aggregate_targets
27
+ context
28
+ end
29
+ end
30
+ else
31
+ # PostInstallHooksContext inherited from BaseContext, just override `generate`
32
+ def self.generate(sandbox, pods_project, aggregate_targets)
33
+ context = super
34
+ UI.info "- generate method of post install hook context override"
35
+ context.aggregate_targets = aggregate_targets
36
+ context
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,99 @@
1
+ # !/usr/bin/env ruby
2
+
3
+ module Xcodeproj
4
+ class Config
5
+ def remove_attr_with_key(key)
6
+ unless key == nil
7
+ @attributes.delete(key)
8
+ end
9
+ end
10
+ def remove_header_search_path(prebuilt_hmap_target_names=nil)
11
+ header_search_paths = @attributes['HEADER_SEARCH_PATHS']
12
+ if header_search_paths
13
+ new_paths = Array.new
14
+ header_search_paths.split(' ').each do |p|
15
+ unless search_path_should_be_deleted?(p, prebuilt_hmap_target_names)
16
+ new_paths << p
17
+ end
18
+ end
19
+ if new_paths.size > 0
20
+ @attributes['HEADER_SEARCH_PATHS'] = new_paths.join(' ')
21
+ else
22
+ remove_attr_with_key('HEADER_SEARCH_PATHS')
23
+ end
24
+ end
25
+ remove_system_option_in_other_cflags(prebuilt_hmap_target_names)
26
+ end
27
+ def search_path_should_be_deleted?(search_path, prebuilt_hmap_target_names=nil)
28
+ # Check if the path should be deleted from search list
29
+ # 1. It must be at the ${PODS_ROOT} directory
30
+ # 2. It has generated hmap
31
+ ret = false
32
+ if search_path.include?('${PODS_ROOT}/Headers')
33
+ if prebuilt_hmap_target_names
34
+ ret = prebuilt_hmap_target_names.select { |name| search_path.include?(name) }.empty? == false
35
+ end
36
+ end
37
+ ret
38
+ end
39
+ def remove_system_option_in_other_cflags(prebuilt_hmap_target_names=nil)
40
+ # ----------------------------------------------
41
+ # -I<dir>, --include-directory <arg>, --include-directory=<arg>
42
+ # Add directory to include search path. For C++ inputs, if there are multiple -I options,
43
+ # these directories are searched in the order they are given before the standard system directories are searched.
44
+ # If the same directory is in the SYSTEM include search paths, for example if also specified with -isystem, the -I option will be ignored
45
+ #
46
+ # -isystem<directory>
47
+ # Add directory to SYSTEM include search path
48
+ # ----------------------------------------------
49
+ flags = @attributes['OTHER_CFLAGS']
50
+ if flags
51
+ new_flags = ''
52
+ is_isystem_flag = false
53
+ flags.split(' ').each do |substr|
54
+ append_str = substr
55
+ # Previous flag is `isystem`
56
+ if is_isystem_flag
57
+ is_isystem_flag = false
58
+ if search_path_should_be_deleted?(append_str, prebuilt_hmap_target_names)
59
+ next
60
+ else
61
+ # recover
62
+ append_str = "-isystem #{append_str}"
63
+ end
64
+ end
65
+
66
+ if append_str == '-isystem'
67
+ is_isystem_flag = true
68
+ next
69
+ end
70
+
71
+ if new_flags.length > 0
72
+ new_flags += ' '
73
+ end
74
+ new_flags += append_str
75
+ end
76
+
77
+ if new_flags.length > 0
78
+ @attributes['OTHER_CFLAGS'] = new_flags
79
+ else
80
+ remove_attr_with_key('OTHER_CFLAGS')
81
+ end
82
+ end
83
+ end
84
+ def reset_header_search_with_relative_hmap_path(hmap_path, prebuilt_hmap_target_names=nil)
85
+ # Delete associate search paths
86
+ remove_header_search_path(prebuilt_hmap_target_names)
87
+ # Add hmap file to search path
88
+ new_paths = Array["${PODS_ROOT}/#{hmap_path}"]
89
+ header_search_paths = @attributes['HEADER_SEARCH_PATHS']
90
+ if header_search_paths
91
+ new_paths.concat(header_search_paths.split(' '))
92
+ end
93
+ @attributes['HEADER_SEARCH_PATHS'] = new_paths.join(' ')
94
+ end
95
+ def set_use_hmap(use=false)
96
+ @attributes['USE_HEADERMAP'] = (use ? 'YES' : 'NO')
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,4 @@
1
+
2
+ require 'swordfish/hmap/podfile_dsl'
3
+ require 'swordfish/hmap/pod_target'
4
+ require 'swordfish/hmap/post_install_hook_context'
@@ -0,0 +1,27 @@
1
+
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,55 @@
1
+
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
+
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ require 'macho'
2
+ require 'cocoapods'
3
+
4
+ module Pod
5
+ class Sandbox
6
+ class FileAccessor
7
+
8
+ # swift动态库 需要设置为true
9
+ def dynamic_binary?(binary)
10
+ @cached_dynamic_binary_results ||= {}
11
+ return @cached_dynamic_binary_results[binary] unless @cached_dynamic_binary_results[binary].nil?
12
+ return false unless binary.file?
13
+
14
+ @cached_dynamic_binary_results[binary] = MachO.open(binary).dylib?
15
+ rescue MachO::MachOError
16
+ @cached_dynamic_binary_results[binary] = true
17
+
18
+ end
19
+
20
+ # def expanded_paths(patterns, options = {})
21
+ # return [] if patterns.empty?
22
+ # path_list.glob(patterns, options).flatten.compact.uniq
23
+ # end
24
+
25
+ #-----------------------------------------------------------------------#
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'cocoapods'
3
+
4
+ module Pod
5
+ class Installer
6
+ class InstallationOptions
7
+ def self.env_option(key, default = true)
8
+ option key, ENV[key.to_s].nil? ? default : ENV[key.to_s] == 'true'
9
+ end
10
+
11
+ # 不同 source 存在相同 spec 名时,默认不警告
12
+ defaults.delete('warn_for_multiple_pod_sources')
13
+ env_option :warn_for_multiple_pod_sources, false
14
+
15
+ # 是否警告不安全 source (如 http )
16
+ env_option :warn_for_unsecure_source, false
17
+
18
+ # 是否多线程执行 install_pod_sources
19
+ env_option :install_with_multi_threads, true
20
+
21
+ # 是否多进程执行 update_repositories
22
+ env_option :update_source_with_multi_processes, true
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,135 @@
1
+ require 'cocoapods/installer/project_cache/target_metadata.rb'
2
+ require 'parallel'
3
+ require 'cocoapods'
4
+ require 'xcodeproj'
5
+ require 'swordfish/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}"
74
+ if has_changed_version && has_changed_repo
75
+ title += " (was #{previous_version} and source changed to `#{current_repo}` from `#{previous_spec_repo}`)"
76
+ end
77
+ if has_changed_version && !has_changed_repo
78
+ title += " (was #{previous_version})"
79
+ end
80
+ if !has_changed_version && has_changed_repo
81
+ title += " (source changed to `#{current_repo}` from `#{previous_spec_repo}`)"
82
+ end
83
+ else
84
+ title = "Installing #{spec}"
85
+ end
86
+ UI.titled_section(title.green, title_options) do
87
+ install_source_of_pod(spec.name)
88
+ end
89
+ else
90
+ UI.titled_section("Using #{spec}", title_options) do
91
+ create_pod_installer(spec.name)
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ alias old_write_lockfiles write_lockfiles
98
+ def write_lockfiles
99
+ old_write_lockfiles
100
+ if File.exist?('Podfile_local')
101
+
102
+ project = Xcodeproj::Project.open(config.sandbox.project_path)
103
+ #获取主group
104
+ group = project.main_group
105
+ group.set_source_tree('SOURCE_ROOT')
106
+ #向group中添加 文件引用
107
+ file_ref = group.new_reference(config.sandbox.root + '../Podfile_local')
108
+ #podfile_local排序
109
+ podfile_local_group = group.children.last
110
+ group.children.pop
111
+ group.children.unshift(podfile_local_group)
112
+ #保存
113
+ project.save
114
+ end
115
+ end
116
+ end
117
+
118
+ module Downloader
119
+ class Cache
120
+ # 多线程锁
121
+ @@lock = Mutex.new
122
+
123
+ # 后面如果要切到进程的话,可以在 cache root 里面新建一个文件
124
+ # 利用这个文件 lock
125
+ # https://stackoverflow.com/questions/23748648/using-fileflock-as-ruby-global-lock-mutex-for-processes
126
+
127
+ # rmtree 在多进程情况下可能 Directory not empty @ dir_s_rmdir 错误
128
+ # old_ensure_matching_version 会移除不是同一个 CocoaPods 版本的组件缓存
129
+ alias old_ensure_matching_version ensure_matching_version
130
+ def ensure_matching_version
131
+ @@lock.synchronize { old_ensure_matching_version }
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'swordfish/native/specification'
3
+
4
+ module Pod
5
+ class Specification
6
+ class Linter
7
+ # !@group Lint steps
8
+
9
+ # Checks that the spec's root name matches the filename.
10
+ #
11
+ # @return [void]
12
+ #
13
+ def validate_root_name
14
+ if spec.root.name && file
15
+ acceptable_names = Specification::VALID_EXTNAME.map { |extname| "#{spec.root.name}#{extname}" }
16
+ names_match = acceptable_names.include?(file.basename.to_s)
17
+ unless names_match
18
+ results.add_error('name', 'The name of the spec should match the ' \
19
+ 'name of the file.')
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+
2
+
3
+ require 'swordfish/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
+
2
+
3
+ require 'swordfish/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