m-git 2.5.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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +85 -0
  4. data/lib/m-git.rb +66 -0
  5. data/lib/m-git/argv.rb +170 -0
  6. data/lib/m-git/argv/opt.rb +38 -0
  7. data/lib/m-git/argv/opt_list.rb +71 -0
  8. data/lib/m-git/argv/parser.rb +66 -0
  9. data/lib/m-git/base_command.rb +271 -0
  10. data/lib/m-git/command/add.rb +41 -0
  11. data/lib/m-git/command/branch.rb +90 -0
  12. data/lib/m-git/command/checkout.rb +106 -0
  13. data/lib/m-git/command/clean.rb +64 -0
  14. data/lib/m-git/command/commit.rb +84 -0
  15. data/lib/m-git/command/config.rb +202 -0
  16. data/lib/m-git/command/delete.rb +99 -0
  17. data/lib/m-git/command/fetch.rb +32 -0
  18. data/lib/m-git/command/forall.rb +81 -0
  19. data/lib/m-git/command/info.rb +74 -0
  20. data/lib/m-git/command/init.rb +324 -0
  21. data/lib/m-git/command/log.rb +73 -0
  22. data/lib/m-git/command/merge.rb +381 -0
  23. data/lib/m-git/command/pull.rb +364 -0
  24. data/lib/m-git/command/push.rb +311 -0
  25. data/lib/m-git/command/rebase.rb +348 -0
  26. data/lib/m-git/command/reset.rb +31 -0
  27. data/lib/m-git/command/self.rb +223 -0
  28. data/lib/m-git/command/stash.rb +189 -0
  29. data/lib/m-git/command/status.rb +135 -0
  30. data/lib/m-git/command/sync.rb +327 -0
  31. data/lib/m-git/command/tag.rb +67 -0
  32. data/lib/m-git/command_manager.rb +24 -0
  33. data/lib/m-git/error.rb +20 -0
  34. data/lib/m-git/foundation.rb +25 -0
  35. data/lib/m-git/foundation/constants.rb +107 -0
  36. data/lib/m-git/foundation/dir.rb +25 -0
  37. data/lib/m-git/foundation/duration_recorder.rb +92 -0
  38. data/lib/m-git/foundation/git_message_parser.rb +50 -0
  39. data/lib/m-git/foundation/lock.rb +32 -0
  40. data/lib/m-git/foundation/loger.rb +129 -0
  41. data/lib/m-git/foundation/mgit_config.rb +222 -0
  42. data/lib/m-git/foundation/operation_progress_manager.rb +139 -0
  43. data/lib/m-git/foundation/timer.rb +74 -0
  44. data/lib/m-git/foundation/utils.rb +361 -0
  45. data/lib/m-git/hooks_manager.rb +96 -0
  46. data/lib/m-git/manifest.rb +181 -0
  47. data/lib/m-git/manifest/cache_manager.rb +44 -0
  48. data/lib/m-git/manifest/internal.rb +182 -0
  49. data/lib/m-git/manifest/light_repo.rb +108 -0
  50. data/lib/m-git/manifest/light_repo_generator.rb +87 -0
  51. data/lib/m-git/manifest/linter.rb +153 -0
  52. data/lib/m-git/open_api.rb +427 -0
  53. data/lib/m-git/open_api/script_download_info.rb +37 -0
  54. data/lib/m-git/output/output.rb +461 -0
  55. data/lib/m-git/plugin_manager.rb +112 -0
  56. data/lib/m-git/repo.rb +133 -0
  57. data/lib/m-git/repo/status.rb +481 -0
  58. data/lib/m-git/repo/sync_helper.rb +254 -0
  59. data/lib/m-git/template.rb +9 -0
  60. data/lib/m-git/template/local_manifest.rb +27 -0
  61. data/lib/m-git/template/manifest_hook.rb +28 -0
  62. data/lib/m-git/template/post_download_hook.rb +29 -0
  63. data/lib/m-git/template/post_hook.rb +31 -0
  64. data/lib/m-git/template/pre_exec_hook.rb +31 -0
  65. data/lib/m-git/template/pre_hook.rb +29 -0
  66. data/lib/m-git/template/pre_push_hook.rb +32 -0
  67. data/lib/m-git/version.rb +6 -0
  68. data/lib/m-git/workspace.rb +648 -0
  69. data/lib/m-git/workspace/path_helper.rb +56 -0
  70. data/lib/m-git/workspace/workspace_helper.rb +159 -0
  71. data/m-git +1 -0
  72. data/mgit +19 -0
  73. metadata +218 -0
