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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +85 -0
- data/lib/m-git.rb +66 -0
- data/lib/m-git/argv.rb +170 -0
- data/lib/m-git/argv/opt.rb +38 -0
- data/lib/m-git/argv/opt_list.rb +71 -0
- data/lib/m-git/argv/parser.rb +66 -0
- data/lib/m-git/base_command.rb +271 -0
- data/lib/m-git/command/add.rb +41 -0
- data/lib/m-git/command/branch.rb +90 -0
- data/lib/m-git/command/checkout.rb +106 -0
- data/lib/m-git/command/clean.rb +64 -0
- data/lib/m-git/command/commit.rb +84 -0
- data/lib/m-git/command/config.rb +202 -0
- data/lib/m-git/command/delete.rb +99 -0
- data/lib/m-git/command/fetch.rb +32 -0
- data/lib/m-git/command/forall.rb +81 -0
- data/lib/m-git/command/info.rb +74 -0
- data/lib/m-git/command/init.rb +324 -0
- data/lib/m-git/command/log.rb +73 -0
- data/lib/m-git/command/merge.rb +381 -0
- data/lib/m-git/command/pull.rb +364 -0
- data/lib/m-git/command/push.rb +311 -0
- data/lib/m-git/command/rebase.rb +348 -0
- data/lib/m-git/command/reset.rb +31 -0
- data/lib/m-git/command/self.rb +223 -0
- data/lib/m-git/command/stash.rb +189 -0
- data/lib/m-git/command/status.rb +135 -0
- data/lib/m-git/command/sync.rb +327 -0
- data/lib/m-git/command/tag.rb +67 -0
- data/lib/m-git/command_manager.rb +24 -0
- data/lib/m-git/error.rb +20 -0
- data/lib/m-git/foundation.rb +25 -0
- data/lib/m-git/foundation/constants.rb +107 -0
- data/lib/m-git/foundation/dir.rb +25 -0
- data/lib/m-git/foundation/duration_recorder.rb +92 -0
- data/lib/m-git/foundation/git_message_parser.rb +50 -0
- data/lib/m-git/foundation/lock.rb +32 -0
- data/lib/m-git/foundation/loger.rb +129 -0
- data/lib/m-git/foundation/mgit_config.rb +222 -0
- data/lib/m-git/foundation/operation_progress_manager.rb +139 -0
- data/lib/m-git/foundation/timer.rb +74 -0
- data/lib/m-git/foundation/utils.rb +361 -0
- data/lib/m-git/hooks_manager.rb +96 -0
- data/lib/m-git/manifest.rb +181 -0
- data/lib/m-git/manifest/cache_manager.rb +44 -0
- data/lib/m-git/manifest/internal.rb +182 -0
- data/lib/m-git/manifest/light_repo.rb +108 -0
- data/lib/m-git/manifest/light_repo_generator.rb +87 -0
- data/lib/m-git/manifest/linter.rb +153 -0
- data/lib/m-git/open_api.rb +427 -0
- data/lib/m-git/open_api/script_download_info.rb +37 -0
- data/lib/m-git/output/output.rb +461 -0
- data/lib/m-git/plugin_manager.rb +112 -0
- data/lib/m-git/repo.rb +133 -0
- data/lib/m-git/repo/status.rb +481 -0
- data/lib/m-git/repo/sync_helper.rb +254 -0
- data/lib/m-git/template.rb +9 -0
- data/lib/m-git/template/local_manifest.rb +27 -0
- data/lib/m-git/template/manifest_hook.rb +28 -0
- data/lib/m-git/template/post_download_hook.rb +29 -0
- data/lib/m-git/template/post_hook.rb +31 -0
- data/lib/m-git/template/pre_exec_hook.rb +31 -0
- data/lib/m-git/template/pre_hook.rb +29 -0
- data/lib/m-git/template/pre_push_hook.rb +32 -0
- data/lib/m-git/version.rb +6 -0
- data/lib/m-git/workspace.rb +648 -0
- data/lib/m-git/workspace/path_helper.rb +56 -0
- data/lib/m-git/workspace/workspace_helper.rb +159 -0
- data/m-git +1 -0
- data/mgit +19 -0
- metadata +218 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'fileutils'
|
5
|
+
module MGit
|
6
|
+
|
7
|
+
# 日志模块配置
|
8
|
+
class Loger
|
9
|
+
|
10
|
+
MGIT_LOG_FILE_NAME = 'mgit.log'
|
11
|
+
|
12
|
+
#
|
13
|
+
# 配置Log模块
|
14
|
+
#
|
15
|
+
# @param root [String] 工程根目录
|
16
|
+
#
|
17
|
+
def self.config(root)
|
18
|
+
# 是否开启log
|
19
|
+
begin
|
20
|
+
log_enable = MGit::MGitConfig.query_with_key(root, :logenable)
|
21
|
+
rescue MGitClass::Error => e
|
22
|
+
log_enable = TRUE
|
23
|
+
end
|
24
|
+
MGit::Loger.set_log_enable(log_enable)
|
25
|
+
|
26
|
+
# 配置log路径
|
27
|
+
log_dir = File.join(root, MGit::Constants::PROJECT_DIR[:log_dir])
|
28
|
+
FileUtils.mkdir_p(log_dir) if !Dir.exist?(log_dir)
|
29
|
+
file_path = File.join(log_dir, MGIT_LOG_FILE_NAME)
|
30
|
+
MGit::Loger.set_log_file(file_path)
|
31
|
+
|
32
|
+
# 配置log的level
|
33
|
+
begin
|
34
|
+
log_level = MGit::MGitConfig.query_with_key(root, :loglevel)
|
35
|
+
rescue MGitClass::Error => e
|
36
|
+
log_level = 1
|
37
|
+
end
|
38
|
+
MGit::Loger.set_log_level(log_level)
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# 日志模块
|
46
|
+
class Loger
|
47
|
+
DEFAULT_SHIFT_SIZE = 1048576 #每个文件1M
|
48
|
+
DEFAULT_SHIFT_AGE = 10 # 保留10个文件
|
49
|
+
DEFAULT_LOG_FILE = "./mgit.log"
|
50
|
+
|
51
|
+
#
|
52
|
+
# 设置mgit log是否开启 默认开启
|
53
|
+
#
|
54
|
+
# @param log_enable [Boolean] 是否开启log日志
|
55
|
+
#
|
56
|
+
def self.set_log_enable(log_enable)
|
57
|
+
@log_enable = log_enable
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# 设置mgit log的打印等级
|
62
|
+
#
|
63
|
+
# @param level [Enumerable]: Logger::DEBUG | Logger::INFO | Logger::ERROR | Logger::FATAL
|
64
|
+
#
|
65
|
+
def self.set_log_level(level)
|
66
|
+
self.logger.level = level
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# 设置mgit log的文件名, 默认路径在工作区的 .mgit/logs/mgit.log
|
71
|
+
#
|
72
|
+
def self.set_log_file(file_path)
|
73
|
+
@log_file = file_path
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# 打印 DEBUG类型的log
|
78
|
+
#
|
79
|
+
def self.debug(message)
|
80
|
+
self.logger.debug(message) if @log_enable
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# 打印 DEBUG类型的log
|
85
|
+
#
|
86
|
+
def self.info(message)
|
87
|
+
self.logger.info(message) if @log_enable
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# 打印 WARN类型的log
|
92
|
+
#
|
93
|
+
def self.warn(message)
|
94
|
+
self.logger.warn(message) if @log_enable
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# 打印 ERROR类型的log
|
99
|
+
#
|
100
|
+
def self.error(message)
|
101
|
+
self.logger.error(message) if @log_enable
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# 打印 FATAL类型的log
|
106
|
+
#
|
107
|
+
def self.fatal(message)
|
108
|
+
self.logger.fatal(message) if @log_enable
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def self.logger
|
113
|
+
unless @logger
|
114
|
+
@log_enable ||= TRUE
|
115
|
+
@log_level ||= Logger::INFO
|
116
|
+
@log_file ||= DEFAULT_LOG_FILE
|
117
|
+
@logger = Logger.new(@log_file, shift_age = DEFAULT_SHIFT_AGE, shift_size = DEFAULT_SHIFT_SIZE)
|
118
|
+
@logger.level = @log_level
|
119
|
+
@logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
120
|
+
@logger.formatter = proc do | severity, datetime, progname, msg|
|
121
|
+
"#{datetime} - #{severity} - : #{msg}\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
@logger
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
require_relative 'utils'
|
4
|
+
|
5
|
+
module MGit
|
6
|
+
class MGitConfig
|
7
|
+
|
8
|
+
CONFIG_KEY = {
|
9
|
+
:managegit => {
|
10
|
+
:info => '是否将.git实体托管给MGit,托管后仓库内的.git目录是软链 (true/false)',
|
11
|
+
:type => 'Boolean',
|
12
|
+
:default => true
|
13
|
+
},
|
14
|
+
:maxconcurrentcount => {
|
15
|
+
:info => 'MGit操作的最大并发数? (Integer)',
|
16
|
+
:type => 'Integer',
|
17
|
+
:default => MGit::Utils.logical_cpu_num
|
18
|
+
},
|
19
|
+
:syncworkspace => {
|
20
|
+
:info => '是否按照配置表同步工作区? (true/false)',
|
21
|
+
:type => 'Boolean',
|
22
|
+
:default => true
|
23
|
+
},
|
24
|
+
:savecache => {
|
25
|
+
:info => '同步工作区时回收的仓库是否保留到缓存中? (true/false)',
|
26
|
+
:type => 'Boolean',
|
27
|
+
:default => false
|
28
|
+
},
|
29
|
+
:logenable => {
|
30
|
+
:info => '是否开启日志打印,操作日志会收集到.mgit/log目录下? (true/false)',
|
31
|
+
:type => 'Boolean',
|
32
|
+
:default => true
|
33
|
+
},
|
34
|
+
:loglevel => {
|
35
|
+
:info => '日志的打印级别, DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, FATAL = 4',
|
36
|
+
:type => 'Integer',
|
37
|
+
:default => 1
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
class << self
|
42
|
+
|
43
|
+
# 查询配置
|
44
|
+
#
|
45
|
+
# @param root [String] 工程根目录
|
46
|
+
#
|
47
|
+
# @raise [MGit::Error] 异常错误
|
48
|
+
#
|
49
|
+
def query(root)
|
50
|
+
config, error = __load_file(root)
|
51
|
+
if !error.nil?
|
52
|
+
raise Error.new(error)
|
53
|
+
return
|
54
|
+
elsif block_given?
|
55
|
+
# 如果文件存在但无内容,此时读取到的数据类型是FalseClass,此处统一规范化
|
56
|
+
config = {} if !config.is_a?(Hash)
|
57
|
+
yield(config)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Description of #query_with_key
|
62
|
+
#
|
63
|
+
# @param root [String] 工程根目录
|
64
|
+
#
|
65
|
+
# @param key_symbol [Symbol] 符号key值
|
66
|
+
#
|
67
|
+
# @return [Object] 配置值
|
68
|
+
#
|
69
|
+
# @raise [MGit::Error] 异常错误
|
70
|
+
def query_with_key(root, key_symbol)
|
71
|
+
query(root) { |config|
|
72
|
+
if !config[key_symbol.to_s].nil?
|
73
|
+
return config[key_symbol.to_s]
|
74
|
+
elsif !CONFIG_KEY[key_symbol].nil?
|
75
|
+
return CONFIG_KEY[key_symbol][:default]
|
76
|
+
else
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
# 更新配置
|
83
|
+
#
|
84
|
+
# @param root [String] 工程根目录
|
85
|
+
#
|
86
|
+
# @raise [MGit::Error] 异常错误
|
87
|
+
#
|
88
|
+
def update(root)
|
89
|
+
# 加载配置
|
90
|
+
config, error = __load_file(root)
|
91
|
+
if !error.nil?
|
92
|
+
raise Error.new(error)
|
93
|
+
return
|
94
|
+
end
|
95
|
+
|
96
|
+
# 如果文件存在但无内容,此时读取到的数据类型是FalseClass,此处统一规范化
|
97
|
+
config = {} if !config.is_a?(Hash)
|
98
|
+
|
99
|
+
# 更新
|
100
|
+
yield(config) if block_given?
|
101
|
+
|
102
|
+
# 更新完后校验格式
|
103
|
+
if !config.is_a?(Hash)
|
104
|
+
raise Error.new("工具配置更新数据格式错误,更新失败!")
|
105
|
+
return
|
106
|
+
end
|
107
|
+
|
108
|
+
# 写回配置
|
109
|
+
error = write_to_file(root, config)
|
110
|
+
if !error.nil?
|
111
|
+
raise Error.new(error)
|
112
|
+
return
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# 列出所有配置
|
117
|
+
#
|
118
|
+
# @param root [String] 工程根目录
|
119
|
+
#
|
120
|
+
def dump_config(root)
|
121
|
+
query(root) { |config|
|
122
|
+
CONFIG_KEY.each_with_index { |(key, value_dict), index|
|
123
|
+
line = "#{Output.blue_message("[#{value_dict[:info]}]")}\n#{key.to_s}: "
|
124
|
+
set_value = config[key.to_s]
|
125
|
+
if !set_value.nil?
|
126
|
+
line += "#{set_value}\n\n"
|
127
|
+
else
|
128
|
+
line += "#{value_dict[:default]}\n\n"
|
129
|
+
end
|
130
|
+
puts line
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
# 验证一个value的值是否符合key的类型
|
136
|
+
#
|
137
|
+
# @param root [String] 工程根目录
|
138
|
+
#
|
139
|
+
# @param key [String] 字符串key值
|
140
|
+
#
|
141
|
+
# @param value [String] 字符串格式的值
|
142
|
+
#
|
143
|
+
# @return [Object] key值对应的合法类型value值
|
144
|
+
#
|
145
|
+
def to_suitable_value_for_key(root, key, value)
|
146
|
+
return unless CONFIG_KEY.keys.include?(key.to_sym)
|
147
|
+
return nil if !value.is_a?(String)
|
148
|
+
|
149
|
+
key_dict = CONFIG_KEY[key.to_sym]
|
150
|
+
set_value = nil
|
151
|
+
|
152
|
+
# 是否是数字
|
153
|
+
if key_dict[:type] == 'Integer' && value.to_i.to_s == value
|
154
|
+
set_value = value.to_i
|
155
|
+
|
156
|
+
# 是否是true
|
157
|
+
elsif key_dict[:type] == 'Boolean' && value.to_s.downcase == 'true'
|
158
|
+
set_value = true
|
159
|
+
|
160
|
+
# 是否是false
|
161
|
+
elsif key_dict[:type] == 'Boolean' && value.to_s.downcase == 'false'
|
162
|
+
set_value = false
|
163
|
+
|
164
|
+
# 是否是其他字符串
|
165
|
+
elsif key_dict[:type] == 'String' && value.is_a?(String)
|
166
|
+
set_value = value
|
167
|
+
end
|
168
|
+
|
169
|
+
set_value
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
# 加载mgit配置文件
|
175
|
+
#
|
176
|
+
# @param root [String] 工程根目录
|
177
|
+
#
|
178
|
+
# @return [(Hash, Boolean)] (配置内容,错误信息)
|
179
|
+
#
|
180
|
+
def __load_file(root)
|
181
|
+
config_path = File.join(root, Constants::MGIT_CONFIG_PATH)
|
182
|
+
if File.exists?(config_path)
|
183
|
+
begin
|
184
|
+
return YAML.load_file(config_path), nil
|
185
|
+
rescue => e
|
186
|
+
return nil, "工具配置文件\"#{File.basename(config_path)}\"读取失败,原因:\n#{e.message}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
[nil, nil]
|
191
|
+
end
|
192
|
+
|
193
|
+
# 将配置写回文件
|
194
|
+
#
|
195
|
+
# @param root [String] 工程根目录
|
196
|
+
#
|
197
|
+
# @param content [Hash] 新配置
|
198
|
+
#
|
199
|
+
# @return [String] 错误信息
|
200
|
+
#
|
201
|
+
def write_to_file(root, content)
|
202
|
+
config_path = File.join(root, Constants::MGIT_CONFIG_PATH)
|
203
|
+
begin
|
204
|
+
FileUtils.rm_f(config_path) if File.exist?(config_path)
|
205
|
+
|
206
|
+
dir_name = File.dirname(config_path)
|
207
|
+
FileUtils.mkdir_p(dir_name) if !Dir.exist?(dir_name)
|
208
|
+
|
209
|
+
file = File.new(config_path, 'w')
|
210
|
+
if !file.nil?
|
211
|
+
file.write(content.to_yaml)
|
212
|
+
file.close
|
213
|
+
end
|
214
|
+
return nil
|
215
|
+
rescue => e
|
216
|
+
return "工具配置文件\"#{File.basename(config_path)}\"写入失败,原因:\n#{e.message}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module MGit
|
4
|
+
# 本类用于缓存/加载操作中间态
|
5
|
+
class OperationProgressContext
|
6
|
+
|
7
|
+
# 现场信息关键字段
|
8
|
+
CONTEXT_CMD = 'cmd'
|
9
|
+
CONTEXT_OPTS = 'opts'
|
10
|
+
CONTEXT_BRANCH = 'branch'
|
11
|
+
CONTEXT_REPOS = 'repos'
|
12
|
+
CONTEXT_OTHER = 'other'
|
13
|
+
|
14
|
+
attr_accessor :type # String: 本次进入中间态的操作类型,可自定义,如'merge_in_progress','rebase_in_progress'等。该字段用于索引缓存的中间态信息,需要唯一。
|
15
|
+
attr_accessor :cmd # String: 本次执行指令,如'merge','checkout'等
|
16
|
+
attr_accessor :opts # String: 本次执行参数,如'--no-ff','--ff'等
|
17
|
+
attr_accessor :branch # String: 仓库当前分支
|
18
|
+
attr_accessor :repos # [String]: 本次执行哪些仓库的名称数组
|
19
|
+
attr_accessor :other # Object: 其他信息,可自定义
|
20
|
+
|
21
|
+
def initialize(type)
|
22
|
+
self.type = type
|
23
|
+
self.other = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# 将中间态对象序列化为Hash
|
27
|
+
def serialize
|
28
|
+
return {
|
29
|
+
CONTEXT_CMD => self.cmd,
|
30
|
+
CONTEXT_OPTS => self.opts,
|
31
|
+
CONTEXT_BRANCH => self.branch,
|
32
|
+
CONTEXT_REPOS => self.repos,
|
33
|
+
CONTEXT_OTHER => self.other
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# 反序列化
|
38
|
+
#
|
39
|
+
# @param dict [Hash] 中间态Hash
|
40
|
+
#
|
41
|
+
def deserialize(dict)
|
42
|
+
self.cmd = dict[CONTEXT_CMD]
|
43
|
+
self.opts = dict[CONTEXT_OPTS]
|
44
|
+
self.branch = dict[CONTEXT_BRANCH]
|
45
|
+
self.repos = dict[CONTEXT_REPOS]
|
46
|
+
self.other = dict[CONTEXT_OTHER]
|
47
|
+
end
|
48
|
+
|
49
|
+
# 校验中间态是否合法,仓库可缺省,若缺省则表示所有仓库
|
50
|
+
#
|
51
|
+
# @return [Boolean] 是否合法
|
52
|
+
#
|
53
|
+
def validate?
|
54
|
+
return !self.cmd.nil? && !self.opts.nil? && !self.branch.nil?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class OperationProgressManager
|
59
|
+
|
60
|
+
PROGRESS_TYPE = {
|
61
|
+
:merge => 'merge_in_progress',
|
62
|
+
:rebase => 'rebase_in_progress',
|
63
|
+
:pull => 'pull_in_progress'
|
64
|
+
}.freeze
|
65
|
+
|
66
|
+
class << self
|
67
|
+
|
68
|
+
# 进入中间态
|
69
|
+
#
|
70
|
+
# @param root [String] 多仓库根目录
|
71
|
+
#
|
72
|
+
# @param context [OperationProgressContext] 中间态对象
|
73
|
+
#
|
74
|
+
def trap_into_progress(root, context)
|
75
|
+
begin
|
76
|
+
MGitConfig.update(root) { |config|
|
77
|
+
config[context.type] = context.serialize
|
78
|
+
}
|
79
|
+
rescue Error => e
|
80
|
+
Output.puts_fail_message(e.msg)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# 删除中间态
|
85
|
+
#
|
86
|
+
# @param root [String] 多仓库根目录
|
87
|
+
#
|
88
|
+
# @param type [String] 自定义Key值,用于索引中间态信息
|
89
|
+
#
|
90
|
+
def remove_progress(root, type)
|
91
|
+
begin
|
92
|
+
MGitConfig.update(root) { |config|
|
93
|
+
config.delete(type)
|
94
|
+
}
|
95
|
+
rescue Error => e
|
96
|
+
Output.puts_fail_message(e.msg)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# 是否处于中间态中
|
101
|
+
def is_in_progress?(root, type)
|
102
|
+
is_in_progress = false
|
103
|
+
begin
|
104
|
+
MGitConfig.query(root) { |config|
|
105
|
+
is_in_progress = !config[type].nil?
|
106
|
+
}
|
107
|
+
rescue Error => e
|
108
|
+
Output.puts_fail_message(e.msg)
|
109
|
+
end
|
110
|
+
return is_in_progress
|
111
|
+
end
|
112
|
+
|
113
|
+
# 加载中间态上下文
|
114
|
+
#
|
115
|
+
# @param root [String] 多仓库根目录
|
116
|
+
#
|
117
|
+
# @param type [String] 自定义Key值,用于索引中间态信息
|
118
|
+
#
|
119
|
+
# @return [OperationProgressContext,String] 中间态对象;错误信息
|
120
|
+
#
|
121
|
+
def load_context(root, type)
|
122
|
+
context = nil
|
123
|
+
error = nil
|
124
|
+
begin
|
125
|
+
MGitConfig.query(root) { |config|
|
126
|
+
dict = config[type]
|
127
|
+
context = OperationProgressContext.new(type)
|
128
|
+
context.deserialize(dict)
|
129
|
+
}
|
130
|
+
rescue Error => e
|
131
|
+
Output.puts_fail_message(e.msg)
|
132
|
+
error = e.msg
|
133
|
+
end
|
134
|
+
return context, error
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|