Class: MGit::Init
Constant Summary
collapse
- OPT_LIST =
{
:git_source => '--git-source',
:git_source_s => '-g',
:config_source => '--config-source',
:config_source_s => '-f',
:branch => '--branch',
:branch_s => '-b',
:local_config => '--local-config',
:local_config_s => '-l',
:all => '--all',
:all_s => '-a'
}.freeze
Constants inherited
from BaseCommand
BaseCommand::HIGH_PRIORITY_OPT_LIST, BaseCommand::SELECTABLE_OPT_LIST
Class Method Summary
collapse
Instance Method Summary
collapse
-
#clone_sub_repos(repo_list, default_branch) ⇒ Object
-
#clone_with_git_url(git_url, branch, use_local, clone_all) ⇒ Object
-
#clone_with_local_config(config_path, clone_all) ⇒ Object
-
#enable_short_basic_option ⇒ Object
-
#execute(argv) ⇒ Object
-
#finish_init(config) ⇒ Object
-
#init_dir ⇒ Object
-
#initial_multi_repo_root ⇒ Object
-
#link_config(config_path, config_cache_path, root) ⇒ Object
-
#move_project_to_root ⇒ Object
-
#options ⇒ Object
-
#post_exec ⇒ Object
-
#pre_exec ⇒ Object
-
#setup_hooks(pre_hook_path, post_hook_path, manifest_hook_path, post_download_hook) ⇒ Object
-
#setup_local_config(path, config_repo, use_local) ⇒ Object
-
#terminate!(msg) ⇒ Object
-
#validate(argv) ⇒ Object
-
#write_content(path, content) ⇒ Object
Methods inherited from BaseCommand
#all_repos, cmd, #exec_light_repos, #generate_config_repo, inherited, #initialize, #locked_repos, #run
Class Method Details
.description ⇒ Object
316
317
318
|
# File 'lib/m-git/command/init.rb', line 316
def self.description
"初始化多仓库目录。"
end
|
.usage ⇒ Object
320
321
322
|
# File 'lib/m-git/command/init.rb', line 320
def self.usage
"mgit init (-f <path> | -g <url> [-b <branch>] [-l]) [-a]"
end
|
Instance Method Details
#clone_sub_repos(repo_list, default_branch) ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
# File 'lib/m-git/command/init.rb', line 222
def clone_sub_repos(repo_list, default_branch)
if repo_list.length != 0
Output.puts_processing_message("正在克隆子仓库...")
try_repos = repo_list
retry_repos = []
error_repos = {}
mutex = Mutex.new
mutex_progress = Mutex.new
task_count = 0
total_try_count = 4
total_retry_count = total_try_count - 1
total_try_count.times { |try_count|
Workspace.concurrent_enumerate(try_repos) { |light_repo|
branch = light_repo.branch ? light_repo.branch : default_branch
Utils.execute_shell_cmd(light_repo.clone_url(Workspace.root, clone_branch:branch)) { |stdout, stderr, status|
repo_dir = light_repo.abs_dest(Workspace.root)
if status.success?
Utils.link_git(repo_dir, light_repo.git_store_dir(Workspace.root))
mutex_progress.lock
task_count += 1
Output.puts_success_message("(#{task_count}/#{try_repos.length}) \"#{light_repo.name}\"克隆完成!")
mutex_progress.unlock
else
Output.puts_remind_message("\"#{light_repo.name}\"克隆失败,已加入重试队列。") if try_count < total_retry_count
mutex.lock
retry_repos.push(light_repo)
error_repos[light_repo.name] = stderr
FileUtils.remove_dir(repo_dir, true) if Dir.exist?(repo_dir)
mutex.unlock
end
}
}
if retry_repos.length == 0 || try_count >= total_retry_count
break
else
Output.puts_processing_block(error_repos.keys, "以上仓库克隆失败,开始第#{try_count + 1}次重试(最多#{total_retry_count}次)...")
try_repos = retry_repos
retry_repos = []
error_repos = {}
task_count = 0
end
}
if error_repos.length > 0
Workspace.show_error(error_repos)
terminate!("初始化停止,请重试!")
end
end
end
|
#clone_with_git_url(git_url, branch, use_local, clone_all) ⇒ Object
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/m-git/command/init.rb', line 152
def clone_with_git_url(git_url, branch, use_local, clone_all)
central_repo_temp_path = File.join(Workspace.root, Constants::CENTRAL_REPO)
Output.puts_processing_message("正在克隆主仓库...")
Utils.execute_shell_cmd("git clone -b #{branch.nil? ? 'master' : branch} -- #{git_url} #{central_repo_temp_path}") { |stdout, stderr, status|
if status.success?
begin
config = Manifest.parse(central_repo_temp_path, strict_mode:false)
rescue Error => e
terminate!(e.msg)
end
central_light_repo = config.config_repo
terminate!("配置文件中未找到主仓库配置,请添加后重试!") if central_light_repo.nil?
terminate!("配置文件中主仓库url与传入的url不一致, 请处理后重试!") if git_url != central_light_repo.url
central_repo_dest_path = central_light_repo.abs_dest(Workspace.root)
if Dir.exist?(central_repo_dest_path) && !central_repo_temp_path.include?(central_repo_dest_path)
FileUtils.remove_dir(central_repo_dest_path, true)
end
FileUtils.mkdir_p(central_repo_dest_path)
mv_cmd = "mv #{central_repo_temp_path + '/{*,.[^.]*}'} #{central_repo_dest_path}"
`#{mv_cmd}`
FileUtils.rm_rf(central_repo_temp_path)
Utils.link_git(central_repo_dest_path, central_light_repo.git_store_dir(Workspace.root))
Output.puts_success_message("主仓库克隆完成!")
setup_local_config(File.join(central_repo_dest_path, Constants::CONFIG_FILE_NAME[:local_manifest]), central_light_repo.name, use_local)
begin
config = Manifest.parse(central_repo_dest_path, strict_mode:false)
rescue Error => e
terminate!(e.msg)
end
clone_sub_repos(config.repo_list(exclusion:[config.config_repo.name], all:clone_all), branch)
finish_init(config)
else
terminate!("主仓库克隆失败,初始化停止,请重试:\n#{stderr}")
end
}
end
|
#clone_with_local_config(config_path, clone_all) ⇒ Object
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'lib/m-git/command/init.rb', line 203
def clone_with_local_config(config_path, clone_all)
terminate!("指定路径\"#{config_path}\"文件不存在!") if !File.exist?(config_path)
begin
config = Manifest.parse(Utils.expand_path(config_path), strict_mode:false)
rescue Error => e
terminate!(e.msg)
end
if !config.config_repo.nil?
clone_list = config.repo_list(exclusion: [config.config_repo.name], all:clone_all)
else
clone_list = config.repo_list(all:clone_all)
end
clone_sub_repos(clone_list, 'master')
finish_init(config)
end
|
#enable_short_basic_option ⇒ Object
312
313
314
|
# File 'lib/m-git/command/init.rb', line 312
def enable_short_basic_option
true
end
|
#execute(argv) ⇒ Object
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/m-git/command/init.rb', line 81
def execute(argv)
init_dir
begin
git_url_opt = argv.opt(OPT_LIST[:git_source])
local_url_opt = argv.opt(OPT_LIST[:config_source])
clone_all = argv.opt_list.did_set_opt?(OPT_LIST[:all])
if !git_url_opt.nil?
git_url = git_url_opt.value
branch = argv.opt(OPT_LIST[:branch]).value if argv.opt_list.did_set_opt?(OPT_LIST[:branch])
use_local = argv.opt_list.did_set_opt?(OPT_LIST[:local_config])
clone_with_git_url(git_url, branch, use_local, clone_all)
elsif !local_url_opt.nil?
clone_with_local_config(local_url_opt.value, clone_all)
end
rescue Interrupt => e
terminate!(e.message)
end
end
|
#finish_init(config) ⇒ Object
306
307
308
309
310
|
# File 'lib/m-git/command/init.rb', line 306
def finish_init(config)
move_project_to_root
config_path, config_cache_path = config.path.sub(Workspace.root, @origin_root), config.cache_path.sub(Workspace.root, @origin_root)
link_config(config_path, config_cache_path, @origin_root)
end
|
#init_dir ⇒ Object
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/m-git/command/init.rb', line 101
def init_dir
Constants::PROJECT_DIR.each { |key, relative_dir|
abs_dir = File.join(Workspace.root, relative_dir)
FileUtils.mkdir_p(abs_dir)
if key == :hooks
setup_hooks(File.join(abs_dir, Constants::HOOK_NAME[:pre_hook]),
File.join(abs_dir, Constants::HOOK_NAME[:post_hook]),
File.join(abs_dir, Constants::HOOK_NAME[:manifest_hook]),
File.join(abs_dir, Constants::HOOK_NAME[:post_download_hook]))
end
}
end
|
#initial_multi_repo_root ⇒ Object
#link_config(config_path, config_cache_path, root) ⇒ Object
278
279
280
281
282
283
284
285
286
287
|
# File 'lib/m-git/command/init.rb', line 278
def link_config(config_path, config_cache_path, root)
Utils.execute_under_dir("#{File.join(root, Constants::PROJECT_DIR[:source_config])}") {
config_link_path = File.join(Dir.pwd, Constants::CONFIG_FILE_NAME[:manifest])
Utils.link(config_path, config_link_path) if config_path != config_link_path
FileUtils.mv(config_cache_path, Dir.pwd) if File.dirname(config_cache_path) != Dir.pwd
}
end
|
#move_project_to_root ⇒ Object
297
298
299
300
301
302
303
304
|
# File 'lib/m-git/command/init.rb', line 297
def move_project_to_root
Dir.foreach(Workspace.root) { |item|
if item != '.' && item != '..' && item != '.DS_Store'
FileUtils.mv(File.join(Workspace.root, item), @origin_root, force: true)
end
}
FileUtils.remove_dir(Workspace.root, true) if Dir.exist?(Workspace.root)
end
|
#options ⇒ Object
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/m-git/command/init.rb', line 22
def options
return [
ARGV::Opt.new(OPT_LIST[:git_source],
short_key:OPT_LIST[:git_source_s],
info:'通过包含多仓库配置表的git仓库来初始化,传入远程仓库地址,如:"mgit init -g https://[email protected]/someone"。不可与"-f","--config-source"同时指定。',
type: :string),
ARGV::Opt.new(OPT_LIST[:config_source],
short_key:OPT_LIST[:config_source_s],
info:'通过本地的多仓库配置表来初始化,传入本地配置文件路径,如:"mgit init -f <local_config_path>/manifest.json"。不可与"-g","--git-source"同时指定。',
type: :string),
ARGV::Opt.new(OPT_LIST[:branch],
short_key:OPT_LIST[:branch_s],
info:'指定配置仓库克隆分支。',
type: :string),
ARGV::Opt.new(OPT_LIST[:local_config],
short_key:OPT_LIST[:local_config_s],
info:'指定是否自动生成本地配置文件模版。指定后会在主仓库下生成名为local_manifest.json的本地配置文件,其内容只包含主仓库信息,并指定其余仓库不纳入mgit管理。初始化时指定该参数将只下载主仓库,若同时指定了"-a"或"--all",则其余仓库也会被下载。',
type: :boolean),
ARGV::Opt.new(OPT_LIST[:all],
short_key:OPT_LIST[:all_s],
info:'指定后会下载所有在配置表中配置了远程地址的仓库,无论该仓库是否被纳入mgit管理(无论是否指定"mgit_excluded:true")。',
type: :boolean)
].concat(super)
end
|
#setup_hooks(pre_hook_path, post_hook_path, manifest_hook_path, post_download_hook) ⇒ Object
#setup_local_config(path, config_repo, use_local) ⇒ Object
#terminate!(msg) ⇒ Object
#validate(argv) ⇒ Object
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/m-git/command/init.rb', line 47
def validate(argv)
Foundation.help!("输入非法参数:#{argv.git_opts}") if argv.git_opts.length > 0
git_source_opt = argv.opt(OPT_LIST[:git_source])
file_source_opt = argv.opt(OPT_LIST[:config_source])
if !git_source_opt.nil? && !file_source_opt.nil?
Foundation.help!("不能同时指定参数\"#{OPT_LIST[:git_source]}\"和\"#{OPT_LIST[:config_source]}!\"")
elsif git_source_opt.nil? && file_source_opt.nil?
Foundation.help!("缺失参数\"#{OPT_LIST[:git_source]}\"或\"#{OPT_LIST[:config_source]}!\"")
end
end
|
#write_content(path, content) ⇒ Object
114
115
116
117
118
119
120
|
# File 'lib/m-git/command/init.rb', line 114
def write_content(path, content)
file = File.new(path, 'w')
if !file.nil?
file.write(content)
file.close
end
end
|