ast-merge-git 7.1.1 → 7.1.3

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: 6527f8c9a9e11a701a0650d6b6eb473c2182368ca1bef5338392ad332461911a
4
- data.tar.gz: d8b813c4d98258a2ed46b016a943e350271b13a5f17d31f13733dea638fccc6f
3
+ metadata.gz: e6c6a8e98b15372fd7b01969b96b15bd463a9c339debba9150d67a336c2592d3
4
+ data.tar.gz: ef2a36f8917e49e6b24e99955c822e100075d0db1fc06a02be2042ccf8fd6732
5
5
  SHA512:
6
- metadata.gz: 8bc8b1aea1fbc0d857a6ce20280b28e634717a1ada45db509a1443ad6465776cb04be45d0c33b5d893a61ff8701dbab48196d67038c46ec4edee41d887329474
7
- data.tar.gz: db7093c64f37155685bdac5ae5b8fdc5120d51a5b1f154bef1bf05badb5a00c721a8bcef9205fed399dae76fc2bcbeb707d749c9c3a67ad122a3d06d724bd9c8
6
+ metadata.gz: 493581576c35445cf976532db9320373bc7de6cdaf09b4a68a860758ea99de388af50052f4b9f14beacc2f0b550884fa27b1557459aec2a5b6d196a2c64d27ec
7
+ data.tar.gz: aa796efcb1e9a40ef136347bcdc47f793302d023ebded28c19dba0328c6993803b4bc84ec9df6289bdf41fa73aee9a43799814e2de98c4a42a847af0315bcd6e
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -26,7 +26,7 @@ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-ta
26
26
  ### Key Features
27
27
 
28
28
  - Git-oriented request and response shaping for three-way merge driver integrations.
29
- - Family detection from path, extension, and configured merge behavior.
29
+ - Provider selection from explicit family/provider, dialect, backend, and profile selectors.
30
30
  - JSON-compatible reports that can be logged, inspected, or replayed by higher-level tooling.
31
31
  - Fallback-friendly behavior for unsupported families or unsafe parser results.
32
32
 
@@ -45,7 +45,7 @@ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-ta
45
45
 
46
46
  ### Compatibility
47
47
 
48
- Compatible with MRI Ruby 4.0.0+, and concordant releases of JRuby, and TruffleRuby.
48
+ Compatible with MRI Ruby 4.0.0+, JRuby, and TruffleRuby.
49
49
  CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
50
50
  This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
51
51
  may be higher than the gem's runtime compatibility floor when legacy Rubies are
@@ -87,17 +87,29 @@ gem install ast-merge-git
87
87
 
88
88
  ## ⚙️ Configuration
89
89
 
90
- Configure `ast-merge-git` through the repository's Git attributes and StructuredMerge family settings. The gem expects callers to provide the ancestor, current, and incoming file contents that Git passes to a custom merge driver.
90
+ Configure `ast-merge-git` through the repository's Git attributes and StructuredMerge provider settings. The gem expects callers to provide the ancestor, current, and incoming file contents that Git passes to a custom merge driver.
91
91
 
92
92
  Keep family-specific parser configuration in the corresponding merge gem. For example, Markdown backend choices belong to `markdown-merge` or its provider gems, while Ruby source backend choices belong to `ruby-merge` or `prism-merge`.
93
93
 
94
+ The executable does not infer or require family implementations. Configure
95
+ `AST_MERGE_REQUIRE` with comma-separated provider require paths and select a
96
+ provider with `AST_MERGE_FAMILY` or `AST_MERGE_PROVIDER`. Optional selectors are
97
+ `AST_MERGE_DIALECT`, `AST_MERGE_BACKEND`, and `AST_MERGE_PROFILE`.
98
+
99
+ ```ini
100
+ [merge "structured-json"]
101
+ name = StructuredMerge JSON-family driver
102
+ driver = AST_MERGE_REQUIRE=json/merge AST_MERGE_FAMILY=json AST_MERGE_DIALECT=json ast-merge-git %O %A %B %P %L
103
+ ```
104
+
94
105
  ## 🔧 Basic Usage
95
106
 
96
107
  ```ruby
97
108
  require "ast/merge/git"
109
+ require "json/merge"
98
110
 
99
111
  result = Ast::Merge::Git.merge3(
100
- language: "json",
112
+ family: "json",
101
113
  dialect: "json",
102
114
  base_source: File.binread("%O"),
103
115
  ours_source: File.binread("%A"),
@@ -112,6 +124,12 @@ else
112
124
  end
113
125
  ```
114
126
 
127
+ For direct Git-driver execution, `ast-merge-git` writes clean provider output to
128
+ `%A` and exits `0`. Unresolved conflicts exit `1`; unsupported capabilities,
129
+ invalid provider output, configuration failures, and file errors exit `2`.
130
+ `AST_MERGE_CONFLICT_POLICY=leave_ours` prevents conflicted output from replacing
131
+ `%A`; the default `write` policy writes provider conflict output when available.
132
+
115
133
  ## 🔐 Security
116
134
 
117
135
  See [SECURITY.md][🔐security].
@@ -119,20 +137,12 @@ See [SECURITY.md][🔐security].
119
137
  ## 🤝 Contributing
120
138
 
121
139
  If you need some ideas of where to help, you could work on adding more code coverage,
122
- or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
123
- or use the gem and think about how it could be better.
140
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
124
141
 
125
142
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
126
143
 
127
144
  See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
128
145
 
129
- ### Code Coverage
130
-
131
- <details markdown="1">
132
- <summary>Coverage service badges</summary>
133
-
134
- </details>
135
-
136
146
  ## 📌 Versioning
137
147
 
138
148
  This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
