podfileDep 2.1.6 → 2.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef9fc2973506646be111abc577b60c06b07129188ed93fe88c815a3e85e9e0a5
4
- data.tar.gz: e52aa4bbfc892537eb91f11930b38a84fa60ac7028734174e45ea9b13bf64029
3
+ metadata.gz: 406874c289ed4d9d0ec411d2fd51ce4c96245e5a77681b3279fea018f59f9352
4
+ data.tar.gz: e9d7611c9061082d53ceba3b4fd779242b2be327b12e4f4439301e48d0713ada
5
5
  SHA512:
6
- metadata.gz: 9a008c66635fe0980898dd5668f02ca4c42c461d5e213510ffe35487ed46de9e23887beb3a8e37917fd59115d2a761bfe4148d59a2d5f1442510f77e8f11487d
7
- data.tar.gz: 2d5a0317b067349e14b4ee302a5218d2a3857b2ab5c16def58364b5e07ddc7addcef58ebbefc8040f2a004eaf8120c8a8a1b7d529579dda1907aca589eda8227
6
+ metadata.gz: 49208d1aa83769ab3c512d32707d9c2897879f27a7bcc9558e03c0ad3cf4ebe81786bd6d2fcd0346173050171d5bece63826d1afb90ed9857ec98f949686ea38
7
+ data.tar.gz: '03164879f5bdd16ab7be623a83add20bba17d4f069c1d46e8bdd668b85b172896c3734fab33251478bc92a66d952a1ce8894689647339f8fb4f1fc27738f9282'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  ## [Released]
2
2
 
3
+ ### [2.2.0] - 2023-7-5
4
+ - 增加编译优化功能
5
+
3
6
  ### [2.1.6] - 2023-6-21
4
7
  - 兼容同时支持最原始的podfile的方式pod依赖库
5
8
  -
@@ -37,9 +37,6 @@ module CocoapodsPlugin
37
37
  # 间接依赖
38
38
  PodfileLock::Indirect.new.log_indirect
39
39
 
40
- # 未被使用的依赖库
41
- Unused::UnusedManager.check_unused
42
-
43
40
  # 添加yaml到引用和忽略
44
41
  Project::ProjectManager.yaml_reference
45
42
 
@@ -52,3 +49,8 @@ module CocoapodsPlugin
52
49
  # puts context
53
50
  # end
54
51
  end
52
+
53
+ END {
54
+ # 未被使用的依赖库
55
+ Unused::UnusedManager.check_unused
56
+ }
@@ -1,6 +1,5 @@
1
- require_relative '../check/xcodeproj'
2
- require_relative '../podfilelock'
3
- require_relative 'uninstall'
1
+
2
+ require_relative '../constants'
4
3
  require_relative '../yaml/yaml_dep'
5
4
 
6
5
  module Unused
@@ -8,152 +7,17 @@ module Unused
8
7
 
9
8
  # 打印未被引用的依赖库
10
9
  def self.check_unused
