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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +23 -13
- data/exe/ast-merge-git +118 -0
- data/lib/ast/merge/git/corpus.rb +580 -0
- data/lib/ast/merge/git/local_benchmark.rb +864 -0
- data/lib/ast/merge/git/version.rb +1 -1
- data/lib/ast/merge/git.rb +196 -343
- data/sig/ast/merge/git.rbs +106 -0
- data.tar.gz.sig +0 -0
- metadata +302 -33
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6c6a8e98b15372fd7b01969b96b15bd463a9c339debba9150d67a336c2592d3
|
|
4
|
+
data.tar.gz: ef2a36f8917e49e6b24e99955c822e100075d0db1fc06a02be2042ccf8fd6732
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
-
|
|
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+,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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)
|