avm 0.5.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/lib/avm/data/package/dump.rb +3 -3
  3. data/lib/avm/{files → data}/rotate.rb +1 -1
  4. data/lib/avm/docker/runner.rb +8 -0
  5. data/lib/avm/instances/application.rb +25 -0
  6. data/lib/avm/instances/base/auto_values/access.rb +40 -0
  7. data/lib/avm/instances/base/auto_values/admin.rb +19 -0
  8. data/lib/avm/instances/base/auto_values/data.rb +26 -0
  9. data/lib/avm/instances/base/auto_values/database.rb +76 -0
  10. data/lib/avm/instances/base/auto_values/filesystem.rb +45 -0
  11. data/lib/avm/instances/base/auto_values/mailer.rb +34 -0
  12. data/lib/avm/instances/base/auto_values/ruby.rb +15 -0
  13. data/lib/avm/instances/base/auto_values/source.rb +15 -0
  14. data/lib/avm/instances/base/auto_values/system.rb +23 -0
  15. data/lib/avm/instances/base/auto_values/web.rb +46 -0
  16. data/lib/avm/instances/base/auto_values.rb +21 -0
  17. data/lib/avm/instances/base/dockerizable.rb +45 -0
  18. data/lib/avm/instances/base/entry_keys.rb +22 -0
  19. data/lib/avm/instances/base.rb +64 -0
  20. data/lib/avm/instances/entries.rb +43 -0
  21. data/lib/avm/instances/entry.rb +54 -0
  22. data/lib/avm/instances/entry_keys.rb +57 -0
  23. data/lib/avm/instances/runner.rb +38 -0
  24. data/lib/avm/instances.rb +8 -0
  25. data/lib/avm/jobs/base.rb +1 -0
  26. data/lib/avm/registry/base.rb +65 -0
  27. data/lib/avm/registry.rb +29 -0
  28. data/lib/avm/rspec/setup.rb +22 -0
  29. data/lib/avm/rspec/shared_examples/in_avm_registry.rb +11 -0
  30. data/lib/avm/rspec/shared_examples/not_in_avm_registry.rb +14 -0
  31. data/lib/avm/{git/organize.rb → rspec.rb} +2 -4
  32. data/lib/avm/runners/base.rb +31 -0
  33. data/lib/avm/scms/base.rb +28 -0
  34. data/lib/avm/scms/commit.rb +43 -0
  35. data/lib/avm/self/docker_image.rb +14 -0
  36. data/lib/avm/self/instance/entry_keys.rb +12 -0
  37. data/lib/avm/self/instance.rb +24 -0
  38. data/lib/avm/source_stereotypes/base.rb +21 -0
  39. data/lib/avm/sources/base.rb +22 -0
  40. data/lib/avm/version.rb +1 -1
  41. metadata +58 -67
  42. data/lib/avm/files/appendable/file_content.rb +0 -24
  43. data/lib/avm/files/appendable/plain_directory.rb +0 -25
  44. data/lib/avm/files/appendable/resource_base.rb +0 -13
  45. data/lib/avm/files/appendable/tar_output_command.rb +0 -26
  46. data/lib/avm/files/appendable/templatized_directory.rb +0 -29
  47. data/lib/avm/files/appendable.rb +0 -55
  48. data/lib/avm/files/appender.rb +0 -11
  49. data/lib/avm/files/deploy.rb +0 -71
  50. data/lib/avm/files/formatter/formats/base.rb +0 -62
  51. data/lib/avm/files/formatter/formats/generic_plain.rb +0 -34
  52. data/lib/avm/files/formatter/formats/html.rb +0 -45
  53. data/lib/avm/files/formatter/formats/javascript.rb +0 -24
  54. data/lib/avm/files/formatter/formats/json.rb +0 -27
  55. data/lib/avm/files/formatter/formats/php.rb +0 -22
  56. data/lib/avm/files/formatter/formats/python.rb +0 -22
  57. data/lib/avm/files/formatter/formats/ruby.rb +0 -22
  58. data/lib/avm/files/formatter/formats/xml.rb +0 -28
  59. data/lib/avm/files/formatter/formats.rb +0 -13
  60. data/lib/avm/files/formatter/utf8_assert.rb +0 -74
  61. data/lib/avm/files/formatter.rb +0 -90
  62. data/lib/avm/files.rb +0 -9
  63. data/lib/avm/git/auto_commit/commit_info.rb +0 -23
  64. data/lib/avm/git/auto_commit/rules/base.rb +0 -39
  65. data/lib/avm/git/auto_commit/rules/last.rb +0 -19
  66. data/lib/avm/git/auto_commit/rules/manual.rb +0 -45
  67. data/lib/avm/git/auto_commit/rules/new.rb +0 -24
  68. data/lib/avm/git/auto_commit/rules/nth.rb +0 -31
  69. data/lib/avm/git/auto_commit/rules/unique.rb +0 -21
  70. data/lib/avm/git/auto_commit/rules.rb +0 -31
  71. data/lib/avm/git/auto_commit_path/ruby.rb +0 -20
  72. data/lib/avm/git/auto_commit_path.rb +0 -28
  73. data/lib/avm/git/commit/class_methods.rb +0 -31
  74. data/lib/avm/git/commit/deploy.rb +0 -38
  75. data/lib/avm/git/commit/deploy_methods.rb +0 -19
  76. data/lib/avm/git/commit/diff_tree_line.rb +0 -32
  77. data/lib/avm/git/commit/file.rb +0 -46
  78. data/lib/avm/git/commit.rb +0 -59
  79. data/lib/avm/git/file_auto_fixup.rb +0 -83
  80. data/lib/avm/git/issue/complete/commits.rb +0 -42
  81. data/lib/avm/git/issue/complete/git_subrepos.rb +0 -23
  82. data/lib/avm/git/issue/complete/local_branch.rb +0 -54
  83. data/lib/avm/git/issue/complete/local_tag.rb +0 -39
  84. data/lib/avm/git/issue/complete/push.rb +0 -54
  85. data/lib/avm/git/issue/complete/remote.rb +0 -33
  86. data/lib/avm/git/issue/complete/test.rb +0 -45
  87. data/lib/avm/git/issue/complete/tracker.rb +0 -28
  88. data/lib/avm/git/issue/complete/validation.rb +0 -31
  89. data/lib/avm/git/issue/complete/validations.rb +0 -53
  90. data/lib/avm/git/issue/complete/working_tree.rb +0 -19
  91. data/lib/avm/git/issue/complete.rb +0 -51
  92. data/lib/avm/git/issue/deliver.rb +0 -56
  93. data/lib/avm/git/issue.rb +0 -11
  94. data/lib/avm/git/organize/reference_update.rb +0 -34
  95. data/lib/avm/git/organize/repository.rb +0 -76
  96. data/lib/avm/git/revision_test.rb +0 -105
  97. data/lib/avm/git/subrepo_check/parent.rb +0 -51
  98. data/lib/avm/git/subrepo_check/remote.rb +0 -89
  99. data/lib/avm/git/subrepo_check/show_result.rb +0 -32
  100. data/lib/avm/git/subrepo_check.rb +0 -38
  101. data/lib/avm/git/subrepo_checks.rb +0 -59
  102. data/lib/avm/git.rb +0 -10
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/files/formatter/formats/generic_plain'
4
- require 'avm/ruby/rubocop'
5
-
6
- module Avm
7
- module Files
8
- class Formatter
9
- module Formats
10
- class Ruby < ::Avm::Files::Formatter::Formats::GenericPlain
11
- VALID_BASENAMES = %w[*.gemspec *.rake *.rb Gemfile Rakefile].freeze
12
- VALID_TYPES = ['x-ruby'].freeze
13
-
14
- def internal_apply(files)
15
- ::Avm::Ruby::Rubocop.new('.', ['-a', '--ignore-parent-exclusion'] + files).run
16
- super(files)
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/executables'
4
- require 'avm/files/formatter/formats/generic_plain'
5
-
6
- module Avm
7
- module Files
8
- class Formatter
9
- module Formats
10
- class Xml < ::Avm::Files::Formatter::Formats::GenericPlain
11
- VALID_BASENAMES = %w[*.xml].freeze
12
- VALID_TYPES = ['xml'].freeze
13
-
14
- def internal_apply(files)
15
- format_command(files).system!
16
- super(files)
17
- end
18
-
19
- def format_command(files)
20
- ::Avm::Executables.tidy.command.append(
21
- %w[-xml -modify --indent auto --indent-spaces 2 --wrap 100] + files
22
- )
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Files
7
- class Formatter
8
- module Formats
9
- require_sub __FILE__
10
- end
11
- end
12
- end
13
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_fs/file_info'
4
-
5
- module Avm
6
- module Files
7
- class Formatter
8
- class Utf8Assert
9
- UTF8_CHARSET = 'utf-8'
10
- UTF8_CHARSETS = [UTF8_CHARSET, 'us-ascii'].freeze
11
-
12
- class << self
13
- def assert_files(files)
14
- asserters = files.map { |file| new(file) }
15
- begin
16
- asserters.each(&:assert)
17
- yield
18
- ensure
19
- asserters.each(&:revert)
20
- end
21
- end
22
- end
23
-
24
- enable_simple_cache
25
- common_constructor :path
26
-
27
- def assert
28
- return if original_utf8?
29
-
30
- convert_self(original_charset, UTF8_CHARSET)
31
- end
32
-
33
- def revert
34
- return if original_utf8?
35
-
36
- convert_self(UTF8_CHARSET, original_charset)
37
- end
38
-
39
- private
40
-
41
- def original_info_uncached
42
- ::EacFs::FileInfo.new(path)
43
- end
44
-
45
- def original_charset_uncached
46
- return original_info.content_type.charset if original_info.content_type.charset.present?
47
-
48
- raise 'No charset found'
49
- rescue StandardError => e
50
- raise "Unable to determine the charset of #{path} (#{e.message})"
51
- end
52
-
53
- def original_utf8?
54
- UTF8_CHARSETS.include?(original_charset)
55
- end
56
-
57
- def convert_file(from_path, from_charset, to_path, to_charset)
58
- File.open(from_path, "r:#{from_charset}") do |input|
59
- File.open(to_path, "w:#{to_charset}") do |output|
60
- output.write(input.read)
61
- end
62
- end
63
- end
64
-
65
- def convert_self(from_charset, to_charset)
66
- temp = ::Tempfile.new
67
- temp.close
68
- convert_file(path, from_charset, temp.path, to_charset)
69
- ::FileUtils.mv(temp.path, path)
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
- require 'eac_ruby_utils/fs/traversable'
5
-
6
- module Avm
7
- module Files
8
- class Formatter
9
- include ::EacRubyUtils::Fs::Traversable
10
- require_sub __FILE__
11
- enable_simple_cache
12
- enable_speaker
13
- enable_listable
14
- lists.add_symbol :option, :apply, :recursive, :verbose
15
- common_constructor :source_paths, :options, default: [{}] do
16
- options.assert_valid_keys(self.class.lists.option.values)
17
- end
18
-
19
- FORMATS = %w[ruby php html python xml javascript json generic_plain].freeze
20
-
21
- def run
22
- clear
23
- search_files
24
- apply
25
- show_results
26
- end
27
-
28
- private
29
-
30
- def apply
31
- infom "Applying #{@formats_files.count} format(s)... "
32
- @formats_files.each do |format, files|
33
- infom "Applying format #{format.name} (Files matched: #{files.count})..."
34
- next unless options[OPTION_APPLY]
35
-
36
- @result += format.apply(files)
37
- end
38
- end
39
-
40
- def traverser_check_file(file)
41
- format = find_format(file)
42
- infov file, format ? format.class : '-' if options[OPTION_VERBOSE]
43
- return unless format
44
-
45
- @formats_files[format] ||= []
46
- @formats_files[format] << file
47
- end
48
-
49
- def clear
50
- @formats_files = {}
51
- @result = []
52
- end
53
-
54
- def find_format(file)
55
- formats.each do |c|
56
- return c if c.match?(file)
57
- end
58
- nil
59
- end
60
-
61
- def formats_uncached
62
- FORMATS.map do |identifier|
63
- "avm/files/formatter/formats/#{identifier}".camelize.constantize.new
64
- end
65
- end
66
-
67
- def search_files
68
- infov 'Directories to search', source_paths.count
69
- source_paths.each do |source_path|
70
- infom "Searching files on \"#{source_path}\"..."
71
- traverser_check_path(source_path)
72
- end
73
- end
74
-
75
- def show_results
76
- changed = @result.select(&:changed)
77
- changed.each do |h|
78
- out h.file.to_s.cyan
79
- out " (#{h.format})".yellow
80
- puts ' changed'.green
81
- end
82
- infov('Files changed', "#{changed.count}/#{@result.count}")
83
- end
84
-
85
- def traverser_recursive
86
- options[OPTION_RECURSIVE]
87
- end
88
- end
89
- end
90
- end
data/lib/avm/files.rb DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/require_sub'
4
- ::EacRubyUtils.require_sub(__FILE__)
5
-
6
- module Avm
7
- module Files
8
- end
9
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- class CommitInfo
9
- enable_immutable
10
-
11
- immutable_accessor :fixup, :message
12
-
13
- def git_commit_args
14
- r = fixup.if_present([]) { |v| ['--fixup', v.sha1] }
15
- r += message.if_present([]) { |v| ['--message', v] }
16
- return r if r.any?
17
-
18
- raise 'Argument list is empty'
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- module Rules
9
- class Base
10
- class << self
11
- def keys
12
- [long_key, short_key]
13
- end
14
-
15
- def long_key
16
- name.demodulize.variableize
17
- end
18
-
19
- def short_key
20
- long_key[0, 1]
21
- end
22
- end
23
-
24
- def with_file(file)
25
- self.class.const_get('WithFile').new(self, file)
26
- end
27
-
28
- class WithFile
29
- common_constructor :rule, :file
30
-
31
- def new_commit_info
32
- ::Avm::Git::AutoCommit::CommitInfo.new
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/git/auto_commit/rules/base'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- module Rules
9
- class Last < ::Avm::Git::AutoCommit::Rules::Base
10
- class WithFile < ::Avm::Git::AutoCommit::Rules::Base::WithFile
11
- def commit_info
12
- file.commits.last.if_present { |v| new_commit_info.fixup(v) }
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/git/auto_commit/rules/base'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- module Rules
9
- class Manual < ::Avm::Git::AutoCommit::Rules::Base
10
- class WithFile < ::Avm::Git::AutoCommit::Rules::Base::WithFile
11
- enable_speaker
12
-
13
- COMMIT_FORMAT = '%h - %s (%cr)'
14
- SKIP_OPTION = 's'
15
-
16
- def commit_info
17
- return nil unless file.commits.any?
18
-
19
- commits_banner
20
- input('Which commit?', list: commits_by_position).if_present do |v|
21
- new_commit_info.fixup(v)
22
- end
23
- end
24
-
25
- def commits_banner
26
- file.commits.each_with_index do |commit, _index|
27
- infov " #{commit.position}", format_commit(commit)
28
- end
29
- infov " #{SKIP_OPTION}", 'skip'
30
- end
31
-
32
- def commits_by_position
33
- (file.commits.map { |commit| [commit.position.to_s, commit] } + [[SKIP_OPTION, nil]])
34
- .to_h
35
- end
36
-
37
- def format_commit(commit)
38
- commit.format(COMMIT_FORMAT)
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/git/auto_commit/rules/base'
4
- require 'avm/git/auto_commit_path'
5
-
6
- module Avm
7
- module Git
8
- module AutoCommit
9
- module Rules
10
- class New < ::Avm::Git::AutoCommit::Rules::Base
11
- class WithFile < ::Avm::Git::AutoCommit::Rules::Base::WithFile
12
- def auto_commit_path
13
- ::Avm::Git::AutoCommitPath.new(file.git, file.path)
14
- end
15
-
16
- def commit_info
17
- new_commit_info.message(auto_commit_path.commit_message)
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/git/auto_commit/rules/base'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- module Rules
9
- class Nth < ::Avm::Git::AutoCommit::Rules::Base
10
- SHORT_KEY = 't'
11
-
12
- class << self
13
- def short_key
14
- SHORT_KEY
15
- end
16
- end
17
-
18
- common_constructor :number do
19
- self.number = number.to_i
20
- end
21
-
22
- class WithFile < ::Avm::Git::AutoCommit::Rules::Base::WithFile
23
- def commit_info
24
- file.commits(number - 1).if_present { |v| new_commit_info.fixup(v) }
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avm/git/auto_commit/rules/base'
4
-
5
- module Avm
6
- module Git
7
- module AutoCommit
8
- module Rules
9
- class Unique < ::Avm::Git::AutoCommit::Rules::Base
10
- class WithFile < ::Avm::Git::AutoCommit::Rules::Base::WithFile
11
- def commit_info
12
- return nil unless file.commits.count == 1
13
-
14
- new_commit_info.fixup(file.commits.first)
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- ::EacRubyUtils.require_sub __FILE__
6
-
7
- module Avm
8
- module Git
9
- module AutoCommit
10
- module Rules
11
- RULES_CLASSES = %w[last manual new nth unique]
12
- .map { |key| ::Avm::Git::AutoCommit::Rules.const_get(key.camelcase) }
13
-
14
- class << self
15
- def parse(string)
16
- parts = string.split(':')
17
-
18
- klass = rule_class_by_key(parts.shift)
19
- klass.new(*parts)
20
- end
21
-
22
- def rule_class_by_key(key)
23
- RULES_CLASSES.find { |klass| klass.keys.include?(key) } ||
24
- raise("Rule not find with key \"#{key}\" (Available: " +
25
- RULES_CLASSES.flat_map(&:keys).join(', ') + ')')
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- class AutoCommitPath
8
- module Ruby
9
- RUBY_CLASS_NAME_PATTERNS = [%r{lib/((?!.*/lib/).+)\.rb\z}, %r{app/[^/]+/(.+)\.rb\z}].freeze
10
-
11
- def ruby_class_name
12
- RUBY_CLASS_NAME_PATTERNS.each do |pattern|
13
- pattern.if_match(relative_path.to_path, false) { |m| return m[1].camelize }
14
- end
15
- nil
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- class AutoCommitPath
8
- require_sub __FILE__, include_modules: true
9
- common_constructor :git, :path do
10
- self.path = path.to_pathname
11
- end
12
-
13
- def class_name
14
- ruby_class_name || relative_path.to_path
15
- end
16
-
17
- def commit_message
18
- r = class_name
19
- r += ': remove' unless path.file?
20
- r + '.'
21
- end
22
-
23
- def relative_path
24
- path.expand_path.relative_path_from(git.root_path.expand_path)
25
- end
26
- end
27
- end
28
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- class Commit
8
- module ClassMethods
9
- common_concern
10
-
11
- module ClassMethods
12
- def target_url_to_env_path(target_url)
13
- uri = ::Addressable::URI.parse(target_url)
14
- uri.scheme = 'file' if uri.scheme.blank?
15
- [uri_to_env(uri), uri.path]
16
- end
17
-
18
- private
19
-
20
- def uri_to_env(uri)
21
- case uri.scheme
22
- when 'file' then ::EacRubyUtils::Envs.local
23
- when 'ssh' then ::EacRubyUtils::Envs.ssh(uri)
24
- else "Invalid schema \"#{uri.schema}\" (URI: #{uri})"
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'addressable'
4
- require 'eac_ruby_utils/core_ext'
5
- require 'avm/files/appendable'
6
- require 'avm/files/deploy'
7
-
8
- module Avm
9
- module Git
10
- class Commit
11
- class Deploy
12
- include ::Avm::Files::Appendable
13
- enable_simple_cache
14
-
15
- attr_reader :build_dir, :commit, :target_env, :target_path
16
-
17
- def initialize(commit, target_env, target_path)
18
- @commit = commit
19
- @target_env = target_env
20
- @target_path = target_path
21
- end
22
-
23
- def run
24
- fd = ::Avm::Files::Deploy.new(target_env, target_path)
25
- fd.append_tar_output_command(git_archive_command)
26
- fd.appended.push(*appended)
27
- fd.run
28
- end
29
-
30
- private
31
-
32
- def git_archive_command
33
- commit.git.command('archive', '--format=tar', commit.sha1)
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Git
7
- class Commit
8
- module DeployMethods
9
- def deploy_to_env_path(target_env, target_path)
10
- Deploy.new(self, target_env, target_path)
11
- end
12
-
13
- def deploy_to_url(target_url)
14
- Deploy.new(self, *self.class.target_url_to_env_path(target_url))
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Avm
4
- module Git
5
- class Commit
6
- class DiffTreeLine
7
- DIFF_TREE_PATTERN = /\A:(\d{6}) (\d{6}) (\S+) (\S+) (\S+)\t(\S.*)\z/.freeze
8
- FIELDS = %w[src_mode dst_mode src_sha1 dst_sha1 status path].freeze
9
- GIT_COMMAND_ARGS = %w[-c core.quotepath=off diff-tree --no-commit-id -r --full-index].freeze
10
-
11
- attr_reader(*FIELDS)
12
-
13
- # line: a line of command "git [GIT_COMMAND_ARGS]"'s output.
14
- # Reference: https://git-scm.com/docs/git-diff-tree
15
- def initialize(line)
16
- m = DIFF_TREE_PATTERN.match(line.strip)
17
- raise "\"#{line}\" did not match pattern" unless m
18
-
19
- FIELDS.count.times { |i| send("#{FIELDS[i]}=", m[i + 1]) }
20
- end
21
-
22
- def fields
23
- FIELDS.map { |field| [field, send(field)] }.to_h
24
- end
25
-
26
- private
27
-
28
- attr_writer(*FIELDS)
29
- end
30
- end
31
- end
32
- end