fastlane-plugin-rocket 0.1.0 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d7b90377f51f1c4a925873ed21028b714b2f5a2b9ffa2c7f8678773158f7a6d
4
- data.tar.gz: 7ebd3a571e3b6f7b55f6b17d30d7f5caedf2b7255ca85faba2296ac45728f73f
3
+ metadata.gz: bbf9ec77d01ca12cd21b9831ac5744821ad22e08b30f102933f51ecd9d456365
4
+ data.tar.gz: 3be0562351b50ed2afd71ec54f1fe8b3b13a777f372e2d1db57ac55754871b0c
5
5
  SHA512:
6
- metadata.gz: faac5fe8336c01c655f99f640a4f0a08313bd44eca8a6829702eaaed99d09c1466f72834bbb24880b9f8b06d3375dcfda1f11ce19d4183cfecbe2cde3fc9018d
7
- data.tar.gz: 734f256ccf891c787ef908f3b9dbe0e3e3f4b9dafa8b1e60a38bc6d6345b6de3dc3cade6ca0d9472083b8a637fa421b82f39dd238f965803f716c59b64697dc5
6
+ metadata.gz: 1809d1e477c6124a4a0e7e719349e64bf4aecf4682775be4a1e8a29a128ff7e469ba1c0d9ae2ff626ff840988773771dcb4f46a56f172e7ffd59440d334e3724
7
+ data.tar.gz: f73405e8ab90f2cb3d49ffa0214dec742908de8d03018f22ea9602207c7eebea948c8c76eea7ed87212dd2045641fc09b68cf8c5f94c24889db5df98ecfa74a1
@@ -0,0 +1,104 @@
1
+ require 'fastlane/action'
2
+ require_relative '../app/app_main'
3
+ require_relative '../tools/message'
4
+ module Fastlane
5
+ module Actions
6
+ class AppAction < Action
7
+ def self.run(params)
8
+
9
+ begin
10
+ App::AppMain.run(params,available_options)
11
+ rescue Exception => e
12
+ Tools.error(e.message)
13
+ end
14
+ Tools.title("完成!!!")
15
+ end
16
+
17
+ def self.description
18
+ "APP打包"
19
+ end
20
+
21
+ def self.authors
22
+ ["三块"]
23
+ end
24
+
25
+ def self.return_value
26
+ # If your method provides a return value, you can describe here what it does
27
+ end
28
+
29
+ def self.details
30
+ "开发者只能打开发者包,App Store包需要移步至rocket平台"
31
+ end
32
+
33
+ def self.available_options
34
+ [
35
+ FastlaneCore::ConfigItem.new(key: :code,
36
+ env_name: 'R_APP_CODE',
37
+ description: '应用的标识码,从rocket平台获取。用于获取应用的相关信息',
38
+ optional: false,
39
+ type: String,
40
+ default_value: "fanDengBook",
41
+ verify_block: proc do |value|
42
+ Tools.error("code不能为空") unless (value and not value.empty?)
43
+ ENV["R_APP_CODE"] = value.to_s
44
+ end),
45
+ FastlaneCore::ConfigItem.new(key: :plan,
46
+ env_name: 'R_APP_PLAN',
47
+ description: '测试计划或发布计划。用于确定组件的版本和打包信息',
48
+ optional: false,
49
+ type: String,
50
+ verify_block: proc do |value|
51
+ Tools.error("plan不能为空") unless (value and not value.empty?)
52
+ ENV["R_APP_PLAN"] = value.to_s
53
+ end),
54
+ FastlaneCore::ConfigItem.new(key: :config,
55
+ env_name: 'R_APP_CONFIG',
56
+ description: '打包环境:Debug/Release',
57
+ optional: false,
58
+ type: String,
59
+ default_value: "Debug",
60
+ verify_block: proc do |value|
61
+ Tools.error("config不能为空") unless (value and not value.empty?)
62
+ Tools.error("config没有#{value}选项") unless (value == "Debug" or value == "Release")
63
+ ENV["R_APP_CONFIG"] = value.to_s
64
+ end),
65
+ FastlaneCore::ConfigItem.new(key: :channel,
66
+ env_name: 'R_APP_CHANNEL',
67
+ description: '打包方式:APP_STORE/DEVELOPMENT',
68
+ optional: false,
69
+ type: String,
70
+ default_value: "DEVELOPMENT",
71
+ verify_block: proc do |value|
72
+ Tools.error("channel不能为空") unless (value and not value.empty?)
73
+ ENV["R_APP_CHANNEL"] = value.to_s
74
+ end),
75
+ FastlaneCore::ConfigItem.new(key: :build,
76
+ env_name: 'R_APP_BUILD',
77
+ description: 'build number',
78
+ optional: false,
79
+ type: Integer,
80
+ verify_block: proc do |value|
81
+ ENV["R_APP_BUILD"] = value.to_s
82
+ end),
83
+ FastlaneCore::ConfigItem.new(key: :note,
84
+ env_name: 'R_APP_NOTE',
85
+ description: '打包日志',
86
+ optional: false,
87
+ type: String,
88
+ verify_block: proc do |value|
89
+ ENV["R_APP_NOTE"] = value.to_s
90
+ end),
91
+
92
+ ]
93
+ end
94
+
95
+ def self.is_supported?(platform)
96
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
97
+ # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
98
+ #
99
+ # [:ios, :mac, :android].include?(platform)
100
+ true
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,75 @@
1
+ require 'fastlane/action'
2
+ require_relative '../ref/ref_main'
3
+ require_relative '../tools/message'
4
+ module Fastlane
5
+ module Actions
6
+ class RefAction < Action
7
+ def self.run(params)
8
+ begin
9
+ Ref::RefMain.run(params,available_options)
10
+ rescue Exception => e
11
+ Tools.error(e.message)
12
+ end
13
+ Tools.title("完成!!!")
14
+ end
15
+
16
+ def self.description
17
+ "查找引入文件,却未在podsepc依赖文件的来源库"
18
+ end
19
+
20
+ def self.authors
21
+ ["三块"]
22
+ end
23
+
24
+ def self.return_value
25
+ # If your method provides a return value, you can describe here what it does
26
+ end
27
+
28
+ def self.details
29
+ "生成表,表明哪些库需要在哪些podspec中引入"
30
+ end
31
+
32
+ def self.available_options
33
+ [
34
+ FastlaneCore::ConfigItem.new(key: :git,
35
+ env_name: 'R_REF_GIT',
36
+ description: '工程仓库地址',
37
+ optional: false,
38
+ type: String,
39
+ verify_block: proc do |value|
40
+ Tools.error("git不能为空") unless (value and not value.empty?)
41
+ ENV["R_REF_GIT"] = value.to_s
42
+ end),
43
+ FastlaneCore::ConfigItem.new(key: :branch,
44
+ env_name: 'R_REF_BRANCH',
45
+ description: '工程分支',
46
+ optional: false,
47
+ type: String,
48
+ verify_block: proc do |value|
49
+ Tools.error("branch不能为空") unless (value and not value.empty?)
50
+ ENV["R_REF_BRANCH"] = value.to_s
51
+ end),
52
+ FastlaneCore::ConfigItem.new(key: :pods,
53
+ env_name: 'R_REF_PODS',
54
+ description: '默认全量查询(耗时很久请勿使用),需要查询的pod组合,逗号分隔。1.找出哪些库使用该pod组件,却未在podsepc依赖库 2.分析import方式错误的依赖库',
55
+ optional: true,
56
+ default_value:"ALL",
57
+ type: String,
58
+ verify_block: proc do |value|
59
+ Tools.error("pods不能为空") unless (value and not value.empty?)
60
+ ENV["R_REF_PODS"] = value.to_s
61
+ end)
62
+
63
+ ]
64
+ end
65
+
66
+ def self.is_supported?(platform)
67
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
68
+ # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
69
+ #
70
+ # [:ios, :mac, :android].include?(platform)
71
+ true
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,73 @@
1
+ require 'fastlane/action'
2
+ require_relative '../tools/message'
3
+ require_relative '../sync/sync_main'
4
+ module Fastlane
5
+ module Actions
6
+ class SyncAction < Action
7
+ def self.run(params)
8
+ begin
9
+ Sync::SyncMain.run(params,available_options)
10
+ rescue Exception => e
11
+ Tools.error(e.message)
12
+ end
13
+ Tools.log("完成!!!")
14
+ end
15
+
16
+ def self.description
17
+ "同步壳工程,将业务库可以独立运行"
18
+ end
19
+
20
+ def self.authors
21
+ ["三块"]
22
+ end
23
+
24
+ def self.return_value
25
+ # If your method provides a return value, you can describe here what it does
26
+ end
27
+
28
+ def self.details
29
+ "将壳工程的podfile和工程同步到业务库,并支持业务库自定义podfile设置"
30
+ end
31
+
32
+ def self.available_options
33
+ [
34
+ FastlaneCore::ConfigItem.new(key: :git,
35
+ env_name: 'R_SYNC_GIT',
36
+ description: '壳工程仓库地址,不传默认取git@gitlab.dushuclub.io:ios-team/dushu-ios-new.git',
37
+ optional: true,
38
+ type: String,
39
+ default_value:"git@gitlab.dushuclub.io:ios-team/dushu-ios-new.git",
40
+ verify_block: proc do |value|
41
+ ENV["R_SYNC_GIT"] = value.to_s
42
+ end),
43
+ FastlaneCore::ConfigItem.new(key: :branch,
44
+ env_name: 'R_SYNC_BRANCH',
45
+ description: '同步壳工程分支,不传默认取当前工程的分支',
46
+ optional: true,
47
+ type: String,
48
+ default_value:"",
49
+ verify_block: proc do |value|
50
+ branch = value.to_s
51
+ if branch.empty?
52
+ tmp_branch = Tools.return_shell("git rev-parse --abbrev-ref HEAD")
53
+ if tmp_branch == -1
54
+ Tools.error("分支错误,需要传分支参数 or 在项目位置执行本命令,将会获取项目的当前分支")
55
+ end
56
+ branch = tmp_branch
57
+ end
58
+ ENV["R_SYNC_BRANCH"] = branch
59
+ end)
60
+
61
+ ]
62
+ end
63
+
64
+ def self.is_supported?(platform)
65
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
66
+ # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
67
+ #
68
+ # [:ios, :mac, :android].include?(platform)
69
+ true
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,12 @@
1
+
2
+ require_relative '../tools/message'
3
+
4
+ module Fastlane
5
+ module App
6
+ class AppMain
7
+ def self.run(params,available_options)
8
+ Tools.formatLog(params,available_options);
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,381 @@
1
+
2
+ require_relative '../tools/message'
3
+ require_relative '../tools/config'
4
+ require_relative '../tools/clone'
5
+ require_relative '../tools/file'
6
+
7
+ require_relative 'ref_pod_info'
8
+
9
+ module Fastlane
10
+ module Ref
11
+
12
+ #脚本生成文件存放地址
13
+ REF_PATH = "#{Tools::ROCKET_PATH}ref"
14
+ XCODEPROJ_PATH = "#{REF_PATH}/xcodeproj"
15
+ SOURCESPECS_PATH = "#{REF_PATH}/SOURCESPECS"
16
+ LOCK_PATH = "#{REF_PATH}/ref.lock"
17
+ PODS_PATH = "#{REF_PATH}/Pods"
18
+
19
+
20
+ class RefMain
21
+ def self.run(params,available_options)
22
+ Tools.formatLog(params,available_options);
23
+
24
+ pod_author = Tools.return_shell("git config user.name")
25
+ user_id = Tools.return_shell("git config user.id")
26
+ if user_id.nil? ||user_id.empty?
27
+ raise "请设置:git config user.id。user.id为gitlab的User ID,在用户设置里查看"
28
+ end
29
+
30
+ git = ENV["R_REF_GIT"]
31
+ branch = ENV["R_REF_BRANCH"]
32
+ all = false
33
+ pods = []
34
+ if ENV["R_REF_PODS"] != "ALL"
35
+ pods = ENV["R_REF_PODS"].split(",");
36
+ else
37
+ all = true
38
+ end
39
+
40
+ Tools.title("拉取工程仓库")
41
+ Tools.log("缓存地址 => #{REF_PATH}")
42
+ Tools.clone(git,branch,XCODEPROJ_PATH)
43
+
44
+ Tools.title("拉取HDSourceSpecs")
45
+ Tools.clone(Tools::SOURCESPECS,"master",SOURCESPECS_PATH)
46
+
47
+ Tools.title("pod update")
48
+ project_path = update()
49
+
50
+ Tools.title("生成pod对象集合")
51
+ lock_path = "#{project_path}/Podfile.lock"
52
+ pods_path = "#{project_path}/Pods"
53
+ pods_hash = RefPodInfo.analysis(lock_path,pods_path,SOURCESPECS_PATH)
54
+
55
+ Tools.title("生成被引用的库集合")
56
+ inspect_pods = inspect(all,pods,pods_hash)
57
+
58
+ Tools.title("开始检查...")
59
+ #获取工程所有文件
60
+ files_hash = RefPodInfo.files(pods_hash)
61
+ files = files_hash.values
62
+ files_str = files.join("\" \"")
63
+ #去掉空格
64
+ Tools.shell("sed -i '' \"s/ //g\" \"#{files_str}\"")
65
+
66
+ #获取所有库的podsepc地址
67
+ git_paths = RefPodInfo.git_paths(pods_hash)
68
+ git_paths_str = git_paths.join("\" \"")
69
+
70
+ count = inspect_pods.keys.size
71
+ for i in 0..count-1
72
+ inspect_key = inspect_pods.keys[i]
73
+ inspect_info = inspect_pods[inspect_key]
74
+ name = inspect_info.name
75
+ Tools.title("检查#{name}中,进度#{i+1}/#{count}")
76
+
77
+
78
+ #查看podsepc是否被引用
79
+ podsepc_rule = "\"#{name}\":"
80
+ podspec_shell = "fgrep '#{podsepc_rule}' \"#{git_paths_str}\""
81
+
82
+ #去掉检查库本身
83
+ tmp_hash = files_hash.clone
84
+ tmp_hash.delete(name)
85
+ select_files_str = tmp_hash.values.join("\" \"")
86
+
87
+ #定义规则
88
+ rules = []
89
+ rules << "import#{name}"
90
+ rules << "import<#{name}/"
91
+ rules << "import\"#{name}/"
92
+ #该库所有文件
93
+ if inspect_info.files_h_name.size != 0
94
+ rules << "#import\"" + inspect_info.files_h_name.join("' -e '#import\"")
95
+ end
96
+
97
+
98
+ rule_str = "-e '" + rules.join("' -e '") + "'"
99
+ note = Tools.return_shell("fgrep #{rule_str} \"#{select_files_str}\"&&#{podspec_shell}")
100
+ if note != -1
101
+ analysis(note,inspect_info,pods_path,pods_hash)
102
+ end
103
+ Tools.log("#{name}检查完成")
104
+ end
105
+
106
+ Tools.title("生成 #{LOCK_PATH}中...")
107
+ lock_file(inspect_pods,all)
108
+ Tools.log("使用命令打开查看详情:open #{LOCK_PATH}")
109
+
110
+ Tools.title("修复问题")
111
+ Tools.delete_path(PODS_PATH)
112
+ update_pods = Hash.new
113
+ branch_pods = Hash.new #分支问题
114
+ #提交到gitlab
115
+
116
+ inspect_pods.values.each do |inspect_info|
117
+
118
+ if inspect_info.deps.keys.size == 0 && inspect_info.reference_errors.keys.size == 0
119
+ next
120
+ end
121
+ Tools.title("修正#{inspect_info.name}引用问题...")
122
+ inspect_info.deps.keys.each do |key|
123
+ dep_info = inspect_info.deps[key].first
124
+ pod = pods_hash[key]
125
+
126
+ if dep_info.podspec_quote == true && !inspect_info.reference_errors.has_key?(key)
127
+ next
128
+ end
129
+
130
+ tmp_file = Dir.glob("#{PODS_PATH}/**/#{key}.podspec").first
131
+ if tmp_file.nil?
132
+ pod_path = "#{PODS_PATH}/#{key}"
133
+ unless File.directory?(pod_path)
134
+ Tools.clone(pod.git,branch,pod_path)
135
+ unless File.directory?(pod_path)
136
+ Tools.clone(pod.git,pod.version,pod_path)
137
+ branch_pods[key] = "master"
138
+ else
139
+ Tools.clone(pod.git,pod.version,pod_path)
140
+ branch_pods[key] = branch
141
+ end
142
+ end
143
+ else
144
+ pod_path = tmp_file.gsub("/#{key}.podspec","")
145
+ end
146
+
147
+ if dep_info.podspec_quote == false
148
+ podsepc_file = Dir.glob("#{pod_path}/**/#{key}.podspec").first
149
+
150
+ spec_n = Tools.return_shell("fgrep \"spec.name\" \"#{podsepc_file}\"")
151
+
152
+ Tools.shell("sed -i '' '$s/end//' '#{podsepc_file}'")
153
+ if spec_n == -1
154
+ str = " s.dependency '#{inspect_info.name}'\nend"
155
+ else
156
+ str = " spec.dependency '#{inspect_info.name}'\nend"
157
+ end
158
+
159
+ f = open("#{podsepc_file}","a")
160
+ f.puts(str)
161
+ f.close
162
+ end
163
+
164
+
165
+ #修复引用错误
166
+ if inspect_info.reference_errors.has_key?(key)
167
+ errors = inspect_info.reference_errors[key]
168
+
169
+ errors.each do |error|
170
+ file = Dir.glob("#{pod_path}/**/#{error.file_name}").first
171
+ notes = error.notes
172
+ old = "\"#{notes.split("\"")[1]}\""
173
+ str = "<#{inspect_info.name}/#{notes.split("\"")[1]}>"
174
+
175
+ tmp_notes = Tools.return_shell("grep '#{str}' \"#{file}\"")
176
+ if tmp_notes == -1
177
+ Tools.shell("sed -i '' 's##{old}##{str}#g' \"#{file}\"")
178
+ Tools.log("#{error.file_name}:#{old} => #{str}")
179
+ else
180
+ Tools.return_shell("sed -i '' '/#{old}/d' \"#{file}\"")
181
+ Tools.log("#{error.file_name}:#{old} => Delete")
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+ update_pods[key] = pod_path
188
+ end
189
+ end
190
+
191
+
192
+ tmp_branch = "reocket_ref_fix"
193
+ web_urls = []
194
+ update_pods.keys.each do |key|
195
+ Tools.title("批量提交修改记录:#{key}")
196
+ path = update_pods[key]
197
+ branch_pod = branch_pods[key]
198
+ Tools.shell_list([
199
+ "cd #{path}",
200
+ "git status",
201
+ "if [ `git branch --list #{tmp_branch}` ];then git branch -D #{tmp_branch};fi",
202
+ "git checkout -b #{tmp_branch}",
203
+ "git add --all",
204
+ "git commit -m '[rocket][fix]修复使用库的类,却没有在podsepc引用的问题 提交人:#{pod_author}'",
205
+ "git push -f origin #{tmp_branch}"
206
+ ])
207
+
208
+ pod = pods_hash[key]
209
+ name = pod.git.split("/")[-1].split(".git").first
210
+ #获取项目的id
211
+ projects = Tools.net_get("http://gitlab.dushuclub.io/api/v4/projects",{"search":"#{name}"})
212
+ if projects.size == 0
213
+ next
214
+ end
215
+ project_id = projects.first["id"]
216
+ params = {"id":"#{project_id}","source_branch":"#{tmp_branch}","target_branch":"#{branch_pod}","title":"[rocket][fix]修复使用库的类,却没有在podsepc引用的问题","remove_source_branch":"true","assignee_id":"#{user_id}"}
217
+ merge_requests = Tools.net_post("http://gitlab.dushuclub.io/api/v4/projects/#{project_id}/merge_requests",params)
218
+ web_url = merge_requests["web_url"]
219
+ web_urls << web_url
220
+ end
221
+ Tools.log("修正完成...")
222
+ web_urls = web_urls.uniq
223
+ Tools.logs("合并请求",web_urls)
224
+ end
225
+
226
+ def self.analysis(note,inspect_info,pods_path,pods_hash)
227
+
228
+ rule = "#import\""
229
+ rule1 = ".podspec.json:"
230
+
231
+ tmp_note = note.clone
232
+ tmp_note = tmp_note.gsub(" ","")
233
+
234
+ #解析note
235
+ notes = note.split("\n")
236
+ notes.each do |tmp|
237
+ if tmp == "" || tmp.include?(rule1)
238
+ next
239
+ end
240
+
241
+ tmps = tmp.split(":")
242
+ #获取库名和文件名
243
+ tmp_file_path = tmps.first
244
+ tmp_paths = tmp_file_path.gsub(pods_path,"").to_s.split("/")
245
+ dep_name = tmp_paths[1]
246
+ dep_file_name = tmp_paths[-1]
247
+
248
+ #判断podsepc是否引用
249
+ podsepc_status = false
250
+ podsepc_rule = "/#{dep_name}.podspec.json:\"#{inspect_info.name}\""
251
+ if tmp_note.include?(podsepc_rule)
252
+ podsepc_status = true
253
+ end
254
+
255
+ #获取有引用具体内容
256
+ tmp_text = tmps[-1]
257
+ if tmp_text.start_with?("//")
258
+ next
259
+ end
260
+
261
+ version = pods_hash[dep_name].version
262
+
263
+
264
+ #add引用不规范
265
+ if tmp_text.include?(rule)
266
+ tmp_file = tmp_text.split("\"")[1]
267
+ tmp_files_h_name_str = pods_hash[dep_name].files_h_name.join(",")
268
+ if tmp_files_h_name_str.include?(tmp_file)
269
+ next
270
+ end
271
+ inspect_info.add_reference_errors(dep_name,version,tmp_file_path,tmp_text,podsepc_status)
272
+ end
273
+
274
+ #add有引用
275
+ inspect_info.add_deps(dep_name,version,tmp_file_path,tmp_text,podsepc_status)
276
+ end
277
+ end
278
+
279
+ def self.update()
280
+ #获取podfile地址
281
+ podfile_path = Dir.glob("#{XCODEPROJ_PATH}/Podfile").first
282
+ if podfile_path == nil
283
+ raise "工程中未找到Podfile文件,请确定该工程是iOS工程?工程地址 => #{XCODEPROJ_PATH}"
284
+ end
285
+
286
+ #通过podfile获取项目的目录
287
+ project_path = File.dirname(podfile_path)
288
+
289
+ #判断是否存在Makefile文件
290
+ makefile_path = Dir.glob("#{project_path}/Makefile").first
291
+ make = "make"
292
+ if makefile_path == nil
293
+ make = "pod update"
294
+ end
295
+
296
+ # 以源码形式执行pod update
297
+ Tools.shell_list([
298
+ "cd #{project_path}",
299
+ "sed -i '' \"s/hd_all_binary!/#hd_all_binary!/g\" \"Podfile\"",
300
+ make
301
+ ])
302
+ return project_path
303
+ end
304
+
305
+ def self.inspect(all,pods,pods_hash)
306
+ inspect_pods = Hash.new
307
+ if all == true
308
+ inspect_pods = pods_hash.clone
309
+ else
310
+ pods.each do |pod|
311
+ pod_info = pods_hash[pod]
312
+ if pod_info == nil
313
+ Tools.warning("#{pod}不存在该工程的Pods中,请确定该库无拼写错误!")
314
+ next
315
+ end
316
+ pod_info.get_files_h_name
317
+ inspect_pods[pod] = pod_info
318
+ end
319
+ end
320
+
321
+ if inspect_pods.empty?
322
+ raise "检查库不存在该工程的Pods中!"
323
+ end
324
+ return inspect_pods
325
+ end
326
+
327
+
328
+ def self.lock_file(inspect_pods,has_info = true)
329
+ lock_text = ""
330
+ count = inspect_pods.keys.size
331
+ for i in 0..count-1
332
+ inspect_info = inspect_pods.values[i]
333
+ Tools.title("解析#{inspect_info.name}中,进度#{i+1}/#{count}")
334
+
335
+ if inspect_info.deps.keys.size != 0 || inspect_info.reference_errors.keys.size != 0
336
+ lock_text += "\n-------------------#{inspect_info.name}(#{inspect_info.version})-------------------\n"
337
+ end
338
+
339
+ if inspect_info.deps.keys.size != 0
340
+ lock_text += "-\s使用库却没有在podsepc引入的列表\n"
341
+ inspect_info.deps.values.each do |deps_infos|
342
+ name = deps_infos.first.name
343
+ podsepc_status = deps_infos.first.podspec_quote
344
+
345
+ if podsepc_status == true
346
+ next
347
+ end
348
+
349
+ lock_text += "\s-\s#{name}\n"
350
+ deps_infos.each do |dep|
351
+ lock_text += "\s\s-\s#{dep.file_name} => #{dep.notes}\n"
352
+ end
353
+ end
354
+
355
+ end
356
+
357
+ if inspect_info.reference_errors.size != 0
358
+ lock_text += "-\s引用方式错误的列表\n"
359
+
360
+ inspect_info.reference_errors.values.each do |errors_infos|
361
+ name = errors_infos.first.name
362
+ lock_text += "\s-\s#{name}\n"
363
+ errors_infos.each do |error|
364
+ lock_text += "\s\s-\s#{error.file_name} => #{error.notes}\n"
365
+ end
366
+ end
367
+
368
+ end
369
+ Tools.log("解析完成")
370
+ end
371
+ f=File.new(LOCK_PATH,"w+")
372
+ f.puts(lock_text)
373
+ f.close
374
+
375
+
376
+ end
377
+
378
+
379
+ end
380
+ end
381
+ end
@@ -0,0 +1,199 @@
1
+
2
+ module Fastlane
3
+ module Ref
4
+ class RefDepInfo
5
+ attr_reader :name,
6
+ :version,
7
+ :dep_name,
8
+ :file_path,
9
+ :file_name,
10
+ :notes,
11
+ :podspec_quote
12
+
13
+ def initialize(name,version,dep_name,file_path,file_name,notes,podspec_quote)
14
+ @name=name
15
+ @version=version
16
+ @dep_name=dep_name
17
+ @file_path=file_path
18
+ @file_name=file_name
19
+ @notes=notes
20
+ @podspec_quote=podspec_quote
21
+ end
22
+
23
+ def string()
24
+ string = []
25
+ string << "引用文件:#{file_name} => #{notes}"
26
+ Tools.logs(nil,string)
27
+ end
28
+
29
+
30
+ end
31
+
32
+ class RefPodInfo
33
+ attr_reader :name,
34
+ :version,
35
+ :git,
36
+ :git_path,
37
+ :files_h,
38
+ :files_swift,
39
+ :files_m,
40
+ :files_h_name,
41
+ :files_swift_name,
42
+ :files_m_name,
43
+ :deps,
44
+ :reference_errors
45
+
46
+ def initialize(name, version, git,git_path,files_h,files_swift,files_m,files_h_name,files_swift_name,files_m_name)
47
+ @name=name
48
+ @version=version
49
+ @git=git
50
+ @git_path=git_path
51
+ @files_h=files_h
52
+ @files_swift=files_swift
53
+ @files_m=files_m
54
+ @files_h_name=files_h_name
55
+ @files_swift_name=files_swift_name
56
+ @files_m_name=files_m_name
57
+ @deps = Hash.new
58
+ @reference_errors = Hash.new
59
+
60
+ end
61
+
62
+
63
+ def add_reference_errors(pod_name,version,file_path,notes,podspec_quote)
64
+ errors_info = RefDepInfo.new(pod_name,version,@name,file_path,File.basename(file_path),notes,podspec_quote)
65
+ unless @reference_errors.has_key?(pod_name)
66
+ @reference_errors[pod_name] = []
67
+ end
68
+ @reference_errors[pod_name] << errors_info
69
+ end
70
+
71
+ def add_deps(pod_name,version,file_path,notes,podspec_quote)
72
+ dep_info = RefDepInfo.new(pod_name,version,@name,file_path,File.basename(file_path),notes,podspec_quote)
73
+ unless @deps.has_key?(pod_name)
74
+ @deps[pod_name] = []
75
+ end
76
+ @deps[pod_name] << dep_info
77
+ end
78
+
79
+ def get_files_h_name()
80
+ unless files_h_name.empty?
81
+ Tools.logs("#{@name}的头文件",@files_h_name)
82
+ end
83
+ end
84
+
85
+ def string()
86
+ string = []
87
+ string << "name => #{name}"
88
+ string << "version => #{version}"
89
+ string << "git => #{git}"
90
+ string << "git_path => #{git_path}"
91
+ Tools.logs("#{name}属性",string)
92
+ end
93
+
94
+ def self.analysis(lock_path,pods_path,specs_path)
95
+
96
+ #生成pod对象
97
+ pods_hash = Hash.new
98
+ pod_list = Dir.glob("#{pods_path}/**")
99
+ pod_list.each do |item|
100
+ pod_name = item.gsub("#{pods_path}/","")
101
+ if pod_name == "Target Support Files" ||
102
+ pod_name == "Local Podspecs" ||
103
+ pod_name == "Headers" ||
104
+ pod_name == "Pods.xcodeproj" ||
105
+ pod_name == "Manifest.lock"
106
+ next
107
+ end
108
+
109
+ #获取版本
110
+ Tools.shell("sed -i '' \"s/ //g\" \"#{lock_path}\"")
111
+ notes = Tools.return_shell("grep -i '#{pod_name}' '#{lock_path}'")
112
+
113
+ notes_tmp = notes.split("(=")
114
+ if notes_tmp.size > 1
115
+ version = notes_tmp[1].split(")").first
116
+ else
117
+ tmp = notes.split("(")
118
+ tmp.each do |t|
119
+ if t.include?("~")
120
+ next
121
+ end
122
+ if t.include?(")")
123
+ version = t.split(")").first
124
+ end
125
+ end
126
+ end
127
+
128
+ #获取git地址
129
+ pod_git_path = "#{specs_path}/#{pod_name}/#{version}/#{pod_name}.podspec.json"
130
+ pod_git = nil
131
+ if File.exist?(pod_git_path)
132
+ json = File.read(pod_git_path)
133
+ json_obj = JSON.parse(json)
134
+ pod_git = json_obj["source"]["git"]
135
+ end
136
+
137
+ #找到库的代码文件
138
+ files_h = Dir.glob("#{item}/**/*.h")
139
+ files_swift = Dir.glob("#{item}/**/*.swift")
140
+ files_m = Dir.glob("#{item}/**/*.{m,mm}")
141
+
142
+ files_h_name = []
143
+ files_h.each do |file|
144
+ files_h_name << File.basename(file)
145
+ end
146
+
147
+ files_swift_name = []
148
+ files_swift.each do |file|
149
+ files_swift_name << File.basename(file)
150
+ end
151
+
152
+ files_m_name = []
153
+ files_m.each do |file|
154
+ files_m_name << File.basename(file)
155
+ end
156
+
157
+ pod_info = RefPodInfo.new(pod_name,version,pod_git,pod_git_path,files_h,files_swift,files_m,files_h_name,files_swift_name,files_m_name)
158
+ pod_info.string
159
+ pods_hash[pod_name] = pod_info
160
+ end
161
+ return pods_hash
162
+ end
163
+
164
+ def self.files(pod_hash)
165
+ files_hash = Hash.new
166
+ tmps = []
167
+ pod_hash.keys.each do |key|
168
+ info = pod_hash[key]
169
+ #忽略第三方库
170
+ if info.git == nil
171
+ tmps << info.name
172
+ next
173
+ end
174
+ files = []
175
+ files += info.files_h
176
+ files += info.files_swift
177
+ files += info.files_m
178
+ files_hash[key] = files
179
+ end
180
+ Tools.log("跳过第三方库 => #{tmps}")
181
+ return files_hash
182
+ end
183
+
184
+ def self.git_paths(pod_hash)
185
+ git_paths = []
186
+ pod_hash.values.each do |pod|
187
+ #忽略第三方库
188
+ if pod.git == nil
189
+ next
190
+ end
191
+ git_paths << pod.git_path
192
+ end
193
+ return git_paths
194
+ end
195
+
196
+ end
197
+ end
198
+ end
199
+
@@ -0,0 +1,118 @@
1
+
2
+ require_relative '../tools/message'
3
+ require_relative '../tools/config'
4
+ require_relative '../tools/clone'
5
+
6
+ require 'find'
7
+
8
+ module Fastlane
9
+ module Sync
10
+
11
+ #脚本生成文件存放地址
12
+ SYNC_PATH = "#{Tools::ROCKET_PATH}sync"
13
+ MAIN_XCODEPROJ_PATH = "#{SYNC_PATH}/xcodeproj"
14
+
15
+
16
+ class SyncMain
17
+ def self.run(params,available_options)
18
+ Tools.formatLog(params,available_options);
19
+ git = ENV["R_SYNC_GIT"]
20
+ branch = ENV["R_SYNC_BRANCH"]
21
+
22
+ Tools.title("拉取壳工程仓库")
23
+ Tools.log("缓存地址 => #{SYNC_PATH}")
24
+ Tools.clone(git,branch,MAIN_XCODEPROJ_PATH,false)
25
+
26
+ Tools.title("同步壳工程")
27
+ #获取壳工程commit
28
+ commit = Tools.return_shell("cd #{MAIN_XCODEPROJ_PATH}&&git rev-parse --short HEAD")
29
+
30
+ #当前脚本执行地址
31
+ pwd_path = Tools.return_shell("pwd")
32
+
33
+ #当前项目的.gitignore
34
+ gitignore_path = "#{pwd_path}/.gitignore"
35
+
36
+ #独立运行文件名
37
+ example = "rocketExample"
38
+
39
+ #独立运行地址
40
+ example_path = "#{pwd_path}/#{example}"
41
+
42
+ #可自定义podfile文件
43
+ yml_path = "#{example_path}/Podfile.yml"
44
+
45
+ #壳工程的Pods文件夹
46
+ pods_path = "#{example_path}/Pods"
47
+
48
+ #壳工程的.git文件夹
49
+ example_git_path = "#{example_path}/.git"
50
+
51
+ #壳工程的.gitlab文件夹
52
+ example_gitlab_path = "#{example_path}/.gitlab"
53
+
54
+ #壳工程的.arcconfig文件
55
+ example_arcconfig_path = "#{example_path}/.arcconfig"
56
+
57
+ #壳工程的.gitignore文件
58
+ example_gitignore_path = "#{example_path}/.gitignore"
59
+
60
+ #壳工程信息 写入Podfile.local
61
+ str = "#壳工程分支:#{branch} 壳工程commit:#{commit}"
62
+ shell_str = "echo '#{str}' >> #{yml_path}"
63
+
64
+ unless File.directory?(example_path)
65
+ Tools.shell("mkdir -p #{example_path}")
66
+ end
67
+
68
+ unless FileTest::exist?(yml_path)
69
+ Tools.shell(shell_str)
70
+ else
71
+ note = Tools.return_shell("fgrep '#壳工程分支' '#{yml_path}'")
72
+ if note == -1
73
+ textAll = File.read(yml_path)
74
+ textAll = str + "\n" + textAll
75
+ f = open("#{yml_path}","w")
76
+ f.puts(textAll)
77
+ f.close
78
+ else
79
+ Tools.shell("sed -i '' \"s/#{note}/#{str}/g\" '#{yml_path}'")
80
+ end
81
+ end
82
+
83
+ #设置yml_path
84
+ # pwd_path = "/Users/leo/Documents/code/iOS/BCLaunchModule"
85
+ podspecs = Dir.glob("#{pwd_path}/*.podspec")
86
+ podspecs.each do |podspec|
87
+ pod_name = File.basename(podspec,".podspec")
88
+ pod_import = "pod '#{pod_name}' ,:path => '../'"
89
+ note = Tools.return_shell("fgrep \"'#{pod_name}'\" '#{yml_path}'")
90
+ if note == -1
91
+ f = open("#{yml_path}","a")
92
+ f.puts("#{pod_import}")
93
+ f.close
94
+ end
95
+ end
96
+
97
+ #删除文件
98
+ Tools.deleteDirPath(example_path,[yml_path,pods_path],example_path)
99
+ #将壳工程文件copy到独立运行地址
100
+ FileUtils.copy_entry(MAIN_XCODEPROJ_PATH,example_path)
101
+ #清理.git等
102
+ Tools.deleteDirPath(example_git_path)
103
+ Tools.deleteDirPath(example_gitlab_path)
104
+ Tools.deleteDirPath(example_arcconfig_path)
105
+ Tools.deleteDirPath(example_gitignore_path)
106
+
107
+ #设置当前项目的.gitignore文件 忽略example
108
+ note = Tools.return_shell("fgrep '#{example}' '#{gitignore_path}'")
109
+ if note == -1
110
+ f = open("#{gitignore_path}","a")
111
+ f.puts("\n#{example}/*\n!#{example}/Podfile.yml")
112
+ f.close
113
+ end
114
+
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'shell'
2
+ require_relative 'message'
3
+ require_relative 'file'
4
+ require 'fileutils'
5
+
6
+ module Fastlane
7
+ module Tools
8
+
9
+ def self.clone(git,branch,path,throw_exception=true)
10
+ #如果存在缓存,就删除缓存
11
+ Tools.delete_path(path)
12
+ url = "git clone #{git} #{path} --template= --single-branch --depth 1 --branch #{branch}"
13
+ status = Tools.shell(url,throw_exception)
14
+ unless status == true
15
+ #--depth 1 , 如果branch没有提交,将会导致拉取失败。去掉--depth 1 解决此问题
16
+ url = "git clone #{git} #{path} --template= --single-branch --branch #{branch}"
17
+ status = Tools.shell(url,throw_exception)
18
+ end
19
+
20
+ Tools.log(url)
21
+ return status
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'openssl'
4
+ require 'open-uri'
5
+
6
+ module Fastlane
7
+ module Tools
8
+ #脚本生成相关文件存放的地址
9
+ ROCKET_PATH = "/Users/Shared/rocket-cache/"
10
+ #源码repo
11
+ SOURCESPECS = "git@gitlab.dushuclub.io:cocoapods/HDSourceSpecs.git"
12
+
13
+
14
+ def self.net_post(api,params)
15
+ url = URI.parse(api)
16
+ http = Net::HTTP.new(url.host, url.port)
17
+ # 设置请求参数
18
+ data = params.to_json
19
+ # 设置请求头
20
+ header = {'content-type':'application/json','PRIVATE-TOKEN':'DSscmq3EPy6QoFw_z3p-'}
21
+
22
+ response = http.post(url, data, header)
23
+ result = JSON.parse(response.body)
24
+ return result
25
+ end
26
+
27
+ def self.net_get(api,params)
28
+ url = URI.parse(api)
29
+ url.query = URI.encode_www_form(params)
30
+ header = {'content-type':'application/json','PRIVATE-TOKEN':'DSscmq3EPy6QoFw_z3p-'}
31
+
32
+ http = Net::HTTP.new(url.host, url.port)
33
+ response = http.get(url, header)
34
+ result = JSON.parse(response.body)
35
+ return result
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ require 'fileutils'
2
+ module Fastlane
3
+ module Tools
4
+
5
+ def self.delete_path(path)
6
+ if File.exist?(path) then
7
+ FileUtils.rm_rf(path)
8
+ end
9
+ end
10
+
11
+ def self.deleteDirPath(dirPath,ignores=[],f="")
12
+ if File.directory?(dirPath)
13
+ Dir.foreach(dirPath) do |subFile|
14
+ if subFile != '.' and subFile != '..'
15
+ deleteDirPath(File.join(dirPath, subFile),ignores,f);
16
+ end
17
+ end
18
+ ignores.each do |i|
19
+ if dirPath == i
20
+ return
21
+ end
22
+ end
23
+ unless f == dirPath
24
+ Dir.rmdir(dirPath);
25
+ end
26
+ else
27
+ ignores.each do |i|
28
+ if dirPath == i
29
+ return
30
+ end
31
+ end
32
+ File.delete(dirPath);
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+
40
+
41
+
42
+
43
+
@@ -0,0 +1,69 @@
1
+ require 'fastlane_core/ui/ui'
2
+
3
+ module Fastlane
4
+ UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
5
+ module Tools
6
+ def self.log(msg)
7
+ if msg == nil
8
+ UI.message("")
9
+ else
10
+ UI.message("rocket-info : #{msg}")
11
+ end
12
+
13
+ end
14
+
15
+ def self.logs(msg,array,number=false)
16
+ unless msg == nil
17
+ title(msg)
18
+ end
19
+ for i in 0..array.size-1
20
+ element = array[i]
21
+ if number == false
22
+ UI.message("rocket-info : #{element}")
23
+ else
24
+ UI.message("rocket-info : #{i+1}.#{element}")
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+
31
+ def self.logh(hash)
32
+ hash.keys.each do |key|
33
+ title(key)
34
+ value = hash[key]
35
+
36
+ if value.is_a? Array
37
+ value.each do |element|
38
+ UI.message("rocket-info : #{element}")
39
+ end
40
+ else
41
+ UI.message("rocket-info : #{value}")
42
+ end
43
+ end
44
+ end
45
+
46
+ def self.title(msg)
47
+ UI.message("")
48
+ UI.message("\033[32mrocket-title : --- #{msg} ---↓↓\033[0m")
49
+ end
50
+
51
+ def self.error(msg)
52
+ UI.user_error!("rocket-error : #{msg}")
53
+ # UI.message("\033[31mrocket-error:#{msg}\033[0m")
54
+ end
55
+
56
+ def self.warning(msg)
57
+ UI.message("\033[33mrocket-warning : --- #{msg} ---↓↓\033[0m")
58
+ end
59
+
60
+ #格式化输出
61
+ def self.formatLog(params,available_options)
62
+ string = []
63
+ available_options.each do |configItem|
64
+ string << "#{configItem.key} => #{params[configItem.key]}"
65
+ end
66
+ logs("参数信息↓↓",string)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,47 @@
1
+ module Fastlane
2
+ module Tools
3
+
4
+ #执行shell命令
5
+ #throw_exception == true 抛出异常
6
+ #throw_exception == false 报错终止命令
7
+ def self.shell(shell,throw_exception=true)
8
+ status = system "#{shell}"
9
+ if throw_exception == false && status == false
10
+ format_shell = "\n\n#{shell.gsub("&&","\n")}\n"
11
+ raise "执行shell命令失败 => #{format_shell} "
12
+ end
13
+ return status
14
+ end
15
+
16
+ #批量执行
17
+ def self.shell_list(shells,throw_exception=true)
18
+ txt = ""
19
+ shells.each do |shell|
20
+ if txt == ""
21
+ txt += "#{shell}"
22
+ else
23
+ txt += "&&#{shell}"
24
+ end
25
+ end
26
+ return shell(txt,throw_exception)
27
+ end
28
+
29
+ #获取shell的返回结果
30
+ def self.return_shell(shell,throw_exception=true)
31
+ code = `#{shell}`.chomp
32
+ status = $?.to_i
33
+ unless status == 0
34
+ if throw_exception == false
35
+ error_log("状态码 => #{status}")
36
+ format_shell = "\n#{shell.gsub("&&","\n")}"
37
+ raise "执行命令失败 => #{format_shell}"
38
+ else
39
+ return -1
40
+ end
41
+ end
42
+ return code
43
+ end
44
+
45
+ end
46
+ end
47
+
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Rocket
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-rocket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - 三块
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-30 00:00:00.000000000 Z
11
+ date: 2021-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -159,8 +159,18 @@ files:
159
159
  - LICENSE
