ast-merge 4.0.1 → 4.0.2
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/CHANGELOG.md +32 -1
- data/README.md +53 -58
- data/exe/ast-merge-recipe +19 -9
- data/lib/ast/merge/recipe/runner.rb +16 -4
- data/lib/ast/merge/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- 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: 29e3c1eb54812e59b30a8ae0dc42792486ef2e4992dbd43234452cfce0f2b1ab
|
|
4
|
+
data.tar.gz: bb1b200aa2a2d8a48c127952510984cf2ccd71e2517ced1d422fe542a7969c78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b0823b5b64b77947faa3213463c18289a4275b5b8fd7d5a0dcf258c1ae4088dcc50a34923f459944473cfae67e7c18dd646e3236f7ff6eb0898edfdb8b5d9ab2
|
|
7
|
+
data.tar.gz: 0f8dafa6c932a75504c898793fb0f51dfa9977d288f70e6e8e9fc8aff9f0f3452742a0302dbdd23aee33db8ab4528834048322af37d7c4d44ec9fb473e682855
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,33 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [4.0.2] - 2026-01-12
|
|
34
|
+
|
|
35
|
+
- TAG: [v4.0.2][4.0.2t]
|
|
36
|
+
- COVERAGE: 97.30% -- 2739/2815 lines in 53 files
|
|
37
|
+
- BRANCH COVERAGE: 89.84% -- 893/994 branches in 53 files
|
|
38
|
+
- 98.81% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **`Recipe::Runner` target file override**: Accept `target_files` parameter to override recipe targets
|
|
43
|
+
- `Runner.new(recipe, target_files: ["file1.md", "file2.md"])` - Process only specified files
|
|
44
|
+
- Paths are expanded relative to `base_dir`
|
|
45
|
+
- When not specified, falls back to recipe's configured targets
|
|
46
|
+
- **`exe/ast-merge-recipe` file arguments**: Accept target files on command line
|
|
47
|
+
- `ast-merge-recipe recipe.yml file1.md file2.md` - Override recipe targets
|
|
48
|
+
- Updated help text and banner to document new usage
|
|
49
|
+
- **`bin/update_gem_family_section` file arguments**: Accept target files on command line
|
|
50
|
+
- `bin/update_gem_family_section vendor/my-gem/README.md` - Process specific file(s)
|
|
51
|
+
- If no files specified, defaults to `README.md` + `vendor/*/README.md`
|
|
52
|
+
- Added `--skip-fix` option to skip the formatting fix step
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- **`bin/update_gem_family_section`**: Refactored to use `OptionParser` for clean option handling
|
|
57
|
+
- Consistent with `bin/fix_readme_formatting` style
|
|
58
|
+
- Properly separates options from file arguments
|
|
59
|
+
|
|
33
60
|
## [4.0.1] - 2026-01-11
|
|
34
61
|
|
|
35
62
|
- TAG: [v4.0.1][4.0.1t]
|
|
@@ -637,7 +664,11 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
637
664
|
|
|
638
665
|
- Initial release
|
|
639
666
|
|
|
640
|
-
[Unreleased]: https://github.com/kettle-rb/ast-merge/compare/v4.0.
|
|
667
|
+
[Unreleased]: https://github.com/kettle-rb/ast-merge/compare/v4.0.3...HEAD
|
|
668
|
+
[4.0.3]: https://github.com/kettle-rb/ast-merge/compare/v4.0.2...v4.0.3
|
|
669
|
+
[4.0.3t]: https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.3
|
|
670
|
+
[4.0.2]: https://github.com/kettle-rb/ast-merge/compare/v4.0.1...v4.0.2
|
|
671
|
+
[4.0.2t]: https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.2
|
|
641
672
|
[4.0.1]: https://github.com/kettle-rb/ast-merge/compare/v4.0.0...v4.0.1
|
|
642
673
|
[4.0.1t]: https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.1
|
|
643
674
|
[4.0.0]: https://github.com/kettle-rb/ast-merge/compare/v3.1.0...v4.0.0
|
data/README.md
CHANGED
|
@@ -208,24 +208,24 @@ The `*-merge` gem family is built on a two-layer architecture:
|
|
|
208
208
|
|
|
209
209
|
[tree\_haver][tree_haver] provides cross-Ruby parsing capabilities:
|
|
210
210
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
- **Universal Backend Support**: Automatically selects the best parsing backend for your Ruby implementation (MRI, JRuby, TruffleRuby)
|
|
212
|
+
- **10 Backend Options**: MRI C extensions, Rust bindings, FFI, Java (JRuby), language-specific parsers (Prism, Psych, Commonmarker, Markly), and pure Ruby fallback (Citrus)
|
|
213
|
+
- **Unified API**: Write parsing code once, run on any Ruby implementation
|
|
214
|
+
- **Grammar Discovery**: Built-in `GrammarFinder` for platform-aware grammar library discovery
|
|
215
|
+
- **Thread-Safe**: Language registry with thread-safe caching
|
|
216
216
|
|
|
217
217
|
#### Layer 2: ast-merge (Merge Infrastructure)
|
|
218
218
|
|
|
219
219
|
Ast::Merge builds on tree\_haver to provide:
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
221
|
+
- **Base Classes**: `FreezeNode`, `MergeResult` base classes with unified constructors
|
|
222
|
+
- **Shared Modules**: `FileAnalysisBase`, `FileAnalyzable`, `MergerConfig`, `DebugLogger`
|
|
223
|
+
- **Freeze Block Support**: Configurable marker patterns for multiple comment syntaxes (preserve sections during merge)
|
|
224
|
+
- **Node Typing System**: `NodeTyping` for canonical node type identification across different parsers
|
|
225
|
+
- **Conflict Resolution**: `ConflictResolverBase` with pluggable strategies
|
|
226
|
+
- **Error Classes**: `ParseError`, `TemplateParseError`, `DestinationParseError`
|
|
227
|
+
- **Region Detection**: `RegionDetectorBase`, `FencedCodeBlockDetector` for text-based analysis
|
|
228
|
+
- **RSpec Shared Examples**: Test helpers for implementing new merge gems
|
|
229
229
|
|
|
230
230
|
### Creating a New Merge Gem
|
|
231
231
|
|
|
@@ -372,10 +372,10 @@ merger = MyFormat::SmartMerger.new(
|
|
|
372
372
|
|
|
373
373
|
This is particularly useful for:
|
|
374
374
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
375
|
+
- Paragraphs with minor edits (typos, rewording)
|
|
376
|
+
- Headings with slight changes
|
|
377
|
+
- Comments with updated text
|
|
378
|
+
- Any text-based node that may have been slightly modified
|
|
379
379
|
|
|
380
380
|
### Namespace Reference
|
|
381
381
|
|
|
@@ -391,11 +391,11 @@ The `Ast::Merge` module is organized into several namespaces, each with detailed
|
|
|
391
391
|
|
|
392
392
|
**Key Classes by Namespace:**
|
|
393
393
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
394
|
+
- **Detector**: `Region`, `Base`, `Mergeable`, `FencedCodeBlock`, `YamlFrontmatter`, `TomlFrontmatter`
|
|
395
|
+
- **Recipe**: `Config`, `Runner`, `ScriptLoader`
|
|
396
|
+
- **Comment**: `Line`, `Block`, `Empty`, `Parser`, `Style`
|
|
397
|
+
- **Text**: `SmartMerger`, `FileAnalysis`, `LineNode`, `WordNode`, `Section`
|
|
398
|
+
- **RSpec**: Shared examples and dependency tags for testing `*-merge` implementations
|
|
399
399
|
|
|
400
400
|
## 💡 Info you can shake a stick at
|
|
401
401
|
|
|
@@ -447,18 +447,13 @@ The maintainers of this and thousands of other packages are working with Tidelif
|
|
|
447
447
|
|
|
448
448
|
[![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
|
|
449
449
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
- [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
|
|
458
|
-
|
|
459
|
-
- [![Get help from me on Upwork][👨🏼🏫expsup-upwork-img]][👨🏼🏫expsup-upwork]
|
|
460
|
-
|
|
461
|
-
- [![Get help from me on Codementor][👨🏼🏫expsup-codementor-img]][👨🏼🏫expsup-codementor]
|
|
450
|
+
- 💡Subscribe for support guarantees covering *all* your FLOSS dependencies
|
|
451
|
+
- 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
|
|
452
|
+
- 💡Tidelift pays maintainers to maintain the software you depend on\!<br/>📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
|
|
453
|
+
Alternatively:
|
|
454
|
+
- [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
|
|
455
|
+
- [![Get help from me on Upwork][👨🏼🏫expsup-upwork-img]][👨🏼🏫expsup-upwork]
|
|
456
|
+
- [![Get help from me on Codementor][👨🏼🏫expsup-codementor-img]][👨🏼🏫expsup-codementor]
|
|
462
457
|
|
|
463
458
|
</details>
|
|
464
459
|
|
|
@@ -537,17 +532,17 @@ merger = SomeFormat::Merge::SmartMerger.new(
|
|
|
537
532
|
|
|
538
533
|
Control which source wins when both files have the same structural element:
|
|
539
534
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
535
|
+
- **`:template`** - Template values replace destination values
|
|
536
|
+
- **`:destination`** (default) - Destination values are preserved
|
|
537
|
+
- **Hash** - Per-node-type preference (see Advanced Configuration)
|
|
543
538
|
|
|
544
539
|
### Template-Only Nodes
|
|
545
540
|
|
|
546
541
|
Control whether to add nodes that only exist in the template:
|
|
547
542
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
543
|
+
- **`true`** - Add all template-only nodes
|
|
544
|
+
- **`false`** (default) - Skip template-only nodes
|
|
545
|
+
- **Callable** - Filter which template-only nodes to add
|
|
551
546
|
|
|
552
547
|
#### Callable Filter
|
|
553
548
|
|
|
@@ -577,10 +572,10 @@ merger = Markly::Merge::SmartMerger.new(
|
|
|
577
572
|
|
|
578
573
|
The `entry` hash contains:
|
|
579
574
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
575
|
+
- `:template_node` - The node being considered for addition
|
|
576
|
+
- `:signature` - The node's signature (Array or other value)
|
|
577
|
+
- `:template_index` - Index in the template statements
|
|
578
|
+
- `:dest_index` - Always `nil` for template-only nodes
|
|
584
579
|
|
|
585
580
|
## 🔧 Basic Usage
|
|
586
581
|
|
|
@@ -606,11 +601,11 @@ end
|
|
|
606
601
|
|
|
607
602
|
### Available Shared Examples
|
|
608
603
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
604
|
+
- `"Ast::Merge::FreezeNode"` - Tests for FreezeNode implementations
|
|
605
|
+
- `"Ast::Merge::MergeResult"` - Tests for MergeResult implementations
|
|
606
|
+
- `"Ast::Merge::DebugLogger"` - Tests for DebugLogger implementations
|
|
607
|
+
- `"Ast::Merge::FileAnalysisBase"` - Tests for FileAnalysis implementations
|
|
608
|
+
- `"Ast::Merge::MergerConfig"` - Tests for SmartMerger implementations
|
|
614
609
|
|
|
615
610
|
## 🎛️ Advanced Configuration
|
|
616
611
|
|
|
@@ -622,9 +617,9 @@ This is useful for hand-edited customizations you never want overwritten.
|
|
|
622
617
|
|
|
623
618
|
A freeze block consists of:
|
|
624
619
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
620
|
+
- A **start marker** comment (e.g., `# mytoken:freeze`)
|
|
621
|
+
- The protected content
|
|
622
|
+
- An **end marker** comment (e.g., `# mytoken:unfreeze`)
|
|
628
623
|
|
|
629
624
|
```ruby
|
|
630
625
|
# In a Ruby file with prism-merge:
|
|
@@ -669,13 +664,13 @@ preferences for different types of nodes (e.g., prefer template for linter confi
|
|
|
669
664
|
|
|
670
665
|
1. **Define a `node_typing`**: A Hash mapping node type symbols to callables that receive a node and return either:
|
|
671
666
|
|
|
672
|
-
|
|
673
|
-
|
|
667
|
+
- The original node (no special handling)
|
|
668
|
+
- A wrapped node with a `merge_type` attribute (via `Ast::Merge::NodeTyping::Wrapper`)
|
|
674
669
|
|
|
675
670
|
2. **Use a Hash-based preference**: Instead of a simple `:destination` or `:template` Symbol, pass a Hash with:
|
|
676
671
|
|
|
677
|
-
|
|
678
|
-
|
|
672
|
+
- `:default` key for the fallback preference
|
|
673
|
+
- Custom keys matching the `merge_type` values from your `node_typing`
|
|
679
674
|
|
|
680
675
|
```ruby
|
|
681
676
|
# Example: Prefer template for lint gem configs, destination for everything else
|
|
@@ -903,7 +898,7 @@ is a *breaking change* to an API, and for that reason the bike shedding is endle
|
|
|
903
898
|
To get a better understanding of how SemVer is intended to work over a project's lifetime,
|
|
904
899
|
read this article from the creator of SemVer:
|
|
905
900
|
|
|
906
|
-
|
|
901
|
+
- ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
|
|
907
902
|
|
|
908
903
|
</details>
|
|
909
904
|
|
|
@@ -1108,7 +1103,7 @@ Thanks for RTFM. ☺️
|
|
|
1108
1103
|
[📌gitmoji]: https://gitmoji.dev
|
|
1109
1104
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
1110
1105
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
1111
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-2.
|
|
1106
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-2.815-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
1112
1107
|
[🔐security]: SECURITY.md
|
|
1113
1108
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
1114
1109
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/exe/ast-merge-recipe
CHANGED
|
@@ -171,9 +171,10 @@ class AstMergeRecipeCLI
|
|
|
171
171
|
|
|
172
172
|
def parse_options(argv)
|
|
173
173
|
@option_parser = OptionParser.new do |opts|
|
|
174
|
-
opts.banner = "Usage: #{File.basename($0)} RECIPE_FILE [options]"
|
|
174
|
+
opts.banner = "Usage: #{File.basename($0)} RECIPE_FILE [FILES...] [options]"
|
|
175
175
|
opts.separator("")
|
|
176
176
|
opts.separator("Run a YAML-based merge recipe against target files.")
|
|
177
|
+
opts.separator("If FILES are specified, they override the recipe's targets.")
|
|
177
178
|
opts.separator("")
|
|
178
179
|
opts.separator("Options:")
|
|
179
180
|
|
|
@@ -225,9 +226,15 @@ class AstMergeRecipeCLI
|
|
|
225
226
|
opts.on("-h", "--help", "Show this help message") do
|
|
226
227
|
puts opts
|
|
227
228
|
puts
|
|
229
|
+
puts "Arguments:"
|
|
230
|
+
puts " RECIPE_FILE Path to the YAML recipe file (required)"
|
|
231
|
+
puts " [FILES...] Target files to process (optional, overrides recipe targets)"
|
|
232
|
+
puts
|
|
228
233
|
puts "Examples:"
|
|
229
234
|
puts " #{File.basename($0)} .merge-recipes/gem_family_section.yml --dry-run"
|
|
230
235
|
puts " #{File.basename($0)} recipe.yml --verbose --parser=commonmarker"
|
|
236
|
+
puts " #{File.basename($0)} recipe.yml vendor/my-gem/README.md"
|
|
237
|
+
puts " #{File.basename($0)} recipe.yml README.md vendor/*/README.md"
|
|
231
238
|
puts
|
|
232
239
|
puts "Recipe YAML format:"
|
|
233
240
|
puts " See lib/ast/merge/recipe/README.md for full documentation"
|
|
@@ -241,10 +248,8 @@ class AstMergeRecipeCLI
|
|
|
241
248
|
# First non-option argument is the recipe file
|
|
242
249
|
@options[:recipe_file] = remaining.shift
|
|
243
250
|
|
|
244
|
-
#
|
|
245
|
-
if remaining.any?
|
|
246
|
-
$stderr.puts Colors.yellow("WARNING: Ignoring extra arguments: #{remaining.join(", ")}")
|
|
247
|
-
end
|
|
251
|
+
# Remaining arguments are target files (override recipe targets)
|
|
252
|
+
@options[:target_files] = remaining if remaining.any?
|
|
248
253
|
end
|
|
249
254
|
|
|
250
255
|
def validate_options!
|
|
@@ -271,14 +276,19 @@ class AstMergeRecipeCLI
|
|
|
271
276
|
recipe = Ast::Merge::Recipe::Config.load(@options[:recipe_file])
|
|
272
277
|
print_recipe_info(recipe)
|
|
273
278
|
|
|
274
|
-
#
|
|
275
|
-
|
|
276
|
-
recipe,
|
|
279
|
+
# Build runner options
|
|
280
|
+
runner_opts = {
|
|
277
281
|
dry_run: @options[:dry_run],
|
|
278
282
|
base_dir: @options[:base_dir],
|
|
279
283
|
parser: @options[:parser],
|
|
280
284
|
verbose: @options[:verbose],
|
|
281
|
-
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
# If target files specified on command line, override recipe targets
|
|
288
|
+
runner_opts[:target_files] = @options[:target_files] if @options[:target_files]
|
|
289
|
+
|
|
290
|
+
# Create runner
|
|
291
|
+
runner = Ast::Merge::Recipe::Runner.new(recipe, **runner_opts)
|
|
282
292
|
|
|
283
293
|
# Run and display results
|
|
284
294
|
puts Colors.cyan("Processing files...")
|
|
@@ -40,6 +40,9 @@ module Ast
|
|
|
40
40
|
# @return [Symbol] Parser to use (:markly, :commonmarker, :prism, :psych, etc.)
|
|
41
41
|
attr_reader :parser
|
|
42
42
|
|
|
43
|
+
# @return [Array<String>, nil] Target files override (from command line)
|
|
44
|
+
attr_reader :target_files
|
|
45
|
+
|
|
43
46
|
# @return [Array<Result>] Results from the last run
|
|
44
47
|
attr_reader :results
|
|
45
48
|
|
|
@@ -50,12 +53,14 @@ module Ast
|
|
|
50
53
|
# @param base_dir [String, nil] Base directory for path resolution
|
|
51
54
|
# @param parser [Symbol] Which parser to use
|
|
52
55
|
# @param verbose [Boolean] Enable verbose output
|
|
53
|
-
|
|
56
|
+
# @param target_files [Array<String>, nil] Override recipe targets with these files
|
|
57
|
+
def initialize(recipe, dry_run: false, base_dir: nil, parser: :markly, verbose: false, target_files: nil, **options)
|
|
54
58
|
@recipe = recipe
|
|
55
59
|
@dry_run = dry_run
|
|
56
60
|
@base_dir = base_dir || Dir.pwd
|
|
57
61
|
@parser = parser
|
|
58
62
|
@verbose = verbose
|
|
63
|
+
@target_files = target_files
|
|
59
64
|
@results = []
|
|
60
65
|
end
|
|
61
66
|
|
|
@@ -66,10 +71,17 @@ module Ast
|
|
|
66
71
|
@results = []
|
|
67
72
|
|
|
68
73
|
template_content = load_template
|
|
69
|
-
# Let the recipe expand targets from its own location
|
|
70
|
-
target_files = recipe.expand_targets
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
# Use command-line targets if provided, otherwise expand from recipe
|
|
76
|
+
files_to_process = if @target_files && !@target_files.empty?
|
|
77
|
+
# Expand paths relative to base_dir
|
|
78
|
+
@target_files.map { |f| File.expand_path(f, @base_dir) }
|
|
79
|
+
else
|
|
80
|
+
# Let the recipe expand targets from its own location
|
|
81
|
+
recipe.expand_targets
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
files_to_process.each do |target_path|
|
|
73
85
|
result = process_file(target_path, template_content)
|
|
74
86
|
@results << result
|
|
75
87
|
yield result if block_given?
|
data/lib/ast/merge/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ast-merge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -382,10 +382,10 @@ licenses:
|
|
|
382
382
|
- MIT
|
|
383
383
|
metadata:
|
|
384
384
|
homepage_uri: https://ast-merge.galtzo.com/
|
|
385
|
-
source_code_uri: https://github.com/kettle-rb/ast-merge/tree/v4.0.
|
|
386
|
-
changelog_uri: https://github.com/kettle-rb/ast-merge/blob/v4.0.
|
|
385
|
+
source_code_uri: https://github.com/kettle-rb/ast-merge/tree/v4.0.2
|
|
386
|
+
changelog_uri: https://github.com/kettle-rb/ast-merge/blob/v4.0.2/CHANGELOG.md
|
|
387
387
|
bug_tracker_uri: https://github.com/kettle-rb/ast-merge/issues
|
|
388
|
-
documentation_uri: https://www.rubydoc.info/gems/ast-merge/4.0.
|
|
388
|
+
documentation_uri: https://www.rubydoc.info/gems/ast-merge/4.0.2
|
|
389
389
|
funding_uri: https://github.com/sponsors/pboling
|
|
390
390
|
wiki_uri: https://github.com/kettle-rb/ast-merge/wiki
|
|
391
391
|
news_uri: https://www.railsbling.com/tags/ast-merge
|
metadata.gz.sig
CHANGED
|
Binary file
|