@@ -0,0 +1,67 @@
1
+ #coding=utf-8
2
+
3
+ module MGit
4
+
5
+ # @!scope 类似 git tag
6
+ #
7
+ class Tag < BaseCommand
8
+
9
+ def execute(argv)
10
+ Workspace.check_branch_consistency
11
+
12
+ Output.puts_start_cmd
13
+
14
+ exec_repos = all_repos + locked_repos
15
+
16
+ if argv.git_opts.empty?
17
+ _, error_repos = Workspace.execute_git_cmd_with_repos(argv.cmd, argv.git_opts, exec_repos)
18
+ Output.puts_succeed_cmd(argv.absolute_cmd) if error_repos.length == 0
19
+ return
20
+ end
21
+
22
+ error_repos = {}
23
+ no_tag_repos = []
24
+ exec_repos.each { |repo|
25
+ success, output = repo.execute_git_cmd(argv.cmd, argv.git_opts)
26
+ if success
27
+ tags = output.split("\n")
28
+ if tags.length > 0
29
+ puts Output.generate_title_block(repo.name) {
30
+ Output.generate_table(tags, separator:"")
31
+ }
32
+ else
33
+ no_tag_repos.push(repo.name)
34
+ end
35
+ else
36
+ error_repos[repo.name] = output
37
+ end
38
+ }
39
+
40
+ if no_tag_repos.length > 0
41
+ puts "\n"
42
+ Output.puts_remind_block(no_tag_repos, "以上仓库尚未创建tag!")
43
+ end
44
+
45
+ if error_repos.length > 0
46
+ Workspace.show_error(error_repos)
47
+ else
48
+ Output.puts_succeed_cmd(argv.absolute_cmd)
49
+ end
50
+
51
+ end
52
+
53
+ def enable_repo_selection
54
+ true
55
+ end
56
+
57
+ def self.description
58
+ "增删查或验证标签。增加标签示例:mgit tag -a 'v0.0.1' -m 'Tag description message'"
59
+ end
60
+
61
+ def self.usage
62
+ "mgit tag [<git-tag-option>] [(--mrepo|--el-mrepo) <repo>...] [--help]"
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module MGit
3
+ class CommandManager
4
+ class << self
5
+ # cmd generate
6
+ #
7
+ def commands
8
+ @commands ||= {}
9
+ end
10
+
11
+ def register_command(cmd, cls)
12
+ commands[cmd] = cls
13
+ end
14
+
15
+ def [](cmd)
16
+ class_with_command(cmd)
17
+ end
18
+
19
+ def class_with_command(cmd)
20
+ commands[cmd]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ #coding=utf-8
2
+
3
+ module MGit
4
+
5
+ MGIT_ERROR_TYPE = {
6
+ :config_name_error => 'config_name_error',
7
+ :config_generate_error => 'config_generate_error'
8
+ }.freeze
9
+
10
+ class Error < StandardError
11
+ attr_reader :msg
12
+ attr_reader :type
13
+
14
+ def initialize(msg, type:nil)
15
+ @msg = msg
16
+ @type = type
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,25 @@
1
+ #coding=utf-8
2
+
3
+ require 'm-git/foundation/constants'
4
+ require 'm-git/foundation/dir'
5
+ require 'm-git/foundation/git_message_parser'
6
+ require 'm-git/foundation/lock'
7
+ require 'm-git/foundation/loger'
8
+ require 'm-git/foundation/duration_recorder'
9
+ require 'm-git/foundation/mgit_config'
10
+ require 'm-git/foundation/operation_progress_manager'
11
+ require 'm-git/foundation/timer'
12
+ require 'm-git/foundation/utils'
13
+
14
+ module MGit
15
+ module Foundation
16
+
17
+ class << self
18
+ # 异常终止
19
+ def help!(msg, title:nil)
20
+ Output.puts_terminate_message(msg, title:title)
21
+ exit
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,107 @@
1
+ #coding=utf-8
2
+
3
+ module MGit
4
+ module Constants
5
+ PROJECT_DIR = {
6
+ :hooks => '.mgit/hooks',
7
+ :source_config => '.mgit/source-config',
8
+ :source_git => '.mgit/source-git',
9
+ :snapshot => '.mgit/snapshot',
10
+ :log_dir => '.mgit/logs'
11
+ }.freeze
12
+
13
+ HOOK_NAME = {
14
+ :pre_hook => 'pre_hook.rb',
15
+ :post_hook => 'post_hook.rb',
16
+ :manifest_hook => 'manifest_hook.rb',
17
+ :post_download_hook => 'post_download_hook.rb',
18
+ :pre_push_hook => 'pre_push_hook.rb',
19
+ :pre_exec_hook => 'pre_exec_hook.rb'
20
+ }.freeze
21
+
22
+ MGIT_CONFIG_PATH = ".mgit/config.yml"
23
+
24
+ CONFIG_FILE_NAME = {
25
+ :manifest => 'manifest.json',
26
+ :manifest_cache => '.manifest_cache.json',
27
+ :local_manifest => 'local_manifest.json'
28
+ }.freeze
29
+
30
+ # 全局配置
31
+ CONFIG_KEY = {
32
+ # [String] 包含仓库的文件夹相对.mgit目录路径,完整路径如:<.mgit所在路径>/dest/<repo_name>,与abs-dest同时指定时无效
33
+ :dest => 'dest',
34
+ # [Boolean] 是否将所有仓库排除mgit管理
35
+ :mgit_excluded => 'mgit-excluded',
36
+ # [String] 远程仓库根目录,完整URL:remote/remote_path
37
+ :remote => 'remote',
38
+ # [String] 远程仓库相对目录,完整URL:remote/remote_path
39
+ :repositories => 'repositories',
40
+ # [String] mgit版本
41
+ :version => 'version',
42
+ }.freeze
43
+
44
+ # 仓库配置
45
+ REPO_CONFIG_KEY = {
46
+ # [String] 仓库完整路径
47
+ :abs_dest => 'abs-dest',
48
+ # [Boolean] 是否是配置仓库
49
+ :config_repo => 'config-repo',
50
+ # [String] 包含仓库的文件夹相对.mgit目录路径,完整路径如:<.mgit所在路径>/dest/<repo_name>,与abs-dest同时指定时无效
51
+ :dest => 'dest',
52
+ # [Boolean] 是否是占位仓库,占位操作不会让mgit进行常规操作(隐含指定mgit_excluded为true),标记为占位的仓库组装器组装时不需要使用
53
+ :dummy => 'dummy',
54
+ # [Json] 锁定状态,见REPO_CONFIG_LOCK_KEY
55
+ :lock => 'lock',
56
+ # [Boolean] 是否排除mgit管理,被排除的仓库不会让mgit进行常规操作,若未标记dummy,则为不被mgit管理,但组装器需要的仓库
57
+ :mgit_excluded => 'mgit-excluded',
58
+ # [String] 远程仓库根目录,完整URL:remote/remote_path
59
+ :remote => 'remote',
60
+ # [String] 远程仓库相对目录,完整URL:remote/remote_path
61
+ :remote_path => 'remote-path'
62
+ }.freeze
63
+
64
+ # 必须全局字段
65
+ REQUIRED_CONFIG_KEY = [
66
+ CONFIG_KEY[:remote],
67
+ CONFIG_KEY[:version],
68
+ CONFIG_KEY[:dest],
69
+ CONFIG_KEY[:repositories]
70
+ ].freeze
71
+
72
+ # 必须仓库配置字段
73
+ REQUIRED_REPO_CONFIG_KEY = [
74
+ REPO_CONFIG_KEY[:remote_path],
75
+ ].freeze
76
+
77
+ REPO_CONFIG_LOCK_KEY = {
78
+ :branch => 'branch',
79
+ :commit_id => 'commit-id',
80
+ :tag => 'tag'
81
+ }.freeze
82
+
83
+ SNAPSHOT_KEY = {
84
+ :time_stamp => 'time-stamp',
85
+ :message => 'message',
86
+ :snapshot => 'snapshot'
87
+ }.freeze
88
+
89
+ CONFIG_CACHE_KEY = {
90
+ :hash => 'hash',
91
+ :cache => 'cache'
92
+ }.freeze
93
+
94
+ # 定义字段用于调用git(shell)指令前export,便于仓库git hook区分来进行其余操作
95
+ MGIT_EXPORT_INFO = {
96
+ # 是否是MGit操作的git指令
97
+ :MGIT_TRIGGERRED => 1,
98
+ # 本次MGit操作的唯一标示
99
+ :MGIT_OPT_ID => SecureRandom.uuid
100
+ }.freeze
101
+
102
+ # 临时中央仓库名
103
+ CENTRAL_REPO = "Central".freeze
104
+
105
+ INIT_CACHE_DIR_NAME = "pmet_tini_tigm".freeze
106
+ end
107
+ end
@@ -0,0 +1,25 @@
1
+
2
+ class Dir
3
+
4
+ # 检查传入路径是不是git仓库
5
+ #
6
+ # @param path [String] 仓库路径
7
+ #
8
+ def self.is_git_repo?(path)
9
+ return false unless File.directory?(path)
10
+ git_dir = File.join(path, '.git')
11
+ File.directory?(git_dir)
12
+ end
13
+
14
+ def self.is_in_git_repo?(path)
15
+ check_path = path
16
+ result = is_git_repo?(check_path)
17
+ while !result
18
+ check_path = File.dirname(check_path)
19
+ break if check_path == '/'
20
+ result = is_git_repo?(check_path)
21
+ end
22
+ result
23
+ end
24
+
25
+ end
@@ -0,0 +1,92 @@
1
+ #coding=utf-8
2
+
3
+ module MGit
4
+
5
+ # 计时器
6
+ #
7
+ class DurationRecorder
8
+
9
+ DEFAULT_DURATION_KEY = 'default_duration_key'
10
+
11
+ module Status
12
+ # 停止态
13
+ IDLE = 0
14
+ # 暂停态
15
+ PAUSE = 1
16
+ # 计时中
17
+ RUNNING = 2
18
+ end
19
+
20
+ include Status
21
+
22
+ @@status = {}
23
+ @@duration = {}
24
+ @@time_stamp = {}
25
+ @@lock = Mutex.new
26
+
27
+ def self.start(duration_key:DEFAULT_DURATION_KEY, use_lock:false)
28
+ mutex_exec(use_lock) {
29
+ status = IDLE if @@status[duration_key].nil?
30
+ if status == IDLE
31
+ @@duration[duration_key] = 0.0
32
+ @@time_stamp[duration_key] = Time.new.to_f
33
+ @@status[duration_key] = RUNNING
34
+ else
35
+ puts '需要停止计时后重新开始计时'
36
+ end
37
+ }
38
+ end
39
+
40
+ def self.pause(duration_key:DEFAULT_DURATION_KEY, use_lock:false)
41
+ mutex_exec(use_lock) {
42
+ if @@status[duration_key] == RUNNING
43
+ current = Time.new.to_f
44
+ @@duration[duration_key] += (current - @@time_stamp[duration_key])
45
+ @@time_stamp.delete(duration_key)
46
+ @@status[duration_key] = PAUSE
47
+ end
48
+ }
49
+ end
50
+
51
+ def self.resume(duration_key:DEFAULT_DURATION_KEY, use_lock:false)
52
+ mutex_exec(use_lock) {
53
+ if @@status[duration_key] == PAUSE
54
+ @@time_stamp[duration_key] = Time.new.to_f
55
+ @@status[duration_key] = RUNNING
56
+ end
57
+ }
58
+ end
59
+
60
+ def self.end(duration_key:DEFAULT_DURATION_KEY, use_lock:false)
61
+ mutex_exec(use_lock) {
62
+ if @@status[duration_key] != IDLE
63
+ current = Time.new.to_f
64
+ @@duration[duration_key] += (current - @@time_stamp[duration_key])
65
+ @@time_stamp.delete(duration_key)
66
+ @@status[duration_key] = IDLE
67
+ return @@duration[duration_key]
68
+ else
69
+ puts '没有需要停止的计时'
70
+ end
71
+ }
72
+ end
73
+
74
+ private
75
+
76
+ # 多线程执行保护
77
+ #
78
+ # @param use_lock [Boolean] 执行是否加锁
79
+ #
80
+ def self.mutex_exec(use_lock)
81
+ if use_lock
82
+ @@lock.lock
83
+ yield if block_given?
84
+ @@lock.unlock
85
+ else
86
+ yield if block_given?
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,50 @@
1
+
2
+ module MGit
3
+ # Git interact message parse with git-server
4
+ #
5
+ class GitMessageParser
6
+
7
+ def initialize(url)
8
+ @url = url
9
+ end
10
+
11
+ # @return [String] error message
12
+ # @return [nil] none error
13
+ #
14
+ def parse_fetch_msg(input)
15
+ parse_pull_msg(input)
16
+ end
17
+
18
+ # @return [String] error message
19
+ # @return [nil] none error
20
+ #
21
+ def parse_pull_msg(input)
22
+ __default_parse_msg(input)
23
+ end
24
+
25
+ # @return [String] error message
26
+ # @return [nil] none error
27
+ #
28
+ def parse_push_msg(input)
29
+ __default_parse_msg(input)
30
+ end
31
+
32
+ # @return [String] codereview的url地址
33
+ # 默认无解析
34
+ def parse_code_review_url(input)
35
+ nil
36
+ end
37
+
38
+ def __default_parse_msg(msg)
39
+ return if msg.nil? || msg.empty?
40
+
41
+ key_word = 'error:'
42
+ error_line = msg.split("\n").find {|line|
43
+ # 解析 "error: failed to push some refs..."
44
+ line.include?(key_word)
45
+ }
46
+ msg if error_line
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,32 @@
1
+
2
+ module MGit
3
+ class Lock
4
+ class << self
5
+
6
+ # @!scope 互斥执行锁
7
+ # @example
8
+ # mutex_exec do
9
+ # exec..
10
+ # end
11
+ def mutex_exec
12
+ @mutex = Mutex.new if @mutex.nil?
13
+ @mutex.lock
14
+ yield if block_given?
15
+ @mutex.unlock
16
+ end
17
+
18
+ # @!scope 互斥显示锁
19
+ # @example
20
+ # mutex_puts do
21
+ # exec..
22
+ # end
23
+ def mutex_puts
24
+ @mutex_puts = Mutex.new if @mutex_puts.nil?
25
+ @mutex_puts.lock
26
+ yield if block_given?
27
+ @mutex_puts.unlock
28
+ end
29
+
30
+ end
31
+ end
32
+ end