11
- puts "\n未被引用的组件检查中..."
12
- start = (Time.now.to_f * 1000).to_i
13
-
14
- podfile_lock_manager = PodfileLock::PodfileLockManager
15
- project_manager = XCProject::XcodeprojManager.share_manager
16
-
17
- # podfile.lock的内容
18
- lock_content = podfile_lock_manager.podfile_lock_content
19
-
20
- # 所有已安装的模块
21
- installed_modules = self.get_installed_modules(lock_content)
22
-
23
- # 壳工程里引用的所有模块
24
- shell_modules = project_manager.get_shell_module
25
- if installed_modules.size == 0
26
- return
27
- end
28
-
29
- # 是否需要快速编译
30
- quick_build = Pod::YamlManager.share_manager.quick_build
31
-
32
- uninstaller = Pod::Uninstall.new
33
-
34
- # 未使用的列表
35
- unused_list = []
36
- uninstall_list = []
37
- installed_modules.each do |module_item|
38
-
39
- module_name = module_item.keys[0]
40
- real_module_name = module_name.include?("/") ? module_name.split("/")[0] : module_name #处理有子模块的情况
41
-
42
- used = self.dep_used(real_module_name, installed_modules)
43
-
44
- unless used
45
- used = self.dep_used_in_shell_modules(real_module_name, shell_modules) #在壳工程里检验看用到没
46
- end
47
-
48
- if not used and not unused_list.include?(real_module_name)
49
- local_contain = Pod::YamlManager.share_manager.local_yaml_contain(real_module_name)
50
- if quick_build and not local_contain
51
- uninstall_list << real_module_name
52
- else
53
- unused_list << real_module_name
54
- end
55
- end
56
- end
57
-
58
- if unused_list.size >0
59
- # puts unused_list
60
- puts "未被任何地方引用的组件:#{unused_list}"
61
- end
62
-
63
- if uninstall_list.size > 0
64
- # puts uninstall_list
65
- puts "被移除组件:#{uninstall_list}"
66
- uninstaller.uninstall(uninstall_list)
67
- end
68
-
69
- duration = ((Time.now.to_f * 1000).to_i - start)*0.001
70
- puts "未被引用的组件处理完毕! 共检查#{installed_modules.size.to_s}个组件 耗时:#{duration.round(2)}秒"
71
- end
72
-
73
- # 获取某个库是否在壳工程内被使用
74
- def self.dep_used_in_shell_modules(module_name, shell_modules)
75
- used = false
76
- shell_modules.each do |shell_module, shell_module_item|
77
- shell_module_item.source_files.each{|source_file|
78
- if self.dep_used_in_file(module_name, source_file)
79
- used = true
80
- break
81
- end
82
- }
83
- end
84
- used
85
- end
86
-
87
- # 获取某个库是否在文件内被使用
88
- def self.dep_used_in_file(module_name, file_path)
89
- if File.directory?(file_path)
90
- return false
91
- end
92
-
93
- line_array = IO.readlines(file_path)
94
- line_array.each_with_index { |line, index|
95
- unless line.start_with?("#import <")
96
- next
97
- end
98
-
99
- line_split_array = line.split("/")
100
- if line_split_array.size < 1
101
- next
102
- end
103
-
104
- line_module_name = line_split_array[0].gsub("#import <","")
105
-
106
- real_module_name = module_name.include?("/") ? module_name.split("/")[0] : module_name #处理有子模块的情况
107
-
108
- if real_module_name == line_module_name
109
- return true
110
- end
111
- }
112
- false
113
- end
114
-
115
- # 获取某个库是否被使用
116
- # @return bool
117
- def self.dep_used(module_name, installed_modules)
118
-
119
- installed_modules.each do |module_item|
120
- module_item.each_value {|deps|
121
- deps.each{|dep|
122
- real_dep = dep.include?("/") ? dep.split("/")[0] : dep #处理有子模块的情况
123
- if real_dep == module_name
124
- return true
125
- end
126
- }
127
- }
128
- end
129
- return false
130
- end
131
-
132
- # 获取已安装的依赖库列表
133
- # @return Array
134
- def self.get_installed_modules(lock_content)
135
- all_modules = lock_content["PODS"]
136
-
137
- result_array = []
138
- Array(all_modules).each do |item|
139
- if item.class == String
140
- dep = item.split(" (")[0]
141
- result_array << {dep => []}
142
- elsif item.class == Hash
143
- item_key = item.keys[0]
144
- dep = item_key.split(" (")[0]
145
10
 
146
- item_value = item.values[0]
147
- child_deps = []
148
- item_value.each { |child|
149
- child_deps << child.split(" (")[0]
150
- }
11
+ yaml_dep = Pod::YamlDep.new
151
12
 