160
160
  - README.md
161
161
  - lib/fastlane/plugin/rocket.rb
162
- - lib/fastlane/plugin/rocket/actions/rocket_action.rb
163
- - lib/fastlane/plugin/rocket/helper/rocket_helper.rb
162
+ - lib/fastlane/plugin/rocket/actions/app_action.rb
163
+ - lib/fastlane/plugin/rocket/actions/ref_action.rb
164
+ - lib/fastlane/plugin/rocket/actions/sync_action.rb
165
+ - lib/fastlane/plugin/rocket/app/app_main.rb
166
+ - lib/fastlane/plugin/rocket/ref/ref_main.rb
167
+ - lib/fastlane/plugin/rocket/ref/ref_pod_info.rb
168
+ - lib/fastlane/plugin/rocket/sync/sync_main.rb
169
+ - lib/fastlane/plugin/rocket/tools/clone.rb
170
+ - lib/fastlane/plugin/rocket/tools/config.rb
171
+ - lib/fastlane/plugin/rocket/tools/file.rb
172
+ - lib/fastlane/plugin/rocket/tools/message.rb
173
+ - lib/fastlane/plugin/rocket/tools/shell.rb
164
174
  - lib/fastlane/plugin/rocket/version.rb
165
175
  homepage:
166
176
  licenses:
