coaster 1.3.28 → 1.3.30

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69a9eb83228b624c93abb0c9a4388db9aefb093e6371c5894db112796be35216
4
- data.tar.gz: e120a8005d27155ad5db3c711085cf69dd946d6521c8e15311b182e0e51290f8
3
+ metadata.gz: aac619d5b87a41007fed3589618ba253e33307659e17aa689d06898e9a11042b
4
+ data.tar.gz: 362d24aedcb8cd9c462a50b059bb51ec7ba65dfee97d8a26dab85a3a2ab46035
5
5
  SHA512:
6
- metadata.gz: ac2f5e5d9e93408837d49926609d76b84eeed06f262404fd1c68aeb887782c2a44fd2e8f96374ce9db2b34bf8062640a645157f7d46b0e2bcaa9baaf31d5483f
7
- data.tar.gz: 5795ff40b61e4cba9405d76a8c20d2f7d743f933ec2d7bfaa683668ccfd80b556f4133b23e0039f40a38dabf9b35d19031cbc2456d9447594e42eb002d38563a
6
+ metadata.gz: c19b75ef110edf238f8423add0213c37f3f88a9d3f3442a6fc9b368acfa48603d6c7beed391ac5802983b9e0d92e930d69014847dd6c8e7e082e73d34f9c73e2
7
+ data.tar.gz: 6a756b8db4c72bb2aa6b91a59fe94e98acc895c8263bf751a08661da0abf1d92bf1b68602ead812fcacfd751a13654c7672d681a6a360cb29d871de8ff22b43b
data/bin/coaster ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'coaster'
4
+ require 'coaster/git'
5
+
6
+ command = ARGV.shift
7
+ if command == 'git'
8
+ repo = Git::Repository.new(Dir.pwd)
9
+ subcommand = ARGV.shift
10
+ repo.send(subcommand, *ARGV)
11
+ else
12
+ puts "Unknown command: #{command}"
13
+ end
@@ -0,0 +1,150 @@
1
+ module Coaster
2
+ module Git
3
+ class Repository
4
+ class << self
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 "Run command: #{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
59
+
60
+ attr_reader :path
61
+
62
+ def initialize(path)
63
+ @path = path
64
+ @sha = current_sha
65
+ end
66
+
67
+ def run_cmd(command)
68
+ self.class.run_cmd(path, command)
69
+ end
70
+
71
+ def run_git_cmd(command, *options)
72
+ cmd = "git #{self.class.option_parser(options)} #{command}"
73
+ run_cmd(cmd)
74
+ end
75
+
76
+ def add!
77
+ run_git_cmd('add .')
78
+ end
79
+
80
+ def commit!(message)
81
+ run_git_cmd("commit -m \"#{message}\"")
82
+ end
83
+
84
+ def branch!(name)
85
+ run_git_cmd("branch #{name}")
86
+ end
87
+
88
+ def checkout!(name)
89
+ run_git_cmd("checkout #{name}")
90
+ end
91
+
92
+ def submodule_add!(path, url, git_options: {})
93
+ run_git_cmd("submodule add #{url} #{path}", **git_options)
94
+ end
95
+
96
+ def submodule_init!(path)
97
+ run_git_cmd("submodule init #{path}")
98
+ end
99
+
100
+ def submodule_update!(*paths, options: {})
101
+ run_git_cmd("submodule update #{self.class.option_parser(options)} #{paths.join(' ')}")
102
+ end
103
+
104
+ def current_sha
105
+ run_git_cmd('rev-parse HEAD').strip
106
+ end
107
+
108
+ def submodule_paths
109
+ @submodule_paths ||= run_git_cmd('submodule status --recursive').split("\n").map do |line|
110
+ line.split(' ')[1]
111
+ end
112
+ end
113
+
114
+ def submodules
115
+ @submodules ||= submodule_paths.map do |path|
116
+ [path, Git::Repository.new(File.join(@path, path))]
117
+ end.to_h
118
+ end
119
+
120
+ def merge(pointer)
121
+ pointers = pointers(pointer).join(',')
122
+ puts "#{path} merged deploy, #{pointers}"
123
+ run_git_cmd("merge #{pointer} --commit -m \"merged deploy, #{pointers}\"")
124
+ end
125
+
126
+ def submodule_sha(path, pointer: nil)
127
+ pointer ||= @sha
128
+ run_git_cmd("ls-tree #{pointer} #{path}").split(' ')[2]
129
+ end
130
+
131
+ def deep_merge(pointer)
132
+ submodules.values.each do |submodule|
133
+ sm_sha = submodule_sha(submodule.path, pointer: pointer)
134
+ submodule.merge(sm_sha)
135
+ end
136
+ merge(pointer)
137
+ end
138
+
139
+ def pointers(sha)
140
+ run_git_cmd("branch --contains #{sha}").split("\n").map do |br|
141
+ (br.start_with?('*') ? br[2..-1] : br).strip
142
+ end
143
+ end
144
+
145
+ def remove
146
+ self.class.run_cmd(path.split('/')[0..-2].join('/'), "rm -rf #{path}")
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,9 @@
1
+ require 'open3'
2
+
3
+ module Coaster
4
+ module Git
5
+
6
+ end
7
+ end
8
+
9
+ require 'coaster/git/repository'
@@ -1,3 +1,3 @@
1
1
  module Coaster