data/exe/ast-merge-git ADDED
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ast/merge/git'
5
+
6
+ if ARGV.first == 'benchmark'
7
+ require 'json'
8
+ require 'optparse'
9
+
10
+ command = ARGV.fetch(1, 'help')
11
+ options = {
12
+ profile: 'micro',
13
+ changed_paths: [],
14
+ tmp_root: File.expand_path('../tmp/benchmark', __dir__),
15
+ timeout: 30
16
+ }
17
+ parser = OptionParser.new do |opts|
18
+ opts.banner = 'usage: ast-merge-git benchmark validate|select|run|report [options]'
19
+ opts.on('--corpus PATH') { |value| options[:corpus] = value }
20
+ opts.on('--profile PROFILE') { |value| options[:profile] = value }
21
+ opts.on('--changed-path PATH') { |value| options[:changed_paths] << value }
22
+ opts.on('--driver PATH') { |value| options[:driver] = value }
23
+ opts.on('--tmp-root PATH') { |value| options[:tmp_root] = value }
24
+ opts.on('--timeout SECONDS', Integer) { |value| options[:timeout] = value }
25
+ end
26
+
27
+ begin
28
+ parser.parse!(ARGV.drop(2))
29
+ raise Ast::Merge::Git::LocalBenchmark::Error, '--corpus is required' unless options[:corpus]
30
+
31
+ benchmark = Ast::Merge::Git::LocalBenchmark.load(options[:corpus])
32
+ output = case command
33
+ when 'validate'
34
+ { schema_version: 1, valid: benchmark.validate!, corpus_id: benchmark.document['id'],
35
+ corpus_digest: benchmark.corpus_digest, cases: benchmark.cases.length }
36
+ when 'select'
37
+ benchmark.select(profile: options[:profile], changed_paths: options[:changed_paths])
38
+ when 'run', 'report'
39
+ driver = options[:driver] || Gem.bin_path('ast-merge-git', 'ast-merge-git')
40
+ run = Ast::Merge::Git::LocalBenchmarkRunner.new(
41
+ benchmark: benchmark,
42
+ driver_path: driver,
43
+ tmp_root: options[:tmp_root],
44
+ timeout: options[:timeout]
45
+ ).run(profile: options[:profile], changed_paths: options[:changed_paths])
46
+ command == 'report' ? Ast::Merge::Git::LocalBenchmarkReport.build(run) : run
47
+ else
48
+ warn parser
49
+ exit 2
50
+ end
51
+ puts JSON.generate(output)
52
+ exit 1 if command == 'report' && output['hard_gate_failed']
53
+ rescue Ast::Merge::Git::LocalBenchmark::Error, OptionParser::ParseError => e
54
+ warn "ast-merge-git benchmark: #{e.message}"
55
+ exit 2
56
+ end
57
+ exit 0
58
+ end
59
+
60
+ if ARGV.first == 'corpus'
61
+ require 'json'
62
+ require 'optparse'
63
+
64
+ command = ARGV.fetch(1, 'help')
65
+ options = { tmp_root: File.expand_path('../tmp/corpus', __dir__), timeout: 30 }
66
+ parser = OptionParser.new do |opts|
67
+ opts.banner = 'usage: ast-merge-git corpus validate|run|acquire [options]'
68
+ opts.on('--manifest PATH') { |value| options[:manifest] = value }
69
+ opts.on('--repository PATH') { |value| options[:repository] = value }
70
+ opts.on('--driver PATH') { |value| options[:driver] = value }
71
+ opts.on('--tmp-root PATH') { |value| options[:tmp_root] = value }
72
+ opts.on('--case ID') { |value| options[:case_id] = value }
73
+ opts.on('--destination PATH') { |value| options[:destination] = value }
74
+ opts.on('--timeout SECONDS', Integer) { |value| options[:timeout] = value }
75
+ end
76
+
77
+ begin
78
+ parser.parse!(ARGV.drop(2))
79
+ raise Ast::Merge::Git::Corpus::Error, '--manifest is required' unless options[:manifest]
80
+
81
+ corpus = Ast::Merge::Git::Corpus.load(options[:manifest])
82
+ case command
83
+ when 'validate'
84
+ corpus.validate!
85
+ puts JSON.generate(schema_version: 1, valid: true, cases: corpus.manifest.fetch('cases').length)
86
+ when 'acquire'
87
+ raise Ast::Merge::Git::Corpus::Error, '--destination is required' unless options[:destination]
88
+
89
+ path = Ast::Merge::Git::CorpusAcquirer.acquire(
90
+ corpus: corpus,
91
+ destination: options[:destination],
92
+ tmp_root: options[:tmp_root]
93
+ )
94
+ puts JSON.generate(schema_version: 1, repository: path.to_s, revision: corpus.manifest.dig('source', 'revision'))
95
+ when 'run'
96
+ raise Ast::Merge::Git::Corpus::Error, '--repository is required' unless options[:repository]
97
+
98
+ driver = options[:driver] || Gem.bin_path('ast-merge-git', 'ast-merge-git')
99
+ runner = Ast::Merge::Git::CorpusRunner.new(
100
+ corpus: corpus,
101
+ repository: options[:repository],
102
+ driver_path: driver,
103
+ tmp_root: options[:tmp_root],
104
+ timeout: options[:timeout]
105
+ )
106
+ puts JSON.generate(schema_version: 1, results: runner.run(case_id: options[:case_id]))
107
+ else
108
+ warn parser
109
+ exit 2
110
+ end
111
+ rescue Ast::Merge::Git::Corpus::Error, OptionParser::ParseError => e
112
+ warn "ast-merge-git corpus: #{e.message}"
113
+ exit 2
114
+ end
115
+ exit 0
116
+ end
117
+
118
+ exit Ast::Merge::Git.run(ARGV)