152
- result_array << {dep => child_deps}
153
- end
13
+ if yaml_dep.quick_build
14
+ puts "🔰 已开启编译优化选项,请关注上方日志 '下载依赖...'部分"
15
+ puts "#{Constants::PODFILE_LOCAL_YAML}文件内的依赖库,将不会被优化忽略掉"
16
+ else
17
+ warn "\n ⚠️ 检测到你未开启编译优化选项,如你处于开发模式,可打开此开关,移除不被引用的依赖库来加速编译"
18
+ warn "位置:#{Constants::PODFILE_LOCAL_YAML} 顶层 QUICK_BUILD字段设置为true, 然后重新pod install"
154
19
  end
155
20
 
156
- result_array
157
21
  end
158
22
 
159
23
  end
@@ -0,0 +1,161 @@
1
+ require 'cocoapods/installer'
2
+ require 'yaml'
3
+ require_relative 'shell'
4
+ require_relative 'local'
5
+ require_relative 'pod_target'
6
+
7
+ module Pod
8
+ class Installer
9
+
10
+ # @return [Hash{String, Pod:Target}] 所有的pod库被使用的次数
11
+ attr_accessor :thin_pods
12
+
13
+ # @return [String] 未被使用的pod库列表
14
+ attr_accessor :thin_unused_pods
15
+
16
+
17
+ def download_dependencies
18
+ UI.section '下载依赖...' do
19
+
20
+ thin_pod_unused #自定义
21
+ thin_delete_pods_unused #自定义
22
+
23
+ install_pod_sources
24
+ run_podfile_pre_install_hooks
25
+ clean_pod_sources
26
+ end
27
+ end
28
+
29
+ # 删除未被使用的依赖
30
+ # @return nil
31
+ def thin_pod_unused
32
+ @thin_pods = Hash.new
33
+ thin_all_deps_pods_targets
34
+ thin_all_deps_shell_targets
35
+ thin_all_deps_local_yaml
36
+ thin_unused_deps
37
+ end
38
+
39
+ # 获取未被使用到的依赖库
40
+ # @return thin_unused_pods
41
+ def thin_unused_deps
42
+ thin_unused_pods = []
43
+ thin_pods.each do |name, pod_target|
44
+ pod_target.reduce_reference_count
45
+ end
46
+
47
+ thin_pods.each do |name, pod_target|
48
+ if pod_target.reference_count <= 0
49
+ thin_unused_pods << name
50
+ end
51
+ end
52
+
53
+ @thin_unused_pods = thin_unused_pods
54
+ end
55
+
56
+ # 获取在pods_targets使用的依赖库
57
+ # @return thin_pods
58
+ def thin_all_deps_pods_targets
59
+
60
+ pod_targets = analysis_result.pod_targets
61
+
62
+ pod_targets.each do |pod_target|
63
+ thin_pods[pod_target.to_s] = pod_target
64
+ end
65
+
66
+ pod_targets.each do |pod_target|
67
+ pod_target.dependent_targets.each do|sub_pod_target|
68
+ thin_update_reference_count(sub_pod_target)
69
+ end
70
+ end
71
+
72
+ thin_pods
73
+ end
74
+
75
+ # 递归更新引用计数
76
+ # @return nil
77
+ def thin_update_reference_count(pod_target)
78
+ pod = thin_pods[pod_target.to_s]
79
+ pod.reference_count += 1
80
+ pod.dependent_targets.each do|sub_pod_target|
81
+ thin_update_reference_count(sub_pod_target)
82
+ end
83
+ end
84
+
85
+ # 获取在壳工程里使用的依赖库
86
+ # @return thin_pods
87
+ def thin_all_deps_shell_targets
88
+ shell = Shell.new
89
+
90
+ shell.deps_shell.each { |shell_pod|
91
+ if thin_pods.has_key?(shell_pod)
92
+ thin_pods[shell_pod].max_reference_count
93
+ end
94
+ }
95
+ thin_pods
96
+ end
97
+
98
+ # 获取在local_yaml里使用的依赖库
99
+ # @return thin_pods
100
+ def thin_all_deps_local_yaml
101
+ local = Local.new
102
+ local.deps_yaml.each do |yaml_pod|
103
+ if thin_pods.has_key?(yaml_pod)
104
+ thin_pods[yaml_pod].max_reference_count
105
+ end
106
+ end
107
+
108
+ thin_pods
109
+ end
110
+
111
+ # 删除某些依赖库
112
+ # @return nil
113
+ def thin_delete_pods_unused
114
+ if thin_unused_pods.empty?
115
+ return
116
+ end
117
+
118
+ thin_unused_pods.each do |unused_pod|
119
+ title_options = { :verbose_prefix => '-> '.red }
120
+ UI.titled_section("忽略 #{unused_pod}".red, title_options) do
121
+ thin_delete_pod(unused_pod)
122
+ end
123
+ end
124
+
125
+ end
126
+
127
+ # 删除某个依赖库
128
+ # @param unused_pod: String 依赖库名字
129
+ # @return nil
130
+ def thin_delete_pod(unused_pod)
131
+ sandbox_state.added.delete(unused_pod)
132
+ sandbox_state.changed.delete(unused_pod)
133
+ sandbox_state.unchanged.delete(unused_pod)
134
+
135
+ pod_targets.delete_if { |pod_target|
136
+ pod_target.to_s == unused_pod
137
+ }
138
+
139
+ aggregate_targets.each { |aggregate_target|
140
+ aggregate_target.pod_targets.delete_if { |pod_target|
141
+ pod_target.to_s == unused_pod
142
+ }
143
+ }
144
+
145
+ aggregate_targets.each do |aggregate_target|
146
+ aggregate_target.user_build_configurations.each_key do |config|
147
+ pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
148
+ pod_targets.delete_if { |pod_target|
149
+ pod_target.to_s == unused_pod
150
+ }
151
+ end
152
+ end
153
+
154
+ analysis_result.specifications.delete_if { |specification|
155
+ real_specification = specification.to_s.split(" (")[0]
156
+ real_pod = real_specification.split("/")[0]
157
+ real_pod == unused_pod
158
+ }
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,40 @@
1
+ require 'pathname'
2
+ require_relative '../yaml/yaml_dep'
3
+
4
+ module Pod
5
+ class Local
6
+
7
+ def initialize
8
+ super
9
+ @reference_pods = []
10
+ end
11
+
12
+ # PODFILE_LOCAL_YAML指定的依赖库
13
+ # @return [String]
14
+ attr_accessor :reference_pods
15
+
16
+ def deps_yaml
17
+
18
+ yaml_dep = YamlDep.new
19
+
20
+ yaml_dep.generate_yaml
21
+
22
+ podfile_local_yaml = yaml_dep.podfile_local_yaml
23
+ yaml_dep.read_yaml_deps_file(podfile_local_yaml)
24
+
25
+ yaml_dependencies = yaml_dep.yaml_deps[podfile_local_yaml]
26
+
27
+ if yaml_dependencies
28
+ # 处理烦人的子模块
29
+ yaml_dependencies.keys.each do |pod|
30
+ real_pod = pod.split("/")[0]
31
+ unless reference_pods.include?(real_pod)
32
+ reference_pods << real_pod
33
+ end
34
+ end
35
+ end
36
+
37
+ reference_pods
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ module Pod
2
+ class PodTarget < Target
3
+
4
+ # 被引用的次数
5
+ # @return Int
6
+ attr_accessor :reference_count
7
+
8
+ # 引用计数最大
9
+ def max_reference_count
10
+ self.reference_count = 99999
11
+ self.dependent_targets.each do |dep|
12
+ dep.max_reference_count
13
+ end
14
+ end
15
+
16
+ # 引用计数减1
17
+ def reduce_reference_count
18
+ if self.reference_count > 0
19
+ self.reference_count -= 1
20
+ end
21
+
22
+ self.dependent_targets.each do |dep|
23
+ if dep.reference_count == 0
24
+ next
25
+ end
26
+ dep.reduce_reference_count
27
+ end
28
+ end
29
+
30
+ # 获取引用计数
31
+ # @return Int
32
+ def reference_count
33
+ @reference_count ? @reference_count : 0
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,128 @@
1
+ require 'xcodeproj'
2
+ require 'pathname'
3
+
4
+ module Pod
5
+ class Shell
6
+
7
+ def initialize
8
+ super
9
+ @reference_files = []
10
+ @reference_pods = []
11
+ end
12
+
13
+ # 壳工程project对象
14
+ # @return Xcodeproj::Project
15
+ attr_accessor :project_shell
16
+
17
+ # 壳工程引用的文件列表
18
+ # @return [Pathname]
19
+ attr_accessor :reference_files
20
+
21
+ # 壳工程引用的依赖库
22
+ # @return [String]
23
+ attr_accessor :reference_pods
24
+
25
+ # 获取壳工程所引用的依赖库
26
+ # @return [String]
27
+ def deps_shell
28
+ init_project_shell
29
+
30
+ reference_code_file(project_shell.root_object.main_group)
31
+
32
+ reference_files.each do |reference_file|
33
+ pod_in_file(reference_file)
34
+ end
35
+
36
+ reference_pods
37
+ end
38
+
39
+ # 初始化project对象
40
+ # @return project_shell
41
+ def init_project_shell
42
+ xcodeproj_file = nil
43
+ Dir.foreach(Dir.pwd) do |file|
44
+ if file.end_with?(".xcodeproj")
45
+ xcodeproj_file = file
46
+ break
47
+ end
48
+ end
49
+
50
+ xcodeproj_path = "#{Dir.pwd}/#{xcodeproj_file}"
51
+ unless File.exist?(xcodeproj_path)
52
+ return nil
53
+ end
54
+
55
+ @project_shell = Xcodeproj::Project.open(xcodeproj_path)
56
+ end
57
+
58
+ # 获取其对应的引用代码文件和路径
59
+ # @return reference_files
60
+ def reference_code_file(group)
61
+ # 文件引用
62
+ file_reference = Xcodeproj::Project::Object::PBXFileReference
63
+ group.children.each {|child|
64
+
65
+ if child.class != file_reference
66
+ self.reference_code_file(child)
67
+ next
68
+ end
69
+
70
+ file_name = child.real_path.basename
71
+ extend_name = file_name.extname
72
+ if not extend_name == ".h" and
73
+ not extend_name == ".m" and
74
+ not extend_name == ".mm" and
75
+ not extend_name == ".pch" and
76
+ not extend_name == ".c" and
77
+ not extend_name == ".cc" and
78
+ not extend_name == ".hpp" and
79
+ not extend_name == ".cpp"
80
+ next
81
+ end
82
+
83
+ # 引用关系路径
84
+ hierarchy_path_array = child.hierarchy_path.split("/")
85
+ if hierarchy_path_array.size < 2
86
+ next
87
+ end
88
+
89
+ reference_files << child.real_path
90
+ }
91
+ end
92
+
93
+ # 获取某个文件里引用的依赖库名字
94
+ # @param file_path 文件路径
95
+ # @return reference_pods
96
+ def pod_in_file(file_path)
97
+ if File.directory?(file_path)
98
+ return reference_pods
99
+ end
100
+
101
+ line_array = IO.readlines(file_path)
102
+ line_array.each_with_index { |line|
103
+ unless line.start_with?("#import <")
104
+ next
105
+ end
106
+
107
+ unless line.include?("/")
108
+ next
109
+ end
110
+
111
+ line_split_array = line.split("/")
112
+ if line_split_array.size < 1
113
+ next
114
+ end
115
+
116
+ line_module_name = line_split_array[0].gsub("#import <","")
117
+
118
+ real_module_name = line_module_name.include?("/") ? line_module_name.split("/")[0] : line_module_name #处理有子模块的情况
119
+
120
+ unless reference_pods.include?(real_module_name)
121
+ reference_pods << real_module_name
122
+ end
123
+ }
124
+ reference_pods
125
+ end
126
+
127
+ end
128
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PodfileDep
4
- VERSION = "2.1.6"
4
+ VERSION = "2.2.0"
5
5
  end