2
- VERSION = '1.3.28'
2
+ VERSION = '1.3.30'
3
3
  end
data/test/test_git.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+ require 'minitest/autorun'
3
+ require 'coaster/git'
4
+
5
+ module Coaster
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
+ end
56
+ end
@@ -24,7 +24,7 @@ module Coaster
24
24
  end
25
25
 
26
26
  def test_translation_missing
27
- assert_equal 'translation missing: en.class.Coaster.NotTranslated.self', NotTranslated._translate
27
+ assert_equal 'Translation missing: en.class.Coaster.NotTranslated.self', NotTranslated._translate
28
28
  end
29
29
 
30
30
  def test_fallback
@@ -64,12 +64,12 @@ module Coaster
64
64
  assert_equal 'user message', e.user_message
65
65
  assert_equal 'standard error title', e.title
66
66
  e = UntitledError.new(tkey: 'no.translation')
67
- assert_equal "translation missing: en.no.translation (Coaster::TestStandardError::UntitledError)", e.to_s
68
- assert_equal "translation missing: en.no.translation (Coaster::TestStandardError::UntitledError)", e.message
67
+ assert_equal "Translation missing: en.no.translation (Coaster::TestStandardError::UntitledError)", e.to_s
68
+ assert_equal "Translation missing: en.no.translation (Coaster::TestStandardError::UntitledError)", e.message
69
69
  assert_nil e.description
70
70
  assert_nil e.desc
71
- assert_equal 'translation missing: en.no.translation', e._translate
72
- assert_equal "translation missing: en.no.translation", e.user_message
71
+ assert_equal 'Translation missing: en.no.translation', e._translate
72
+ assert_equal "Translation missing: en.no.translation", e.user_message
73
73
  assert_equal 'standard error title', e.title
74
74
  end
75
75
 
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.28
4
+ version: 1.3.30
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-05-02 00:00:00.000000000 Z
11
+ date: 2023-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -180,13 +180,15 @@ dependencies:
180
180
  version: '0'
181
181
  description: Ruby Core Extensions
182
182
  email: buzz@frograms.com
183
- executables: []
183
+ executables:
184
+ - coaster
184
185
  extensions: []
185
186
  extra_rdoc_files: []
186
187
  files:
187
188
  - LICENSE
188
189
  - README.md
189
190
  - Rakefile
191
+ - bin/coaster
190
192
  - lib/coaster.rb
191
193
  - lib/coaster/core_ext.rb
192
194
  - lib/coaster/core_ext/array.rb
@@ -197,6 +199,8 @@ files:
197
199
  - lib/coaster/core_ext/standard_error.rb
198
200
  - lib/coaster/core_ext/standard_error/raven.rb
199
201
  - lib/coaster/core_ext/standard_error/sentry.rb
202
+ - lib/coaster/git.rb
203
+ - lib/coaster/git/repository.rb
200
204
  - lib/coaster/rails_ext.rb
201
205
  - lib/coaster/rails_ext/backtrace_cleaner.rb
202
206
  - lib/coaster/safe_yaml_serializer.rb
@@ -207,6 +211,7 @@ files:
207
211
  - test/support/models.rb
208
212
  - test/support/schema.rb
209
213
  - test/test_backtrace.rb
214
+ - test/test_git.rb
210
215
  - test/test_helper.rb
211
216
  - test/test_month.rb
212
217
  - test/test_object_translation.rb
@@ -216,7 +221,9 @@ files:
216
221
  homepage: http://github.com/frograms/coaster
217
222
  licenses:
218
223
  - MIT
219
- metadata: {}
224
+ metadata:
225
+ source_code_uri: https://github.com/frograms/coaster
226
+ bug_tracker_uri: https://github.com/frograms/coaster/issues
220
227
  post_install_message:
221
228
  rdoc_options: []
222
229
  require_paths:
@@ -241,6 +248,7 @@ test_files:
241
248
  - test/support/models.rb
242
249
  - test/support/schema.rb
243
250
  - test/test_backtrace.rb
251
+ - test/test_git.rb
244
252
  - test/test_helper.rb
245
253
  - test/test_month.rb
246
254
  - test/test_object_translation.rb