ios_double_source 0.1.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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib_blur/core/auto_build.rb +162 -0
- data/lib_blur/core/build_item.rb +39 -0
- data/lib_blur/core/commit.rb +10 -0
- data/lib_blur/core/config.rb +44 -0
- data/lib_blur/core/cost.rb +43 -0
- data/lib_blur/core/git_helper.rb +94 -0
- data/lib_blur/core/github_fork.rb +74 -0
- data/lib_blur/core/github_helper.rb +97 -0
- data/lib_blur/core/gitlab_helper.rb +270 -0
- data/lib_blur/core/hook_manager.rb +21 -0
- data/lib_blur/core/podspec.rb +92 -0
- data/lib_blur/core/push.rb +54 -0
- data/lib_blur/core/repo.rb +161 -0
- data/lib_blur/core/repo_cocoapods.rb +46 -0
- data/lib_blur/core/repo_module.rb +120 -0
- data/lib_blur/core/repo_module_binary.rb +175 -0
- data/lib_blur/core/repo_module_source.rb +155 -0
- data/lib_blur/core/repo_xcode.rb +27 -0
- data/lib_blur/core/repo_xcode_package.rb +199 -0
- data/lib_blur/core/repo_xcode_shell.rb +101 -0
- data/lib_blur/core/util/file_helper.rb +62 -0
- data/lib_blur/core/util/request.rb +50 -0
- data/lib_blur/core/util/string.rb +37 -0
- data/lib_blur/ios_double_source.rb +5 -0
- data/lib_blur/version.rb +4 -0
- metadata +145 -0
@@ -0,0 +1,270 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'gitlab'
|
3
|
+
require 'uri'
|
4
|
+
require_relative 'push'
|
5
|
+
require_relative 'util/string'
|
6
|
+
require_relative 'repo_module'
|
7
|
+
require 'singleton'
|
8
|
+
module Build
|
9
|
+
class GitLabHelper
|
10
|
+
include Singleton
|
11
|
+
attr_accessor :endpoint
|
12
|
+
attr_accessor :private_token
|
13
|
+
attr_accessor :pusher
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
@endpoint = nil
|
17
|
+
@private_token = nil
|
18
|
+
init_endpoint
|
19
|
+
init_private_token
|
20
|
+
init_gitlab
|
21
|
+
end
|
22
|
+
def create_project_if_need(project_name, http_url, private = false , description = nil)
|
23
|
+
puts ""
|
24
|
+
unless is_gitlab_url(http_url)
|
25
|
+
puts "不使用gitlab接口检查和创建项目"
|
26
|
+
return
|
27
|
+
end
|
28
|
+
puts "-> 检查gitlab项目(#{http_url})是否存在"
|
29
|
+
repo_url = http_url.gsub("+", "_")
|
30
|
+
project_obj = fetch_project(project_name, http_url, false)
|
31
|
+
if project_obj
|
32
|
+
puts "已存在 项目ID: #{project_obj.id} 群组:#{project_obj.namespace.id} 无需新建"
|
33
|
+
project_obj.id
|
34
|
+
else
|
35
|
+
puts "不存在 需要创建项目,项目描述: #{description}"
|
36
|
+
do_create_project(project_name, http_url, description, false, private)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def fetch_project(pod_name, http_url, can_raise = true)
|
40
|
+
unless is_gitlab_url(http_url)
|
41
|
+
puts "不使用gitlab接口查询项目ID"
|
42
|
+
return
|
43
|
+
end
|
44
|
+
project_obj = nil
|
45
|
+
projects = Gitlab.project_search(pod_name)
|
46
|
+
projects.each { |project|
|
47
|
+
project_hash = project.to_hash
|
48
|
+
if project.name == pod_name
|
49
|
+
if http_url == project_hash["http_url_to_repo"] or http_url == project_hash["ssh_url_to_repo"] or http_url == project_hash["web_url"]
|
50
|
+
project_obj = project
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
}
|
55
|
+
if not project_obj and can_raise
|
56
|
+
error = "当前配置private_token检索不到#{pod_name},可能是如下原因:\n"
|
57
|
+
error += "1、该组件在git仓库中的名字和#{pod_name}不一致\n"
|
58
|
+
error += "2、打包的该账号在该链接下#{http_url没有}权限,注:添加需要Maintainer权限\n"
|
59
|
+
pusher.push("❌ 打包失败", error)
|
60
|
+
Process.exit(-1)
|
61
|
+
end
|
62
|
+
project_obj
|
63
|
+
end
|
64
|
+
def lock_branch(project_id, branch)
|
65
|
+
res = Gitlab.protected_branches(project_id)
|
66
|
+
res.each { |obj|
|
67
|
+
if obj.name == branch
|
68
|
+
Gitlab.unprotect_branch(project_id, branch)
|
69
|
+
break
|
70
|
+
end
|
71
|
+
}
|
72
|
+
Gitlab.protect_branch(project_id, branch, {allow_force_push: false, push_access_level: 0, merge_access_level: 0})
|
73
|
+
end
|
74
|
+
def do_create_project(pod_name, http_url, description, allow_force_push, private)
|
75
|
+
url = URI(http_url)
|
76
|
+
repo_path = url.path.gsub("/#{pod_name}.git", "")
|
77
|
+
repo_path = repo_path.gsub("#{pod_name}", "")
|
78
|
+
namespace_id = get_project_namespace_id(repo_path)
|
79
|
+
if namespace_id == nil
|
80
|
+
error = "获取namespace_id失败, 无法创建项目"
|
81
|
+
pusher.push("❌ 打包失败", error)
|
82
|
+
Process.exit(-1)
|
83
|
+
end
|
84
|
+
visibility = !!private ? "private" : "internal"
|
85
|
+
puts "创建的项目在群组ID:#{namespace_id} "
|
86
|
+
res = Gitlab.create_project(pod_name, { description: description, initialize_with_readme: true, default_branch: "master", namespace_id: namespace_id, "merge_method":"ff", visibility:visibility})
|
87
|
+
unless res.id
|
88
|
+
error = "创建项目失败"
|
89
|
+
pusher.push("❌ 打包失败", error)
|
90
|
+
Process.exit(-1)
|
91
|
+
end
|
92
|
+
if allow_force_push
|
93
|
+
Gitlab.unprotect_branch(res.id, "master")
|
94
|
+
Gitlab.protect_branch(res.id, "master", allow_force_push: true)
|
95
|
+
end
|
96
|
+
res.id
|
97
|
+
end
|
98
|
+
def get_project_namespace_id(repo_path)
|
99
|
+
puts "仓库命名空间路径:#{repo_path}"
|
100
|
+
group_name = repo_path.split('/').last
|
101
|
+
puts "组名:#{group_name}"
|
102
|
+
groups = Gitlab.group_search(group_name)
|
103
|
+
groups.each { |group|
|
104
|
+
if repo_path.include? group.full_path
|
105
|
+
return group.id
|
106
|
+
end
|
107
|
+
}
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
def branch_contain_commit(project_id, branch, commit)
|
111
|
+
current_page = 1
|
112
|
+
per_page = 20
|
113
|
+
commits = Gitlab.commits(project_id, { ref_name: branch , page:current_page, per_page: per_page})
|
114
|
+
commits.each { |obj|
|
115
|
+
if obj.to_hash["id"] == commit
|
116
|
+
return true
|
117
|
+
end
|
118
|
+
}
|
119
|
+
while commits.size == per_page
|
120
|
+
current_page += 1
|
121
|
+
commits = Gitlab.repo_commits(project_id, { ref_name: branch , page:current_page, per_page: per_page})
|
122
|
+
commits.each { |obj|
|
123
|
+
if obj.to_hash["id"] == commit
|
124
|
+
return true
|
125
|
+
end
|
126
|
+
}
|
127
|
+
end
|
128
|
+
false
|
129
|
+
end
|
130
|
+
def merge_branch(repo_module, target_branch)
|
131
|
+
puts "\n⏩ 开始合并分支到#{target_branch}(#{File.basename(repo_module.path)}):"
|
132
|
+
unless repo_module.ssh_url.is_gitlab_url
|
133
|
+
puts "非gitlab项目, 不支持此功能"
|
134
|
+
return
|
135
|
+
end
|
136
|
+
unless check_merge_branch(repo_module, target_branch)
|
137
|
+
return
|
138
|
+
end
|
139
|
+
project_id = repo_module.project_id
|
140
|
+
Gitlab.edit_project(project_id, { merge_method: 'ff' })
|
141
|
+
sleep 1
|
142
|
+
message = "#ignore_scan# [merge] #{repo_module.branch} => #{target_branch}"
|
143
|
+
merge_request = Gitlab.create_merge_request(project_id, message,{ source_branch: repo_module.branch, target_branch:target_branch})
|
144
|
+
merge_url = "#{self.endpoint}/projects/#{project_id}/merge_requests/#{merge_request.iid}/merge"
|
145
|
+
puts "合并请求的ID: #{merge_request.iid} 链接: #{merge_url}"
|
146
|
+
merge_request = Gitlab.merge_request(project_id, merge_request.iid)
|
147
|
+
merge_status = merge_request.to_hash["merge_status"]
|
148
|
+
state = merge_request.to_hash["state"]
|
149
|
+
can_be_merged = (merge_status == "can_be_merged")
|
150
|
+
retry_count = 0
|
151
|
+
while retry_count <= 60 and not can_be_merged
|
152
|
+
puts "合并请求检查中...(当前状态: #{state} #{merge_status})"
|
153
|
+
merge_request = Gitlab.merge_request(project_id, merge_request.iid)
|
154
|
+
merge_status = merge_request.to_hash["merge_status"]
|
155
|
+
can_be_merged = (merge_status == "can_be_merged")
|
156
|
+
retry_count += 1
|
157
|
+
sleep 2
|
158
|
+
end
|
159
|
+
if state != "opened"
|
160
|
+
error = "自动合并失败, 合并请求状态错误:#{state} #{merge_url}"
|
161
|
+
pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
|
162
|
+
Process.exit(-1)
|
163
|
+
end
|
164
|
+
unless can_be_merged
|
165
|
+
error = "自动合并失败, 检查状态超时: #{merge_status} #{merge_url}"
|
166
|
+
pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
|
167
|
+
Process.exit(-1)
|
168
|
+
end
|
169
|
+
puts "merge_request检查完毕,当前状态:#{state} #{merge_status}"
|
170
|
+
res = Gitlab.accept_merge_request(project_id, merge_request.iid, { merge_commit_message: message })
|
171
|
+
if res.state == "merged"
|
172
|
+
puts "自动合并完毕 #{repo_module.branch} => #{target_branch}"
|
173
|
+
pusher.push("【✅组件合并到#{target_branch}成功】")
|
174
|
+
else
|
175
|
+
error = "自动合并失败, 请检查:#{merge_url}"
|
176
|
+
pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
|
177
|
+
Process.exit(-1)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
private
|
181
|
+
def check_merge_branch(repo_module, target_branch)
|
182
|
+
unless repo_module.build_item.merge_master
|
183
|
+
puts "本次构建 merge_master = false 不执行自动合并"
|
184
|
+
return false
|
185
|
+
end
|
186
|
+
if target_branch == repo_module.branch
|
187
|
+
puts "⚠️ 源分支#{repo_module.branch}和目标分支#{target_branch}指定名字一样, 无需执行合并"
|
188
|
+
return false
|
189
|
+
end
|
190
|
+
unless repo_module.project_id
|
191
|
+
error = "project_id为空,无法执行自动合并"
|
192
|
+
pusher.push("❌ 打包失败", error)
|
193
|
+
Process.exit(-1)
|
194
|
+
end
|
195
|
+
project_id = repo_module.project_id
|
196
|
+
current_page = 1
|
197
|
+
per_page = 20
|
198
|
+
target_commits = Gitlab.commits(project_id, { ref_name: target_branch , page:current_page, per_page: per_page})
|
199
|
+
target_last_commit = target_commits.size > 0 ? target_commits[0].to_hash["id"] : nil
|
200
|
+
unless target_last_commit
|
201
|
+
return true
|
202
|
+
end
|
203
|
+
source_commits = Gitlab.commits(project_id, { ref_name: repo_module.branch, page:current_page, per_page: per_page})
|
204
|
+
source_last_commit = source_commits.size > 0 ? source_commits[0].to_hash["id"] : nil
|
205
|
+
if target_last_commit == source_last_commit
|
206
|
+
puts "⚠️ 源分支#{repo_module.branch}和目标分支#{target_branch}最新提交一致, 无需执行合并"
|
207
|
+
return false
|
208
|
+
end
|
209
|
+
source_commits.each { |obj|
|
210
|
+
if target_last_commit == obj.to_hash["id"]
|
211
|
+
return true
|
212
|
+
end
|
213
|
+
}
|
214
|
+
while source_commits.size == per_page
|
215
|
+
current_page += 1
|
216
|
+
source_commits = Gitlab.repo_commits(project_id, { ref_name: repo_module.branch, page:current_page, per_page: per_page})
|
217
|
+
source_commits.each { |obj|
|
218
|
+
if target_last_commit == obj.to_hash["id"]
|
219
|
+
return true
|
220
|
+
end
|
221
|
+
}
|
222
|
+
end
|
223
|
+
error = "当前分支#{repo_module.branch}落后于#{target_branch}, 请先手动合并分支后再打包并执行自动合并分支"
|
224
|
+
pusher.push("❌ 打包失败", error)
|
225
|
+
Process.exit(-1)
|
226
|
+
end
|
227
|
+
private
|
228
|
+
def is_gitlab_url(http_url)
|
229
|
+
url = URI(http_url)
|
230
|
+
host = url.host
|
231
|
+
unless host
|
232
|
+
puts "❌ 参数http_url:#{http_url}转换出错"
|
233
|
+
return false
|
234
|
+
end
|
235
|
+
unless host.include? "gitlab"
|
236
|
+
puts "❌ 非gitlab项目"
|
237
|
+
return false
|
238
|
+
end
|
239
|
+
true
|
240
|
+
end
|
241
|
+
def init_gitlab
|
242
|
+
Gitlab.configure do |config|
|
243
|
+
config.endpoint = @endpoint
|
244
|
+
config.private_token = @private_token
|
245
|
+
end
|
246
|
+
end
|
247
|
+
def init_endpoint
|
248
|
+
res = %x(git config --global gitlab.apiurl)
|
249
|
+
res = res.delete("\n")
|
250
|
+
if res.length <= 0
|
251
|
+
error = "未读取到配置的gitlabAPI, 请先执行命令配置:git config --global gitlab.apiurl \"xxx\" 示例:https://gitlab.xxx.com/api/v4"
|
252
|
+
pusher.push("❌ 打包失败", error)
|
253
|
+
Process.exit(-1)
|
254
|
+
end
|
255
|
+
puts "读取配置的gitlabAPI地址是:#{res}"
|
256
|
+
@endpoint = res
|
257
|
+
end
|
258
|
+
def init_private_token
|
259
|
+
res = %x(git config --global gitlab.privatetoken)
|
260
|
+
res = res.delete("\n")
|
261
|
+
if res.length <= 0
|
262
|
+
error = "未读取到配置的private_token, 请执行命令配置:git config --global gitlab.privatetoken \"xxx\""
|
263
|
+
pusher.push("❌ 打包失败", error)
|
264
|
+
Process.exit(-1)
|
265
|
+
end
|
266
|
+
puts "读取配置的private_token地址是:#{res}"
|
267
|
+
@private_token = res
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'singleton'
|
3
|
+
module Status
|
4
|
+
XCODE_PACKAGE_COPY_YAML = "XCODE_PACKAGE_COPY_YAML".downcase
|
5
|
+
end
|
6
|
+
class HookManager
|
7
|
+
include Singleton
|
8
|
+
def initialize
|
9
|
+
@hooks = {}
|
10
|
+
end
|
11
|
+
def register_hook(status, &block)
|
12
|
+
@hooks[status] ||= []
|
13
|
+
@hooks[status] << block
|
14
|
+
end
|
15
|
+
def trigger_hook(status, *args)
|
16
|
+
if @hooks[status]
|
17
|
+
puts "\n执行hook阶段#{status}逻辑"
|
18
|
+
@hooks[status].each { |hook| hook.call(*args) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
module Build
|
5
|
+
class Podspec
|
6
|
+
attr_accessor :path
|
7
|
+
attr_accessor :podspec_content
|
8
|
+
def initialize(path)
|
9
|
+
@path = path
|
10
|
+
@podspec_content = update_need_framework
|
11
|
+
end
|
12
|
+
private
|
13
|
+
def update_need_framework
|
14
|
+
code_path = File.dirname(self.path)
|
15
|
+
json = File.read(self.path)
|
16
|
+
podspec_content = JSON.parse(json)
|
17
|
+
need_adds = []
|
18
|
+
framework1 = "CoreServices"
|
19
|
+
contain1 = code_contain_framework(code_path, framework1)
|
20
|
+
if contain1
|
21
|
+
need_adds << framework1
|
22
|
+
puts "⚠️ 源码podspec缺少依赖:s.frameworks '#{framework1}', 已为自动添加"
|
23
|
+
end
|
24
|
+
need_adds.each do |framework|
|
25
|
+
unless podspec_content["frameworks"]
|
26
|
+
podspec_content["frameworks"] = []
|
27
|
+
podspec_content["frameworks"] << framework
|
28
|
+
end
|
29
|
+
if podspec_content["frameworks"].class == String
|
30
|
+
origin = podspec_content["frameworks"]
|
31
|
+
if origin != framework
|
32
|
+
podspec_content["frameworks"] = [origin]
|
33
|
+
podspec_content["frameworks"] << framework
|
34
|
+
end
|
35
|
+
end
|
36
|
+
if podspec_content["frameworks"].class == Array
|
37
|
+
origin = podspec_content["frameworks"]
|
38
|
+
unless origin.include?(framework)
|
39
|
+
podspec_content["frameworks"] << framework
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
podspec_content
|
44
|
+
end
|
45
|
+
def code_contain_framework(code_path, framework)
|
46
|
+
files = Dir["#{code_path}/**/*"]
|
47
|
+
all_reference_pods = []
|
48
|
+
files.each do |file_path_str|
|
49
|
+
file_path = Pathname(file_path_str)
|
50
|
+
extend_name = file_path.extname
|
51
|
+
if not extend_name == ".h" and
|
52
|
+
not extend_name == ".m" and
|
53
|
+
not extend_name == ".mm" and
|
54
|
+
not extend_name == ".pch" and
|
55
|
+
not extend_name == ".c" and
|
56
|
+
not extend_name == ".cc" and
|
57
|
+
not extend_name == ".hpp" and
|
58
|
+
not extend_name == ".cpp"
|
59
|
+
next
|
60
|
+
end
|
61
|
+
reference_pods = pod_in_file(file_path)
|
62
|
+
all_reference_pods = all_reference_pods | reference_pods
|
63
|
+
end
|
64
|
+
all_reference_pods.include?(framework)
|
65
|
+
end
|
66
|
+
def pod_in_file(file_path)
|
67
|
+
reference_pods = []
|
68
|
+
if File.directory?(file_path)
|
69
|
+
return reference_pods
|
70
|
+
end
|
71
|
+
line_array = IO.readlines(file_path)
|
72
|
+
line_array.each_with_index { |line|
|
73
|
+
unless line.start_with?("#import <")
|
74
|
+
next
|
75
|
+
end
|
76
|
+
unless line.include?("/")
|
77
|
+
next
|
78
|
+
end
|
79
|
+
line_split_array = line.split("/")
|
80
|
+
if line_split_array.size < 1
|
81
|
+
next
|
82
|
+
end
|
83
|
+
line_module_name = line_split_array[0].gsub("#import <","")
|
84
|
+
real_module_name = line_module_name.include?("/") ? line_module_name.split("/")[0] : line_module_name #处理有子模块的情况
|
85
|
+
unless reference_pods.include?(real_module_name)
|
86
|
+
reference_pods << real_module_name
|
87
|
+
end
|
88
|
+
}
|
89
|
+
reference_pods
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'config'
|
3
|
+
require_relative 'repo_module'
|
4
|
+
require_relative 'repo_xcode_package'
|
5
|
+
require_relative 'repo_xcode_shell'
|
6
|
+
require 'singleton'
|
7
|
+
module Build
|
8
|
+
class Push
|
9
|
+
include Singleton
|
10
|
+
attr_accessor :sender
|
11
|
+
attr_accessor :repo_module
|
12
|
+
attr_accessor :repo_xcode_shell
|
13
|
+
def setup(sender = nil, repo_module = nil, repo_xcode_shell = nil)
|
14
|
+
@sender = sender
|
15
|
+
@repo_module = repo_module
|
16
|
+
@repo_xcode_shell = repo_xcode_shell
|
17
|
+
end
|
18
|
+
def push(title, summary = nil)
|
19
|
+
if not repo_module or not repo_module.last_commit.committer
|
20
|
+
puts "\n⛔️未获取到仓库信息或提交者信息,不推送以下内容:"
|
21
|
+
puts title
|
22
|
+
puts "-> #{summary}"
|
23
|
+
return
|
24
|
+
end
|
25
|
+
to = repo_module.last_commit.committer
|
26
|
+
content = create_push_content(summary)
|
27
|
+
puts "\n⏩ 开始推送通知流程"
|
28
|
+
log_content = "#{title}\n#{content}\n"
|
29
|
+
puts "即将推送给#{to}如下内容:\n#{log_content}"
|
30
|
+
if @sender
|
31
|
+
@sender.send_msg(to.upcase, title, content.to_s)
|
32
|
+
puts "推送通知完毕流程"
|
33
|
+
else
|
34
|
+
puts "⛔未提供推送配置,不进行推送"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def create_push_content(summary = nil)
|
38
|
+
shell_http_url = repo_xcode_shell ? repo_xcode_shell.http_url : "null"
|
39
|
+
shell_branch = repo_xcode_shell ? repo_xcode_shell.branch : "null"
|
40
|
+
jenkins_url = Build::Config.instance.jenkins_url
|
41
|
+
content = ""
|
42
|
+
content += "🔹组件: #{repo_module.pod_name}\n"
|
43
|
+
content += "🔹版本: #{repo_module.pod_version_final}\n"
|
44
|
+
content += "🔹分支: #{repo_module.branch}\n"
|
45
|
+
content += "🔹提交: #{repo_module.last_commit.commit_msg}\n"
|
46
|
+
content += "🔹组件 地址: #{repo_module.http_url}\n"
|
47
|
+
content += "🔹壳工程地址: #{shell_http_url}\n"
|
48
|
+
content += "🔹壳工程分支: #{shell_branch}\n"
|
49
|
+
content += "🔹打包地址: #{jenkins_url}\n"
|
50
|
+
content += summary ? "🔸摘要: #{summary}\n\n" : "\n"
|
51
|
+
content += "🔹#{Time.new.strftime("%Y-%m-%d %H:%M:%S")}\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'git'
|
3
|
+
require_relative 'gitlab_helper'
|
4
|
+
require_relative 'commit'
|
5
|
+
require_relative 'push'
|
6
|
+
require_relative 'git_helper'
|
7
|
+
require_relative 'util/file_helper'
|
8
|
+
module Build
|
9
|
+
class Repo
|
10
|
+
attr_reader :page_url
|
11
|
+
attr_reader :http_url
|
12
|
+
attr_reader :ssh_url
|
13
|
+
attr_reader :branch
|
14
|
+
attr_accessor :gitlab_helper
|
15
|
+
attr_accessor :pusher
|
16
|
+
attr_accessor :user_name
|
17
|
+
attr_accessor :user_email
|
18
|
+
attr_accessor :repo_path
|
19
|
+
attr_accessor :path
|
20
|
+
attr_accessor :last_commit
|
21
|
+
attr_accessor :size
|
22
|
+
attr_accessor :size_format
|
23
|
+
def initialize(path, ssh_url, branch = nil)
|
24
|
+
@ssh_url = ssh_url.to_s
|
25
|
+
@branch = branch.to_s
|
26
|
+
@path = path.to_s
|
27
|
+
@repo_path = Pathname.new(path.to_s)
|
28
|
+
@user_name = "jenkins"
|
29
|
+
@user_email = "jenkins@jenkins.com"
|
30
|
+
@last_commit = Commit.new
|
31
|
+
@pusher = Push.instance
|
32
|
+
__validate
|
33
|
+
end
|
34
|
+
public
|
35
|
+
def git_clone(only_head)
|
36
|
+
puts "\n(#{File.basename(self.path)})下载[#{self.ssh_url}] [#{self.branch}] [#{only_head ? "深度1" : "全量"}]"
|
37
|
+
options = only_head ? {:depth => 1} : {}
|
38
|
+
Git.clone(self.ssh_url, self.repo_path, branch: self.branch, options: options)
|
39
|
+
repo = Git.open(self.repo_path)
|
40
|
+
repo.config('user.name', user_name)
|
41
|
+
repo.config('user.email', user_email)
|
42
|
+
puts "完成"
|
43
|
+
log = Git::Log.new(repo).first
|
44
|
+
if log
|
45
|
+
committer = log.committer
|
46
|
+
puts "最近提交记录: [#{log.sha}] [#{log.message}] [#{committer.date}] [#{committer.name}] [#{committer.email}]"
|
47
|
+
last_commit.commit_id = log.sha
|
48
|
+
last_commit.commit_msg = log.message
|
49
|
+
last_commit.committer = committer.name
|
50
|
+
last_commit.commit_mail = committer.email
|
51
|
+
last_commit.commit_time = committer.date.strftime("%Y-%m-%d %H:%M:%S")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
def git_status
|
55
|
+
GitHelper.status(self.path)
|
56
|
+
end
|
57
|
+
def git_pull
|
58
|
+
GitHelper.pull(self.path)
|
59
|
+
end
|
60
|
+
def git_add_stag
|
61
|
+
GitHelper.add_stag(self.path)
|
62
|
+
end
|
63
|
+
def git_commit(commit_msg = nil)
|
64
|
+
GitHelper.commit(self.path, commit_msg)
|
65
|
+
end
|
66
|
+
def git_push
|
67
|
+
GitHelper.push(self.path, self.branch)
|
68
|
+
end
|
69
|
+
def git_push_f
|
70
|
+
GitHelper.push_f(self.path, self.branch)
|
71
|
+
end
|
72
|
+
def git_push_tags
|
73
|
+
GitHelper.push_tags(self.path)
|
74
|
+
end
|
75
|
+
def git_reset_hard
|
76
|
+
GitHelper.reset_hard(self.path)
|
77
|
+
end
|
78
|
+
def git_fetch
|
79
|
+
GitHelper.fetch(self.path)
|
80
|
+
end
|
81
|
+
def git_checkout(checkout_branch)
|
82
|
+
GitHelper.checkout(self.path, checkout_branch)
|
83
|
+
end
|
84
|
+
def git_tag_delete_local(tag)
|
85
|
+
GitHelper.tag_delete_local(self.path, tag)
|
86
|
+
end
|
87
|
+
def git_tag_delete_origin(tag)
|
88
|
+
GitHelper.tag_delete_origin(path, tag)
|
89
|
+
end
|
90
|
+
def git_tag_local(tag)
|
91
|
+
GitHelper.tag_local(self.path, tag)
|
92
|
+
end
|
93
|
+
def git_tag_origin(tag)
|
94
|
+
GitHelper.tag_origin(self.path, tag)
|
95
|
+
end
|
96
|
+
def discard_pull
|
97
|
+
current = Dir.pwd
|
98
|
+
Dir.chdir(self.path)
|
99
|
+
puts "丢弃修改并拉取代码"
|
100
|
+
git_add_stag
|
101
|
+
git_reset_hard
|
102
|
+
git_fetch
|
103
|
+
git_checkout(branch)
|
104
|
+
git_pull
|
105
|
+
Dir.chdir(current)
|
106
|
+
end
|
107
|
+
def push_code
|
108
|
+
puts "\n⏩ 推送产物(#{File.basename(self.path)})"
|
109
|
+
git_pull
|
110
|
+
if git_status
|
111
|
+
git_add_stag
|
112
|
+
git_commit(nil)
|
113
|
+
git_push
|
114
|
+
end
|
115
|
+
end
|
116
|
+
def clear
|
117
|
+
current = Dir.pwd
|
118
|
+
Dir.chdir(self.path)
|
119
|
+
command = 'ls | xargs rm -rf'
|
120
|
+
puts "-> 清空仓库(#{File.basename(self.path)}):#{command}"
|
121
|
+
system command
|
122
|
+
Dir.chdir(current)
|
123
|
+
end
|
124
|
+
def page_url
|
125
|
+
http_url.gsub(".git","")
|
126
|
+
end
|
127
|
+
def http_url
|
128
|
+
if ssh_url.start_with?"git@"
|
129
|
+
repo_url = ssh_url.gsub(":","/")
|
130
|
+
repo_url = repo_url.gsub("git@","http://")
|
131
|
+
return repo_url
|
132
|
+
end
|
133
|
+
ssh_url
|
134
|
+
end
|
135
|
+
def size
|
136
|
+
file_array = Array.new
|
137
|
+
FileHelper.recursion_files(self.path, file_array)
|
138
|
+
size = 0
|
139
|
+
file_array.each { |file|
|
140
|
+
size += File.size(file)
|
141
|
+
}
|
142
|
+
@size = size*0.001
|
143
|
+
end
|
144
|
+
def size_format
|
145
|
+
self.size > 1024 ? "#{(self.size * 0.001).round(1).to_s}MB": "#{self.size.round(0).to_s}KB"
|
146
|
+
end
|
147
|
+
private
|
148
|
+
def __validate
|
149
|
+
if ssh_url.to_s.empty? or not ssh_url.to_s.start_with?("git@")
|
150
|
+
error = "repo初始化参数ssh_url必须不能为空, 且是ssh地址"
|
151
|
+
pusher.push("❌ 打包失败", error)
|
152
|
+
Process.exit(-1)
|
153
|
+
end
|
154
|
+
if path.to_s.empty?
|
155
|
+
error = "目标路径为空, 请先设置路径"
|
156
|
+
pusher.push("❌ 打包失败", error)
|
157
|
+
Process.exit(-1)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'repo'
|
3
|
+
require_relative 'repo_module'
|
4
|
+
module Build
|
5
|
+
class RepoCocoapods < Repo
|
6
|
+
attr_accessor :repo_module
|
7
|
+
def pod_name_versions(pod_name)
|
8
|
+
pod_name_path = "#{self.path}/#{pod_name}"
|
9
|
+
unless File.directory?(pod_name_path)
|
10
|
+
return nil
|
11
|
+
end
|
12
|
+
entries = Dir.entries(pod_name_path)
|
13
|
+
entries.select { |entry| entry != '.' && entry != '..' }
|
14
|
+
end
|
15
|
+
def copy_podspec(repo_module)
|
16
|
+
@repo_module = repo_module
|
17
|
+
puts "\n⏩ 拷贝podspec文件到cocoapods中(#{File.basename(self.path)}):"
|
18
|
+
pod_name = repo_module.pod_name
|
19
|
+
pod_version_final = repo_module.pod_version_final
|
20
|
+
pod_name_path = "#{self.path}/#{pod_name}"
|
21
|
+
unless File.directory?(pod_name_path)
|
22
|
+
Dir.mkdir(pod_name_path)
|
23
|
+
end
|
24
|
+
pod_version_path = "#{pod_name_path}/#{pod_version_final}"
|
25
|
+
if File.directory?(pod_version_path)
|
26
|
+
if not repo_module.build_item.snapshot and not repo_module.third
|
27
|
+
error = "#{pod_name}已发布相同版本#{pod_version_final},请更换更高的版本号"
|
28
|
+
pusher.push("❌ 打包失败", error)
|
29
|
+
Process.exit(-1)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
Dir.mkdir(pod_version_path)
|
33
|
+
end
|
34
|
+
FileUtils.cp(repo_module.podspec_json_path, pod_version_path)
|
35
|
+
podspec_path = "#{pod_version_path}/#{pod_name}.podspec"
|
36
|
+
if File.exist?(podspec_path)
|
37
|
+
FileUtils.rm(podspec_path)
|
38
|
+
end
|
39
|
+
puts "拷贝完毕"
|
40
|
+
end
|
41
|
+
def git_commit(commit_msg = nil)
|
42
|
+
commit_msg = repo_module.get_commit_msg
|
43
|
+
super commit_msg
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|