fastlane-plugin-rocket 0.1.0 → 0.1.4

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: 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