coaster 1.3.31 → 1.3.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/coaster +1 -1
- data/lib/coaster/cmd_options.rb +159 -0
- data/lib/coaster/git/options.rb +118 -0
- data/lib/coaster/git/repository.rb +69 -82
- data/lib/coaster/git.rb +20 -0
- data/lib/coaster/version.rb +1 -1
- data/test/test_git.rb +0 -48
- data/test/test_git_options.rb +32 -0
- data/test/test_git_repository.rb +64 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 684eb09e07b2184d93f7dd1ba8ef28df6d75c29bbaac226e4e513da16e0d22f5
|
4
|
+
data.tar.gz: 5479f75d9364214c164b022a7fc2fb96802c7258663909b16afbdcb75d45ad8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58f78f7427f2069f3c69389f23dfec8140c365f0d9817e8ee71cc00db978365344d2f4b109acc9268889150509ce63ae56f6b02f087915815ac6d91e5b91e183
|
7
|
+
data.tar.gz: 3e70c07f05f01312fd95a33b711ea7bd4289db6e4e447392250a8c22568ed8af236456c80f3846ae530621e1038320b70a5f11d74d269a99f13b0bed32b81879
|
data/bin/coaster
CHANGED
@@ -0,0 +1,159 @@
|
|
1
|
+
module Coaster
|
2
|
+
class CmdOptions
|
3
|
+
class << self
|
4
|
+
def options_to_s(options)
|
5
|
+
case options
|
6
|
+
when Hash then options_h_to_s(options)
|
7
|
+
when Array, Set then options.map{|o| options_to_s(o)}.join(' ')
|
8
|
+
else options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def options_s_to_h(options)
|
13
|
+
opts = {}
|
14
|
+
options = " #{options}"
|
15
|
+
options_indexes = options.enum_for(:scan, / -\w| --\w+| -- /).map { Regexp.last_match.begin(0) }
|
16
|
+
options_indexes << 0
|
17
|
+
options_indexes.each_cons(2) do |a, b|
|
18
|
+
option = options[a+1..b-1]
|
19
|
+
h = option_s_to_h(option)
|
20
|
+
options_h_merger(h, base: opts)
|
21
|
+
end
|
22
|
+
opts
|
23
|
+
end
|
24
|
+
|
25
|
+
def option_s_to_h(option)
|
26
|
+
if option.start_with?(/--\w/)
|
27
|
+
opt = option.split('=', 2)
|
28
|
+
opt << '' if opt.length == 1
|
29
|
+
elsif option.start_with?(/-\w/)
|
30
|
+
opt = option.split(' ', 2)
|
31
|
+
opt << '' if opt.length == 1
|
32
|
+
elsif option.start_with?('-- ')
|
33
|
+
opt = ['--', option[3..-1].split(' ')]
|
34
|
+
else
|
35
|
+
return {}
|
36
|
+
end
|
37
|
+
opt[1] = opt[1].split(',') if opt[1].include?(',')
|
38
|
+
opt[1] = opt[1].map{|s| s.include?('=') ? Hash[s.split('=', 2)] : s}.to_h if opt[1].is_a?(Array)
|
39
|
+
[opt].to_h
|
40
|
+
end
|
41
|
+
|
42
|
+
def option_v_to_s(option_v)
|
43
|
+
case option_v
|
44
|
+
when Hash then option_v.map{|vk,vv| Set[vk, vv]}.to_set
|
45
|
+
when Array then option_v.map{|v| option_v_to_s(v)}.join(',')
|
46
|
+
when Set then option_v.map{|v| option_v_to_s(v)}.join('=')
|
47
|
+
else
|
48
|
+
option_v = (option_v || '').to_s
|
49
|
+
option_v = option_v.gsub(/"/, '\"')
|
50
|
+
option_v = "\"#{option_v}\"" if option_v.include?(' ')
|
51
|
+
option_v
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def options_h_to_s(options)
|
56
|
+
opts = []
|
57
|
+
|
58
|
+
# multiple options can be passed by set
|
59
|
+
options.map do |k, v|
|
60
|
+
if v.is_a?(Set)
|
61
|
+
v.each {|set_v| opts << [k, set_v]}
|
62
|
+
else
|
63
|
+
opts << [k, v]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
targets = ''
|
68
|
+
parsed = opts.map do |k, v|
|
69
|
+
if k.start_with?(/--\w/)
|
70
|
+
v = option_v_to_s(v)
|
71
|
+
if v.is_a?(Set)
|
72
|
+
v.map {|vv| "#{k}=#{option_v_to_s(vv)}" }.join(' ')
|
73
|
+
else
|
74
|
+
"#{k}#{v.length > 0 ? "=#{v}" : ''}" # ex, --config-env=<name>=<envvar>
|
75
|
+
end
|
76
|
+
elsif k.start_with?(/-\w/)
|
77
|
+
v = option_v_to_s(v)
|
78
|
+
if v.is_a?(Set)
|
79
|
+
v.map {|vv| "#{k} #{option_v_to_s(vv)}"}.join(' ')
|
80
|
+
else
|
81
|
+
"#{k} #{v}" # ex, -c <name>=<value>
|
82
|
+
end
|
83
|
+
elsif k == '--'
|
84
|
+
if v.present?
|
85
|
+
v = Array.wrap(v)
|
86
|
+
v = v.map{|e| option_v_to_s(e)}.join(' ')
|
87
|
+
targets = "-- #{v}" # ex, -- <args>
|
88
|
+
''
|
89
|
+
end
|
90
|
+
else
|
91
|
+
raise "Unknown option: #{k}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
parsed << targets
|
96
|
+
parsed.join(' ')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
attr_accessor :repository
|
101
|
+
|
102
|
+
def initialize(cmd, *args, **options)
|
103
|
+
arg_options = args.extract_options!
|
104
|
+
options = options.merge(arg_options)
|
105
|
+
@cmd = cmd
|
106
|
+
@cmd, @sub_cmd = @cmd if @cmd.is_a?(Array)
|
107
|
+
remain_ix = args.index{ |k| k == '--'}
|
108
|
+
if remain_ix
|
109
|
+
@remain_args = args[remain_ix+1..-1]
|
110
|
+
@args = args[0...remain_ix]
|
111
|
+
else
|
112
|
+
@args = args
|
113
|
+
end
|
114
|
+
if @args.first.is_a?(self.class)
|
115
|
+
options = @args.first.to_h.merge(options)
|
116
|
+
end
|
117
|
+
if @args.last.is_a?(self.class)
|
118
|
+
options = @args.last.to_h.merge(options)
|
119
|
+
end
|
120
|
+
options['--'] ||= []
|
121
|
+
options['--'] += @remain_args if @remain_args
|
122
|
+
@options = options
|
123
|
+
@args << self.class.options_to_s(options).strip
|
124
|
+
@str = @args.join(' ')
|
125
|
+
end
|
126
|
+
|
127
|
+
def parser_proc(*args)
|
128
|
+
raise 'Not implemented'
|
129
|
+
end
|
130
|
+
|
131
|
+
def parser
|
132
|
+
parser_proc = parser_proc(@cmd, @sub_cmd)
|
133
|
+
instance_exec(&parser_proc)
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_h
|
137
|
+
return @hash if defined?(@hash)
|
138
|
+
@hash = {}
|
139
|
+
remain_args = parser.parse!(@str.split(' '))
|
140
|
+
@hash['--'] = remain_args if remain_args.any?
|
141
|
+
@hash
|
142
|
+
end
|
143
|
+
delegate :[], :[]=, :key?, :map, :each, to: :to_h
|
144
|
+
|
145
|
+
def merge(*args, **options)
|
146
|
+
if args.first.is_a?(CmdOptions)
|
147
|
+
other = args.shift
|
148
|
+
else
|
149
|
+
other = self.class.new([@cmd, @sub_cmd], *args, **options)
|
150
|
+
end
|
151
|
+
self.class.new(to_h.merge(other.to_h))
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_s
|
155
|
+
return self.class.options_h_to_s(@hash) if defined?(@hash)
|
156
|
+
@str
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'coaster/cmd_options'
|
2
|
+
|
3
|
+
module Coaster
|
4
|
+
module Git
|
5
|
+
class Options < ::Coaster::CmdOptions
|
6
|
+
OPTION_PARSER = {
|
7
|
+
'git' => {
|
8
|
+
nil => proc do
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.on('-c', '--config-env=NAME=VALUE') { |v|
|
11
|
+
name, envvar = v.split('=')
|
12
|
+
@hash['--config-env'] ||= {}
|
13
|
+
@hash['--config-env'][name] = envvar
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end,
|
17
|
+
},
|
18
|
+
'config' => {
|
19
|
+
nil => proc do
|
20
|
+
OptionParser.new do |opts|
|
21
|
+
end
|
22
|
+
end,
|
23
|
+
},
|
24
|
+
'status' => {
|
25
|
+
nil => proc do
|
26
|
+
OptionParser.new do |opts|
|
27
|
+
end
|
28
|
+
end,
|
29
|
+
},
|
30
|
+
'add' => {
|
31
|
+
nil => proc do
|
32
|
+
OptionParser.new do |opts|
|
33
|
+
end
|
34
|
+
end,
|
35
|
+
},
|
36
|
+
'commit' => {
|
37
|
+
nil => proc do
|
38
|
+
OptionParser.new do |opts|
|
39
|
+
opts.on('-m', '--message') { |v| @hash['--message'] = v }
|
40
|
+
end
|
41
|
+
end,
|
42
|
+
},
|
43
|
+
'fetch' => {
|
44
|
+
nil => proc do
|
45
|
+
OptionParser.new do |opts|
|
46
|
+
end
|
47
|
+
end,
|
48
|
+
},
|
49
|
+
'branch' => {
|
50
|
+
nil => proc do
|
51
|
+
OptionParser.new do |opts|
|
52
|
+
end
|
53
|
+
end
|
54
|
+
},
|
55
|
+
'checkout' => {
|
56
|
+
nil => proc do
|
57
|
+
OptionParser.new do |opts|
|
58
|
+
end
|
59
|
+
end
|
60
|
+
},
|
61
|
+
'merge' => {
|
62
|
+
nil => proc do
|
63
|
+
OptionParser.new do |opts|
|
64
|
+
opts.on('-m', '--message') { |v| @hash['--message'] = v }
|
65
|
+
opts.on('--no-commit') { |v| @hash['--no-commit'] = '' }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
},
|
69
|
+
'log' => {
|
70
|
+
nil => proc do
|
71
|
+
OptionParser.new do |opts|
|
72
|
+
end
|
73
|
+
end
|
74
|
+
},
|
75
|
+
'diff' => {
|
76
|
+
nil => proc do
|
77
|
+
OptionParser.new do |opts|
|
78
|
+
end
|
79
|
+
end
|
80
|
+
},
|
81
|
+
'submodule' => {
|
82
|
+
nil => proc do
|
83
|
+
OptionParser.new do |opts|
|
84
|
+
end
|
85
|
+
end,
|
86
|
+
'add' => proc do
|
87
|
+
OptionParser.new do |opts|
|
88
|
+
end
|
89
|
+
end,
|
90
|
+
'init' => proc do
|
91
|
+
OptionParser.new do |opts|
|
92
|
+
end
|
93
|
+
end,
|
94
|
+
'update' => proc do
|
95
|
+
OptionParser.new do |opts|
|
96
|
+
end
|
97
|
+
end
|
98
|
+
},
|
99
|
+
'ls-tree' => {
|
100
|
+
nil => proc do
|
101
|
+
OptionParser.new do |opts|
|
102
|
+
end
|
103
|
+
end
|
104
|
+
},
|
105
|
+
'rev-parse' => {
|
106
|
+
nil => proc do
|
107
|
+
OptionParser.new do |opts|
|
108
|
+
end
|
109
|
+
end
|
110
|
+
},
|
111
|
+
}
|
112
|
+
|
113
|
+
def parser_proc(cmd, sub_cmd, *args)
|
114
|
+
OPTION_PARSER[cmd][sub_cmd]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -1,104 +1,67 @@
|
|
1
1
|
module Coaster
|
2
2
|
module Git
|
3
3
|
class Repository
|
4
|
-
|
5
|
-
def option_parser(options)
|
6
|
-
case options
|
7
|
-
when Hash then hash_option_parser(options)
|
8
|
-
when Array, Set then options.map{|o| option_parser(o)}.join(' ')
|
9
|
-
else options
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def hash_option_parser(options)
|
14
|
-
opts = []
|
15
|
-
|
16
|
-
# multiple options can be passed by set
|
17
|
-
options.map do |k, v|
|
18
|
-
if v.is_a?(Set)
|
19
|
-
v.each {|set_v| opts << [k, set_v]}
|
20
|
-
else
|
21
|
-
opts << [k, v]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
parsed = opts.map do |k, v|
|
26
|
-
v = case v
|
27
|
-
when Hash then v.map{|vk,vv| "#{vk}=#{vv}"}.join(',')
|
28
|
-
when Array then v.join(',')
|
29
|
-
else v || ''
|
30
|
-
end
|
31
|
-
v = v.strip
|
32
|
-
if k.start_with?('--')
|
33
|
-
"#{k}#{v.length > 0 ? "=#{v}" : ''}" # ex, --config-env=<name>=<envvar>
|
34
|
-
else
|
35
|
-
"#{k} #{v.length > 0 ? "#{v}" : ''}" # ex, -c <name>=<value>
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
parsed.join(' ')
|
40
|
-
end
|
41
|
-
|
42
|
-
def run_cmd(path, command)
|
43
|
-
puts "#{path}: #{command}"
|
44
|
-
stdout, stderr, status = Open3.capture3(command, chdir: path)
|
45
|
-
if status.success?
|
46
|
-
puts " ↳ success: #{stdout}"
|
47
|
-
stdout
|
48
|
-
else
|
49
|
-
raise "Error executing command: #{command}\n ↳ #{stderr}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def create(path)
|
54
|
-
run_cmd(path.split('/')[0..-2].join('/'), "git init #{path}")
|
55
|
-
run_cmd(path, "git commit --allow-empty -m 'initial commit'")
|
56
|
-
new(path)
|
57
|
-
end
|
58
|
-
end
|
4
|
+
include Coaster::Git
|
59
5
|
|
60
6
|
attr_reader :path
|
61
7
|
|
62
8
|
def initialize(path)
|
63
9
|
@path = path
|
64
|
-
@sha = current_sha
|
65
10
|
end
|
66
11
|
|
67
|
-
def run_cmd(command)
|
68
|
-
|
12
|
+
def run_cmd(command, path: nil)
|
13
|
+
super(path || @path, command)
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_git_options(*args, **options, &block)
|
17
|
+
@git_options = Options.new('git', *args, **options)
|
18
|
+
yield
|
19
|
+
@git_options = nil
|
69
20
|
end
|
70
21
|
|
71
|
-
def run_git_cmd(command, *options)
|
72
|
-
|
22
|
+
def run_git_cmd(command, *args, **options)
|
23
|
+
opts = Options.new(command, *args, **options)
|
24
|
+
cmd = "git #{@git_options} #{Array.wrap(command).join(' ')} #{opts}"
|
73
25
|
run_cmd(cmd)
|
74
26
|
end
|
75
27
|
|
76
|
-
def add
|
77
|
-
|
28
|
+
def add(*paths, **options)
|
29
|
+
opts = Options.new('add', **options)
|
30
|
+
run_git_cmd("add", *paths, opts)
|
78
31
|
end
|
79
32
|
|
80
|
-
def commit
|
81
|
-
|
33
|
+
def commit(*args, **options)
|
34
|
+
opts = Options.new('commit', *options)
|
35
|
+
opts['--message'] ||= "no message"
|
36
|
+
run_git_cmd("commit", opts)
|
82
37
|
end
|
83
38
|
|
84
|
-
def branch
|
85
|
-
run_git_cmd("branch
|
39
|
+
def branch(*args, **options)
|
40
|
+
run_git_cmd("branch", *args, **options)
|
86
41
|
end
|
87
42
|
|
88
|
-
def checkout
|
89
|
-
run_git_cmd("checkout
|
43
|
+
def checkout(*args, **options)
|
44
|
+
run_git_cmd("checkout", *args, **options)
|
90
45
|
end
|
91
46
|
|
92
|
-
def submodule_add!(path,
|
93
|
-
run_git_cmd("submodule add
|
47
|
+
def submodule_add!(repo, path, *args, **options)
|
48
|
+
run_git_cmd(["submodule", 'add'], repo, path, *args, **options)
|
94
49
|
end
|
95
50
|
|
96
|
-
def submodule_init!(
|
97
|
-
run_git_cmd("submodule init
|
51
|
+
def submodule_init!(*paths)
|
52
|
+
run_git_cmd(["submodule", "init"], *paths)
|
98
53
|
end
|
99
54
|
|
100
|
-
def submodule_update!(*paths, options
|
101
|
-
run_git_cmd("submodule update
|
55
|
+
def submodule_update!(*paths, **options)
|
56
|
+
run_git_cmd(["submodule", "update"], *paths, **options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def fetch(*args, **options)
|
60
|
+
run_git_cmd("fetch", *args, **options)
|
61
|
+
end
|
62
|
+
|
63
|
+
def status(*args, **options)
|
64
|
+
run_git_cmd("status", *args, **options)
|
102
65
|
end
|
103
66
|
|
104
67
|
def current_sha
|
@@ -117,33 +80,57 @@ module Coaster
|
|
117
80
|
end.to_h
|
118
81
|
end
|
119
82
|
|
120
|
-
def merge(pointer)
|
83
|
+
def merge(pointer, *args, **options)
|
84
|
+
opts = Options.new('merge', *args, **options)
|
121
85
|
pointers = pointers(pointer).join(',')
|
122
|
-
puts "#{path}
|
123
|
-
|
86
|
+
puts "[MERGE] #{path} #{pointers} #{options}"
|
87
|
+
opts['--message'] ||= "Merge #{pointers}"
|
88
|
+
run_git_cmd("merge #{pointer} #{opts}")
|
124
89
|
end
|
125
90
|
|
126
91
|
def submodule_sha(path, pointer: nil)
|
127
|
-
pointer ||=
|
92
|
+
pointer ||= current_sha
|
128
93
|
run_git_cmd("ls-tree #{pointer} #{path}").split(' ')[2]
|
129
94
|
end
|
130
95
|
|
96
|
+
def merge_without_submodules
|
97
|
+
run_git_cmd('config merge.ours.name "Keep ours merge driver"')
|
98
|
+
run_git_cmd('config merge.ours.driver true')
|
99
|
+
ga_file = File.join(@path, '.gitattributes')
|
100
|
+
run_cmd("touch #{ga_file}")
|
101
|
+
ga_lines = File.read(ga_file).split("\n")
|
102
|
+
ga_lines_appended = ga_lines + submodules.keys.map{|sb_path| "#{sb_path} merge=ours" }
|
103
|
+
File.open(ga_file, 'w') do |f|
|
104
|
+
f.puts ga_lines_appended.join("\n")
|
105
|
+
end
|
106
|
+
add('.')
|
107
|
+
commit
|
108
|
+
yield
|
109
|
+
File.open(ga_file, 'w') do |f|
|
110
|
+
f.puts ga_lines.join("\n")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
131
114
|
def deep_merge(pointer)
|
115
|
+
puts "[DEEP_MERGE] #{path} #{pointer}"
|
132
116
|
submodules.values.each do |submodule|
|
133
117
|
sm_sha = submodule_sha(submodule.path, pointer: pointer)
|
134
118
|
submodule.merge(sm_sha)
|
135
119
|
end
|
136
|
-
|
120
|
+
merge_without_submodules do
|
121
|
+
merge(pointer)
|
122
|
+
end
|
137
123
|
end
|
138
124
|
|
139
125
|
def pointers(sha)
|
140
126
|
run_git_cmd("branch --contains #{sha}").split("\n").map do |br|
|
141
|
-
(br.start_with?('*') ? br[2..-1] : br).strip
|
142
|
-
|
127
|
+
br = (br.start_with?('*') ? br[2..-1] : br).strip
|
128
|
+
br.match?(/^\(.*\)$/) ? nil : br
|
129
|
+
end.compact
|
143
130
|
end
|
144
131
|
|
145
132
|
def remove
|
146
|
-
|
133
|
+
run_cmd("rm -rf #{path}", path: path.split('/')[0..-2].join('/'))
|
147
134
|
end
|
148
135
|
end
|
149
136
|
end
|
data/lib/coaster/git.rb
CHANGED
@@ -2,8 +2,28 @@ require 'open3'
|
|
2
2
|
|
3
3
|
module Coaster
|
4
4
|
module Git
|
5
|
+
def run_cmd(path, command)
|
6
|
+
puts "#{path}: #{command}"
|
7
|
+
stdout, stderr, status = Open3.capture3(command, chdir: path)
|
8
|
+
if status.success?
|
9
|
+
puts " ↳ success: #{stdout.split("\n").join("\n ")}"
|
10
|
+
stdout
|
11
|
+
else
|
12
|
+
raise "Error executing command\nPATH: #{path}\nCMD: #{command}\nSTDERR:\n ↳ #{stderr.split("\n").join("\n ")}\nSTDOUT:\n ↳ #{stdout.split("\n").join("\n ")}"
|
13
|
+
end
|
14
|
+
end
|
5
15
|
|
16
|
+
class << self
|
17
|
+
include Coaster::Git
|
18
|
+
|
19
|
+
def create(path)
|
20
|
+
run_cmd(path.split('/')[0..-2].join('/'), "git init #{path}")
|
21
|
+
run_cmd(path, "git commit --allow-empty -m 'initial commit'")
|
22
|
+
Repository.new(path)
|
23
|
+
end
|
24
|
+
end
|
6
25
|
end
|
7
26
|
end
|
8
27
|
|
28
|
+
require 'coaster/git/options'
|
9
29
|
require 'coaster/git/repository'
|
data/lib/coaster/version.rb
CHANGED
data/test/test_git.rb
CHANGED
@@ -4,53 +4,5 @@ require 'coaster/git'
|
|
4
4
|
|
5
5
|
module Coaster
|
6
6
|
class TestGit < Minitest::Test
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@test_repo_root = File.expand_path('../../tmp/test_repo', __FILE__)
|
10
|
-
FileUtils.rm_rf(@test_repo_root)
|
11
|
-
FileUtils.mkdir_p(@test_repo_root)
|
12
|
-
@beta = Git::Repository.create(File.join(@test_repo_root, 'beta'))
|
13
|
-
@beta.run_cmd('echo "hello beta" > README.md')
|
14
|
-
@beta.run_git_cmd('add .')
|
15
|
-
@beta.run_git_cmd('commit -m "hello"')
|
16
|
-
@beta.branch!('beta_feature')
|
17
|
-
@beta.checkout!('beta_feature')
|
18
|
-
@beta.run_cmd('echo "beta_feature" >> README.md')
|
19
|
-
@beta.run_git_cmd('add .')
|
20
|
-
@beta.run_git_cmd('commit -m "beta_feature"')
|
21
|
-
@beta.run_git_cmd('checkout main')
|
22
|
-
|
23
|
-
@alpha = Git::Repository.create(File.join(@test_repo_root, 'alpha'))
|
24
|
-
@alpha.submodule_add!('sb/beta', @beta.path, git_options: {'-c' => {'protocol.file.allow' => 'always'}})
|
25
|
-
@alpha.submodule_update!('sb/beta')
|
26
|
-
@alpha.run_cmd('echo "hello alpha" > README.md')
|
27
|
-
@alpha.run_git_cmd('add .')
|
28
|
-
@alpha.run_git_cmd('commit -m "hello"')
|
29
|
-
end
|
30
|
-
|
31
|
-
def teardown
|
32
|
-
FileUtils.rm_rf(@test_repo_root)
|
33
|
-
super
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_git_deep_merge
|
37
|
-
assert_equal "hello alpha\n", @alpha.run_cmd('cat README.md')
|
38
|
-
assert_equal "hello beta\n", @alpha.run_cmd('cat sb/beta/README.md')
|
39
|
-
|
40
|
-
@alpha.branch!('alpha_feature')
|
41
|
-
@alpha.checkout!('alpha_feature')
|
42
|
-
@alpha.run_cmd('echo "alpha_feature" >> README.md')
|
43
|
-
@alpha.submodules['sb/beta'].run_git_cmd('checkout beta_feature')
|
44
|
-
@alpha.run_git_cmd('add .')
|
45
|
-
@alpha.run_git_cmd('commit -m "alpha_feature"')
|
46
|
-
assert_equal "README.md\nsb/beta\n", @alpha.run_git_cmd('diff --name-only HEAD~1 HEAD')
|
47
|
-
|
48
|
-
@alpha.checkout!('main')
|
49
|
-
@alpha.submodule_update!
|
50
|
-
assert_equal "hello beta\n", @alpha.run_cmd('cat sb/beta/README.md')
|
51
|
-
@alpha.deep_merge('alpha_feature')
|
52
|
-
assert_equal "hello alpha\nalpha_feature\n", @alpha.run_cmd('cat README.md')
|
53
|
-
assert_equal "hello beta\nbeta_feature\n", @alpha.run_cmd('cat sb/beta/README.md')
|
54
|
-
end
|
55
7
|
end
|
56
8
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'coaster/git'
|
4
|
+
|
5
|
+
module Coaster
|
6
|
+
module Git
|
7
|
+
class TestOptions < Minitest::Test
|
8
|
+
def test_options_to_s
|
9
|
+
# assert_equal '-a b -c d ', Options.new(nil, '-a' => 'b', '-c' => 'd').to_s
|
10
|
+
assert_equal '--no-commit ', Options.new(nil, '--no-commit').to_s
|
11
|
+
assert_equal '-c a=b', Options.new(nil, '-c' => {'a' => 'b'}).to_s
|
12
|
+
assert_equal '-c a=b -c c=d', Options.new(nil, '-c' => {'a' => 'b', 'c' => 'd'}).to_s
|
13
|
+
assert_equal '-c a=b -c c=d', Options.new(nil, '-c' => Set[{'a' => 'b'}, {'c' => 'd'}]).to_s
|
14
|
+
assert_equal '--config=a=b,c=d', Options.new(nil, '--config' => [Set['a', 'b'], Set['c', 'd']]).to_s
|
15
|
+
assert_equal '--config=a=b --config=c=d', Options.new(nil, '--config' => Set[{'a' => 'b'}, {'c' => 'd'}]).to_s
|
16
|
+
assert_equal '-c a=b -- aaa bbb', Options.new(nil, '-c' => {'a' => 'b'}, '--' => ['aaa', 'bbb']).to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_options_to_h
|
20
|
+
opts = Options.new('git', '-c' => {'b' => 1}, '--config-env' => 'd=1')
|
21
|
+
assert_equal({"--config-env"=>{"b"=>"1", "d"=>"1"}}, opts.to_h)
|
22
|
+
assert_equal('--config-env=b=1 --config-env=d=1 ', opts.to_s)
|
23
|
+
opts = Options.new('merge', '--no-commit')
|
24
|
+
assert_equal({"--no-commit" => ''}, opts.to_h)
|
25
|
+
assert_equal('--no-commit ', opts.to_s)
|
26
|
+
opts = Options.new('git', {'-c' => {'a' => 'b'}, '--' => ['aaa', 'bbb']})
|
27
|
+
assert_equal('-c a=b -- aaa bbb', opts.to_s)
|
28
|
+
assert_equal({"--config-env" => {"a" => "b"}, '--' => ['aaa', 'bbb']}, opts.to_h)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'coaster/git'
|
4
|
+
|
5
|
+
module Coaster
|
6
|
+
class TestGitRepository < Minitest::Test
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
@test_repo_root = File.expand_path('../../tmp/test_repo', __FILE__)
|
10
|
+
FileUtils.rm_rf(@test_repo_root)
|
11
|
+
FileUtils.mkdir_p(@test_repo_root)
|
12
|
+
@beta = Coaster::Git.create(File.join(@test_repo_root, 'beta'))
|
13
|
+
@beta.run_cmd('echo "hello beta" > README.md')
|
14
|
+
@beta.add('.')
|
15
|
+
@beta.run_git_cmd('commit -m "hello"')
|
16
|
+
@beta.branch('beta_feature')
|
17
|
+
@beta.checkout('beta_feature')
|
18
|
+
@beta.run_cmd('echo "beta_feature" >> README.md')
|
19
|
+
@beta.add('.')
|
20
|
+
@beta.run_git_cmd('commit -m "beta_feature"')
|
21
|
+
@beta.run_git_cmd('checkout main')
|
22
|
+
|
23
|
+
@alpha = Coaster::Git.create(File.join(@test_repo_root, 'alpha'))
|
24
|
+
@alpha.with_git_options({'-c' => {'protocol.file.allow' => 'always'}}) do
|
25
|
+
@alpha.submodule_add!(@beta.path, 'sb/beta')
|
26
|
+
end
|
27
|
+
@alpha.submodule_update!('sb/beta')
|
28
|
+
@alpha.run_cmd('echo "hello alpha" > README.md')
|
29
|
+
@alpha.add('.')
|
30
|
+
@alpha.run_git_cmd('commit -m "hello"')
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown
|
34
|
+
FileUtils.rm_rf(@test_repo_root)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_git_deep_merge
|
39
|
+
assert_equal "hello alpha\n", @alpha.run_cmd('cat README.md')
|
40
|
+
assert_equal "hello beta\n", @alpha.run_cmd('cat sb/beta/README.md')
|
41
|
+
|
42
|
+
@alpha.branch('alpha_feature')
|
43
|
+
@alpha.checkout('alpha_feature')
|
44
|
+
@alpha.run_cmd('echo "alpha_feature" >> README.md')
|
45
|
+
@alpha.submodules['sb/beta'].run_git_cmd('checkout beta_feature')
|
46
|
+
@alpha.add('.')
|
47
|
+
@alpha.run_git_cmd('commit -m "alpha_feature"')
|
48
|
+
assert_equal "README.md\nsb/beta\n", @alpha.run_git_cmd('diff --name-only HEAD~1 HEAD')
|
49
|
+
|
50
|
+
@alpha.checkout('main')
|
51
|
+
@alpha.submodule_update!
|
52
|
+
@alpha.submodules['sb/beta'].run_cmd('echo "main new commit" >> README2.md')
|
53
|
+
@alpha.submodules['sb/beta'].add('.')
|
54
|
+
@alpha.submodules['sb/beta'].run_git_cmd('commit -m "main new commit"')
|
55
|
+
@alpha.add('.')
|
56
|
+
@alpha.run_git_cmd('commit -m "main new commit"')
|
57
|
+
assert_equal "hello beta\n", @alpha.run_cmd('cat sb/beta/README.md')
|
58
|
+
|
59
|
+
@alpha.deep_merge('alpha_feature')
|
60
|
+
assert_equal "hello alpha\nalpha_feature\n", @alpha.run_cmd('cat README.md')
|
61
|
+
assert_equal "hello beta\nbeta_feature\n", @alpha.run_cmd('cat sb/beta/README.md')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.33
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- buzz jung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -190,6 +190,7 @@ files:
|
|
190
190
|
- Rakefile
|
191
191
|
- bin/coaster
|
192
192
|
- lib/coaster.rb
|
193
|
+
- lib/coaster/cmd_options.rb
|
193
194
|
- lib/coaster/core_ext.rb
|
194
195
|
- lib/coaster/core_ext/array.rb
|
195
196
|
- lib/coaster/core_ext/date.rb
|
@@ -200,6 +201,7 @@ files:
|
|
200
201
|
- lib/coaster/core_ext/standard_error/raven.rb
|
201
202
|
- lib/coaster/core_ext/standard_error/sentry.rb
|
202
203
|
- lib/coaster/git.rb
|
204
|
+
- lib/coaster/git/options.rb
|
203
205
|
- lib/coaster/git/repository.rb
|
204
206
|
- lib/coaster/rails_ext.rb
|
205
207
|
- lib/coaster/rails_ext/backtrace_cleaner.rb
|
@@ -212,6 +214,8 @@ files:
|
|
212
214
|
- test/support/schema.rb
|
213
215
|
- test/test_backtrace.rb
|
214
216
|
- test/test_git.rb
|
217
|
+
- test/test_git_options.rb
|
218
|
+
- test/test_git_repository.rb
|
215
219
|
- test/test_helper.rb
|
216
220
|
- test/test_month.rb
|
217
221
|
- test/test_object_translation.rb
|
@@ -249,6 +253,8 @@ test_files:
|
|
249
253
|
- test/support/schema.rb
|
250
254
|
- test/test_backtrace.rb
|
251
255
|
- test/test_git.rb
|
256
|
+
- test/test_git_options.rb
|
257
|
+
- test/test_git_repository.rb
|
252
258
|
- test/test_helper.rb
|
253
259
|
- test/test_month.rb
|
254
260
|
- test/test_object_translation.rb
|