git-thin 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ require 'claide'
2
+ require 'json'
3
+ require 'git-thin/command/action'
4
+
5
+ module GitThin
6
+
7
+ class Pull < Thin
8
+ include Action
9
+ self.arguments = Action.arguments
10
+ self.summary = Action.summary 'pull'
11
+ self.description = Action.description 'pull'
12
+
13
+ def initialize(argv)
14
+ super
15
+ setup(argv,'pull')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,326 @@
1
+ require 'claide'
2
+ require 'json'
3
+ # require 'git-thin/utils/utils'
4
+
5
+ module GitThin
6
+ class ThinConfig
7
+ include GitThinUtils
8
+ DEFAULT = 'default'.freeze
9
+ def initialize(name,keys)
10
+ @name = name
11
+ @keys = keys
12
+ @config = {}
13
+ end
14
+
15
+ def name
16
+ return @name
17
+ end
18
+ def keys
19
+ return @keys
20
+ end
21
+ def setValue(value,key = nil )
22
+ if key
23
+ if @keys.include? key
24
+ @config[key] = value
25
+ end
26
+ else
27
+ for key in @keys
28
+ @config[key] = value
29
+ end
30
+ end
31
+ end
32
+
33
+ def getValue(key = nil )
34
+ if key
35
+ value = @config[key]
36
+ if value.nil? && key == 'path'
37
+ value = @config['lfs']
38
+ end
39
+ return value
40
+ else
41
+ return @config.values
42
+ end
43
+ end
44
+
45
+ def self.prase_config(configs)
46
+ ret_configs = {}
47
+ for config in configs
48
+ items = config.split('=')
49
+ if items.length != 2
50
+ logE 'error thin config:'+config
51
+ next
52
+ end
53
+ name = items[0].strip.downcase
54
+ value = items[1].strip.split(',')
55
+ name_items = name.split('.')
56
+ if name_items.length <= 1
57
+ logE 'error thin config:'+config
58
+ next
59
+ end
60
+ if name_items[0] != 'thin'
61
+ # logE 'error thin config:'+config
62
+ next
63
+ end
64
+
65
+ config_name = name_items[1]
66
+ config = ret_configs[config_name]
67
+ if not config
68
+ config = ThinConfig.new config_name,['lfs','path']
69
+ ret_configs[config_name] = config
70
+ end
71
+
72
+ if name_items.length > 2
73
+ config_key = name_items[2]
74
+ config.setValue(value,config_key)
75
+ else
76
+ config.setValue value
77
+ end
78
+ end
79
+
80
+ return ret_configs
81
+ end
82
+
83
+ def self.prase_pwd_config(configs,source_root,pwd)
84
+ types = []
85
+ if pwd.index(source_root) == 0
86
+ # 在git 目录中,判断是否命中path路径
87
+ length = source_root.length
88
+ sub = pwd[length+1..-1]
89
+ if sub
90
+ for key in configs.keys
91
+ paths = configs[key].getValue('path')
92
+ for path in paths
93
+ if sub.index(path) == 0
94
+ types.push key.downcase
95
+ end
96
+ end
97
+ end
98
+ end
99
+ else
100
+ logW 'You are out of the repo'
101
+ end
102
+ return types
103
+ end
104
+
105
+ def self.prase_type_config(argv,configs,source_root=nil ,pwd=nil )
106
+ types = []
107
+ if argv.arguments.length > 0 && argv.arguments[0].index('-')!=0
108
+ first_args = argv.arguments[0].split '|'
109
+ need_shift = false
110
+ for arg in first_args
111
+ if configs.keys.include? arg.downcase
112
+ types.push arg.downcase
113
+ need_shift = true
114
+ end
115
+ end
116
+ if need_shift
117
+ argv.shift_argument
118
+ end
119
+ elsif pwd && source_root
120
+ types = types.concat prase_pwd_config(configs,source_root,pwd)
121
+ end
122
+ if types.length == 0
123
+ types.push(DEFAULT)
124
+ end
125
+ return types
126
+ end
127
+
128
+ end
129
+ class Config < Thin
130
+ include GitThinUtils
131
+ self.summary = 'Config lfs with .thinconfig'
132
+
133
+ self.arguments = [
134
+ CLAide::Argument.new('TYPE', false )
135
+ ]
136
+ self.description = <<-DESC
137
+ According to .thinconfig, configure the platform directory to LFS
138
+ DESC
139
+ def self.options
140
+ [
141
+ ['--source_root', 'Specify the warehouse address manually if necessary.'],
142
+ ['--store', 'Store config to lfs'],
143
+ ['--list', 'List the configs supported by the locally repository, (configured by.thinconfig) '],
144
+ ['--current', 'Displays the current configuration'],
145
+ ['--reset', 'Reset config to thin and lfs'],
146
+ ['--check', 'Check the integrity of the config'],
147
+ ].concat(super)
148
+ end
149
+ def initialize(argv)
150
+ super
151
+ @pwd = Dir.pwd
152
+ @types = []
153
+ @configs = {}
154
+ @source_root = argv.option('source_root')
155
+ @store = argv.flag?('store')
156
+ @list = argv.flag?('list')
157
+ @current = argv.flag?('current')
158
+ @reset = argv.flag?('reset')
159
+ @check = argv.flag?('check')
160
+
161
+ if not @source_root
162
+ run_shell 'git rev-parse --show-toplevel',false ,LOGNone do |out,err,status|
163
+ if status == 0
164
+ @source_root = out[0].strip
165
+ end
166
+ end
167
+
168
+ if not File.exist? @source_root+'/.git'
169
+ UI.puts "git repository not found"
170
+ exit 1
171
+ end
172
+ else
173
+ if @source_root[-1] == '/'
174
+ @source_root = @source_root[0..-2 ]
175
+ end
176
+ end
177
+ if not Dir.exist? @source_root
178
+ @source_root = nil
179
+ return
180
+ end
181
+ if FileTest.exist? @source_root+'/.thinconfig'
182
+ run_shell "git config -lf #{@source_root}/.thinconfig",true ,true do |out,err,status|
183
+ @configs = ThinConfig.prase_config out
184
+ end
185
+ end
186
+ @types =ThinConfig.prase_type_config argv,@configs
187
+ end
188
+
189
+ def validate!
190
+ super
191
+ help! 'validate SOURCE_ROOT is required' unless @source_root
192
+ end
193
+
194
+ def git_config
195
+ if not @git_configs
196
+ run_shell 'git config -l',true ,true do |outs,errs,status|
197
+ @git_configs = ThinConfig.prase_config outs
198
+ end
199
+ end
200
+ end
201
+ def run_config
202
+ values=[]
203
+ for type in @types
204
+ config = @configs[type]
205
+ if type == ThinConfig::DEFAULT
206
+ git_config
207
+ config = @git_configs[ThinConfig::DEFAULT]
208
+ end
209
+ if config
210
+ values.push config.getValue('lfs')
211
+ end
212
+ end
213
+ if values.length > 0
214
+ run_shell "git config thin.#{ThinConfig::DEFAULT} "+values.join(','),true ,true
215
+ if @store
216
+ run_shell "git config lfs.fetchinclude "+values.join(',')
217
+ end
218
+ end
219
+ return values
220
+ end
221
+
222
+ def list
223
+ logN 'List the configs supported by the locally repository: '
224
+ git_config
225
+ config = @git_configs[ThinConfig::DEFAULT]
226
+ if config
227
+ log = "name:#{config.name}"
228
+ for key in config.keys
229
+ log += " #{key}:#{config.getValue key}"
230
+ end
231
+ logN log
232
+ end
233
+ for config in @configs.values
234
+ log = "name:#{config.name}"
235
+ for key in config.keys
236
+ log += " #{key}:#{config.getValue key}"
237
+ end
238
+ logN log
239
+ end
240
+ end
241
+ def reset
242
+ run_shell "git config --unset thin.#{ThinConfig::DEFAULT} ",true ,true
243
+ run_shell "git config --unset lfs.fetchinclude ",true ,true
244
+ end
245
+ def current
246
+
247
+ types = ThinConfig::prase_pwd_config(@configs,@source_root,@pwd)
248
+ if types.length == 0
249
+ types.push ThinConfig::DEFAULT
250
+ end
251
+ for type in types
252
+ config = @configs[type]
253
+ if type == ThinConfig::DEFAULT
254
+ git_config
255
+ config = @git_configs[ThinConfig::DEFAULT]
256
+ end
257
+ if config
258
+ logN "name:#{type} lfs:#{config.getValue('lfs')}"
259
+ end
260
+ end
261
+ end
262
+
263
+ def match_config(match_file)
264
+ for config in @configs.values
265
+ lfs = config.getValue 'lfs'
266
+ if lfs
267
+ lfs = lfs.map do|file|
268
+ file.strip
269
+ end
270
+ for lf in lfs
271
+ if match_file.index(lf) == 0
272
+ return config
273
+ end
274
+ end
275
+ end
276
+ end
277
+ return nil
278
+ end
279
+ def check
280
+ lfs_files = []
281
+ run_shell "git lfs ls-files",false ,LOGNone do |outs,errs,status|
282
+ if status
283
+ for line in outs
284
+ line[13..-2]
285
+ lfs_files.push line[13..-2]
286
+ end
287
+ end
288
+ end
289
+ unmatch_files = []
290
+ for lfs_file in lfs_files
291
+
292
+ if match_config(lfs_file).nil?
293
+ unmatch_files.push lfs_file
294
+ end
295
+ end
296
+ if unmatch_files.length > 0
297
+ logN 'The following LFS files are not configured:'
298
+ for unmatch_file in unmatch_files
299
+ logW unmatch_file
300
+ end
301
+ else
302
+ logN 'All LFS files are configured'
303
+ end
304
+ end
305
+ def run
306
+ Dir.chdir @source_root
307
+ if @list
308
+ list
309
+ elsif @reset
310
+ reset
311
+ elsif @current
312
+ current
313
+ elsif @check
314
+ check
315
+ else
316
+ values = run_config
317
+ if values.length > 0
318
+ logN "git config thin.#{ThinConfig::DEFAULT} "+values.join(",")
319
+ else
320
+ logW "not match analyze config"
321
+ end
322
+ end
323
+ Dir.chdir @pwd
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,3 @@
1
+ module GitThin
2
+ VERSION = "0.0.13"
3
+ end
@@ -0,0 +1,133 @@
1
+ require 'open3'
2
+ require 'io/console'
3
+ module GitThinUtils
4
+
5
+ LOGC= 1<<0
6
+ LOGN= 1<<1
7
+ LOGPRUNE = 1<<2
8
+ LOGNone= 0
9
+ LOGA = LOGC|LOGN
10
+
11
+
12
+ def set_progress(index, char = '*')
13
+ print (char * (index / 2.5).floor).ljust(40, " "), " #{index}%\r"
14
+ end
15
+
16
+ def run_shell(command,force = 0,log_type = LOGA,retryCount = 0 )
17
+ if log_type === false
18
+ log_type = LOGPRUNE
19
+ elsif log_type === true
20
+ log_type = LOGNone
21
+ end
22
+ if (log_type & LOGC ) == LOGC
23
+ logC command+"\n",(log_type & LOGPRUNE )!=LOGPRUNE
24
+ end
25
+ stdin, stdout, stderr,wait_thr = Open3.popen3(command)
26
+ pid = wait_thr[:pid]
27
+ out_lines = []
28
+ error_lines = []
29
+ stdout.sync = true
30
+ stderr.sync = true
31
+ out = Thread.new do
32
+ # while !stdout.eof?
33
+ # c = stdout.getc
34
+ # putc c
35
+ # stdout.flush
36
+ # end
37
+ stdout.each do |line|
38
+ out_lines.push line
39
+ if log_type && log_type > LOGC
40
+ logN line,(log_type & LOGPRUNE )!=LOGPRUNE
41
+ end
42
+ end
43
+ end
44
+ err = Thread.new do
45
+ # while !stderr.eof?
46
+ # c = stderr.getc
47
+ # putc c
48
+ # stderr.flush
49
+ # end
50
+ stderr.each do |line|
51
+ error_lines.push line
52
+
53
+ if log_type
54
+ logW line,(log_type & LOGPRUNE )!=LOGPRUNE
55
+ end
56
+ end
57
+ end
58
+ out.join
59
+ err.join
60
+
61
+ stderr.close
62
+ stdin.close
63
+ stdout.close
64
+ status = wait_thr.value
65
+ if status.exitstatus != 0
66
+ if !force
67
+ if retryCount > 0
68
+ sleep 1
69
+ run_shell command,force,log_type,retryCount-1
70
+ return
71
+ else
72
+ logE error_lines,(log_type & LOGPRUNE )
73
+
74
+ exit 1
75
+ end
76
+ end
77
+ end
78
+ unless block_given?
79
+
80
+ return [out_lines,error_lines,status.exitstatus]
81
+ else
82
+ yield out_lines, error_lines,status.exitstatus
83
+ end
84
+ end
85
+
86
+ def print_console(str)
87
+ run_shell "echo #{str}"
88
+ end
89
+
90
+ def logInner(color_code,text)
91
+ clolr="\033[#{color_code}m"
92
+ nc="\033[0m"
93
+ puts "#{clolr}#{text}#{nc}"
94
+ end
95
+
96
+ # 打印不同级别的 log。根据级别不同,样式(颜色)不同
97
+ def logE(text,note = true )
98
+ if note
99
+ logInner '31',"[ERROR] !!#{text}"
100
+ else
101
+ print(text)
102
+ end
103
+ end
104
+
105
+ def logP(text)
106
+ print("\r")
107
+ print(text)
108
+ STDOUT.flush
109
+ end
110
+ def logW(text,note = true )
111
+ if note
112
+ logInner '33',"[WARNING] #{text}"
113
+ else
114
+ print(text)
115
+ end
116
+ end
117
+
118
+ def logN(text,note = true)
119
+ if note
120
+ logInner '32',"[NOTE] #{text}"
121
+ else
122
+ print(text)
123
+ end
124
+ end
125
+
126
+ def logC(text,note = true)
127
+ if note
128
+ logInner '34',"[COMMAND] #{text}"
129
+ else
130
+ print(text)
131
+ end
132
+ end
133
+ end