@@ -1,47 +0,0 @@
1
- require 'fastlane/action'
2
- require_relative '../helper/rocket_helper'
3
-
4
- module Fastlane
5
- module Actions
6
- class RocketAction < Action
7
- def self.run(params)
8
- UI.message("The rocket plugin is working!")
9
- end
10
-
11
- def self.description
12
- "rocket 支持app打包、组件打包等功能"
13
- end
14
-
15
- def self.authors
16
- ["三块"]
17
- end
18
-
19
- def self.return_value
20
- # If your method provides a return value, you can describe here what it does
21
- end
22
-
23
- def self.details
24
- # Optional:
25
- "rocket 支持app打包、组件打包等功能"
26
- end
27
-
28
- def self.available_options
29
- [
30
- FastlaneCore::ConfigItem.new(key: :"sssss",
31
- env_name: "ROCKET_YOUR_OPTION",
32
- description: "A description of your option",
33
- optional: false,
34
- type: String)
35
- ]
36
- end
37
-
38
- def self.is_supported?(platform)
39
- # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
40
- # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
41
- #
42
- # [:ios, :mac, :android].include?(platform)
43
- true
44
- end
45
- end
46
- end
47
- end
@@ -1,16 +0,0 @@
1
- require 'fastlane_core/ui/ui'
2
-
3
- module Fastlane
4
- UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
5
-
6
- module Helper
7
- class RocketHelper
8
- # class methods that you define here become available in your action
9
- # as `Helper::RocketHelper.your_method`
10
- #
11
- def self.show_message
12
- UI.message("Hello from the rocket plugin helper!")
13
- end
14
- end
15
- end
16
- end