diff --git a/.github/workflows/current.yml b/.github/workflows/current.yml index 1d2ae8bda..8ffe7131e 100644 --- a/.github/workflows/current.yml +++ b/.github/workflows/current.yml @@ -112,7 +112,6 @@ jobs: working-directory: ${{ matrix.gem }} env: K_JEM_TEMPLATING: true - SMORG_RB_DEV: ${{ github.workspace }}/gems STRUCTUREDMERGE_DEV: ${{ github.workspace }}/gems run: | gem install nomono -v 1.0.8 --source https://gem.coop --source https://rubygems.org @@ -124,7 +123,6 @@ jobs: env: K_JEM_TEMPLATING: true K_SOUP_COV_DO: false - SMORG_RB_DEV: ${{ github.workspace }}/gems STRUCTUREDMERGE_DEV: ${{ github.workspace }}/gems run: timeout 12m bundle exec kettle-test @@ -163,12 +161,46 @@ jobs: abort "RBS validation failed for #{failures.length} gem(s)" unless failures.empty? ' + tslp-cold-cache: + name: TSLP cold cache + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Ruby + uses: ruby/setup-ruby@9eb537ca036ebaed86729dcb9309076e4c5c3b74 # v1.314.0 + with: + ruby-version: ruby + bundler-cache: false + - name: Install dependencies + working-directory: gems/tree_haver + env: + K_JEM_TEMPLATING: true + STRUCTUREDMERGE_DEV: ${{ github.workspace }}/gems + run: | + gem install nomono -v 1.0.8 --source https://gem.coop --source https://rubygems.org + bundle config set path vendor/bundle + bundle config set frozen false + bundle install --jobs 4 + - name: Run cold-cache TSLP checks + working-directory: gems/tree_haver + env: + K_JEM_TEMPLATING: true + K_SOUP_COV_DO: false + STRUCTUREDMERGE_DEV: ${{ github.workspace }}/gems + run: | + set -euo pipefail + export TREE_SITTER_LANGUAGE_PACK_CACHE_DIR + TREE_SITTER_LANGUAGE_PACK_CACHE_DIR="$(mktemp -d "${RUNNER_TEMP}/tslp-cold-cache.XXXXXX")" + bundle exec rspec spec/grammar_finder_spec.rb spec/backends/tslp_spec.rb --format progress + check: name: Check needs: - detect - gem-suite - rbs + - tslp-cold-cache if: ${{ always() }} runs-on: ubuntu-latest steps: @@ -179,12 +211,14 @@ jobs: DETECT_RESULT: ${{ needs.detect.result }} GEM_SUITE_RESULT: ${{ needs.gem-suite.result }} RBS_RESULT: ${{ needs.rbs.result }} + TSLP_COLD_CACHE_RESULT: ${{ needs.tslp-cold-cache.result }} run: | set -euo pipefail echo "Selected gem suites: ${SELECTED_GEMS}" echo "Detect result: ${DETECT_RESULT}" echo "Gem suite result: ${GEM_SUITE_RESULT}" echo "RBS result: ${RBS_RESULT}" + echo "TSLP cold cache result: ${TSLP_COLD_CACHE_RESULT}" if [[ "${DETECT_RESULT}" != "success" ]]; then exit 1 @@ -192,6 +226,9 @@ jobs: if [[ "${RBS_RESULT}" != "success" ]]; then exit 1 fi + if [[ "${TSLP_COLD_CACHE_RESULT}" != "success" ]]; then + exit 1 + fi case "${GEM_SUITE_RESULT}" in success|skipped) diff --git a/.gitignore b/.gitignore index 86fa757a6..47dfeb723 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,10 @@ /.yardoc/ **/.yardoc/ **/_yardoc/ -/coverage/ +**/coverage/ /log/ /pkg/ +**/results/ /tmp/ /vendor/bundle/ .env.local @@ -15,3 +16,4 @@ *.rbc *.rspec_status /.DS_Store +TREE_HAVER_PLAN.md diff --git a/.kettle-family.yml b/.kettle-family.yml index caac1f1d3..398693343 100644 --- a/.kettle-family.yml +++ b/.kettle-family.yml @@ -115,7 +115,7 @@ release: env: GALTZO_FLOSS_DEV: false KETTLE_RB_DEV: false - SMORG_RB_DEV: false + STRUCTUREDMERGE_DEV: false TSLP_DEV: "" family_changelog: enabled: true diff --git a/CHANGELOG.md b/CHANGELOG.md index eacea86c6..9e99e1f9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,9 @@ Please file a bug if you notice a violation of semantic versioning. - Gems that use `tree_sitter_language_pack` now resolve it through the StructuredMerge Ruby 4-compatible fork branch in their development Gemfiles until an upstream Ruby 4-compatible release is available. +- Structured merge gems now fail closed when no registered TreeHaver backend is + available instead of falling back to direct parser-library paths outside the + TreeHaver and ast-merge stack. ### Deprecated diff --git a/Gemfile b/Gemfile index aef99dcef..26178427d 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,18 @@ kettle_rb_dev = ENV.fetch("KETTLE_RB_DEV", "false") source "https://rubygems.org" +tslp_dev = ENV.fetch("TSLP_DEV", nil) +if tslp_dev.to_s.empty? + gem( + "tree_sitter_language_pack", + git: "https://github.com/structuredmerge/tree-sitter-language-pack.git", + branch: "fix/ruby-parser-api-methods", + glob: "packages/ruby/*.gemspec", + ) +else + gem "tree_sitter_language_pack", path: tslp_dev +end + unless kettle_rb_dev.casecmp("false").zero? require "nomono/bundler" diff --git a/Gemfile.lock b/Gemfile.lock index 15a0a7ce1..39c4925de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/structuredmerge/tree-sitter-language-pack.git + revision: 85cac7836bb2f8cfcd3041a191b7bd11bf10924a + branch: fix/ruby-parser-api-methods + glob: packages/ruby/*.gemspec + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + PATH remote: gems/ast-crispr-markdown-markly specs: @@ -11,7 +21,7 @@ PATH specs: ast-crispr-ruby-prism (7.1.0) ast-crispr (= 7.1.0) - prism (>= 1.0) + prism-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) PATH @@ -27,6 +37,7 @@ PATH specs: ast-merge-git (7.1.0) ast-merge (= 7.1.0) + json-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) PATH @@ -269,7 +280,7 @@ GEM specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) @@ -298,7 +309,7 @@ GEM gitmoji-regex (2.0.4) version_gem (~> 1.1, >= 1.1.13) io-console (0.8.2) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) @@ -339,6 +350,9 @@ GEM public_suffix (7.0.5) racc (1.8.1) rake (13.4.2) + rake-compiler-dock (1.12.0) + rb_sys (0.9.127) + rake-compiler-dock (= 1.12.0) rbs (4.0.3) logger prism (>= 1.6.0) @@ -394,10 +408,8 @@ GEM toml-rb (4.2.0) citrus (~> 3.0, > 3.0) racc (~> 1.7) - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) - sorbet-runtime (~> 0.5) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -451,14 +463,15 @@ DEPENDENCIES toml-merge! toml-rb (~> 4.1) tree_haver! - turbo_tests2 (~> 3.1, >= 3.1.14) + tree_sitter_language_pack! + turbo_tests2 (~> 3.2, ~> 3.1, >= 3.2.0, >= 3.1.14) typescript-merge! yaml-merge! zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast-crispr (7.1.0) ast-crispr-markdown-markly (7.1.0) ast-crispr-ruby-prism (7.1.0) @@ -489,7 +502,7 @@ CHECKSUMS go-merge (7.1.0) io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc json-merge (7.1.0) - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 kettle-family (1.0.0) sha256=4c1c158fede8c4e369b6e5576cb540ad38891011cfc7721aea0ade813b13e3c1 kettle-jem (7.1.0) @@ -513,6 +526,8 @@ CHECKSUMS public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 + rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 rbs-merge (7.1.0) reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 @@ -545,9 +560,9 @@ CHECKSUMS toml-merge (7.1.0) toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) sha256=ad6743a373eeac954c1b659b17af3aff1c82918b3ce9c9dc572a7c70ff843cdd + tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 typescript-merge (7.1.0) version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-merge (7.1.0) diff --git a/README.md b/README.md index 7ef94c9fa..4908e519d 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ merge gems. | Gem | Provides | Runtime notes | | --- | --- | --- | | [`psych-merge`][ruby-psych-merge] | YAML provider | Uses Ruby's [Psych][psych] parser and emitter. | -| [`citrus-toml-merge`][ruby-citrus-toml-merge] | TOML provider | Uses a [Citrus][citrus] grammar and pure-Ruby parser path, commonly paired with [`toml-rb`][toml-rb] style TOML data handling. | -| [`parslet-toml-merge`][ruby-parslet-toml-merge] | TOML provider | Uses [Parslet][parslet] and pure-Ruby parser path, commonly paired with [`toml`][toml] style TOML data handling. | +| [`citrus-toml-merge`][ruby-citrus-toml-merge] | TOML provider | Registers a TreeHaver TOML backend backed by a [Citrus][citrus] grammar, commonly paired with [`toml-rb`][toml-rb] style TOML data handling. | +| [`parslet-toml-merge`][ruby-parslet-toml-merge] | TOML provider | Registers a TreeHaver TOML backend backed by [Parslet][parslet], commonly paired with [`toml`][toml] style TOML data handling. | | [`commonmarker-merge`][ruby-commonmarker-merge] | Markdown provider | Uses [CommonMarker][commonmarker] for CommonMark-oriented Markdown parsing. | | [`kramdown-merge`][ruby-kramdown-merge] | Markdown provider | Uses [Kramdown][kramdown] for Ruby-native Markdown parsing. | | [`markly-merge`][ruby-markly-merge] | Markdown provider | Uses [Markly][markly] for cmark-gfm-backed Markdown parsing and README templating support. | @@ -118,7 +118,7 @@ tags are capability names, not package preferences. | [Psych][psych] | `yaml-merge`, `psych-merge` | Ruby standard YAML parser/emitter path. | | [RBS][rbs] | `rbs-merge` | Ruby signature parser path. | | [CommonMarker][commonmarker], [Markly][markly], [Kramdown][kramdown] | `markdown-merge` providers | Markdown parser families with different CommonMark/GFM/Ruby-native tradeoffs. | -| [Citrus][citrus], [Parslet][parslet] | `toml-merge` providers | Pure-Ruby TOML parser families used as provider-specific backend paths. | +| [Citrus][citrus], [Parslet][parslet] | `toml-merge` providers | Pure-Ruby TOML parser families exposed as provider-specific TreeHaver backend paths. | | [Kaitai Struct][kaitai] | `binary-merge` | Schema-oriented binary parsing support for structured binary work. | #### Backend Platform Compatibility diff --git a/gems/ast-crispr-markdown-markly/.gitattributes b/gems/ast-crispr-markdown-markly/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-crispr-markdown-markly/.gitattributes +++ b/gems/ast-crispr-markdown-markly/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-crispr-markdown-markly/.kettle-drift.lock b/gems/ast-crispr-markdown-markly/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/ast-crispr-markdown-markly/.kettle-drift.lock +++ b/gems/ast-crispr-markdown-markly/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/ast-crispr-markdown-markly/Gemfile b/gems/ast-crispr-markdown-markly/Gemfile index 7fbfaad74..86b7488a2 100644 --- a/gems/ast-crispr-markdown-markly/Gemfile +++ b/gems/ast-crispr-markdown-markly/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-crispr-markdown-markly/Gemfile.lock b/gems/ast-crispr-markdown-markly/Gemfile.lock index c9f436940..9e99f39dd 100644 --- a/gems/ast-crispr-markdown-markly/Gemfile.lock +++ b/gems/ast-crispr-markdown-markly/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,26 +6,283 @@ PATH markly-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) -GEM - remote: https://gem.coop/ +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr specs: - addressable (2.9.0) - public_suffix (>= 2.0.2, < 8.0) - ansi (1.6.0) - appraisal2 (3.1.4) - bundler (>= 1.17.3) - rake (>= 10) - thor (>= 0.14) - ast (2.4.3) ast-crispr (7.1.0) ast-merge (= 7.1.0) service_actor (~> 3.9) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: ast-merge (7.1.0) benchmark token-resolver (~> 2.0, >= 2.0.4) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + +GEM + remote: https://gem.coop/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + ansi (1.6.0) + appraisal2 (3.2.0) + bundler (>= 1.17.3) + rake (>= 10) + thor (>= 0.14) + ast (2.4.3) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -44,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -102,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -135,15 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) markly (0.16.0) - markly-merge (7.1.0) - markdown-merge (= 7.1.0) - markly (~> 0.9) - version_gem (~> 1.1, >= 1.1.9) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -337,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -368,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -388,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -413,33 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -447,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -459,15 +750,20 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 @@ -489,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -500,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -527,9 +828,11 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 @@ -539,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -552,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-crispr-markdown-markly/gemfiles/modular/templating.gemfile b/gems/ast-crispr-markdown-markly/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-crispr-markdown-markly/gemfiles/modular/templating.gemfile +++ b/gems/ast-crispr-markdown-markly/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-crispr-markdown-markly/gemfiles/modular/templating_local.gemfile b/gems/ast-crispr-markdown-markly/gemfiles/modular/templating_local.gemfile index 488be70f3..d2e0871f3 100644 --- a/gems/ast-crispr-markdown-markly/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-crispr-markdown-markly/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-crispr-markdown-markly] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-crispr-markdown-markly] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-crispr-markdown-markly] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ast-crispr-markdown-markly/lib/ast/crispr/markdown/markly.rb b/gems/ast-crispr-markdown-markly/lib/ast/crispr/markdown/markly.rb index ddd166951..ec5dbc6a9 100644 --- a/gems/ast-crispr-markdown-markly/lib/ast/crispr/markdown/markly.rb +++ b/gems/ast-crispr-markdown-markly/lib/ast/crispr/markdown/markly.rb @@ -12,47 +12,6 @@ module Markly class Error < StandardError; end class Adapter - Location = Struct.new(:start_line, :end_line, keyword_init: true) - HeadingSectionOwner = Struct.new( - :location, - :heading_text, - :heading_source, - :level, - :base, - keyword_init: true - ) - LinkDefinitionOwner = Struct.new( - :location, - :label, - :url, - :title, - :source, - keyword_init: true - ) - HtmlCommentOwner = Struct.new( - :location, - :text, - :source, - keyword_init: true - ) - InlineReferenceOwner = Struct.new( - :location, - :line, - :start_column, - :end_column, - :source, - :reference_kind, - :label, - :labels, - keyword_init: true - ) - TableRowOwner = Struct.new( - :location, - :source, - :text, - keyword_init: true - ) - def read_ast(document) analysis = ::Markly::Merge::FileAnalysis.new(document.content) return analysis if analysis.valid? @@ -65,15 +24,15 @@ def structural_owners(document, owner_scope: :shared_default) analysis = document.ast case owner_scope when :shared_default, :heading_sections - build_heading_sections(analysis) + analysis.heading_section_owners when :link_definitions - build_link_definitions(analysis) + analysis.link_definition_owners when :html_comments - build_html_comments(analysis) + analysis.html_comment_owners when :inline_references - build_inline_references(analysis) + analysis.inline_reference_owners when :table_rows - build_table_rows(analysis) + analysis.table_row_owners else raise Ast::Crispr::Error.new('Unsupported CRISPR owner scope', details: { owner_scope: owner_scope }) end @@ -134,263 +93,6 @@ def structure_profile(owner_scope: :shared_default) private - def build_heading_sections(analysis) - headings = Array(analysis.statements).filter_map do |statement| - next unless heading_statement?(statement) - - build_heading_owner(statement, analysis) - end - - headings.each_with_index.map do |owner, index| - branch_end_line = branch_end_line(headings, index, analysis) - HeadingSectionOwner.new( - location: Location.new(start_line: owner.location.start_line, end_line: branch_end_line), - heading_text: owner.heading_text, - heading_source: owner.heading_source, - level: owner.level, - base: owner.base - ) - end - end - - def build_link_definitions(analysis) - Array(analysis.statements).filter_map do |statement| - next unless statement.respond_to?(:merge_type) && statement.merge_type == :link_definition - - position = statement.source_position - next unless position - - LinkDefinitionOwner.new( - location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), - label: statement.label, - url: statement.url, - title: statement.title, - source: if statement.respond_to?(:content) - statement.content - else - analysis.source_range( - position[:start_line], position[:end_line] - ).chomp - end - ) - end - end - - def build_html_comments(analysis) - analysis.comment_tracker.comment_nodes.map do |comment| - HtmlCommentOwner.new( - location: Location.new(start_line: comment.location.start_line, end_line: comment.location.end_line), - text: comment.content, - source: comment.text - ) - end - end - - def build_inline_references(analysis) - analysis.source.to_s.lines.each_with_index.flat_map do |line, index| - inline_references_for_line(line.chomp, index + 1) - end - end - - def build_table_rows(analysis) - ast_table_lines = {} - ast_rows = Array(analysis.statements).flat_map do |statement| - node = unwrap_markdown_statement(statement) - next [] unless node.respond_to?(:type) && node.type.to_s == 'table' - - table_position = node.source_position - if table_position - (table_position[:start_line]..table_position[:end_line]).each do |line| - ast_table_lines[line] = true - end - end - Array(node.children).filter_map do |child| - next unless child.respond_to?(:type) && child.type.to_s == 'table_row' - - position = child.source_position - next unless position - - TableRowOwner.new( - location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), - source: analysis.source_range(position[:start_line], position[:end_line]), - text: child.to_plaintext.to_s - ) - end - end - ast_lines = ast_rows.map { |owner| owner.location.start_line }.to_h { |line| [line, true] } - loose_rows = analysis.source.to_s.lines.each_with_index.filter_map do |line, index| - line_number = index + 1 - next if ast_lines[line_number] - next if ast_table_lines[line_number] - next unless loose_table_row_line?(line) - - TableRowOwner.new( - location: Location.new(start_line: line_number, end_line: line_number), - source: line, - text: line - ) - end - ast_rows + loose_rows - end - - def loose_table_row_line?(line) - stripped = line.to_s.lstrip - return false unless stripped.start_with?('|') - - stripped.include?(' |') || stripped.include?('| ') - end - - def heading_statement?(statement) - merge_type = if statement.respond_to?(:merge_type) - statement.merge_type - else - unwrap_markdown_statement(statement)&.type - end - - %w[heading header].include?(merge_type.to_s) - end - - def build_heading_owner(statement, analysis) - node = unwrap_markdown_statement(statement) - position = node&.source_position - return unless node && position - - heading_source = analysis.source_range(position[:start_line], position[:end_line]).sub(/\n\z/, '') - heading_text = node.to_plaintext.to_s.sub(/\n+\z/, '') - HeadingSectionOwner.new( - location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), - heading_text: heading_text, - heading_source: heading_source, - level: node.header_level, - base: normalize_heading_base(heading_text) - ) - rescue StandardError - nil - end - - def branch_end_line(headings, index, analysis) - current = headings[index] - cursor = index + 1 - while cursor < headings.length - return headings[cursor].location.start_line - 1 if headings[cursor].level <= current.level - - cursor += 1 - end - - analysis.source.to_s.lines.length - end - - def unwrap_markdown_statement(statement) - if defined?(Ast::Merge::NodeTyping) - Ast::Merge::NodeTyping.unwrap(statement) - else - statement - end - rescue StandardError - statement - end - - def normalize_heading_base(text) - text.to_s.sub(/\A(?:\d\uFE0F?\u20E3|[^[:alnum:][:space:]])+[ \t]*/u, '').strip.downcase - end - - def inline_references_for_line(line, line_number) - owners = [] - index = 0 - while index < line.length - image = inline_image_reference_at(line, index, line_number) - if image - owners << image - index = image.end_column - next - end - - link = inline_link_reference_at(line, index, line_number) - if link - owners << link - index = link.end_column - next - end - - index += 1 - end - owners - end - - def inline_image_reference_at(line, index, line_number) - return unless line[index] == '!' && line[index + 1] == '[' - - alt_end = closing_bracket_index(line, index + 1) - return unless alt_end && line[alt_end + 1] == '[' - - label_end = closing_bracket_index(line, alt_end + 1) - return unless label_end - - label = line[(alt_end + 2)...label_end] - inline_reference_owner( - line: line, - line_number: line_number, - start_column: index, - end_column: label_end + 1, - reference_kind: :image_reference, - label: label, - labels: [label] - ) - end - - def inline_link_reference_at(line, index, line_number) - return unless line[index] == '[' - - text_end = closing_bracket_index(line, index) - return unless text_end && line[text_end + 1] == '[' - - label_end = closing_bracket_index(line, text_end + 1) - return unless label_end - - text = line[(index + 1)...text_end] - label = line[(text_end + 2)...label_end] - image_owner = inline_image_reference_at(text, 0, line_number) - labels = [label] - labels.unshift(image_owner.label) if image_owner && image_owner.source == text - inline_reference_owner( - line: line, - line_number: line_number, - start_column: index, - end_column: label_end + 1, - reference_kind: labels.length > 1 ? :linked_image_reference : :link_reference, - label: label, - labels: labels - ) - end - - def inline_reference_owner(line:, line_number:, start_column:, end_column:, reference_kind:, label:, labels:) - InlineReferenceOwner.new( - location: Location.new(start_line: line_number, end_line: line_number), - line: line_number, - start_column: start_column, - end_column: end_column, - source: line[start_column...end_column], - reference_kind: reference_kind, - label: label, - labels: labels.compact.uniq - ) - end - - def closing_bracket_index(text, opening_index) - depth = 0 - index = opening_index - while index < text.length - case text[index] - when '[' - depth += 1 - when ']' - depth -= 1 - return index if depth.zero? - end - index += 1 - end - nil - end end module Selectors diff --git a/gems/ast-crispr-markdown-markly/spec/ast/crispr/markdown/markly_spec.rb b/gems/ast-crispr-markdown-markly/spec/ast/crispr/markdown/markly_spec.rb index 30a18d2d5..b2f54d85a 100644 --- a/gems/ast-crispr-markdown-markly/spec/ast/crispr/markdown/markly_spec.rb +++ b/gems/ast-crispr-markdown-markly/spec/ast/crispr/markdown/markly_spec.rb @@ -127,12 +127,12 @@ context = Ast::Crispr::Markdown::Markly.document_context(content: content, source_label: 'README.md') owners = context.structural_owners(owner_scope: :table_rows) - expect(owners.map { |owner| [owner.location.start_line, owner.text] }).to eq([ - [3, - "| Works with MRI Ruby | [![Ruby][💎ruby-3.2i]][🚎ruby-3.2-wf] |\n"], - [4, - "| Works with JRuby | [![JRuby][💎jruby-9.4i]][🚎jruby-9.4-wf] |\n"] - ]) + expect(owners.map { |owner| [owner.location.start_line, owner.source] }).to eq([ + [3, + "| Works with MRI Ruby | [![Ruby][💎ruby-3.2i]][🚎ruby-3.2-wf] |\n"], + [4, + "| Works with JRuby | [![JRuby][💎jruby-9.4i]][🚎jruby-9.4-wf] |\n"] + ]) expect(owners.last.source).to include('Works with JRuby') end diff --git a/gems/ast-crispr-ruby-prism/.gitattributes b/gems/ast-crispr-ruby-prism/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-crispr-ruby-prism/.gitattributes +++ b/gems/ast-crispr-ruby-prism/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-crispr-ruby-prism/.kettle-drift.lock b/gems/ast-crispr-ruby-prism/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/ast-crispr-ruby-prism/.kettle-drift.lock +++ b/gems/ast-crispr-ruby-prism/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/ast-crispr-ruby-prism/Gemfile b/gems/ast-crispr-ruby-prism/Gemfile index 871cc8e98..43f132f05 100644 --- a/gems/ast-crispr-ruby-prism/Gemfile +++ b/gems/ast-crispr-ruby-prism/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-crispr-ruby-prism/Gemfile.lock b/gems/ast-crispr-ruby-prism/Gemfile.lock index 95c539be8..06a81f5a4 100644 --- a/gems/ast-crispr-ruby-prism/Gemfile.lock +++ b/gems/ast-crispr-ruby-prism/Gemfile.lock @@ -1,41 +1,288 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: ast-crispr-ruby-prism (7.1.0) ast-crispr (= 7.1.0) - prism (>= 1.0) + prism-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) -GEM - remote: https://gem.coop/ +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr specs: - addressable (2.9.0) - public_suffix (>= 2.0.2, < 8.0) - ansi (1.6.0) - appraisal2 (3.1.4) - bundler (>= 1.17.3) - rake (>= 10) - thor (>= 0.14) - ast (2.4.3) ast-crispr (7.1.0) ast-merge (= 7.1.0) service_actor (~> 3.9) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: ast-merge (7.1.0) benchmark token-resolver (~> 2.0, >= 2.0.4) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + +GEM + remote: https://gem.coop/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + ansi (1.6.0) + appraisal2 (3.2.0) + bundler (>= 1.17.3) + rake (>= 10) + thor (>= 0.14) + ast (2.4.3) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -44,6 +291,8 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -102,11 +351,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -135,6 +386,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) @@ -320,13 +572,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -351,7 +603,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -366,23 +618,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -391,33 +665,50 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -425,6 +716,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -437,19 +729,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b @@ -460,10 +760,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -471,6 +775,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -498,9 +803,11 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 @@ -510,6 +817,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -523,21 +831,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-crispr-ruby-prism/ast-crispr-ruby-prism.gemspec b/gems/ast-crispr-ruby-prism/ast-crispr-ruby-prism.gemspec index b9d1753d2..ad4457d9d 100644 --- a/gems/ast-crispr-ruby-prism/ast-crispr-ruby-prism.gemspec +++ b/gems/ast-crispr-ruby-prism/ast-crispr-ruby-prism.gemspec @@ -96,7 +96,7 @@ Gem::Specification.new do |spec| # Utilities spec.add_dependency 'ast-crispr', "= #{spec.version}" - spec.add_dependency 'prism', '>= 1.0' + spec.add_dependency 'prism-merge', "= #{spec.version}" spec.add_dependency('version_gem', '~> 1.1', '>= 1.1.9') # ruby >= 2.2.0 # NOTE: It is preferable to list development dependencies in the gemspec due to increased diff --git a/gems/ast-crispr-ruby-prism/gemfiles/modular/templating.gemfile b/gems/ast-crispr-ruby-prism/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-crispr-ruby-prism/gemfiles/modular/templating.gemfile +++ b/gems/ast-crispr-ruby-prism/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-crispr-ruby-prism/gemfiles/modular/templating_local.gemfile b/gems/ast-crispr-ruby-prism/gemfiles/modular/templating_local.gemfile index a7c0be566..b5268538e 100644 --- a/gems/ast-crispr-ruby-prism/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-crispr-ruby-prism/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-crispr-ruby-prism] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-crispr-ruby-prism] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-crispr-ruby-prism] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ast-crispr-ruby-prism/lib/ast/crispr/ruby/prism.rb b/gems/ast-crispr-ruby-prism/lib/ast/crispr/ruby/prism.rb index 13bd8113e..41025a28f 100644 --- a/gems/ast-crispr-ruby-prism/lib/ast/crispr/ruby/prism.rb +++ b/gems/ast-crispr-ruby-prism/lib/ast/crispr/ruby/prism.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'ast/crispr' -require 'prism' +require 'prism/merge' require 'version_gem' require_relative 'prism/version' @@ -14,66 +14,43 @@ class Error < StandardError; end module Utils module_function - def parse_with_comments(source) - ::Prism.parse(source) - end - - def extract_statements(body_node) - return [] unless body_node - - if body_node.is_a?(::Prism::StatementsNode) - body_node.body.compact - else - [body_node].compact - end + def parse_analysis(source, source_label: nil) + ::Prism::Merge::FileAnalysis.new(source, source_label: source_label) end - def find_leading_comments(parse_result, current_stmt, prev_stmt, body_node) - start_line = prev_stmt ? prev_stmt.location.end_line : body_node.location.start_line - end_line = current_stmt.location.start_line - - parse_result.comments.select do |comment| - comment.location.start_line > start_line && - comment.location.start_line < end_line - end + def parse_with_comments(source) + parse_analysis(source).parse_result end end class Adapter def read_ast(document) - result = Utils.parse_with_comments(document.content) - return result if result.success? + analysis = Utils.parse_analysis(document.content, source_label: document.source_label) + return analysis if analysis.valid? raise Ast::Crispr::Error.new("Unable to read structural owners from #{document.source_label}", details: { source_label: document.source_label }) end def structural_owners(document, owner_scope: :shared_default) - parse_result = document.ast + analysis = document.ast case owner_scope when :shared_default, :line_bound_statements, :top_level_statements - Utils.extract_statements(parse_result.value.statements) + analysis.statements when :ruby_comments - parse_result.comments + analysis.parse_result.comments else raise Ast::Crispr::Error.new('Unsupported CRISPR owner scope', details: { owner_scope: owner_scope }) end end def comment_regions_for(document, owner, region: :leading, owner_scope: :shared_default) - parse_result = document.ast + analysis = document.ast owners = structural_owners(document, owner_scope: owner_scope) - index = owners.index(owner) - return [] unless index case region when :leading - previous_owner = index.positive? ? owners[index - 1] : nil - if previous_owner - Utils.find_leading_comments(parse_result, owner, previous_owner, parse_result.value.statements) - else - parse_result.comments.select { |comment| comment.location.start_line < owner.location.start_line } - end + analysis.leading_comments_for_owner(owner, owners: owners) else raise Ast::Crispr::Error.new('Unsupported CRISPR comment region', details: { region: region }) end diff --git a/gems/ast-crispr-ruby-prism/spec/ast/crispr/ruby/prism_spec.rb b/gems/ast-crispr-ruby-prism/spec/ast/crispr/ruby/prism_spec.rb index 790eb77c0..78002983c 100644 --- a/gems/ast-crispr-ruby-prism/spec/ast/crispr/ruby/prism_spec.rb +++ b/gems/ast-crispr-ruby-prism/spec/ast/crispr/ruby/prism_spec.rb @@ -12,6 +12,15 @@ expect(context.adapter).to be_a(Ast::Crispr::Ruby::Prism::Adapter) end + it 'uses prism-merge analysis for Ruby structure' do + analysis = described_class::Utils.parse_analysis("puts :ok\n", source_label: 'example.rb') + result = described_class::Utils.parse_with_comments("puts :ok\n") + + expect(analysis).to be_a(::Prism::Merge::FileAnalysis) + expect(analysis).to be_valid + expect(result).to be_success + end + context 'with a structure profile' do let(:context) { described_class.document_context(content: "puts :ok\n", source_label: 'example.rb') } let(:profile) { context.structure_profile(owner_scope: :top_level_statements) } diff --git a/gems/ast-crispr/.gitattributes b/gems/ast-crispr/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-crispr/.gitattributes +++ b/gems/ast-crispr/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-crispr/.kettle-drift.lock b/gems/ast-crispr/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/ast-crispr/.kettle-drift.lock +++ b/gems/ast-crispr/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/ast-crispr/Gemfile b/gems/ast-crispr/Gemfile index 2ebdddbb1..408241295 100644 --- a/gems/ast-crispr/Gemfile +++ b/gems/ast-crispr/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-crispr/Gemfile.lock b/gems/ast-crispr/Gemfile.lock index 72148c0bf..0b6a216c5 100644 --- a/gems/ast-crispr/Gemfile.lock +++ b/gems/ast-crispr/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH service_actor (~> 3.9) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -324,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -355,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -376,22 +636,44 @@ DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -400,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -433,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -445,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -472,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -483,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -510,9 +828,11 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 @@ -522,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -535,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-crispr/gemfiles/modular/templating.gemfile b/gems/ast-crispr/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-crispr/gemfiles/modular/templating.gemfile +++ b/gems/ast-crispr/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-crispr/gemfiles/modular/templating_local.gemfile b/gems/ast-crispr/gemfiles/modular/templating_local.gemfile index a39610b04..33f003f01 100644 --- a/gems/ast-crispr/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-crispr/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-crispr] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-crispr] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-crispr] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ast-crispr/lib/ast/crispr.rb b/gems/ast-crispr/lib/ast/crispr.rb index c04d41e3b..04d239161 100644 --- a/gems/ast-crispr/lib/ast/crispr.rb +++ b/gems/ast-crispr/lib/ast/crispr.rb @@ -290,24 +290,15 @@ def to_h private def normalize_start_boundary(value) - boundary = value&.to_sym - return boundary if KNOWN_START_BOUNDARIES.include?(boundary) - - raise Error.new('Unsupported CRISPR match start boundary', details: { start_boundary: value.inspect }) + value&.to_sym end def normalize_end_boundary(value) - boundary = value&.to_sym - return boundary if KNOWN_END_BOUNDARIES.include?(boundary) - - raise Error.new('Unsupported CRISPR match end boundary', details: { end_boundary: value.inspect }) + value&.to_sym end def normalize_payload_kind(value) - kind = value&.to_sym - return kind if KNOWN_PAYLOAD_KINDS.include?(kind) - - raise Error.new('Unsupported CRISPR match payload kind', details: { payload_kind: value.inspect }) + value&.to_sym end end @@ -435,25 +426,15 @@ def to_h private def normalize_resolution_kind(value) - kind = value&.to_sym - return kind if KNOWN_RESOLUTION_KINDS.include?(kind) - - raise Error.new('Unsupported CRISPR destination resolution kind', details: { resolution_kind: value.inspect }) + value&.to_sym end def normalize_resolution_source(value) - source = value&.to_sym - return source if KNOWN_RESOLUTION_SOURCES.include?(source) - - raise Error.new('Unsupported CRISPR destination resolution source', - details: { resolution_source: value.inspect }) + value&.to_sym end def normalize_anchor_boundary(value) - boundary = value&.to_sym - return boundary if KNOWN_ANCHOR_BOUNDARIES.include?(boundary) - - raise Error.new('Unsupported CRISPR destination anchor boundary', details: { anchor_boundary: value.inspect }) + value&.to_sym end end @@ -528,14 +509,19 @@ class SelectionProfile attr_reader :owner_scope, :selector_kind, :selection_intent, :comment_region, :include_trailing_gap, :structure_profile, :metadata - def initialize(owner_scope:, selector_kind:, selection_intent:, structure_profile:, comment_region: nil, + def initialize(owner_scope:, selector_kind:, selection_intent:, structure_profile: nil, owner_selector: nil, + comment_region: nil, include_trailing_gap: false, metadata: {}, **options) @owner_scope = owner_scope&.to_sym @selector_kind = selector_kind&.to_sym @selection_intent = selection_intent&.to_sym @comment_region = comment_region&.to_sym @include_trailing_gap = include_trailing_gap ? true : false - @structure_profile = structure_profile + @structure_profile = structure_profile || StructureProfile.new( + owner_scope: owner_scope, + owner_selector: owner_selector || :line_bound_statements, + supported_comment_regions: [comment_region].compact + ) @metadata = metadata.merge(options).freeze end @@ -586,6 +572,10 @@ class OperationProfile family: :rewrite, description: 'Replace selected content with explicit replacement text' }, + merge_replace: { + family: :rewrite, + description: 'Replace selected content with the result of a merge-gem slice merge' + }, delete: { family: :removal, description: 'Delete selected content without inserting replacement text' @@ -600,7 +590,7 @@ class OperationProfile } }.freeze KNOWN_REQUIREMENTS = %i[none optional required].freeze - KNOWN_REPLACEMENT_SOURCES = %i[none explicit_text captured_text_or_explicit].freeze + KNOWN_REPLACEMENT_SOURCES = %i[none explicit_text captured_text_or_explicit merge_template_text].freeze attr_reader :operation_kind, :source_requirement, :destination_requirement, :replacement_source, :metadata @@ -676,18 +666,11 @@ def to_h private def normalize_requirement(value, field_name) - requirement = value&.to_sym - return requirement if KNOWN_REQUIREMENTS.include?(requirement) - - raise Error.new('Unsupported CRISPR operation requirement', - details: { field: field_name, value: value.inspect }) + value&.to_sym end def normalize_replacement_source(value) - replacement = value&.to_sym - return replacement if KNOWN_REPLACEMENT_SOURCES.include?(replacement) - - raise Error.new('Unsupported CRISPR replacement source', details: { replacement_source: value.inspect }) + value&.to_sym end end @@ -1060,6 +1043,79 @@ def replace_line_ranges(source, matches, replacement) Ast::Merge::StructuralEdit::PlanSet.new(source: source, plans: plans).merged_content end + def merge_replace_line_ranges(source, matches, replacement, merger_class:, merger_options:) + assert_non_overlapping!(matches) + merge_results = [] + plans = matches.map do |match| + destination_slice = match.slice_from(source) + merge_result = merge_replacement_slice( + replacement.to_s, + destination_slice, + merger_class: merger_class, + merger_options: merger_options + ) + merge_results << merge_result + + Ast::Merge::StructuralEdit::SplicePlan.new( + source: source, + replace_start_line: match.start_line, + replace_end_line: match.end_line, + replacement: merge_result.fetch(:content), + metadata: { merge_result: merge_result, mode: :merge_replace } + ) + end + + [ + Ast::Merge::StructuralEdit::PlanSet.new(source: source, plans: plans).merged_content, + merge_results + ] + end + + def merge_replacement_slice(template_slice, destination_slice, merger_class:, merger_options:) + merger = merger_class.new(template_slice, destination_slice, **merger_options) + result = merger.respond_to?(:merge_result) ? merger.merge_result : merger.merge + content = merge_result_content(result) + + { + content: content, + result: result, + stats: merge_result_stats(result, merger), + conflicts: merge_result_conflicts(result), + unresolved: merge_result_unresolved?(result) + } + end + + def merge_result_content(result) + return result if result.is_a?(String) + return result.output if result.respond_to?(:output) + return result.content if result.respond_to?(:content) && result.content.is_a?(String) + + result.to_s + end + + def merge_result_stats(result, merger) + if result.respond_to?(:stats) + stats = result.stats + return stats unless stats.respond_to?(:empty?) && stats.empty? + end + return merger.stats if merger.respond_to?(:stats) + + {} + end + + def merge_result_conflicts(result) + return result.conflicts if result.respond_to?(:conflicts) + + [] + end + + def merge_result_unresolved?(result) + return result.unresolved? if result.respond_to?(:unresolved?) + return result.review_required? if result.respond_to?(:review_required?) + + false + end + def assert_non_overlapping!(matches) ranges = matches.map(&:line_range).sort_by(&:begin) ranges.each_cons(2) do |left, right| @@ -1215,6 +1271,59 @@ def operation_profile end end + class MergeReplace < Actor + include OperationSupport + include OperationProfilable + + declare_operation_profile( + operation_kind: :merge_replace, + source_requirement: :required, + destination_requirement: :none, + replacement_source: :merge_template_text, + captures_source_text: true, + supports_if_missing: false + ) + + input :content, type: String + input :target, type: OwnerSelector + input :replacement, type: String + input :merger_class + input :merger_options, default: -> { {} } + input :source_label, type: String, default: 'source' + + output :updated_content + output :matches, default: -> { [] } + output :match_count, type: Integer, default: 0 + output :changed, default: false + output :captured_text, allow_nil: true, default: nil + output :merge_results, default: -> { [] } + output :operation_profile + + def call + self.operation_profile = self.class.operation_profile + context = context_for(content: content, source_label: source_label, target: target) + self.matches = normalize_matches(target, context) + self.match_count = matches.size + self.captured_text = capture_text(content, matches) + if matches.empty? + self.updated_content = content + self.changed = false + return + end + + self.updated_content, self.merge_results = merge_replace_line_ranges( + content, + matches, + replacement, + merger_class: merger_class, + merger_options: merger_options.to_h + ) + self.changed = updated_content != content + rescue Error => e + crispr_fail!(e) + end + end + class Replace < Actor include OperationSupport include OperationProfilable @@ -1427,18 +1536,6 @@ def report ) stringified_report(data) end - - def normalize_start_boundary(value) - value&.to_sym - end - - def normalize_end_boundary(value) - value&.to_sym - end - - def normalize_payload_kind(value) - value&.to_sym - end end class SelectionProfile @@ -1463,21 +1560,6 @@ class SelectionProfile section_heading: :section }.freeze - def initialize(owner_scope:, selector_kind:, selection_intent:, structure_profile: nil, owner_selector: nil, - comment_region: nil, include_trailing_gap: false, metadata: {}, **options) - @owner_scope = owner_scope&.to_sym - @selector_kind = selector_kind&.to_sym - @selection_intent = selection_intent&.to_sym - @comment_region = comment_region&.to_sym - @include_trailing_gap = include_trailing_gap ? true : false - @structure_profile = structure_profile || StructureProfile.new( - owner_scope: owner_scope, - owner_selector: owner_selector || :line_bound_statements, - supported_comment_regions: [comment_region].compact - ) - @metadata = metadata.merge(options).freeze - end - def report data = to_h selector_kind_family = KNOWN_SELECTOR_KINDS[selector_kind]&.fetch(:family, nil) @@ -1497,24 +1579,6 @@ def report ) stringified_report(data) end - - def normalize_owner_selector(value) - value&.to_sym - end - - def normalize_selector_kind(value) - value&.to_sym - end - - def normalize_selection_intent(value) - value&.to_sym - end - - def normalize_comment_region(value) - return nil if value.nil? - - value&.to_sym - end end class DestinationProfile @@ -1530,18 +1594,6 @@ def report ) stringified_report(data) end - - def normalize_resolution_kind(value) - value&.to_sym - end - - def normalize_resolution_source(value) - value&.to_sym - end - - def normalize_anchor_boundary(value) - value&.to_sym - end end class OperationProfile @@ -1562,18 +1614,6 @@ def report ) stringified_report(data) end - - def normalize_operation_kind(value) - value&.to_sym - end - - def normalize_requirement(value, *) - value&.to_sym - end - - def normalize_replacement_source(value) - value&.to_sym - end end class StructureProfile @@ -1582,14 +1622,6 @@ class StructureProfile def report stringified_report(to_h) end - - def normalize_owner_selector(value) - value&.to_sym - end - - def normalize_comment_region(value) - value&.to_sym - end end class << self diff --git a/gems/ast-crispr/spec/old_runtime_spec.rb b/gems/ast-crispr/spec/old_runtime_spec.rb index 96130da78..7e8509493 100644 --- a/gems/ast-crispr/spec/old_runtime_spec.rb +++ b/gems/ast-crispr/spec/old_runtime_spec.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +require 'json' +require 'pathname' + RSpec.describe Ast::Crispr do FakeLocation = Struct.new(:start_line, :end_line, keyword_init: true) FakeCommentRegion = Struct.new(:location, :text, keyword_init: true) @@ -55,6 +58,14 @@ def structure_profile(owner_scope: :shared_default) end let(:adapter) { FakeAdapter.new(owners: owners, comments: comments) } + def fixtures_root + Pathname(__dir__).join('..', '..', '..', '..', 'fixtures').expand_path + end + + def read_json(path) + Ast::Merge.normalize_value(JSON.parse(path.read)) + end + it 'has a version number' do expect(Ast::Crispr::VERSION).not_to be_nil end @@ -331,6 +342,26 @@ def structure_profile(owner_scope: :shared_default) it_behaves_like 'Ast::Crispr::OperationProfile contract' end + describe Ast::Crispr::MergeReplace do + let(:operation_profile) { described_class.operation_profile } + let(:expected_operation_kind) { :merge_replace } + let(:expected_operation_family) { :rewrite } + let(:expected_known_operation_kind) { true } + let(:expected_source_requirement) { :required } + let(:expected_destination_requirement) { :none } + let(:expected_replacement_source) { :merge_template_text } + let(:expected_captures_source_text) { true } + let(:expected_supports_if_missing) { false } + let(:expected_selects_source) { true } + let(:expected_requires_source) { true } + let(:expected_supports_destination) { false } + let(:expected_requires_destination) { false } + let(:expected_explicit_replacement) { false } + let(:expected_may_reuse_captured_text) { false } + + it_behaves_like 'Ast::Crispr::OperationProfile contract' + end + describe Ast::Crispr::Delete do let(:operation_profile) { described_class.operation_profile } let(:expected_operation_kind) { :delete } @@ -415,6 +446,39 @@ def structure_profile(owner_scope: :shared_default) end end + describe described_class::MergeReplace do + it 'merges replacement text into the selected slice before splicing it back' do + fixture = read_json(fixtures_root.join('diagnostics', 'slice-1018-crispr-slice-merge', + 'crispr-slice-merge.json')) + operation = fixture.fetch(:operation) + selector = operation.fetch(:selector) + merge = operation.fetch(:merge) + target = Ast::Crispr::Selectors.line_block( + start_line_text: selector.fetch(:start_line_text), + end_line_text: selector.fetch(:end_line_text), + limit: selector.fetch(:limit) + ) + + actor = described_class.call( + content: operation.fetch(:content), + target: target, + replacement: operation.fetch(:replacement), + merger_class: Ast::Merge::Text::SmartMerger, + merger_options: { + preference: merge.fetch(:preference).to_sym, + add_template_only_nodes: merge.fetch(:add_template_only_nodes) + } + ) + + expected = fixture.fetch(:expected) + expect(actor.changed).to eq(expected.fetch(:changed)) + expect(actor.match_count).to eq(expected.fetch(:match_count)) + expect(actor.captured_text).to include(expected.fetch(:captured_text_contains)) + expect(actor.merge_results.first.fetch(:stats)).not_to be_empty + expect(actor.updated_content).to eq(expected.fetch(:output)) + end + end + describe described_class::Insert do it 'appends when configured and no destination is resolved' do content = <<~RUBY diff --git a/gems/ast-crispr/spec/provider_architecture_spec.rb b/gems/ast-crispr/spec/provider_architecture_spec.rb new file mode 100644 index 000000000..d816944b9 --- /dev/null +++ b/gems/ast-crispr/spec/provider_architecture_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'pathname' + +RSpec.describe 'Ast::Crispr provider architecture' do + let(:repo_root) { Pathname(__dir__).join('..', '..', '..').expand_path } + let(:provider_lib_files) { repo_root.join('gems').glob('ast-crispr-*/lib/**/*.rb') } + + let(:forbidden_patterns) do + { + /(? 'delegate Ruby/Prism analysis to prism-merge', + /(? 'delegate Markdown/Markly analysis to markly-merge', + /(? 'delegate Markdown/CommonMarker analysis to commonmarker-merge', + /Kramdown::Document\.new\b/ => 'delegate Markdown/Kramdown analysis to kramdown-merge', + /(? 'delegate JSON analysis to json-merge', + /(? 'delegate YAML analysis to yaml-merge or psych-merge', + /\bTomlRB\b/ => 'delegate TOML analysis to toml-merge or a TOML provider merge gem', + /\bTOML::Parslet\b/ => 'delegate TOML analysis to toml-merge or parslet-toml-merge', + /TreeHaver\.register_language\b/ => 'register TreeHaver backends in merge gems', + /TreeHaver::BackendRegistry\.register\b/ => 'register TreeHaver backends in merge gems', + /TreeHaver\.parser_for\b/ => 'delegate parsing and analysis to merge gems' + } + end + + it 'keeps provider gems above merge-gem analysis instead of parser APIs' do + violations = provider_lib_files.flat_map do |path| + content = path.read + relative_path = path.relative_path_from(repo_root) + + forbidden_patterns.filter_map do |pattern, guidance| + next unless content.match?(pattern) + + "#{relative_path}: matches #{pattern.inspect}; #{guidance}" + end + end + + expect(violations).to be_empty, violations.join("\n") + end +end diff --git a/gems/ast-merge-git/.gitattributes b/gems/ast-merge-git/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-merge-git/.gitattributes +++ b/gems/ast-merge-git/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-merge-git/.kettle-drift.lock b/gems/ast-merge-git/.kettle-drift.lock index 1dad17e1d..e3a4ed60c 100644 --- a/gems/ast-merge-git/.kettle-drift.lock +++ b/gems/ast-merge-git/.kettle-drift.lock @@ -3,8 +3,15 @@ { "file": "Gemfile", "lines": [ - 79, - 119 + 80, + 120, + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -12,8 +19,15 @@ { "file": "Gemfile", "lines": [ - 90, - 130 + 91, + 131, + 171, + 211, + 251, + 291, + 331, + 371, + 411 ] } ], @@ -21,8 +35,15 @@ { "file": "Gemfile", "lines": [ - 80, - 120 + 81, + 121, + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -30,8 +51,15 @@ { "file": "Gemfile", "lines": [ - 92, - 132 + 93, + 133, + 173, + 213, + 253, + 293, + 333, + 373, + 413 ] } ], @@ -39,8 +67,15 @@ { "file": "Gemfile", "lines": [ - 95, - 135 + 96, + 136, + 176, + 216, + 256, + 296, + 336, + 376, + 416 ] } ], @@ -48,8 +83,15 @@ { "file": "Gemfile", "lines": [ - 81, - 121 + 82, + 122, + 162, + 202, + 242, + 282, + 322, + 362, + 402 ] } ], @@ -57,9 +99,16 @@ { "file": "Gemfile", "lines": [ - 59, - 99, - 139 + 60, + 100, + 140, + 180, + 220, + 260, + 300, + 340, + 380, + 420 ] } ], @@ -67,8 +116,15 @@ { "file": "Gemfile", "lines": [ - 100, - 140 + 101, + 141, + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -76,9 +132,16 @@ { "file": "Gemfile", "lines": [ - 42, - 86, - 126 + 43, + 87, + 127, + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -86,8 +149,15 @@ { "file": "Gemfile", "lines": [ - 109, - 149 + 110, + 150, + 190, + 230, + 270, + 310, + 350, + 390, + 430 ] } ], @@ -95,9 +165,16 @@ { "file": "Gemfile", "lines": [ - 34, - 78, - 118 + 35, + 79, + 119, + 159, + 199, + 239, + 279, + 319, + 359, + 399 ] } ], @@ -105,9 +182,16 @@ { "file": "Gemfile", "lines": [ - 68, - 108, - 148 + 69, + 109, + 149, + 189, + 229, + 269, + 309, + 349, + 389, + 429 ] } ], @@ -115,8 +199,15 @@ { "file": "Gemfile", "lines": [ - 84, - 124 + 85, + 125, + 165, + 205, + 245, + 285, + 325, + 365, + 405 ] } ], @@ -124,9 +215,16 @@ { "file": "Gemfile", "lines": [ - 47, - 91, - 131 + 48, + 92, + 132, + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -134,9 +232,16 @@ { "file": "Gemfile", "lines": [ - 43, - 87, - 127 + 44, + 88, + 128, + 168, + 208, + 248, + 288, + 328, + 368, + 408 ] } ], @@ -144,8 +249,15 @@ { "file": "Gemfile", "lines": [ - 85, - 125 + 86, + 126, + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -153,8 +265,15 @@ { "file": "Gemfile", "lines": [ - 102, - 142 + 103, + 143, + 183, + 223, + 263, + 303, + 343, + 383, + 423 ] } ], @@ -162,8 +281,15 @@ { "file": "Gemfile", "lines": [ - 101, - 141 + 102, + 142, + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -171,8 +297,15 @@ { "file": "Gemfile", "lines": [ - 96, - 136 + 97, + 137, + 177, + 217, + 257, + 297, + 337, + 377, + 417 ] } ], @@ -180,8 +313,15 @@ { "file": "Gemfile", "lines": [ - 105, - 145 + 106, + 146, + 186, + 226, + 266, + 306, + 346, + 386, + 426 ] } ], diff --git a/gems/ast-merge-git/.rubocop_gradual.lock b/gems/ast-merge-git/.rubocop_gradual.lock index bc438def4..ff0066794 100644 --- a/gems/ast-merge-git/.rubocop_gradual.lock +++ b/gems/ast-merge-git/.rubocop_gradual.lock @@ -8,11 +8,11 @@ [163, 121, 22, "Layout/LineLength: Line is too long. [142/120]", 1367093088], [166, 121, 18, "Layout/LineLength: Line is too long. [138/120]", 3881946477] ], - "ast-merge-git.gemspec:646301195": [ - [127, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], - [142, 121, 50, "Layout/LineLength: Line is too long. [170/120]", 3888612416], - [143, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949], - [150, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 4229808912] + "ast-merge-git.gemspec:151757427": [ + [128, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], + [143, 121, 50, "Layout/LineLength: Line is too long. [170/120]", 3888612416], + [144, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949], + [151, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 4229808912] ], "gemfiles/modular/benchmark/r4/v0.5.gemfile:3644720371": [ [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177542] @@ -82,46 +82,38 @@ "lib/ast-merge-git.rb:2225160157": [ [1, 1, 0, "Naming/FileName: The name of this source file (`ast-merge-git.rb`) should use snake_case.", 5381] ], - "lib/ast/merge/git.rb:1842264944": [ - [11, 5, 10, "Style/Documentation: Missing top-level documentation comment for `module Ast::Merge::Git`.", 3851934373], - [11, 5, 16583, "Metrics/ModuleLength: Module has too many lines. [376/100]", 1524969990], - [17, 7, 487, "Metrics/MethodLength: Method has too many lines. [15/10]", 186495496], - [35, 7, 2131, "Metrics/AbcSize: Assignment Branch Condition size for `merge3_json` is too high. [<10, 21, 5> 23.79/17]", 4226122829], - [35, 7, 2131, "Metrics/MethodLength: Method has too many lines. [49/10]", 4226122829], - [92, 7, 1030, "Metrics/MethodLength: Method has too many lines. [23/10]", 3760313662], - [119, 7, 1773, "Metrics/AbcSize: Assignment Branch Condition size for `response` is too high. [<0, 20, 6> 20.88/17]", 2729446571], - [119, 7, 1773, "Metrics/MethodLength: Method has too many lines. [33/10]", 2729446571], - [119, 19, 285, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [13/5]", 1214652168], - [119, 20, 2, "Naming/MethodParameterName: Method parameter must be at least 3 characters long.", 5861217], - [120, 121, 90, "Layout/LineLength: Line is too long. [210/120]", 198321059], - [136, 121, 4, "Layout/LineLength: Line is too long. [124/120]", 2089543276], - [143, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 1756879393], - [150, 121, 10, "Layout/LineLength: Line is too long. [130/120]", 3825289243], - [156, 7, 1545, "Metrics/MethodLength: Method has too many lines. [22/10]", 3913227083], - [158, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 3143802438], - [182, 7, 633, "Metrics/MethodLength: Method has too many lines. [17/10]", 1596017211], - [211, 7, 580, "Metrics/MethodLength: Method has too many lines. [14/10]", 806995714], - [228, 7, 1207, "Metrics/AbcSize: Assignment Branch Condition size for `render_json_owned_region_conflict_source` is too high. [<11, 31, 9> 34.1/17]", 3379641138], - [228, 7, 1207, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `render_json_owned_region_conflict_source` is too high. [9/7]", 3379641138], - [228, 7, 1207, "Metrics/MethodLength: Method has too many lines. [22/10]", 3379641138], - [228, 7, 1207, "Metrics/PerceivedComplexity: Perceived complexity for `render_json_owned_region_conflict_source` is too high. [9/8]", 3379641138], - [267, 7, 1003, "Metrics/MethodLength: Method has too many lines. [21/10]", 3925322740], - [322, 7, 647, "Metrics/AbcSize: Assignment Branch Condition size for `merge_json_objects` is too high. [<9, 19, 8> 22.49/17]", 3282600463], - [322, 7, 647, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_json_objects` is too high. [9/7]", 3282600463], - [322, 7, 647, "Metrics/MethodLength: Method has too many lines. [14/10]", 3282600463], - [322, 7, 647, "Metrics/PerceivedComplexity: Perceived complexity for `merge_json_objects` is too high. [9/8]", 3282600463], - [339, 7, 1225, "Metrics/AbcSize: Assignment Branch Condition size for `classify_json_changes` is too high. [<9, 26, 19> 33.44/17]", 1184093629], - [339, 7, 1225, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `classify_json_changes` is too high. [16/7]", 1184093629], - [339, 7, 1225, "Metrics/MethodLength: Method has too many lines. [18/10]", 1184093629], - [339, 7, 1225, "Metrics/PerceivedComplexity: Perceived complexity for `classify_json_changes` is too high. [16/8]", 1184093629], - [372, 7, 1204, "Metrics/AbcSize: Assignment Branch Condition size for `merge_json_entry` is too high. [<3, 4, 24> 24.52/17]", 4167732292], - [372, 7, 1204, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_json_entry` is too high. [19/7]", 4167732292], - [372, 7, 1204, "Metrics/MethodLength: Method has too many lines. [23/10]", 4167732292], - [372, 7, 1204, "Metrics/PerceivedComplexity: Perceived complexity for `merge_json_entry` is too high. [19/8]", 4167732292] - ], - "spec/fixtures_integration_spec.rb:3913389885": [ - [5, 1, 4397, "Metrics/BlockLength: Block has too many lines. [76/25]", 3987365418], - [14, 3, 2790, "Metrics/BlockLength: Block has too many lines. [44/25]", 1864930381], - [19, 5, 2476, "Metrics/BlockLength: Block has too many lines. [39/25]", 2685930561] + "lib/ast/merge/git.rb:1420427255": [ + [12, 5, 10, "Style/Documentation: Missing top-level documentation comment for `module Ast::Merge::Git`.", 3851934373], + [12, 5, 14569, "Metrics/ModuleLength: Module has too many lines. [364/100]", 863629740], + [19, 7, 487, "Metrics/MethodLength: Method has too many lines. [15/10]", 186495496], + [37, 7, 892, "Metrics/MethodLength: Method has too many lines. [23/10]", 4223005176], + [66, 7, 813, "Metrics/MethodLength: Method has too many lines. [18/10]", 1966785319], + [96, 7, 771, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_json_values` is too high. [8/7]", 3825199411], + [96, 7, 771, "Metrics/MethodLength: Method has too many lines. [16/10]", 3825199411], + [96, 7, 771, "Metrics/PerceivedComplexity: Perceived complexity for `merge_json_values` is too high. [9/8]", 3825199411], + [117, 7, 791, "Metrics/MethodLength: Method has too many lines. [20/10]", 3551257045], + [173, 7, 578, "Metrics/MethodLength: Method has too many lines. [16/10]", 3163340030], + [192, 7, 1178, "Metrics/MethodLength: Method has too many lines. [22/10]", 4051400949], + [217, 7, 678, "Metrics/AbcSize: Assignment Branch Condition size for `render_owned_json_conflict_source` is too high. [<3, 20, 1> 20.25/17]", 3860921953], + [217, 7, 678, "Metrics/MethodLength: Method has too many lines. [15/10]", 3860921953], + [235, 7, 470, "Metrics/MethodLength: Method has too many lines. [12/10]", 962148087], + [261, 7, 1030, "Metrics/MethodLength: Method has too many lines. [23/10]", 3760313662], + [288, 7, 1773, "Metrics/AbcSize: Assignment Branch Condition size for `response` is too high. [<0, 20, 6> 20.88/17]", 2729446571], + [288, 7, 1773, "Metrics/MethodLength: Method has too many lines. [33/10]", 2729446571], + [288, 19, 285, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [13/5]", 1214652168], + [288, 20, 2, "Naming/MethodParameterName: Method parameter must be at least 3 characters long.", 5861217], + [289, 121, 90, "Layout/LineLength: Line is too long. [210/120]", 198321059], + [305, 121, 4, "Layout/LineLength: Line is too long. [124/120]", 2089543276], + [312, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 1756879393], + [319, 121, 10, "Layout/LineLength: Line is too long. [130/120]", 3825289243], + [325, 7, 1545, "Metrics/MethodLength: Method has too many lines. [22/10]", 3913227083], + [327, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 3143802438], + [351, 7, 633, "Metrics/MethodLength: Method has too many lines. [17/10]", 1596017211], + [380, 7, 580, "Metrics/MethodLength: Method has too many lines. [14/10]", 806995714] + ], + "spec/fixtures_integration_spec.rb:2251743409": [ + [5, 1, 4009, "Metrics/BlockLength: Block has too many lines. [66/25]", 2498851053], + [14, 3, 2402, "Metrics/BlockLength: Block has too many lines. [34/25]", 3612522178], + [19, 5, 2088, "Metrics/BlockLength: Block has too many lines. [29/25]", 113456270] ] } diff --git a/gems/ast-merge-git/Gemfile b/gems/ast-merge-git/Gemfile index 47d5e04b4..d8a97d415 100644 --- a/gems/ast-merge-git/Gemfile +++ b/gems/ast-merge-git/Gemfile @@ -25,6 +25,7 @@ gem 'nomono', *nomono_requirements, require: false # ruby >= 2.2 # Direct sibling dependencies (env-switched via STRUCTUREDMERGE_DEV) direct_sibling_gems = %w[ ast-merge + json-merge ] direct_sibling_dev = ENV.fetch('STRUCTUREDMERGE_DEV', '') direct_sibling_local = @@ -151,7 +152,287 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +441,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +449,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-merge-git/Gemfile.lock b/gems/ast-merge-git/Gemfile.lock index e46a16edd..6c4aeff4b 100644 --- a/gems/ast-merge-git/Gemfile.lock +++ b/gems/ast-merge-git/Gemfile.lock @@ -1,36 +1,288 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: ast-merge-git (7.1.0) ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -39,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -97,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -130,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -269,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -321,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -352,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -372,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -518,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -531,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-merge-git/ast-merge-git.gemspec b/gems/ast-merge-git/ast-merge-git.gemspec index 8a8945ca1..f0b4704eb 100644 --- a/gems/ast-merge-git/ast-merge-git.gemspec +++ b/gems/ast-merge-git/ast-merge-git.gemspec @@ -96,6 +96,7 @@ Gem::Specification.new do |spec| # Utilities spec.add_dependency 'ast-merge', "= #{spec.version}" + spec.add_dependency 'json-merge', "= #{spec.version}" spec.add_dependency('version_gem', '~> 1.1', '>= 1.1.9') # ruby >= 2.2.0 # NOTE: It is preferable to list development dependencies in the gemspec due to increased diff --git a/gems/ast-merge-git/gemfiles/modular/templating.gemfile b/gems/ast-merge-git/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-merge-git/gemfiles/modular/templating.gemfile +++ b/gems/ast-merge-git/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-merge-git/gemfiles/modular/templating_local.gemfile b/gems/ast-merge-git/gemfiles/modular/templating_local.gemfile index ab827c840..62371754c 100644 --- a/gems/ast-merge-git/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-merge-git/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-merge-git] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-merge-git] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-merge-git] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ast-merge-git/lib/ast/merge/git.rb b/gems/ast-merge-git/lib/ast/merge/git.rb index f1766c986..ff5e800f5 100644 --- a/gems/ast-merge-git/lib/ast/merge/git.rb +++ b/gems/ast-merge-git/lib/ast/merge/git.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true -require 'json' require 'version_gem' require 'ast/merge' +require 'json' +require 'json/merge' require_relative 'git/version' module Ast @@ -11,6 +12,7 @@ module Merge module Git PACKAGE_NAME = 'ast-merge-git' MERGE_CONFLICT_CATEGORY = 'merge_conflict' + MISSING = Object.new.freeze module_function @@ -33,58 +35,225 @@ def merge3(request) end def merge3_json(request) - base = parse_json_role('base', request.fetch(:base_source)) - ours = parse_json_role('ours', request.fetch(:ours_source)) - theirs = parse_json_role('theirs', request.fetch(:theirs_source)) - conflicts = [] - change_classifications = classify_json_changes(base, ours, theirs) - merged = merge_json_value(base, ours, theirs, '', conflicts) - if conflicts.any? - owned_regions = json_owned_regions_for_conflicts(request, conflicts) - render_strategy = owned_regions.empty? ? 'full_file_conflict_markers' : 'owned_region_conflict_markers' + parsed = parse_json_merge3_inputs(request) + return parsed unless parsed.is_a?(Hash) && parsed[:ok] + + merge = merge_json_values( + parsed.fetch(:base), + parsed.fetch(:ours), + parsed.fetch(:theirs), + path: '' + ) + + if merge.fetch(:conflicts).empty? + merged_source = "#{JSON.pretty_generate(merge.fetch(:value))}\n" return response( - ok: false, + ok: true, request: request, - conflicted_source: render_json_owned_region_conflict_source(request, - owned_regions.first) || render_conflict_source( - request, conflicts - ), - conflicts: conflicts, - change_classifications: change_classifications, - owned_regions: owned_regions, - render_strategy: render_strategy, - diagnostics: [{ - severity: 'error', - category: MERGE_CONFLICT_CATEGORY, - message: "merge3 found #{conflicts.length} unresolved conflict(s)." - }] + merged_source: merged_source, + change_classifications: merge.fetch(:change_classifications), + reparse_after_render: reparse_json_source(merged_source), + formatting_preservation: { + line_diff_score: 1.0, + character_diff_score: 1.0 + } ) end - output = JSON.generate(merged) - response( + render_conflicted_json(request, merge) + end + + def parse_json_merge3_inputs(request) + dialect = request[:dialect].to_s.empty? ? 'json' : request[:dialect].to_s + { ok: true, - request: request, - merged_source: output, - change_classifications: change_classifications, - reparse_after_render: JSON.parse(output) && true, - formatting_preservation: { - line_diff_score: 1.0, - character_diff_score: 1.0 - } - ) - rescue JSON::ParserError => e + base: Json::Merge.json_value_for_source(request.fetch(:base_source), dialect: dialect), + ours: Json::Merge.json_value_for_source(request.fetch(:ours_source), dialect: dialect), + theirs: Json::Merge.json_value_for_source(request.fetch(:theirs_source), dialect: dialect) + } + rescue Json::Merge::ParseError => e + source_role = parse_error_role(request, dialect) response( ok: false, request: request, diagnostics: [{ severity: 'error', category: 'parse_error', - message: e.message + message: "#{source_role} parse error: #{e.message}" }] ) end + def parse_error_role(request, dialect) + %i[base ours theirs].find do |role| + Json::Merge.json_value_for_source(request.fetch(:"#{role}_source"), dialect: dialect) + false + rescue Json::Merge::ParseError + true + end || :unknown + end + + def merge_json_values(base, ours, theirs, path:) + if ours == theirs + return merge_success(ours) + elsif base == ours + return merge_success(theirs, change: classify_json_change(path, base, ours, theirs)) + elsif base == theirs + return merge_success(ours, change: classify_json_change(path, base, ours, theirs)) + end + + if base.is_a?(Hash) && ours.is_a?(Hash) && theirs.is_a?(Hash) + return merge_json_objects(base, ours, theirs, path: path) + end + + conflict = json_conflict(path, base, ours, theirs) + { + value: ours.equal?(MISSING) ? theirs : ours, + conflicts: [conflict], + change_classifications: [conflict.fetch(:change_classification)] + } + end + + def merge_json_objects(base, ours, theirs, path:) + merged = {} + conflicts = [] + change_classifications = [] + ordered_keys(base, ours, theirs).each do |key| + child_path = "#{path}/#{key}" + child = merge_json_values( + base.fetch(key, MISSING), + ours.fetch(key, MISSING), + theirs.fetch(key, MISSING), + path: child_path + ) + merged[key] = child.fetch(:value) unless child.fetch(:value).equal?(MISSING) + conflicts.concat(child.fetch(:conflicts)) + change_classifications.concat(child.fetch(:change_classifications)) + end + + { + value: merged, + conflicts: conflicts, + change_classifications: change_classifications + } + end + + def ordered_keys(*objects) + objects.each_with_object([]) do |object, keys| + next unless object.is_a?(Hash) + + object.each_key { |key| keys << key unless keys.include?(key) } + end + end + + def merge_success(value, change: nil) + { + value: value, + conflicts: [], + change_classifications: change ? [change] : [] + } + end + + def classify_json_change(path, base, ours, theirs) + { + path: path, + ours: json_change_state(base, ours), + theirs: json_change_state(base, theirs) + } + end + + def json_change_state(base, value) + return 'unchanged' if base == value + return 'added' if base.equal?(MISSING) + return 'deleted' if value.equal?(MISSING) + + 'edited' + end + + def json_conflict(path, base, ours, theirs) + category = + if ours.equal?(MISSING) || theirs.equal?(MISSING) + 'delete_edit' + else + 'edit_edit' + end + { + conflict_id: "json-conflict-#{path.delete_prefix('/').tr('/', '-')}", + category: category, + path: path, + message: "JSON value changed incompatibly at #{path}", + base: base, + ours: ours, + theirs: theirs, + change_classification: classify_json_change(path, base, ours, theirs) + } + end + + def render_conflicted_json(request, merge) + conflicts = merge.fetch(:conflicts) + full_file = conflicts.any? { |conflict| conflict.fetch(:category) == 'delete_edit' } + conflicted_source = if full_file + render_conflict_source(request, conflicts) + else + render_owned_json_conflict_source(request, conflicts.first) + end + response( + ok: false, + request: request, + conflicted_source: conflicted_source, + conflicts: conflicts.map { |conflict| conflict.slice(:conflict_id, :category, :path, :message) }, + change_classifications: merge.fetch(:change_classifications), + diagnostics: [{ + severity: 'error', + category: MERGE_CONFLICT_CATEGORY, + message: "#{conflicts.length} unresolved JSON merge conflict(s)." + }], + owned_regions: full_file ? [] : [owned_json_region(conflicts.first)], + reparse_after_render: nil, + render_strategy: full_file ? 'full_file_conflict_markers' : 'owned_region_conflict_markers' + ) + end + + def render_owned_json_conflict_source(request, conflict) + marker_size = request[:conflict_marker_size].to_i + marker_size = 7 unless marker_size.positive? + key = conflict.fetch(:path).split('/').last + [ + '{', + "#{'<' * marker_size} ours", + "#{JSON.generate(key)}:#{JSON.generate(conflict.fetch(:ours))}", + "#{'|' * marker_size} base", + "#{JSON.generate(key)}:#{JSON.generate(conflict.fetch(:base))}", + '=' * marker_size, + "#{JSON.generate(key)}:#{JSON.generate(conflict.fetch(:theirs))}", + "#{'>' * marker_size} theirs", + '}', + '' + ].join("\n") + end + + def owned_json_region(conflict) + { + owner_path: conflict.fetch(:path), + node_id: "json:key:#{conflict.fetch(:path).split('/').last}", + region_kind: 'node', + line_range: { start: 1, end: 1 }, + attached_spans: [], + backend_id: 'tree-haver', + parser_identity: 'tree_sitter_language_pack', + can_replace: true, + can_line_merge: false, + requires_reparse: true + } + end + + def reparse_json_source(source) + Json::Merge.json_value_for_source(source) + true + rescue Json::Merge::ParseError + false + end + def normalize_request(request) request.transform_keys(&:to_sym) end @@ -202,7 +371,7 @@ def secondary_formatting_metrics_for(merged) def render_identity(request) case normalize_language(request) when 'json' - { backend_id: 'native-json', parser_identity: 'standard-json' } + { backend_id: 'tree-haver', parser_identity: 'tree_sitter_language_pack' } else {} end @@ -225,188 +394,6 @@ def render_conflict_source(request, conflicts) ].join("\n") end - def render_json_owned_region_conflict_source(request, region) - return nil unless region && region.fetch(:region_kind) == 'node' - - key = region.fetch(:owner_path).delete_prefix('/') - ours_region = json_member_source(request.fetch(:ours_source), key) - base_region = json_member_source(request.fetch(:base_source), key) - theirs_region = json_member_source(request.fetch(:theirs_source), key) - return nil unless ours_region && base_region && theirs_region - - marker_size = request[:conflict_marker_size].to_i - marker_size = 7 unless marker_size.positive? - replacement = [ - "#{'<' * marker_size} ours", - ours_region.fetch(:text), - "#{'|' * marker_size} base", - base_region.fetch(:text), - '=' * marker_size, - theirs_region.fetch(:text), - "#{'>' * marker_size} theirs" - ].join("\n") - range = ours_region.fetch(:byte_range) - source = request.fetch(:ours_source) - prefix = source.byteslice(0, range.fetch(:start)) || '' - suffix = source.byteslice(range.fetch(:end), source.bytesize - range.fetch(:end)) || '' - prefix + replacement + suffix - end - - def json_member_source(source, key) - return nil unless source.include?("\"#{key}\"") - - range = json_key_byte_range(source, key) - return nil if range.fetch(:end) <= range.fetch(:start) - - { - byte_range: range, - text: source.byteslice(range.fetch(:start)...range.fetch(:end)) - } - end - - def json_owned_regions_for_conflicts(request, conflicts) - conflicts.filter_map do |conflict| - path = conflict.fetch(:path).to_s - next unless path.start_with?('/') && path.count('/') == 1 - - key = path.delete_prefix('/') - base_region = json_member_source(request.fetch(:base_source), key) - next unless base_region && json_member_source(request.fetch(:ours_source), - key) && json_member_source(request.fetch(:theirs_source), key) - - { - owner_path: path, - node_id: "json:key:#{key}", - region_kind: 'node', - byte_range: base_region.fetch(:byte_range), - line_range: { start: 1, end: 1 }, - attached_spans: [], - backend_id: 'native-json', - parser_identity: 'standard-json', - can_replace: true, - can_line_merge: false, - requires_reparse: true - } - end - end - - def json_key_byte_range(source, key) - needle = "\"#{key}\"" - start = source.index(needle) - return { start: 0, end: source.bytesize } unless start - - finish = start + needle.bytesize - finish += 1 while finish < source.bytesize && ![',', '}'].include?(source[finish]) - { start: start, end: finish } - end - - def parse_json_role(role, source) - JSON.parse(source) - rescue JSON::ParserError => e - raise JSON::ParserError, "#{role} parse error: #{e.message}" - end - - def merge_json_value(base, ours, theirs, path, conflicts) - return ours if ours == theirs - return theirs if base == ours - return ours if base == theirs - if base.is_a?(Hash) && ours.is_a?(Hash) && theirs.is_a?(Hash) - return merge_json_objects(base, ours, theirs, path, - conflicts) - end - - add_conflict(conflicts, 'edit_edit', path, 'value changed differently in ours and theirs') - ours - end - - def merge_json_objects(base, ours, theirs, path, conflicts) - base = base.transform_keys(&:to_s) - ours = ours.transform_keys(&:to_s) - theirs = theirs.transform_keys(&:to_s) - keys = (base.keys | ours.keys | theirs.keys).sort - keys.each_with_object({}) do |key, result| - merged, keep = merge_json_entry( - base.key?(key) ? base[key] : :__absent__, - ours.key?(key) ? ours[key] : :__absent__, - theirs.key?(key) ? theirs[key] : :__absent__, - json_pointer_join(path, key), - conflicts - ) - result[key] = merged if keep - end - end - - def classify_json_changes(base, ours, theirs) - if base.is_a?(Hash) && ours.is_a?(Hash) && theirs.is_a?(Hash) - base = base.transform_keys(&:to_s) - ours = ours.transform_keys(&:to_s) - theirs = theirs.transform_keys(&:to_s) - keys = (base.keys | ours.keys | theirs.keys).sort - return keys.filter_map do |key| - ours_change = classify_json_value_change(base.key?(key) ? base[key] : :__absent__, - ours.key?(key) ? ours[key] : :__absent__) - theirs_change = classify_json_value_change(base.key?(key) ? base[key] : :__absent__, - theirs.key?(key) ? theirs[key] : :__absent__) - next if ours_change == 'unchanged' && theirs_change == 'unchanged' - - { path: json_pointer_join('', key), ours: ours_change, theirs: theirs_change } - end - end - - ours_change = classify_json_value_change(base, ours) - theirs_change = classify_json_value_change(base, theirs) - return [] if ours_change == 'unchanged' && theirs_change == 'unchanged' - - [{ path: '/', ours: ours_change, theirs: theirs_change }] - end - - def classify_json_value_change(base, value) - return 'unchanged' if base == :__absent__ && value == :__absent__ - return 'added' if base == :__absent__ - return 'deleted' if value == :__absent__ - return 'unchanged' if base == value - - 'edited' - end - - def merge_json_entry(base, ours, theirs, path, conflicts) - base_absent = base == :__absent__ - ours_absent = ours == :__absent__ - theirs_absent = theirs == :__absent__ - return [nil, false] if base_absent && ours_absent && theirs_absent - return [theirs, true] if base_absent && ours_absent - return [ours, true] if base_absent && theirs_absent - return [ours, true] if base_absent && ours == theirs - - if base_absent - add_conflict(conflicts, 'add_add', path, 'same path added differently in ours and theirs') - return [ours, true] - end - return [nil, false] if ours_absent && theirs_absent - return [nil, false] if ours_absent && base == theirs - return [nil, false] if theirs_absent && base == ours - - if ours_absent - add_conflict(conflicts, 'delete_edit', path, 'ours deleted a value that theirs edited') - return [theirs, true] - end - if theirs_absent - add_conflict(conflicts, 'delete_edit', path, 'theirs deleted a value that ours edited') - return [ours, true] - end - - [merge_json_value(base, ours, theirs, path, conflicts), true] - end - - def add_conflict(conflicts, category, path, message) - conflicts << { - conflict_id: "conflict-#{conflicts.length + 1}", - category: category, - path: path.empty? ? '/' : path, - message: message - } - end - def comment_conflict(category, path, message) { conflict_id: 'comment-conflict-1', @@ -416,11 +403,6 @@ def comment_conflict(category, path, message) } end - def json_pointer_join(parent, token) - escaped = token.to_s.gsub('~', '~0').gsub('/', '~1') - parent.empty? ? "/#{escaped}" : "#{parent}/#{escaped}" - end - def normalize_language(request) language = request[:language].to_s.strip.downcase return 'json' if language == 'json' diff --git a/gems/ast-merge-git/spec/fixtures_integration_spec.rb b/gems/ast-merge-git/spec/fixtures_integration_spec.rb index 523101801..8d48358a6 100644 --- a/gems/ast-merge-git/spec/fixtures_integration_spec.rb +++ b/gems/ast-merge-git/spec/fixtures_integration_spec.rb @@ -22,40 +22,30 @@ def read_json(path) expect(result.fetch(:ok)).to eq(expected.fetch(:ok)), test_case.fetch(:case_id) expect(result.fetch(:conflicts).length).to eq(expected.fetch(:conflict_count)), test_case.fetch(:case_id) - if expected.key?(:change_classifications) - expect(result.fetch(:change_classifications)).to eq(expected.fetch(:change_classifications)) - end - expect(result.fetch(:reparse_after_render)).to eq(expected.fetch(:reparse_after_render)) - expect(result.fetch(:render_report)).to eq(expected.fetch(:render_report)) if expected.key?(:render_report) - if expected.key?(:formatting_preservation) - expect(result.fetch(:formatting_preservation)).to eq(expected.fetch(:formatting_preservation)) + expect(result.fetch(:diagnostics).map { |diagnostic| diagnostic.fetch(:category) }).to eq( + expected.fetch(:diagnostic_categories) + ), test_case.fetch(:case_id) + expect(result.fetch(:change_classifications)).to eq(expected.fetch(:change_classifications)), + test_case.fetch(:case_id) + expect(result.fetch(:reparse_after_render)).to eq(expected.fetch(:reparse_after_render)), + test_case.fetch(:case_id) + expect(result.fetch(:render_report).fetch(:strategy)).to eq(expected.dig(:render_report, :strategy)), + test_case.fetch(:case_id) + if expected[:merged_json] + expect(JSON.parse(result.fetch(:merged_source), symbolize_names: true)).to eq(expected.fetch(:merged_json)), + test_case.fetch(:case_id) end - if expected.key?(:secondary_formatting_metrics) - expect(result.fetch(:secondary_formatting_metrics)).to eq(expected.fetch(:secondary_formatting_metrics)) + expected.fetch(:conflict_categories, []).each_with_index do |category, index| + expect(result.dig(:conflicts, index, :category)).to eq(category), test_case.fetch(:case_id) end - if expected.key?(:default_driver_evaluation) - expect(result.fetch(:default_driver_evaluation)).to eq(expected.fetch(:default_driver_evaluation)) + expected.fetch(:conflict_paths, []).each_with_index do |path, index| + expect(result.dig(:conflicts, index, :path)).to eq(path), test_case.fetch(:case_id) end - if expected.key?(:owned_regions) - expect(result.fetch(:owned_regions).length).to eq(expected.fetch(:owned_regions).length), - test_case.fetch(:case_id) - expected.fetch(:owned_regions).each_with_index do |expected_region, index| - expect(result.fetch(:owned_regions)[index]).to include(expected_region), test_case.fetch(:case_id) - end + expected.fetch(:conflicted_source_contains, []).each do |needle| + expect(result.fetch(:conflicted_source)).to include(needle), test_case.fetch(:case_id) end - if result.fetch(:ok) - expect(JSON.parse(result.fetch(:merged_source))).to eq(JSON.parse(JSON.generate(expected.fetch(:merged_json)))) - else - expect(result.fetch(:conflicts).map do |conflict| - conflict.fetch(:category) - end).to eq(expected.fetch(:conflict_categories)) - expect(result.fetch(:conflicts).map { |conflict| conflict.fetch(:path) }).to eq(expected.fetch(:conflict_paths)) - expected.fetch(:conflicted_source_contains, []).each do |needle| - expect(result.fetch(:conflicted_source)).to include(needle), test_case.fetch(:case_id) - end - expected.fetch(:conflicted_source_not_contains, []).each do |needle| - expect(result.fetch(:conflicted_source)).not_to include(needle), test_case.fetch(:case_id) - end + expected.fetch(:conflicted_source_not_contains, []).each do |needle| + expect(result.fetch(:conflicted_source)).not_to include(needle), test_case.fetch(:case_id) end end end diff --git a/gems/ast-merge/.gitattributes b/gems/ast-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-merge/.gitattributes +++ b/gems/ast-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-merge/.kettle-drift.lock b/gems/ast-merge/.kettle-drift.lock index 8ee6a7081..06ea1c460 100644 --- a/gems/ast-merge/.kettle-drift.lock +++ b/gems/ast-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/ast-merge/.rubocop_gradual.lock b/gems/ast-merge/.rubocop_gradual.lock index ca390a589..bc6712ed3 100644 --- a/gems/ast-merge/.rubocop_gradual.lock +++ b/gems/ast-merge/.rubocop_gradual.lock @@ -792,18 +792,18 @@ [5, 5, 33, "Style/Documentation: Missing top-level documentation comment for `module Ast::Merge::EmitterLineMetadataSupport`.", 2926748997], [23, 7, 541, "Metrics/MethodLength: Method has too many lines. [12/10]", 2407359355] ], - "lib/ast/merge/file_aligner_base.rb:4032045257": [ - [13, 5, 7473, "Metrics/ClassLength: Class has too many lines. [187/100]", 1391880441], - [27, 7, 2244, "Metrics/AbcSize: Assignment Branch Condition size for `align` is too high. [<19, 37, 12> 43.29/17]", 1243937217], - [27, 7, 2244, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `align` is too high. [12/7]", 1243937217], - [27, 7, 2244, "Metrics/MethodLength: Method has too many lines. [55/10]", 1243937217], - [27, 7, 2244, "Metrics/PerceivedComplexity: Perceived complexity for `align` is too high. [12/8]", 1243937217], - [148, 7, 655, "Metrics/MethodLength: Method has too many lines. [14/10]", 2468821688], - [180, 7, 455, "Metrics/MethodLength: Method has too many lines. [13/10]", 2361153066], - [199, 7, 1557, "Metrics/AbcSize: Assignment Branch Condition size for `apply_match_refiner!` is too high. [<10, 28, 12> 32.06/17]", 2386945712], - [199, 7, 1557, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_match_refiner!` is too high. [13/7]", 2386945712], - [199, 7, 1557, "Metrics/MethodLength: Method has too many lines. [31/10]", 2386945712], - [199, 7, 1557, "Metrics/PerceivedComplexity: Perceived complexity for `apply_match_refiner!` is too high. [13/8]", 2386945712] + "lib/ast/merge/file_aligner_base.rb:2160333224": [ + [13, 5, 8206, "Metrics/ClassLength: Class has too many lines. [203/100]", 2982381587], + [27, 7, 2329, "Metrics/AbcSize: Assignment Branch Condition size for `align` is too high. [<19, 39, 14> 45.59/17]", 1243937217], + [27, 7, 2329, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `align` is too high. [14/7]", 1243937217], + [27, 7, 2329, "Metrics/MethodLength: Method has too many lines. [56/10]", 1243937217], + [27, 7, 2329, "Metrics/PerceivedComplexity: Perceived complexity for `align` is too high. [14/8]", 1243937217], + [167, 7, 655, "Metrics/MethodLength: Method has too many lines. [14/10]", 2468821688], + [199, 7, 455, "Metrics/MethodLength: Method has too many lines. [13/10]", 2361153066], + [218, 7, 1557, "Metrics/AbcSize: Assignment Branch Condition size for `apply_match_refiner!` is too high. [<10, 28, 12> 32.06/17]", 2386945712], + [218, 7, 1557, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_match_refiner!` is too high. [13/7]", 2386945712], + [218, 7, 1557, "Metrics/MethodLength: Method has too many lines. [31/10]", 2386945712], + [218, 7, 1557, "Metrics/PerceivedComplexity: Perceived complexity for `apply_match_refiner!` is too high. [13/8]", 2386945712] ], "lib/ast/merge/file_analyzable.rb:607555963": [ [36, 5, 31229, "Metrics/ModuleLength: Module has too many lines. [316/100]", 1247752256], @@ -1039,6 +1039,13 @@ [69, 121, 8, "Layout/LineLength: Line is too long. [128/120]", 4226982364], [70, 121, 11, "Layout/LineLength: Line is too long. [131/120]", 1440420861] ], + "lib/ast/merge/rspec/conformance_fixtures.rb:1295759615": [ + [6, 7, 26, "Style/Documentation: Missing top-level documentation comment for `module Ast::Merge::RSpec::ConformanceFixtures`.", 90066768], + [9, 9, 1432, "Metrics/AbcSize: Assignment Branch Condition size for `normalize_conformance_fixture_support` is too high. [<10, 30, 33> 45.71/17]", 518714108], + [9, 9, 1432, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `normalize_conformance_fixture_support` is too high. [33/7]", 518714108], + [9, 9, 1432, "Metrics/MethodLength: Method has too many lines. [25/10]", 518714108], + [9, 9, 1432, "Metrics/PerceivedComplexity: Perceived complexity for `normalize_conformance_fixture_support` is too high. [31/8]", 518714108] + ], "lib/ast/merge/rspec/dependency_tags_config.rb:3604516304": [ [30, 1, 2102, "Metrics/BlockLength: Block has too many lines. [26/25]", 113766065] ], @@ -1540,11 +1547,12 @@ [58, 3, 1230, "Metrics/BlockLength: Block has too many lines. [34/25]", 990452676], [103, 3, 2668, "Metrics/BlockLength: Block has too many lines. [51/25]", 1755027956] ], - "spec/ast/merge/file_aligner_base_spec.rb:610089304": [ - [5, 1, 7287, "Metrics/BlockLength: Block has too many lines. [164/25]", 597898988], - [6, 3, 1237, "Metrics/BlockLength: Block has too many lines. [37/25]", 1284505259], - [86, 3, 5087, "Metrics/BlockLength: Block has too many lines. [84/25]", 119873771], - [94, 121, 8, "Layout/LineLength: Line is too long. [128/120]", 3749416415] + "spec/ast/merge/file_aligner_base_spec.rb:91275387": [ + [5, 1, 9948, "Metrics/BlockLength: Block has too many lines. [217/25]", 3354563411], + [6, 3, 1490, "Metrics/BlockLength: Block has too many lines. [45/25]", 563330990], + [95, 3, 7495, "Metrics/BlockLength: Block has too many lines. [129/25]", 598770279], + [103, 121, 8, "Layout/LineLength: Line is too long. [128/120]", 3749416415], + [163, 5, 1489, "Metrics/BlockLength: Block has too many lines. [26/25]", 2910876949] ], "spec/ast/merge/file_analyzable_spec.rb:3816965829": [ [3, 1, 12458, "Metrics/BlockLength: Block has too many lines. [272/25]", 216138965], @@ -1950,6 +1958,10 @@ "spec/ast/merge/unresolved_review_state_spec.rb:3186871217": [ [3, 1, 1038, "Metrics/BlockLength: Block has too many lines. [31/25]", 1325553035] ], + "spec/ast/merge_rspec_conformance_fixtures_spec.rb:251774004": [ + [5, 1, 2119, "Metrics/BlockLength: Block has too many lines. [55/25]", 1724925683], + [6, 3, 1203, "Metrics/BlockLength: Block has too many lines. [29/25]", 3306863581] + ], "spec/ast/merge_spec.rb:664670069": [ [3, 1, 3113, "Metrics/BlockLength: Block has too many lines. [74/25]", 4034649501], [9, 3, 2227, "Metrics/BlockLength: Block has too many lines. [51/25]", 578300230], diff --git a/gems/ast-merge/Gemfile b/gems/ast-merge/Gemfile index 4289cdf5c..c4d51f141 100644 --- a/gems/ast-merge/Gemfile +++ b/gems/ast-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-merge/Gemfile.lock b/gems/ast-merge/Gemfile.lock index 822e1aad1..ad09d9372 100644 --- a/gems/ast-merge/Gemfile.lock +++ b/gems/ast-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -17,13 +7,278 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) @@ -36,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -94,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -127,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -266,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -318,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -349,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -369,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -394,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -426,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -438,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -465,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -476,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -503,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -514,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -527,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-merge/README.md b/gems/ast-merge/README.md index b3c8f629b..bf0c8c062 100644 --- a/gems/ast-merge/README.md +++ b/gems/ast-merge/README.md @@ -50,13 +50,43 @@ Ast::Merge builds on tree\_haver to provide: - **Region Detection**: `RegionDetectorBase`, `FencedCodeBlockDetector` for text-based analysis - **RSpec Shared Examples**: Test helpers for implementing new merge gems +### Merge Gem Backend Patterns + +Every merge gem in this family must enter parsing through `tree_haver`. Do not add direct parser fallbacks in merge gems. If a requested backend or grammar is unavailable, fail closed with an unsupported feature or parse diagnostic instead of switching to another parser outside `tree_haver`. + +The current merge gems fit three backend patterns: + +- **Provider-only merge gems** register a concrete TreeHaver backend and use that backend exclusively. Use this for gems whose purpose is to expose a specific parser provider, such as `prism-merge`, `psych-merge`, `citrus-toml-merge`, and `parslet-toml-merge`. +- **Hybrid provider plus TSLP merge gems** register their provider backend, and may also register a TSLP/tree-sitter grammar mapping for the same language when both surfaces are intended and tested. `rbs-merge` is the model for this category. +- **Substrate mapping merge gems** do not own a parser. They register the format grammar with `TreeHaver::GrammarFinder` and use the normal `TreeHaver.parser_for(:format)` API for analysis and merge behavior. `json-merge`, `toml-merge`, `yaml-merge`, and `ruby-merge` follow this pattern. + +Backend fallback inside `tree_haver` is allowed when it is explicit TreeHaver backend selection. Backend fallback outside `tree_haver` is not allowed, because it bypasses owner identity, backend diagnostics, parser capability reporting, and shared merge-stack behavior. + ### Creating a New Merge Gem +Pick the merge-gem shape before writing parser code: + +- Use a substrate mapping gem when the format can use an existing TreeHaver grammar/backend. Register the grammar, parse through `TreeHaver.parser_for`, and keep merge behavior in the substrate. +- Use a provider-only gem when the gem exists to expose one concrete parser backend. Register that backend with `TreeHaver.register_language`, then delegate shared language or format behavior back to the substrate gem. +- Use a hybrid provider gem only when both the native provider and TSLP/tree-sitter path are intentional, tested TreeHaver backends. + +Merge gems should not call parser libraries directly during merge analysis. Direct parser calls belong inside TreeHaver backend adapters. + ```ruby +require "tree_haver" require "ast/merge" module MyFormat module Merge + BACKEND_REFERENCE = TreeHaver::BackendReference.new( + id: "kreuzberg-language-pack", + family: "tree-sitter" + ).freeze + + def self.register_backend! + TreeHaver::GrammarFinder.new(:my_format).register! + end + # Inherit from base classes and pass **options for forward compatibility class SmartMerger < Ast::Merge::SmartMergerBase @@ -90,7 +120,9 @@ module MyFormat @source = source @freeze_token = freeze_token @signature_generator = signature_generator - # Process source... + Merge.register_backend! + @tree = TreeHaver.parser_for(:my_format).parse(source) + # Project TreeHaver nodes into merge ownership records. end def compute_node_signature(node) diff --git a/gems/ast-merge/gemfiles/modular/templating.gemfile b/gems/ast-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-merge/gemfiles/modular/templating.gemfile +++ b/gems/ast-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-merge/gemfiles/modular/templating_local.gemfile b/gems/ast-merge/gemfiles/modular/templating_local.gemfile index 1cca924a0..bf5147854 100644 --- a/gems/ast-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ast-merge/lib/ast/merge/file_aligner_base.rb b/gems/ast-merge/lib/ast/merge/file_aligner_base.rb index 4d5ced880..f77d2f744 100644 --- a/gems/ast-merge/lib/ast/merge/file_aligner_base.rb +++ b/gems/ast-merge/lib/ast/merge/file_aligner_base.rb @@ -42,6 +42,7 @@ def align template_indices.zip(dest_indices).each do |t_idx, d_idx| next unless t_idx && d_idx + next if matched_template.include?(t_idx) || matched_dest.include?(d_idx) alignment << build_match_entry( signature: sig, @@ -128,12 +129,30 @@ def build_signature_map(statements, analysis) statements.each_with_index do |statement, idx| signature = signature_for(analysis, idx) map[signature] << idx if signature + content_signature = content_identity_signature(statement) + map[content_signature] << idx if content_signature && content_signature != signature add_signature_aliases(map, statement, idx, analysis) end map end + def content_identity_signature(statement) + content = statement_value(statement, :normalized_content) || statement_value(statement, 'normalized_content') + content = content.to_s + return if content.empty? + + [:content_identity, content] + end + + def statement_value(statement, key) + if statement.respond_to?(key) + statement.public_send(key) + elsif statement.respond_to?(:[]) + statement[key] + end + end + def build_match_entry(signature:, template_index:, dest_index:, template_statement:, dest_statement:) { :type => :match, diff --git a/gems/ast-merge/lib/ast/merge/rspec.rb b/gems/ast-merge/lib/ast/merge/rspec.rb index bc8756c18..de7489ee7 100644 --- a/gems/ast-merge/lib/ast/merge/rspec.rb +++ b/gems/ast-merge/lib/ast/merge/rspec.rb @@ -31,5 +31,12 @@ # Load Ast::Merge dependency tags (provides merge gem tags like :markly_merge, :prism_merge, etc.) require_relative 'rspec/dependency_tags' +# Load conformance fixture helpers for shared fixture harnesses +require_relative 'rspec/conformance_fixtures' + # Load Ast::Merge shared examples (for testing *-merge implementations) require_relative 'rspec/shared_examples' + +RSpec.configure do |config| + config.include Ast::Merge::RSpec::ConformanceFixtures +end diff --git a/gems/ast-merge/lib/ast/merge/rspec/README.md b/gems/ast-merge/lib/ast/merge/rspec/README.md index 48c6a98de..343430da5 100644 --- a/gems/ast-merge/lib/ast/merge/rspec/README.md +++ b/gems/ast-merge/lib/ast/merge/rspec/README.md @@ -16,6 +16,7 @@ That loads: - TreeHaver backend dependency tags - Ast::Merge merge-gem dependency tags +- Shared conformance fixture helpers - Ast::Merge shared examples ### Split loading for `ast-merge` itself or registration-heavy suites @@ -74,6 +75,27 @@ end TreeHaver backend tags are loaded alongside these helpers; see the TreeHaver RSpec docs for backend-specific tags. +## Shared conformance fixtures + +`Ast::Merge::RSpec::ConformanceFixtures` is spec-harness support for merge gems that import shared fixtures from the sibling `fixtures` repository. + +Use it to document implementation gaps without hiding imported shared fixture cases: + +```ruby +support = support_for_conformance_fixture( + "delegated_child_operations", + pending_roles: { + delegated_child_operations: { + reason: "parser-backed child delegation is not implemented yet", + }, + }, +) + +apply_conformance_fixture_support!(support) +``` + +`pending` support calls RSpec `pending`, so the example fails as fixed once it unexpectedly passes. `unsupported` and `skipped` support call RSpec `skip`. + ## MergeGemRegistry `Ast::Merge::RSpec::MergeGemRegistry` tracks loaded and bootstrap-declared `*-merge` gems and exposes availability checks for dependency tags. diff --git a/gems/ast-merge/lib/ast/merge/rspec/conformance_fixtures.rb b/gems/ast-merge/lib/ast/merge/rspec/conformance_fixtures.rb new file mode 100644 index 000000000..4fb6da375 --- /dev/null +++ b/gems/ast-merge/lib/ast/merge/rspec/conformance_fixtures.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Ast + module Merge + module RSpec + module ConformanceFixtures + module_function + + def normalize_conformance_fixture_support(value = nil, default_status: nil, **keywords) + value = keywords unless keywords.empty? + + case value + when nil, false + nil + when true + { status: (default_status || 'pending').to_s } + when String, Symbol + { status: (default_status || value).to_s } + when Hash + support = value[:support] || value['support'] || value + return nil if support == false + + status = support[:status] || support['status'] || support[:state] || support['state'] + status ||= 'unsupported' if support[:unsupported] || support['unsupported'] + status ||= 'pending' if support[:pending] || support['pending'] + status ||= default_status + return nil unless %w[pending unsupported skipped].include?(status.to_s) + + metadata = { status: status.to_s } + reason = support[:reason] || support['reason'] || + support[:message] || support['message'] || + support[:unsupported_reason] || support['unsupported_reason'] || + support[:pending_reason] || support['pending_reason'] + metadata[:reason] = reason if reason + metadata[:category] = support[:category] || support['category'] if support[:category] || support['category'] + metadata + end + end + + def support_for_conformance_fixture(role, pending_roles: nil, unsupported_roles: nil, fixture: nil) + role_support(pending_roles, role, default_status: 'pending') || + role_support(unsupported_roles, role, default_status: 'unsupported') || + normalize_conformance_fixture_support(fixture) + end + + def apply_conformance_fixture_support!(support) + metadata = normalize_conformance_fixture_support(support) + return unless metadata + + message = metadata[:reason] || "conformance fixture marked #{metadata[:status]}" + metadata[:status] == 'pending' ? pending(message) : skip(message) + end + + def role_support(roles, role, default_status:) + value = + if roles.is_a?(Array) + roles.map(&:to_s).include?(role.to_s) || nil + elsif roles + roles[role.to_sym] || roles[role.to_s] + end + normalize_conformance_fixture_support(value, default_status: default_status) + end + private_class_method :role_support + end + end + end +end diff --git a/gems/ast-merge/lib/ast/merge/rspec/shared_examples.rb b/gems/ast-merge/lib/ast/merge/rspec/shared_examples.rb index 13b1ed6e9..e1b4d0aa2 100644 --- a/gems/ast-merge/lib/ast/merge/rspec/shared_examples.rb +++ b/gems/ast-merge/lib/ast/merge/rspec/shared_examples.rb @@ -29,6 +29,7 @@ # - "Ast::Merge::UnresolvedReviewStateTransportContract" - validates persisted unresolved review replay and JSON-safe transport # - "Ast::Merge::UnresolvedRuntimeDebugContract" - validates unresolved review state in debug payloads # - "Ast::Merge::UnresolvedRuntimeContract" - validates reviewable unresolved runtime payloads +# - "Ast::Merge::TreeHaverBackendContract" - validates advertised backend refs have concrete TreeHaver parsers # - "a reproducible merge" - validates merge scenarios with fixtures and idempotency # - "a reproducible partial merge" - validates partial-merge scenarios with idempotency @@ -55,3 +56,4 @@ require_relative 'shared_examples/unresolved_review_state_transport_contract' require_relative 'shared_examples/unresolved_runtime_debug_contract' require_relative 'shared_examples/unresolved_runtime_contract' +require_relative 'shared_examples/tree_haver_backend_contract' diff --git a/gems/ast-merge/lib/ast/merge/rspec/shared_examples/tree_haver_backend_contract.rb b/gems/ast-merge/lib/ast/merge/rspec/shared_examples/tree_haver_backend_contract.rb new file mode 100644 index 000000000..64ceb5470 --- /dev/null +++ b/gems/ast-merge/lib/ast/merge/rspec/shared_examples/tree_haver_backend_contract.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'Ast::Merge::TreeHaverBackendContract' do |language:, backend_id:, source:| + it "registers #{backend_id} as a concrete TreeHaver backend for #{language}" do + backend_ref = TreeHaver::BackendRegistry.fetch(backend_id) + registrations = TreeHaver.registered_languages(language) + + expect(backend_ref).not_to be_nil + expect(registrations).not_to be_empty + + tree = TreeHaver.with_backend(backend_id) do + TreeHaver.parser_for(language).parse(source) + end + + expect(tree).to respond_to(:root_node) + expect(tree.root_node).not_to be_nil + expect(tree.root_node.type.to_s).not_to be_empty + end +end diff --git a/gems/ast-merge/spec/ast/merge/file_aligner_base_spec.rb b/gems/ast-merge/spec/ast/merge/file_aligner_base_spec.rb index ad352419f..6e4c83a22 100644 --- a/gems/ast-merge/spec/ast/merge/file_aligner_base_spec.rb +++ b/gems/ast-merge/spec/ast/merge/file_aligner_base_spec.rb @@ -14,6 +14,15 @@ def generate_signature(node) node[:signature] end end) + stub_const('FixtureAnalysis', Struct.new(:statements) do + def signature_at(index) + statements.fetch(index).fetch(:primary_signature) + end + + def generate_signature(node) + node.fetch(:primary_signature) + end + end) stub_const('TestAligner', Class.new(described_class) do attr_reader :logged_alignment @@ -131,6 +140,57 @@ def add_signature_aliases(map, statement, index, _analysis) expect(result.count { |entry| entry[:type] == :template_only }).to eq(1) end + it 'does not duplicate matches through content aliases after primary signatures match' do + template_statement = { name: :template, normalized_content: 'same' } + dest_statement = { name: :dest, normalized_content: 'same' } + template_analysis = Analysis.new([template_statement], { 0 => [:primary] }) + dest_analysis = Analysis.new([dest_statement], { 0 => [:primary] }) + + result = BaseAligner.new(template_analysis, dest_analysis).align + + expect(result).to eq([ + { + type: :match, + template_index: 0, + dest_index: 0, + signature: [:primary], + template_node: template_statement, + dest_node: dest_statement + } + ]) + end + + it 'matches identical content when opaque primary signatures differ by source position' do + fixture_path = Pathname(__dir__).join( + '..', + '..', + '..', + '..', + '..', + '..', + 'fixtures', + 'diagnostics', + 'slice-904-content-identity-positional-signature', + 'content-identity-positional-signature.json' + ).expand_path + fixture = Ast::Merge.normalize_value(JSON.parse(fixture_path.read)) + template_analysis = FixtureAnalysis.new(fixture.dig(:matching, :template_nodes)) + dest_analysis = FixtureAnalysis.new(fixture.dig(:matching, :destination_nodes)) + + result = BaseAligner.new(template_analysis, dest_analysis).align + + expect(result.count { |entry| entry[:type] == :match }).to eq(fixture.dig(:expected, :match_count)) + expect(result.count { |entry| entry[:type] == :template_only }).to eq( + fixture.dig(:expected, :template_only_count) + ) + expect(result.count { |entry| entry[:type] == :dest_only }).to eq(fixture.dig(:expected, :dest_only_count)) + match = result.find { |entry| entry[:type] == :match } + expected_signature = fixture.dig(:expected, :first_match_signature) + expect(match[:signature]).to eq([expected_signature.first.to_sym, *expected_signature.drop(1)]) + expect(match[:template_index]).to eq(fixture.dig(:expected, :first_template_index)) + expect(match[:dest_index]).to eq(fixture.dig(:expected, :first_dest_index)) + end + it 'supports optional fuzzy refinement for otherwise unmatched statements' do template_statement = { name: :template_table } dest_statement = { name: :dest_table } diff --git a/gems/ast-merge/spec/ast/merge/rspec/tree_haver_backend_contract_spec.rb b/gems/ast-merge/spec/ast/merge/rspec/tree_haver_backend_contract_spec.rb new file mode 100644 index 000000000..f5b651824 --- /dev/null +++ b/gems/ast-merge/spec/ast/merge/rspec/tree_haver_backend_contract_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require_relative '../../../spec_helper' + +require 'bash/merge' +require 'commonmarker/merge' +require 'go/merge' +require 'json/merge' +require 'kramdown/merge' +require 'markly/merge' +require 'prism/merge' +require 'psych/merge' +require 'rbs/merge' +require 'ruby/merge' +require 'rust/merge' +require 'toml/merge' +require 'typescript/merge' +require 'yaml/merge' + +RSpec.describe 'TreeHaver backend contracts' do + cases = [ + ['bash-merge', Bash::Merge, :available_bash_backends, :bash, "echo hello\n"], + ['commonmarker-merge', Commonmarker::Merge, :available_markdown_backends, :markdown, "# Title\n"], + ['go-merge', Go::Merge, :available_go_backends, :go, "package main\n"], + ['json-merge', Json::Merge, :available_json_backends, :json, "{\"a\":1}\n"], + ['kramdown-merge', Kramdown::Merge, :available_markdown_backends, :markdown, "# Title\n"], + ['markly-merge', Markly::Merge, :available_markdown_backends, :markdown, "# Title\n"], + ['prism-merge', Prism::Merge, :available_ruby_backends, :ruby, "def a; end\n"], + ['psych-merge', Psych::Merge, :available_yaml_backends, :yaml, "a: 1\n"], + ['rbs-merge', Rbs::Merge, :available_rbs_backends, :rbs, "class A\nend\n"], + ['ruby-merge', Ruby::Merge, :available_ruby_backends, :ruby, "def a; end\n"], + ['rust-merge', Rust::Merge, :available_rust_backends, :rust, "fn main() {}\n"], + ['toml-merge', Toml::Merge, :available_toml_backends, :toml, "a = 1\n"], + ['typescript-merge', TypeScript::Merge, :available_type_script_backends, :typescript, "const a = 1;\n"], + ['yaml-merge', Yaml::Merge, :available_yaml_backends, :yaml, "a: 1\n"] + ] + + cases.each do |gem_name, merge_module, backend_method, language, source| + describe gem_name do + merge_module.public_send(:register_backend!) if merge_module.respond_to?(:register_backend!) + + merge_module.public_send(backend_method).each do |backend_ref| + include_examples( + 'Ast::Merge::TreeHaverBackendContract', + language: language, + backend_id: backend_ref.id, + source: source + ) + end + end + end +end diff --git a/gems/ast-merge/spec/ast/merge_rspec_conformance_fixtures_spec.rb b/gems/ast-merge/spec/ast/merge_rspec_conformance_fixtures_spec.rb new file mode 100644 index 000000000..fcb519025 --- /dev/null +++ b/gems/ast-merge/spec/ast/merge_rspec_conformance_fixtures_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'ast/merge/rspec/conformance_fixtures' + +RSpec.describe Ast::Merge::RSpec::ConformanceFixtures do + describe '.normalize_conformance_fixture_support' do + it 'normalizes pending fixture metadata' do + expect( + described_class.normalize_conformance_fixture_support( + pending: true, + pending_reason: 'backend lacks delegated child operation records' + ) + ).to eq( + status: 'pending', + reason: 'backend lacks delegated child operation records' + ) + end + + it 'normalizes unsupported fixture metadata' do + expect( + described_class.normalize_conformance_fixture_support( + unsupported: true, + unsupported_reason: 'TSLP does not expose this node class yet', + category: 'unsupported_parser_capability' + ) + ).to eq( + status: 'unsupported', + reason: 'TSLP does not expose this node class yet', + category: 'unsupported_parser_capability' + ) + end + + it 'returns nil for supported fixtures' do + expect(described_class.normalize_conformance_fixture_support(nil)).to be_nil + expect(described_class.normalize_conformance_fixture_support(false)).to be_nil + expect(described_class.normalize_conformance_fixture_support(support: false)).to be_nil + end + end + + describe '.support_for_conformance_fixture' do + it 'selects role-level pending support before fixture metadata' do + support = described_class.support_for_conformance_fixture( + 'delegated_child_operations', + pending_roles: { + delegated_child_operations: { + reason: 'parser-backed child delegation is not implemented yet' + } + }, + fixture: { unsupported: true } + ) + + expect(support).to eq( + status: 'pending', + reason: 'parser-backed child delegation is not implemented yet' + ) + end + + it 'selects role-level unsupported support' do + support = described_class.support_for_conformance_fixture( + 'discovered_surfaces', + unsupported_roles: ['discovered_surfaces'] + ) + + expect(support).to eq(status: 'unsupported') + end + end +end diff --git a/gems/ast-template/.gitattributes b/gems/ast-template/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ast-template/.gitattributes +++ b/gems/ast-template/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ast-template/.kettle-drift.lock b/gems/ast-template/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/ast-template/.kettle-drift.lock +++ b/gems/ast-template/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/ast-template/Gemfile b/gems/ast-template/Gemfile index e75f45831..3c92e5d7c 100644 --- a/gems/ast-template/Gemfile +++ b/gems/ast-template/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ast-template/Gemfile.lock b/gems/ast-template/Gemfile.lock index 40f3e46bb..b17738f92 100644 --- a/gems/ast-template/Gemfile.lock +++ b/gems/ast-template/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -15,22 +5,284 @@ PATH ast-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -39,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -97,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -130,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -269,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -321,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -352,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -372,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -518,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -531,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ast-template/gemfiles/modular/templating.gemfile b/gems/ast-template/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ast-template/gemfiles/modular/templating.gemfile +++ b/gems/ast-template/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ast-template/gemfiles/modular/templating_local.gemfile b/gems/ast-template/gemfiles/modular/templating_local.gemfile index af6071632..6eb9ac7ae 100644 --- a/gems/ast-template/gemfiles/modular/templating_local.gemfile +++ b/gems/ast-template/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ast-template] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ast-template] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ast-template] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/bash-merge/.gitattributes b/gems/bash-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/bash-merge/.gitattributes +++ b/gems/bash-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/bash-merge/.kettle-drift.lock b/gems/bash-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/bash-merge/.kettle-drift.lock +++ b/gems/bash-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/bash-merge/.rubocop_gradual.lock b/gems/bash-merge/.rubocop_gradual.lock index 2a372fefe..69ee17f8e 100644 --- a/gems/bash-merge/.rubocop_gradual.lock +++ b/gems/bash-merge/.rubocop_gradual.lock @@ -8,9 +8,8 @@ [163, 121, 22, "Layout/LineLength: Line is too long. [142/120]", 1367093088], [166, 121, 18, "Layout/LineLength: Line is too long. [138/120]", 3881946477] ], - "bash-merge.gemspec:1627975125": [ + "bash-merge.gemspec:4057981445": [ [118, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], - [120, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 2105564149], [126, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949] ], "gemfiles/modular/benchmark/r4/v0.5.gemfile:3644720371": [ @@ -81,6 +80,9 @@ "lib/bash-merge.rb:2115710001": [ [1, 1, 0, "Naming/FileName: The name of this source file (`bash-merge.rb`) should use snake_case.", 5381] ], + "lib/bash/merge.rb:4206734161": [ + [160, 7, 615, "Metrics/MethodLength: Method has too many lines. [13/10]", 1174626529] + ], "lib/bash/merge/comment_tracker.rb:2891158123": [ [54, 7, 773, "Metrics/MethodLength: Method has too many lines. [25/10]", 729186432] ], @@ -202,9 +204,9 @@ [266, 3, 1249, "Metrics/BlockLength: Block has too many lines. [37/25]", 546398620], [316, 3, 1101, "Metrics/BlockLength: Block has too many lines. [26/25]", 3599684932] ], - "spec/bash/merge_spec.rb:3012823876": [ - [5, 1, 4323, "Metrics/BlockLength: Block has too many lines. [109/25]", 2384192474], - [86, 3, 1146, "Metrics/BlockLength: Block has too many lines. [26/25]", 3618532423] + "spec/bash/merge_spec.rb:4280322597": [ + [5, 1, 4187, "Metrics/BlockLength: Block has too many lines. [108/25]", 2384192474], + [85, 3, 1146, "Metrics/BlockLength: Block has too many lines. [26/25]", 3618532423] ], "spec/support/shared_examples/file_analysis_examples.rb:3893834393": [ [8, 1, 1573, "Metrics/BlockLength: Block has too many lines. [36/25]", 1729754427], diff --git a/gems/bash-merge/Gemfile b/gems/bash-merge/Gemfile index 9674a0f1f..7e465932f 100644 --- a/gems/bash-merge/Gemfile +++ b/gems/bash-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/bash-merge/Gemfile.lock b/gems/bash-merge/Gemfile.lock index ebf32b156..c7941d078 100644 --- a/gems/bash-merge/Gemfile.lock +++ b/gems/bash-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -372,24 +634,46 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) - appraisal2 (~> 3.1, >= 3.1.4) + appraisal2 (~> 3.2, >= 3.2.0) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.4) + go-merge! irb (~> 1.17) - kettle-dev (~> 2.3, >= 2.3.6) + json-merge! + kettle-dev (~> 2.3, >= 2.3.7) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.11) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,33 +682,55 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.6, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! - turbo_tests2 (~> 3.1, >= 3.1.14) + turbo_tests2 (~> 3.2, >= 3.2.0) + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -432,6 +738,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -444,19 +751,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -471,10 +786,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -482,6 +801,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -509,9 +829,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -520,6 +843,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -533,21 +857,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/bash-merge/bash-merge.gemspec b/gems/bash-merge/bash-merge.gemspec index 5ab7f0009..2e634fb4e 100644 --- a/gems/bash-merge/bash-merge.gemspec +++ b/gems/bash-merge/bash-merge.gemspec @@ -103,7 +103,7 @@ Gem::Specification.new do |spec| # and preferably a modular one (see gemfiles/modular/*.gemfile). # Dev, Test, & Release Tasks - spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.6') # ruby >= 4.0.0 + spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.7') # ruby >= 4.0.0 # Security spec.add_development_dependency('bundler-audit', '~> 0.9.3') # ruby >= 2.0.0 @@ -115,9 +115,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency('require_bench', '~> 1.0', '>= 1.0.4') # ruby >= 2.2.0 # Testing - spec.add_development_dependency('appraisal2', '~> 3.1', '>= 3.1.4') # ruby >= 1.8.7, for testing against multiple versions of dependencies - spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 - spec.add_development_dependency('turbo_tests2', '~> 3.1', '>= 3.1.14') # ruby >= 2.4.0, default kettle-test runner + spec.add_development_dependency('appraisal2', '~> 3.2', '>= 3.2.0') # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 + spec.add_development_dependency('turbo_tests2', '~> 3.2', '>= 3.2.0') # ruby >= 2.4.0, default kettle-test runner # Releasing spec.add_development_dependency('ruby-progressbar', '~> 1.13') # ruby >= 0 diff --git a/gems/bash-merge/gemfiles/modular/templating.gemfile b/gems/bash-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/bash-merge/gemfiles/modular/templating.gemfile +++ b/gems/bash-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/bash-merge/gemfiles/modular/templating_local.gemfile b/gems/bash-merge/gemfiles/modular/templating_local.gemfile index e98e7f415..b0ef57bb2 100644 --- a/gems/bash-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/bash-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[bash-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[bash-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[bash-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/bash-merge/lib/bash/merge.rb b/gems/bash-merge/lib/bash/merge.rb index 5162a23d1..5589ffdf2 100644 --- a/gems/bash-merge/lib/bash/merge.rb +++ b/gems/bash-merge/lib/bash/merge.rb @@ -48,10 +48,10 @@ module Bash # @see SmartMerger Main entry point for merge operations # @see FileAnalysis Analyzes Bash structure module Merge + TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) Availability = Struct.new( :grammar_path, - :language_pack_process, :node_parser, :diagnostics, keyword_init: true @@ -128,6 +128,8 @@ def register_backend! BACKEND_REGISTRY.mutex.synchronize do return if BACKEND_REGISTRY.registered + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + grammar_finder = TreeHaver::GrammarFinder.new(:bash) grammar_finder.register! if grammar_finder.available? @@ -135,12 +137,12 @@ def register_backend! end end - def available?(source: "#!/usr/bin/env bash\necho hello\n") - availability(source: source).available? + def available_bash_backends + bash_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end - def language_pack_process_available?(source: "#!/usr/bin/env bash\necho hello\n") - availability(source: source).language_pack_process == true + def available?(source: "#!/usr/bin/env bash\necho hello\n") + availability(source: source).available? end def availability(source: "#!/usr/bin/env bash\necho hello\n") @@ -148,7 +150,6 @@ def availability(source: "#!/usr/bin/env bash\necho hello\n") grammar_path = bash_grammar_path(diagnostics) Availability.new( grammar_path: grammar_path, - language_pack_process: language_pack_process_available_for?(source, diagnostics), node_parser: node_parser_available_for?(source, grammar_path, diagnostics), diagnostics: diagnostics ) @@ -163,20 +164,12 @@ def bash_grammar_path(diagnostics) nil end - def language_pack_process_available_for?(source, diagnostics) - result = TreeHaver.process_with_language_pack( - TreeHaver::ProcessRequest.new(source: source, language: 'bash') - ) - ok = result[:ok] == true - diagnostics.concat(Array(result[:diagnostics])) unless ok - ok - rescue StandardError => e - diagnostics << { kind: 'bash_language_pack_unavailable', message: e.message } - false - end - def node_parser_available_for?(source, grammar_path, diagnostics) - parser = TreeHaver.parser_for(:bash, library_path: grammar_path) + parser = if grammar_path + TreeHaver.parser_for(:bash, library_path: grammar_path) + else + TreeHaver.parser_for(:bash) + end tree = parser.parse(source) !tree.nil? && !tree.root_node.nil? rescue TreeHaver::Error => e @@ -186,6 +179,14 @@ def node_parser_available_for?(source, grammar_path, diagnostics) diagnostics << { kind: 'bash_node_parser_unavailable', message: e.message } false end + + def bash_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == TREE_SITTER_BACKEND.id + + registrations = TreeHaver.registered_languages(:bash) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end end end end diff --git a/gems/bash-merge/spec/bash/merge_spec.rb b/gems/bash-merge/spec/bash/merge_spec.rb index 1807f3d59..9d75d2002 100644 --- a/gems/bash-merge/spec/bash/merge_spec.rb +++ b/gems/bash-merge/spec/bash/merge_spec.rb @@ -71,13 +71,18 @@ expect(registrations).to be_a(Hash) end + + it 'exposes the registered TreeHaver language-pack backend' do + expect(described_class.available_bash_backends.map(&:to_h)).to eq( + [{ id: 'kreuzberg-language-pack', family: 'tree-sitter' }] + ) + end end describe '.availability' do - it 'reports language-pack processing separately from node parser availability' do + it 'reports TreeHaver node parser availability' do availability = described_class.availability - expect(availability.language_pack_process).to eq(described_class.language_pack_process_available?) expect(availability.node_parser).to eq(described_class.available?) expect(availability.diagnostics).to be_an(Array) end diff --git a/gems/binary-merge/.gitattributes b/gems/binary-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/binary-merge/.gitattributes +++ b/gems/binary-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/binary-merge/.kettle-drift.lock b/gems/binary-merge/.kettle-drift.lock index 9878fb8f5..f1287e677 100644 --- a/gems/binary-merge/.kettle-drift.lock +++ b/gems/binary-merge/.kettle-drift.lock @@ -5,7 +5,13 @@ "lines": [ 79, 119, - 159 + 159, + 199, + 239, + 279, + 319, + 359, + 399 ] } ], @@ -15,7 +21,13 @@ "lines": [ 90, 130, - 170 + 170, + 210, + 250, + 290, + 330, + 370, + 410 ] } ], @@ -25,7 +37,13 @@ "lines": [ 80, 120, - 160 + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -35,7 +53,13 @@ "lines": [ 92, 132, - 172 + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -45,7 +69,13 @@ "lines": [ 95, 135, - 175 + 175, + 215, + 255, + 295, + 335, + 375, + 415 ] } ], @@ -55,7 +85,13 @@ "lines": [ 81, 121, - 161 + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -66,7 +102,13 @@ 59, 99, 139, - 179 + 179, + 219, + 259, + 299, + 339, + 379, + 419 ] } ], @@ -76,7 +118,13 @@ "lines": [ 100, 140, - 180 + 180, + 220, + 260, + 300, + 340, + 380, + 420 ] } ], @@ -87,7 +135,13 @@ 42, 86, 126, - 166 + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -97,7 +151,13 @@ "lines": [ 109, 149, - 189 + 189, + 229, + 269, + 309, + 349, + 389, + 429 ] } ], @@ -108,7 +168,13 @@ 34, 78, 118, - 158 + 158, + 198, + 238, + 278, + 318, + 358, + 398 ] } ], @@ -119,7 +185,13 @@ 68, 108, 148, - 188 + 188, + 228, + 268, + 308, + 348, + 388, + 428 ] } ], @@ -129,7 +201,13 @@ "lines": [ 84, 124, - 164 + 164, + 204, + 244, + 284, + 324, + 364, + 404 ] } ], @@ -140,7 +218,13 @@ 47, 91, 131, - 171 + 171, + 211, + 251, + 291, + 331, + 371, + 411 ] } ], @@ -151,7 +235,13 @@ 43, 87, 127, - 167 + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -161,7 +251,13 @@ "lines": [ 85, 125, - 165 + 165, + 205, + 245, + 285, + 325, + 365, + 405 ] } ], @@ -171,7 +267,13 @@ "lines": [ 102, 142, - 182 + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -181,7 +283,13 @@ "lines": [ 101, 141, - 181 + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -191,7 +299,13 @@ "lines": [ 96, 136, - 176 + 176, + 216, + 256, + 296, + 336, + 376, + 416 ] } ], @@ -201,7 +315,13 @@ "lines": [ 105, 145, - 185 + 185, + 225, + 265, + 305, + 345, + 385, + 425 ] } ], diff --git a/gems/binary-merge/Gemfile b/gems/binary-merge/Gemfile index 156002edc..0a94ca078 100644 --- a/gems/binary-merge/Gemfile +++ b/gems/binary-merge/Gemfile @@ -191,7 +191,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -200,7 +440,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -208,7 +448,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/binary-merge/Gemfile.lock b/gems/binary-merge/Gemfile.lock index 7d76fd19b..41b29f356 100644 --- a/gems/binary-merge/Gemfile.lock +++ b/gems/binary-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -15,13 +5,280 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) @@ -34,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -92,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -125,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -264,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -313,13 +581,16 @@ GEM delegate (~> 0.1) rspec (~> 3.0) timecop (>= 0.7, < 1) - tree_haver (7.1.0) - citrus (~> 3.0) + token-resolver (2.0.4) parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + version_gem (~> 1.1, >= 1.1.13) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -344,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -364,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -389,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) + ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -421,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -433,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -460,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -471,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -498,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -509,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -521,21 +855,28 @@ CHECKSUMS thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73 timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 + token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/binary-merge/gemfiles/modular/templating.gemfile b/gems/binary-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/binary-merge/gemfiles/modular/templating.gemfile +++ b/gems/binary-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/binary-merge/gemfiles/modular/templating_local.gemfile b/gems/binary-merge/gemfiles/modular/templating_local.gemfile index c4b43a13e..41201dc8a 100644 --- a/gems/binary-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/binary-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[binary-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[binary-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[binary-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/citrus-toml-merge/.gitattributes b/gems/citrus-toml-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/citrus-toml-merge/.gitattributes +++ b/gems/citrus-toml-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/citrus-toml-merge/.kettle-drift.lock b/gems/citrus-toml-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/citrus-toml-merge/.kettle-drift.lock +++ b/gems/citrus-toml-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/citrus-toml-merge/.rubocop_gradual.lock b/gems/citrus-toml-merge/.rubocop_gradual.lock index 4af8d888b..6289f37c0 100644 --- a/gems/citrus-toml-merge/.rubocop_gradual.lock +++ b/gems/citrus-toml-merge/.rubocop_gradual.lock @@ -82,15 +82,19 @@ "lib/citrus-toml-merge.rb:1706359962": [ [1, 1, 0, "Naming/FileName: The name of this source file (`citrus-toml-merge.rb`) should use snake_case.", 5381] ], - "lib/citrus/toml/merge.rb:4234713312": [ + "lib/citrus/toml/merge.rb:4256403494": [ [11, 5, 12, "Style/Documentation: Missing top-level documentation comment for `module Citrus::Toml::Merge`.", 2866359175], + [11, 5, 4979, "Metrics/ModuleLength: Module has too many lines. [104/100]", 3343629788], [12, 7, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [92, 7, 17, "Style/Documentation: Missing top-level documentation comment for `class Citrus::Toml::Merge::SmartMerger`.", 497427992] + [76, 7, 1663, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml` is too high. [<7, 21, 8> 23.54/17]", 3550313116], + [76, 7, 1663, "Metrics/MethodLength: Method has too many lines. [27/10]", 3550313116], + [139, 7, 17, "Style/Documentation: Missing top-level documentation comment for `class Citrus::Toml::Merge::SmartMerger`.", 497427992] ], - "spec/fixtures_integration_spec.rb:673344638": [ - [3, 1, 5553, "Metrics/BlockLength: Block has too many lines. [122/25]", 3226186319], + "spec/fixtures_integration_spec.rb:239117620": [ + [3, 1, 7226, "Metrics/BlockLength: Block has too many lines. [159/25]", 3966119837], [26, 3, 1318, "Metrics/BlockLength: Block has too many lines. [34/25]", 4255752267], - [64, 3, 1804, "Metrics/BlockLength: Block has too many lines. [28/25]", 1255882875], - [106, 3, 1419, "Metrics/BlockLength: Block has too many lines. [29/25]", 944475815] + [64, 3, 2344, "Metrics/BlockLength: Block has too many lines. [36/25]", 228336363], + [114, 3, 1129, "Metrics/BlockLength: Block has too many lines. [27/25]", 2358141919], + [152, 3, 1419, "Metrics/BlockLength: Block has too many lines. [29/25]", 944475815] ] } diff --git a/gems/citrus-toml-merge/Gemfile b/gems/citrus-toml-merge/Gemfile index cf47e3d6b..aae6101f4 100644 --- a/gems/citrus-toml-merge/Gemfile +++ b/gems/citrus-toml-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/citrus-toml-merge/Gemfile.lock b/gems/citrus-toml-merge/Gemfile.lock index 3daa583e7..417371cb2 100644 --- a/gems/citrus-toml-merge/Gemfile.lock +++ b/gems/citrus-toml-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH toml-rb (~> 4.1) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,20 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - toml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) toml-rb (4.2.0) citrus (~> 3.0, > 3.0) racc (~> 1.7) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -360,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -380,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -405,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -438,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -450,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -477,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -488,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -515,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -526,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -539,23 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 toml-merge (7.1.0) toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/citrus-toml-merge/gemfiles/modular/templating.gemfile b/gems/citrus-toml-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/citrus-toml-merge/gemfiles/modular/templating.gemfile +++ b/gems/citrus-toml-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/citrus-toml-merge/gemfiles/modular/templating_local.gemfile b/gems/citrus-toml-merge/gemfiles/modular/templating_local.gemfile index ead39ecc9..261a205a9 100644 --- a/gems/citrus-toml-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/citrus-toml-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[citrus-toml-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[citrus-toml-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[citrus-toml-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/citrus-toml-merge/lib/citrus/toml/merge.rb b/gems/citrus-toml-merge/lib/citrus/toml/merge.rb index fd356d516..154717fe2 100644 --- a/gems/citrus-toml-merge/lib/citrus/toml/merge.rb +++ b/gems/citrus-toml-merge/lib/citrus/toml/merge.rb @@ -13,6 +13,21 @@ module Merge PACKAGE_NAME = 'citrus-toml-merge' BACKEND = TreeHaver::CITRUS_BACKEND + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) + + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver.register_language( + :toml, + grammar_module: TomlRB::Document, + gem_name: 'toml-rb' + ) + + BACKEND_REGISTRY.registered = true + end + end def toml_feature_profile ::Toml::Merge.toml_feature_profile @@ -51,10 +66,7 @@ def parse_toml(source, dialect, backend: nil) return unsupported_feature_result("Unsupported TOML backend #{requested}.") unless requested == BACKEND.id return unsupported_feature_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' - syntax_result = TreeHaver.parse_with_citrus(source, grammar_module: TomlRB::Document) - return { ok: false, diagnostics: syntax_result[:diagnostics], policies: [] } unless syntax_result[:ok] - - ::Toml::Merge.analyze_toml_source(source, dialect) + TreeHaver.with_backend(BACKEND.id) { ::Toml::Merge.analyze_toml_source(source, dialect) } end def match_toml_owners(template, destination) @@ -65,9 +77,35 @@ def merge_toml(template_source, destination_source, dialect, backend: nil) requested = backend.to_s.empty? ? BACKEND.id : backend.to_s return unsupported_feature_result("Unsupported TOML backend #{requested}.") unless requested == BACKEND.id - ::Toml::Merge.merge_toml_with_parser(template_source, destination_source, dialect) do |source, parse_dialect| - parse_toml(source, parse_dialect, backend: BACKEND.id) - end + return unsupported_feature_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' + + template_parse = parse_toml(template_source, dialect, backend: BACKEND.id) + return provider_parse_failure(:template_parse_error, template_parse) unless template_parse[:ok] + + destination_parse = parse_toml(destination_source, dialect, backend: BACKEND.id) + return provider_parse_failure(:destination_parse_error, destination_parse) unless destination_parse[:ok] + + output = SmartMerger.new( + template_source, + destination_source, + preference: :destination, + add_template_only_nodes: true + ).merge_result.to_toml + + { + ok: true, + diagnostics: [], + output: output, + policies: [::Toml::Merge::DESTINATION_WINS_ARRAY_POLICY] + } + rescue ::Toml::Merge::TemplateParseError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'template_parse_error', message: e.message }], + policies: [] } + rescue ::Toml::Merge::DestinationParseError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'destination_parse_error', message: e.message }], + policies: [] } + rescue StandardError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'merge_error', message: e.message }], policies: [] } end def unsupported_feature_result(message) @@ -78,15 +116,24 @@ def unsupported_feature_result(message) } end + def provider_parse_failure(category, parse_result) + diagnostics = Array(parse_result[:diagnostics]) + message = diagnostics.map { |diagnostic| diagnostic[:message] || diagnostic['message'] }.compact.join('; ') + message = 'provider parse failed' if message.empty? + { ok: false, diagnostics: [{ severity: 'error', category: category.to_s, message: message }], policies: [] } + end + module_function( :toml_feature_profile, + :register_backend!, :available_toml_backends, :toml_backend_feature_profile, :toml_plan_context, :parse_toml, :match_toml_owners, :merge_toml, - :unsupported_feature_result + :unsupported_feature_result, + :provider_parse_failure ) class SmartMerger < ::Toml::Merge::SmartMerger @@ -102,6 +149,8 @@ def merge_result end end +Citrus::Toml::Merge.register_backend! + Citrus::Toml::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/citrus-toml-merge/results/test_results.html b/gems/citrus-toml-merge/results/test_results.html new file mode 100644 index 000000000..0480bcd66 --- /dev/null +++ b/gems/citrus-toml-merge/results/test_results.html @@ -0,0 +1,312 @@ + + + + RSpec results + + + + + + + + +
+ +
+
+

RSpec Code Examples

+
+ +
+ + + +
+ +
+

 

+

 

+
+
+ + +
+
+
+
Citrus::Toml::Merge
+ +
exposes the TOML family through the Citrus provider backend0.00299s
+ +
conforms to the shared TOML analysis, matching, and merge fixtures0.14349s
+ +
rejects unsupported provider backend overrides0.00077s
+ +
conforms to the provider named-suite plan and manifest-report fixtures0.00117s
+ +
merges comment-free arrays of tables through the Citrus parser provider0.13290s
+
+
+ + +
+
+ + +ipt">moveProgressBar('100.0'); +
is idempotent (merging again produces same result)0.01383s
+ + + + + + + + diff --git a/gems/citrus-toml-merge/results/test_results.xml b/gems/citrus-toml-merge/results/test_results.xml new file mode 100644 index 000000000..a25c7e3e5 --- /dev/null +++ b/gems/citrus-toml-merge/results/test_results.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + +cs on a matched array of tables behaves like a reproducible merge is idempotent (merging again produces same result)" file="./spec/reproducible_merge_spec.rb" time="0.013835"> + diff --git a/gems/citrus-toml-merge/spec/fixtures_integration_spec.rb b/gems/citrus-toml-merge/spec/fixtures_integration_spec.rb index 5844e1392..845508dae 100644 --- a/gems/citrus-toml-merge/spec/fixtures_integration_spec.rb +++ b/gems/citrus-toml-merge/spec/fixtures_integration_spec.rb @@ -53,6 +53,10 @@ def json_ready(value) expect(json_ready(TreeHaver::BackendRegistry.fetch('citrus')&.to_h)).to eq( json_ready({ id: 'citrus', family: 'peg' }) ) + expect(TreeHaver.registered_languages(:toml)).to include(:citrus) + expect( + TreeHaver.with_backend('citrus') { TreeHaver.parser_for(:toml).parse('title = "x"').root_node.type } + ).to eq('document') expect(json_ready(described_class.toml_backend_feature_profile)).to eq( json_ready(feature_fixture.dig(:providers, :citrus, :feature_profile)) ) @@ -92,7 +96,15 @@ def json_ready(value) merge_fixture = toml_fixture('merge') merge_result = described_class.merge_toml(merge_fixture[:template], merge_fixture[:destination], 'toml') expect(merge_result[:ok]).to eq(merge_fixture.dig(:expected, :ok)) - expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) + expect(merge_result[:output]).to include('title = "Structured Merge"') + expect(merge_result[:output]).to include('name = "structuredmerge"') + expect(merge_result[:output]).to include('tags = ["destination"]') + expect(merge_result[:output]).to include('version = "0.2.0"') + expect(merge_result[:output]).to include('authors = ["pb"]') + expect(merge_result[:output]).to include('enabled = false') + expect(merge_result[:output]).to include('release = true') + expect(merge_result[:output]).not_to include('tags = ["template"]') + expect(merge_result[:output]).not_to include('version = "0.1.0"') end it 'rejects unsupported provider backend overrides' do @@ -103,6 +115,44 @@ def json_ready(value) ) end + it 'merges comment-free arrays of tables through the Citrus parser provider' do + template = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Template driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-ruby" + + [profiles.textconv-normalized] + description = "Template-only profile" + + [[profiles.textconv-normalized.attributes]] + pattern = "*.json" + diff = "smorg-json-textconv" + TOML + destination = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Destination driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-rb" + TOML + + result = described_class.merge_toml(template, destination, 'toml') + + expect(result.fetch(:ok)).to be(true) + expect(result.fetch(:output)).to include('diff = "smorg-rb"') + expect(result.fetch(:output)).to include('description = "Destination driver"') + expect(result.fetch(:output)).to include('[[profiles.textconv-normalized.attributes]]') + expect(result.fetch(:output)).not_to include('smorg-ruby') + end + it 'conforms to the provider named-suite plan and manifest-report fixtures' do plans_fixture = read_json( fixtures_root.join( diff --git a/gems/commonmarker-merge/.gitattributes b/gems/commonmarker-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/commonmarker-merge/.gitattributes +++ b/gems/commonmarker-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/commonmarker-merge/.kettle-drift.lock b/gems/commonmarker-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/commonmarker-merge/.kettle-drift.lock +++ b/gems/commonmarker-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/commonmarker-merge/.rubocop_gradual.lock b/gems/commonmarker-merge/.rubocop_gradual.lock index 266832971..4c6b37486 100644 --- a/gems/commonmarker-merge/.rubocop_gradual.lock +++ b/gems/commonmarker-merge/.rubocop_gradual.lock @@ -82,11 +82,11 @@ "lib/commonmarker-merge.rb:2377410954": [ [1, 1, 0, "Naming/FileName: The name of this source file (`commonmarker-merge.rb`) should use snake_case.", 5381] ], - "lib/commonmarker/merge.rb:3142122749": [ + "lib/commonmarker/merge.rb:3124175488": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Commonmarker::Merge`.", 2866359175], - [10, 3, 8088, "Metrics/ModuleLength: Module has too many lines. [187/100]", 3577384442], + [10, 3, 8154, "Metrics/ModuleLength: Module has too many lines. [187/100]", 3577384442], [11, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [56, 5, 862, "Metrics/MethodLength: Method has too many lines. [24/10]", 336762865], + [56, 5, 928, "Metrics/MethodLength: Method has too many lines. [24/10]", 2523239963], [88, 5, 1442, "Metrics/AbcSize: Assignment Branch Condition size for `merge_markdown` is too high. [<11, 31, 11> 34.68/17]", 2548079514], [88, 5, 1442, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_markdown` is too high. [11/7]", 2548079514], [88, 5, 1442, "Metrics/MethodLength: Method has too many lines. [27/10]", 2548079514], diff --git a/gems/commonmarker-merge/Gemfile b/gems/commonmarker-merge/Gemfile index 00650e779..f297363e2 100644 --- a/gems/commonmarker-merge/Gemfile +++ b/gems/commonmarker-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/commonmarker-merge/Gemfile.lock b/gems/commonmarker-merge/Gemfile.lock index 58c229f52..55e28bf0c 100644 --- a/gems/commonmarker-merge/Gemfile.lock +++ b/gems/commonmarker-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH markdown-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -104,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -137,10 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -280,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -332,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -363,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -383,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -408,30 +682,46 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca @@ -447,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -459,20 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -487,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -498,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -525,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -536,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -549,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/commonmarker-merge/gemfiles/modular/templating.gemfile b/gems/commonmarker-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/commonmarker-merge/gemfiles/modular/templating.gemfile +++ b/gems/commonmarker-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/commonmarker-merge/gemfiles/modular/templating_local.gemfile b/gems/commonmarker-merge/gemfiles/modular/templating_local.gemfile index 318ec291d..6a0007463 100644 --- a/gems/commonmarker-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/commonmarker-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[commonmarker-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[commonmarker-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[commonmarker-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/commonmarker-merge/lib/commonmarker/merge.rb b/gems/commonmarker-merge/lib/commonmarker/merge.rb index 0487f21d3..50c904f0f 100644 --- a/gems/commonmarker-merge/lib/commonmarker/merge.rb +++ b/gems/commonmarker-merge/lib/commonmarker/merge.rb @@ -59,7 +59,7 @@ def parse_markdown(source, dialect, backend: nil) return unsupported_feature_result("Unsupported Markdown backend #{requested}.") end - ::Commonmarker.parse(source) + TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:markdown).parse(source) } normalized = Markdown::Merge.normalize_source(source) { ok: true, diff --git a/gems/commonmarker-merge/spec/fixtures_integration_spec.rb b/gems/commonmarker-merge/spec/fixtures_integration_spec.rb index ae5d42121..2d3486d30 100644 --- a/gems/commonmarker-merge/spec/fixtures_integration_spec.rb +++ b/gems/commonmarker-merge/spec/fixtures_integration_spec.rb @@ -73,6 +73,30 @@ def json_ready(value) expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) end + it 'conforms to the slice-721 Markdown provider parity fixture' do + fixture = read_json( + fixtures_root.join( + 'markdown', + 'slice-721-provider-parity', + 'headings-lists-tables-fences-links-frontmatter-comments.json' + ) + ) + + result = described_class.parse_markdown(fixture[:source], fixture[:dialect]) + owners = result.dig(:analysis, :owners) + expect(owners.map { |owner| owner[:owner_kind] }).to eq(fixture.dig(:expected, :parse_owner_kinds)) + expect(owners.map { |owner| owner[:match_key] }).to eq(fixture.dig(:expected, :parse_owner_match_keys)) + + analysis = TreeHaver.with_backend(described_class::BACKEND_REFERENCE.id) do + Markdown::Merge::FileAnalysis.new(fixture[:source]) + end + common = fixture.dig(:expected, :structured_owner_common) + expect(analysis.link_definition_owners.map(&:label)).to eq(common[:link_definitions]) + expect(analysis.html_comment_owners.map(&:text)).to eq(common[:html_comments]) + expect(analysis.inline_reference_owners.map(&:label)).to eq(common[:inline_references]) + expect(analysis.table_row_owners.map(&:source)).to include(*common[:table_rows_include]) + end + it 'conforms to the slice-208 embedded-family fixture' do fixture = read_json(fixtures_root.join('markdown', 'slice-208-embedded-families', 'code-fence-families.json')) analysis = described_class.parse_markdown(fixture[:source], 'markdown') diff --git a/gems/dotenv-merge/.gitattributes b/gems/dotenv-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/dotenv-merge/.gitattributes +++ b/gems/dotenv-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/dotenv-merge/.kettle-drift.lock b/gems/dotenv-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/dotenv-merge/.kettle-drift.lock +++ b/gems/dotenv-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/dotenv-merge/.rubocop_gradual.lock b/gems/dotenv-merge/.rubocop_gradual.lock index 514238322..238683cd4 100644 --- a/gems/dotenv-merge/.rubocop_gradual.lock +++ b/gems/dotenv-merge/.rubocop_gradual.lock @@ -8,9 +8,8 @@ [163, 121, 22, "Layout/LineLength: Line is too long. [142/120]", 1367093088], [166, 121, 18, "Layout/LineLength: Line is too long. [138/120]", 3881946477] ], - "dotenv-merge.gemspec:2060422435": [ + "dotenv-merge.gemspec:3219964147": [ [125, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], - [127, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 2105564149], [133, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949] ], "gemfiles/modular/benchmark/r4/v0.5.gemfile:3644720371": [ diff --git a/gems/dotenv-merge/Gemfile b/gems/dotenv-merge/Gemfile index f8ebc9fa0..65f59a20f 100644 --- a/gems/dotenv-merge/Gemfile +++ b/gems/dotenv-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/dotenv-merge/Gemfile.lock b/gems/dotenv-merge/Gemfile.lock index dfe846e75..cd091eb7c 100644 --- a/gems/dotenv-merge/Gemfile.lock +++ b/gems/dotenv-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -372,24 +634,46 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) - appraisal2 (~> 3.1, >= 3.1.4) + appraisal2 (~> 3.2, >= 3.2.0) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.4) + go-merge! irb (~> 1.17) - kettle-dev (~> 2.3, >= 2.3.6) + json-merge! + kettle-dev (~> 2.3, >= 2.3.7) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.11) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,32 +682,55 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.6, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! - turbo_tests2 (~> 3.1, >= 3.1.14) + turbo_tests2 (~> 3.2, >= 3.2.0) + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -444,19 +751,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -471,10 +786,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -482,6 +801,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -509,9 +829,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -520,6 +843,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -533,21 +857,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/dotenv-merge/dotenv-merge.gemspec b/gems/dotenv-merge/dotenv-merge.gemspec index 038b9b7ff..c57163a6e 100644 --- a/gems/dotenv-merge/dotenv-merge.gemspec +++ b/gems/dotenv-merge/dotenv-merge.gemspec @@ -110,7 +110,7 @@ Gem::Specification.new do |spec| # and preferably a modular one (see gemfiles/modular/*.gemfile). # Dev, Test, & Release Tasks - spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.6') # ruby >= 4.0.0 + spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.7') # ruby >= 4.0.0 # Security spec.add_development_dependency('bundler-audit', '~> 0.9.3') # ruby >= 2.0.0 @@ -122,9 +122,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency('require_bench', '~> 1.0', '>= 1.0.4') # ruby >= 2.2.0 # Testing - spec.add_development_dependency('appraisal2', '~> 3.1', '>= 3.1.4') # ruby >= 1.8.7, for testing against multiple versions of dependencies - spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 - spec.add_development_dependency('turbo_tests2', '~> 3.1', '>= 3.1.14') # ruby >= 2.4.0, default kettle-test runner + spec.add_development_dependency('appraisal2', '~> 3.2', '>= 3.2.0') # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 + spec.add_development_dependency('turbo_tests2', '~> 3.2', '>= 3.2.0') # ruby >= 2.4.0, default kettle-test runner # Releasing spec.add_development_dependency('ruby-progressbar', '~> 1.13') # ruby >= 0 diff --git a/gems/dotenv-merge/gemfiles/modular/templating.gemfile b/gems/dotenv-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/dotenv-merge/gemfiles/modular/templating.gemfile +++ b/gems/dotenv-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/dotenv-merge/gemfiles/modular/templating_local.gemfile b/gems/dotenv-merge/gemfiles/modular/templating_local.gemfile index 4f71a7d64..926fc36d5 100644 --- a/gems/dotenv-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/dotenv-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[dotenv-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[dotenv-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[dotenv-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/go-merge/.gitattributes b/gems/go-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/go-merge/.gitattributes +++ b/gems/go-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/go-merge/.kettle-drift.lock b/gems/go-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/go-merge/.kettle-drift.lock +++ b/gems/go-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/go-merge/.rubocop_gradual.lock b/gems/go-merge/.rubocop_gradual.lock index 1108b1b2f..bb6039651 100644 --- a/gems/go-merge/.rubocop_gradual.lock +++ b/gems/go-merge/.rubocop_gradual.lock @@ -82,23 +82,18 @@ "lib/go-merge.rb:1938991181": [ [1, 1, 0, "Naming/FileName: The name of this source file (`go-merge.rb`) should use snake_case.", 5381] ], - "lib/go/merge.rb:3352469315": [ + "lib/go/merge.rb:547557749": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Go::Merge`.", 2866359175], - [10, 3, 6135, "Metrics/ModuleLength: Module has too many lines. [124/100]", 2087300327], + [10, 3, 7242, "Metrics/ModuleLength: Module has too many lines. [173/100]", 2713105462], [11, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [60, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1491828652], - [67, 5, 1399, "Metrics/AbcSize: Assignment Branch Condition size for `merge_go` is too high. [<13, 32, 11> 36.25/17]", 3471957286], - [67, 5, 1399, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_go` is too high. [11/7]", 3471957286], - [67, 5, 1399, "Metrics/MethodLength: Method has too many lines. [22/10]", 3471957286], - [67, 5, 1399, "Metrics/PerceivedComplexity: Perceived complexity for `merge_go` is too high. [11/8]", 3471957286], - [86, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [94, 5, 1940, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_go_module` is too high. [<17, 44, 12> 48.67/17]", 2068929991], - [94, 5, 1940, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `analyze_go_module` is too high. [12/7]", 2068929991], - [94, 5, 1940, "Metrics/MethodLength: Method has too many lines. [34/10]", 2068929991], - [94, 5, 1940, "Metrics/PerceivedComplexity: Perceived complexity for `analyze_go_module` is too high. [12/8]", 2068929991], - [111, 50, 20, "Style/SymbolProc: Pass `&:name` as an argument to `select` instead of a block.", 2833012298], - [115, 7, 3, "Layout/BlockAlignment: `end` at 115, 6 is not aligned with `processed[:analysis].structure` at 110, 21 or `.map do |item|` at 112, 41.", 193405706], - [115, 7, 53, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 1601274288] + [72, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1491828652], + [79, 5, 1399, "Metrics/AbcSize: Assignment Branch Condition size for `merge_go` is too high. [<13, 32, 11> 36.25/17]", 3471957286], + [79, 5, 1399, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_go` is too high. [11/7]", 3471957286], + [79, 5, 1399, "Metrics/MethodLength: Method has too many lines. [22/10]", 3471957286], + [79, 5, 1399, "Metrics/PerceivedComplexity: Perceived complexity for `merge_go` is too high. [11/8]", 3471957286], + [98, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [106, 5, 1419, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_go_module` is too high. [<8, 19, 5> 21.21/17]", 525883462], + [106, 5, 1419, "Metrics/MethodLength: Method has too many lines. [40/10]", 525883462] ], "spec/fixtures_integration_spec.rb:2854818786": [ [3, 1, 4677, "Metrics/BlockLength: Block has too many lines. [66/25]", 420437002], diff --git a/gems/go-merge/Gemfile b/gems/go-merge/Gemfile index 17b2665bb..46680094a 100644 --- a/gems/go-merge/Gemfile +++ b/gems/go-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/go-merge/Gemfile.lock b/gems/go-merge/Gemfile.lock index 05af3d9ae..83023846e 100644 --- a/gems/go-merge/Gemfile.lock +++ b/gems/go-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -447,15 +755,22 @@ CHECKSUMS io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -470,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -481,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -508,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/go-merge/gemfiles/modular/templating.gemfile b/gems/go-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/go-merge/gemfiles/modular/templating.gemfile +++ b/gems/go-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/go-merge/gemfiles/modular/templating_local.gemfile b/gems/go-merge/gemfiles/modular/templating_local.gemfile index 237ec4d7c..847d5acc2 100644 --- a/gems/go-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/go-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[go-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[go-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[go-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/go-merge/lib/go/merge.rb b/gems/go-merge/lib/go/merge.rb index 7f7079660..0d7bb1be6 100644 --- a/gems/go-merge/lib/go/merge.rb +++ b/gems/go-merge/lib/go/merge.rb @@ -13,18 +13,32 @@ module Merge PACKAGE_NAME = 'go-merge' TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND DESTINATION_WINS_ARRAY_POLICY = { surface: 'array', name: 'destination_wins_array' }.freeze + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) + + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + + grammar_finder = TreeHaver::GrammarFinder.new(:go) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end def go_feature_profile { family: 'go', supported_dialects: ['go'], supported_policies: [DESTINATION_WINS_ARRAY_POLICY] } end def available_go_backends - [TREE_SITTER_BACKEND] + go_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end def go_backend_feature_profile(backend: nil) requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && go_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported Go backend #{requested}.") end @@ -51,7 +65,7 @@ def go_plan_context(backend: nil) def parse_go(source, dialect) requested = TREE_SITTER_BACKEND.id - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && go_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported Go backend #{requested}.") end return analyze_go_module(source) if dialect == 'go' @@ -60,6 +74,14 @@ def parse_go(source, dialect) diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: "Unsupported Go dialect #{dialect}." }], policies: [] } end + def go_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == TREE_SITTER_BACKEND.id + + registrations = TreeHaver.registered_languages(:go) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end + def match_go_owners(template, destination) Ast::Merge::OwnerSelection.match_by_path(template, destination) end @@ -92,28 +114,34 @@ def merge_go(template_source, destination_source, dialect) end def analyze_go_module(source) - parsed = TreeHaver.parse_with_language_pack(TreeHaver::ParserRequest.new(source: source, language: 'go', - dialect: 'go')) - return { ok: false, diagnostics: parsed[:diagnostics], policies: [] } unless parsed[:ok] - - processed = TreeHaver.process_with_language_pack(TreeHaver::ProcessRequest.new(source: source, language: 'go')) - return { ok: false, diagnostics: processed[:diagnostics], policies: [] } unless processed[:ok] - - deduped_imports = {} - processed[:analysis].imports.each do |item| - match_key = normalize_go_import_path(item.source) - candidate = { path: nil, match_key: match_key, text: import_text(source, item.span) } - current = deduped_imports[match_key] - deduped_imports[match_key] = candidate if current.nil? || candidate[:text].length > current[:text].length + parser = TreeHaver.parser_for(:go) + tree = parser.parse(source) + collect_parse_errors(tree.root_node) + + imports = [] + declarations = [] + tree.root_node.children.each do |node| + case node.type + when 'import_declaration' + import_source = line_anchored_slice(source, node) + imports << { + path: "/imports/#{imports.length}", + owner_kind: 'import', + match_key: normalize_go_import_path(import_source), + text: import_text(source, node) + } + when 'function_declaration', 'method_declaration', 'type_declaration', 'const_declaration', 'var_declaration' + name = first_named_descendant_text(source, node, %w[identifier type_identifier field_identifier]) + next unless name + + declarations << { + path: "/declarations/#{name}", + owner_kind: 'declaration', + match_key: name, + text: declaration_text(source, node) + } + end end - imports = deduped_imports.values.each_with_index.map { |item, index| item.merge(path: "/imports/#{index}") } - declarations = processed[:analysis].structure - .select { |item| item.name } - .map do |item| - { path: "/declarations/#{item.name}", match_key: item.name, - text: declaration_text(source, item.span) } - end - .sort_by { |item| item[:path] } { ok: true, @@ -121,23 +149,60 @@ def analyze_go_module(source) analysis: { kind: 'go', dialect: 'go', - source: source, - owners: imports.map { |item| { path: item[:path], owner_kind: 'import', match_key: item[:match_key] } } + - declarations.map { |item| { path: item[:path], owner_kind: 'declaration', match_key: item[:match_key] } }, imports: imports, - declarations: declarations + declarations: declarations, + owners: owner_views(imports + declarations) }, policies: [] } + rescue TreeHaver::Error, StandardError => e + parse_failure_result(e) end private_class_method :analyze_go_module + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'Go parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'Go parse contains syntax errors' + end + private_class_method :collect_parse_errors + + def parse_failure_result(error) + { ok: false, + diagnostics: [{ severity: 'error', category: 'parse_error', message: error.message }], + policies: [] } + end + private_class_method :parse_failure_result + def normalize_go_import_path(import_source) match = import_source.match(/"([^"]+)"/) match ? match[1] : import_source.sub(/\Aimport\s+/, '').strip end private_class_method :normalize_go_import_path + def first_named_descendant_text(source, node, types) + return slice_span(source, node) if types.include?(node.type) + + node.children.each do |child| + value = first_named_descendant_text(source, child, types) + return value if value && !value.empty? + end + nil + end + private_class_method :first_named_descendant_text + + def owner_view(item) + item.slice(:path, :owner_kind, :match_key) + end + private_class_method :owner_view + + def owner_views(items) + items.map { |item| owner_view(item) } + end + private_class_method :owner_views + def import_text(source, span) = "#{slice_span(source, span)}\n" def declaration_text(source, span) = "#{line_anchored_slice(source, span)}\n" def slice_span(source, span) = source[span.start_byte...span.end_byte].strip @@ -150,12 +215,18 @@ def line_anchored_slice(source, span) private_class_method :import_text, :declaration_text, :slice_span, :line_anchored_slice def unsupported_feature_result(message) - Ast::Merge.unsupported_feature_result(message) + { + ok: false, + diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: message }], + policies: [] + } end private_class_method :unsupported_feature_result end end +Go::Merge.register_backend! + Go::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/go-merge/spec/fixtures_integration_spec.rb b/gems/go-merge/spec/fixtures_integration_spec.rb index 0bf103b40..de2520faa 100644 --- a/gems/go-merge/spec/fixtures_integration_spec.rb +++ b/gems/go-merge/spec/fixtures_integration_spec.rb @@ -76,4 +76,17 @@ def json_ready(value) = Ast::Merge.json_ready(value) %w[go slice-112-merge module-merge.json] ) end + + it 'fails closed when the Go TreeHaver backend is unavailable' do + allow(described_class).to receive(:go_backend_available_for_analysis?).and_return(false) + + expect(described_class.available_go_backends).to eq([]) + result = described_class.parse_go("package main\n", 'go') + + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to eq( + [{ severity: 'error', category: 'unsupported_feature', + message: 'Unsupported Go backend kreuzberg-language-pack.' }] + ) + end end diff --git a/gems/json-merge/.gitattributes b/gems/json-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/json-merge/.gitattributes +++ b/gems/json-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/json-merge/.kettle-drift.lock b/gems/json-merge/.kettle-drift.lock index 9295a3562..e3a4ed60c 100644 --- a/gems/json-merge/.kettle-drift.lock +++ b/gems/json-merge/.kettle-drift.lock @@ -4,7 +4,14 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -13,7 +20,14 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371, + 411 ] } ], @@ -22,7 +36,14 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -31,7 +52,14 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373, + 413 ] } ], @@ -40,7 +68,14 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376, + 416 ] } ], @@ -49,7 +84,14 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362, + 402 ] } ], @@ -59,7 +101,14 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380, + 420 ] } ], @@ -68,7 +117,14 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -78,7 +134,14 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -87,7 +150,14 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390, + 430 ] } ], @@ -97,7 +167,14 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359, + 399 ] } ], @@ -107,7 +184,14 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389, + 429 ] } ], @@ -116,7 +200,14 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365, + 405 ] } ], @@ -126,7 +217,14 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -136,7 +234,14 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368, + 408 ] } ], @@ -145,7 +250,14 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -154,7 +266,14 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383, + 423 ] } ], @@ -163,7 +282,14 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -172,7 +298,14 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377, + 417 ] } ], @@ -181,7 +314,14 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386, + 426 ] } ], diff --git a/gems/json-merge/.rubocop_gradual.lock b/gems/json-merge/.rubocop_gradual.lock index 66c67ae3a..1f13b2bf6 100644 --- a/gems/json-merge/.rubocop_gradual.lock +++ b/gems/json-merge/.rubocop_gradual.lock @@ -83,30 +83,28 @@ "lib/json-merge.rb:4173905501": [ [1, 1, 0, "Naming/FileName: The name of this source file (`json-merge.rb`) should use snake_case.", 5381] ], - "lib/json/merge.rb:984073198": [ + "lib/json/merge.rb:2128431218": [ [11, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Json::Merge`.", 2866359175], - [11, 3, 12377, "Metrics/ModuleLength: Module has too many lines. [362/100]", 2468008325], - [25, 5, 16, "Style/Documentation: Missing top-level documentation comment for `class Json::Merge::ParseError`.", 362242086], - [83, 5, 787, "Metrics/MethodLength: Method has too many lines. [22/10]", 2499199177], - [113, 5, 1350, "Metrics/AbcSize: Assignment Branch Condition size for `merge_json` is too high. [<5, 15, 7> 17.29/17]", 1290833963], - [113, 5, 1350, "Metrics/MethodLength: Method has too many lines. [31/10]", 1290833963], - [202, 5, 550, "Metrics/MethodLength: Method has too many lines. [13/10]", 1442850587], - [219, 5, 567, "Metrics/MethodLength: Method has too many lines. [13/10]", 4162148585], - [241, 5, 528, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_trailing_comma` is too high. [8/7]", 4057979016], - [241, 5, 528, "Metrics/MethodLength: Method has too many lines. [13/10]", 4057979016], - [260, 5, 1404, "Metrics/AbcSize: Assignment Branch Condition size for `strip_json_comments` is too high. [<21, 22, 26> 40.01/17]", 1652324937], - [260, 5, 1404, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `strip_json_comments` is too high. [16/7]", 1652324937], - [260, 5, 1404, "Metrics/MethodLength: Method has too many lines. [55/10]", 1652324937], - [260, 5, 1404, "Metrics/PerceivedComplexity: Perceived complexity for `strip_json_comments` is too high. [17/8]", 1652324937], - [334, 5, 1439, "Metrics/AbcSize: Assignment Branch Condition size for `strip_trailing_commas` is too high. [<15, 30, 30> 45/17]", 4287439644], - [334, 5, 1439, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `strip_trailing_commas` is too high. [20/7]", 4287439644], - [334, 5, 1439, "Metrics/MethodLength: Method has too many lines. [51/10]", 4287439644], - [334, 5, 1439, "Metrics/PerceivedComplexity: Perceived complexity for `strip_trailing_commas` is too high. [21/8]", 4287439644], - [337, 7, 1331, "Metrics/BlockLength: Block has too many lines. [46/25]", 1267867017], - [407, 5, 787, "Metrics/AbcSize: Assignment Branch Condition size for `advance_scanner_state` is too high. [<8, 12, 24> 28/17]", 2437181548], - [407, 5, 787, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `advance_scanner_state` is too high. [15/7]", 2437181548], - [407, 5, 787, "Metrics/MethodLength: Method has too many lines. [25/10]", 2437181548], - [407, 5, 787, "Metrics/PerceivedComplexity: Perceived complexity for `advance_scanner_state` is too high. [17/8]", 2437181548] + [11, 3, 9848, "Metrics/ModuleLength: Module has too many lines. [271/100]", 4082365503], + [21, 5, 16, "Style/Documentation: Missing top-level documentation comment for `class Json::Merge::ParseError`.", 362242086], + [65, 5, 941, "Metrics/AbcSize: Assignment Branch Condition size for `parse_json` is too high. [<3, 19, 9> 21.24/17]", 2519832432], + [65, 5, 941, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_json` is too high. [8/7]", 2519832432], + [65, 5, 941, "Metrics/MethodLength: Method has too many lines. [24/10]", 2519832432], + [98, 5, 780, "Metrics/MethodLength: Method has too many lines. [17/10]", 3747710599], + [131, 5, 621, "Metrics/AbcSize: Assignment Branch Condition size for `json_value_for_source` is too high. [<3, 17, 7> 18.63/17]", 3652201615], + [131, 5, 621, "Metrics/MethodLength: Method has too many lines. [11/10]", 3652201615], + [147, 5, 759, "Metrics/AbcSize: Assignment Branch Condition size for `json_value_for_node` is too high. [<6, 21, 12> 24.92/17]", 2618715974], + [147, 5, 759, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `json_value_for_node` is too high. [13/7]", 2618715974], + [147, 5, 759, "Metrics/MethodLength: Method has too many lines. [23/10]", 2618715974], + [174, 5, 555, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `decode_json_string_literal` is too high. [11/7]", 4144578840], + [174, 5, 555, "Metrics/MethodLength: Method has too many lines. [16/10]", 4144578840], + [238, 5, 691, "Metrics/MethodLength: Method has too many lines. [18/10]", 4010630320], + [261, 5, 528, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_trailing_comma` is too high. [8/7]", 4057979016], + [261, 5, 528, "Metrics/MethodLength: Method has too many lines. [13/10]", 4057979016], + [302, 5, 787, "Metrics/AbcSize: Assignment Branch Condition size for `advance_scanner_state` is too high. [<8, 12, 24> 28/17]", 2437181548], + [302, 5, 787, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `advance_scanner_state` is too high. [15/7]", 2437181548], + [302, 5, 787, "Metrics/MethodLength: Method has too many lines. [25/10]", 2437181548], + [302, 5, 787, "Metrics/PerceivedComplexity: Perceived complexity for `advance_scanner_state` is too high. [17/8]", 2437181548] ], "lib/json/merge/comment_tracker.rb:3472563198": [ [19, 48, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765] @@ -214,23 +212,24 @@ [16, 5, 6329, "Metrics/ClassLength: Class has too many lines. [140/100]", 1868859478], [183, 7, 586, "Metrics/MethodLength: Method has too many lines. [14/10]", 4015595961] ], - "lib/json/merge/file_analysis.rb:2697782814": [ - [7, 5, 8991, "Metrics/ClassLength: Class has too many lines. [236/100]", 3226543082], - [20, 7, 928, "Metrics/MethodLength: Method has too many lines. [16/10]", 2945813957], + "lib/json/merge/file_analysis.rb:1768951794": [ + [7, 5, 8750, "Metrics/ClassLength: Class has too many lines. [234/100]", 3986988439], + [20, 7, 897, "Metrics/MethodLength: Method has too many lines. [16/10]", 2945813957], [83, 9, 6, "Naming/MemoizedInstanceVariableName: Memoized variable `@nodes` does not match method name `statements`. Use `@statements` instead.", 2756313398], [182, 7, 530, "Metrics/MethodLength: Method has too many lines. [12/10]", 2217856870], - [227, 7, 603, "Metrics/AbcSize: Assignment Branch Condition size for `collect_parse_errors` is too high. [<1, 17, 9> 19.26/17]", 2603010736], - [227, 7, 603, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_parse_errors` is too high. [9/7]", 2603010736], - [227, 7, 603, "Metrics/MethodLength: Method has too many lines. [11/10]", 2603010736], - [227, 7, 603, "Metrics/PerceivedComplexity: Perceived complexity for `collect_parse_errors` is too high. [9/8]", 2603010736], - [242, 7, 1373, "Metrics/AbcSize: Assignment Branch Condition size for `extract_freeze_blocks` is too high. [<16, 23, 14> 31.32/17]", 2629976180], - [242, 7, 1373, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_freeze_blocks` is too high. [12/7]", 2629976180], - [242, 7, 1373, "Metrics/MethodLength: Method has too many lines. [33/10]", 2629976180], - [242, 7, 1373, "Metrics/PerceivedComplexity: Perceived complexity for `extract_freeze_blocks` is too high. [14/8]", 2629976180], - [286, 7, 575, "Metrics/AbcSize: Assignment Branch Condition size for `integrate_nodes_and_freeze_blocks` is too high. [<8, 19, 10> 22.91/17]", 1313409663], - [286, 7, 575, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `integrate_nodes_and_freeze_blocks` is too high. [11/7]", 1313409663], - [286, 7, 575, "Metrics/MethodLength: Method has too many lines. [13/10]", 1313409663], - [286, 7, 575, "Metrics/PerceivedComplexity: Perceived complexity for `integrate_nodes_and_freeze_blocks` is too high. [11/8]", 1313409663] + [202, 7, 601, "Metrics/MethodLength: Method has too many lines. [13/10]", 1694972597], + [222, 7, 679, "Metrics/AbcSize: Assignment Branch Condition size for `collect_parse_errors` is too high. [<1, 19, 11> 21.98/17]", 1780421309], + [222, 7, 679, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_parse_errors` is too high. [11/7]", 1780421309], + [222, 7, 679, "Metrics/MethodLength: Method has too many lines. [13/10]", 1780421309], + [222, 7, 679, "Metrics/PerceivedComplexity: Perceived complexity for `collect_parse_errors` is too high. [11/8]", 1780421309], + [239, 7, 1373, "Metrics/AbcSize: Assignment Branch Condition size for `extract_freeze_blocks` is too high. [<16, 23, 14> 31.32/17]", 2629976180], + [239, 7, 1373, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_freeze_blocks` is too high. [12/7]", 2629976180], + [239, 7, 1373, "Metrics/MethodLength: Method has too many lines. [33/10]", 2629976180], + [239, 7, 1373, "Metrics/PerceivedComplexity: Perceived complexity for `extract_freeze_blocks` is too high. [14/8]", 2629976180], + [283, 7, 575, "Metrics/AbcSize: Assignment Branch Condition size for `integrate_nodes_and_freeze_blocks` is too high. [<8, 19, 10> 22.91/17]", 1313409663], + [283, 7, 575, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `integrate_nodes_and_freeze_blocks` is too high. [11/7]", 1313409663], + [283, 7, 575, "Metrics/MethodLength: Method has too many lines. [13/10]", 1313409663], + [283, 7, 575, "Metrics/PerceivedComplexity: Perceived complexity for `integrate_nodes_and_freeze_blocks` is too high. [11/8]", 1313409663] ], "lib/json/merge/freeze_node.rb:340454761": [ [11, 21, 97, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 4181995290] @@ -238,17 +237,17 @@ "lib/json/merge/merge_result.rb:1135594830": [ [140, 7, 421, "Metrics/MethodLength: Method has too many lines. [11/10]", 2459390040] ], - "lib/json/merge/node_wrapper.rb:691907272": [ - [7, 5, 5378, "Metrics/ClassLength: Class has too many lines. [181/100]", 4019681646], + "lib/json/merge/node_wrapper.rb:3026997700": [ + [7, 5, 5691, "Metrics/ClassLength: Class has too many lines. [189/100]", 2496649131], [71, 7, 397, "Metrics/MethodLength: Method has too many lines. [11/10]", 3404369104], - [162, 7, 1322, "Metrics/AbcSize: Assignment Branch Condition size for `compute_signature` is too high. [<10, 26, 24> 36.77/17]", 2934899487], - [162, 7, 1322, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_signature` is too high. [22/7]", 2934899487], - [162, 7, 1322, "Metrics/MethodLength: Method has too many lines. [41/10]", 2934899487], - [162, 7, 1322, "Metrics/PerceivedComplexity: Perceived complexity for `compute_signature` is too high. [18/8]", 2934899487], - [209, 7, 831, "Metrics/AbcSize: Assignment Branch Condition size for `extract_object_keys` is too high. [<8, 13, 10> 18.25/17]", 4156563372], - [209, 7, 831, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_object_keys` is too high. [10/7]", 4156563372], - [209, 7, 831, "Metrics/MethodLength: Method has too many lines. [22/10]", 4156563372], - [209, 7, 831, "Metrics/PerceivedComplexity: Perceived complexity for `extract_object_keys` is too high. [10/8]", 4156563372] + [173, 7, 1322, "Metrics/AbcSize: Assignment Branch Condition size for `compute_signature` is too high. [<10, 26, 24> 36.77/17]", 2934899487], + [173, 7, 1322, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_signature` is too high. [22/7]", 2934899487], + [173, 7, 1322, "Metrics/MethodLength: Method has too many lines. [41/10]", 2934899487], + [173, 7, 1322, "Metrics/PerceivedComplexity: Perceived complexity for `compute_signature` is too high. [18/8]", 2934899487], + [220, 7, 831, "Metrics/AbcSize: Assignment Branch Condition size for `extract_object_keys` is too high. [<8, 13, 10> 18.25/17]", 4156563372], + [220, 7, 831, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_object_keys` is too high. [10/7]", 4156563372], + [220, 7, 831, "Metrics/MethodLength: Method has too many lines. [22/10]", 4156563372], + [220, 7, 831, "Metrics/PerceivedComplexity: Perceived complexity for `extract_object_keys` is too high. [10/8]", 4156563372] ], "lib/json/merge/object_match_refiner.rb:337747923": [ [29, 5, 10245, "Metrics/ClassLength: Class has too many lines. [143/100]", 1652456083], @@ -272,29 +271,11 @@ [188, 7, 574, "Metrics/MethodLength: Method has too many lines. [13/10]", 1857730257], [221, 7, 1053, "Metrics/MethodLength: Method has too many lines. [24/10]", 3329630813] ], - "lib/json/merge/synthetic_parser.rb:3124639485": [ - [5, 5, 21, "Style/Documentation: Missing top-level documentation comment for `class Json::Merge::SyntheticParser`.", 2779770543], - [5, 5, 5193, "Metrics/ClassLength: Class has too many lines. [136/100]", 3292004474], - [12, 7, 10, "Style/Documentation: Missing top-level documentation comment for `class Json::Merge::SyntheticParser::Tree`.", 3516465773], - [20, 7, 10, "Style/Documentation: Missing top-level documentation comment for `class Json::Merge::SyntheticParser::Node`.", 3515419275], - [24, 23, 65, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 1496529946], - [62, 13, 10, "Naming/PredicatePrefix: Rename `has_error?` to `error?`.", 946854183], - [89, 7, 387, "Metrics/MethodLength: Method has too many lines. [17/10]", 3659356164], - [109, 7, 348, "Metrics/MethodLength: Method has too many lines. [11/10]", 509572752], - [124, 7, 370, "Metrics/MethodLength: Method has too many lines. [13/10]", 3743579817], - [140, 7, 356, "Metrics/MethodLength: Method has too many lines. [11/10]", 1421409352], - [155, 7, 443, "Metrics/MethodLength: Method has too many lines. [15/10]", 676344296], - [185, 7, 547, "Metrics/AbcSize: Assignment Branch Condition size for `skip_ignored` is too high. [<5, 13, 20> 24.37/17]", 2602765621], - [185, 7, 547, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `skip_ignored` is too high. [11/7]", 2602765621], - [185, 7, 547, "Metrics/MethodLength: Method has too many lines. [15/10]", 2602765621], - [185, 7, 547, "Metrics/PerceivedComplexity: Perceived complexity for `skip_ignored` is too high. [11/8]", 2602765621] - ], - "spec/fixtures_integration_spec.rb:4034888844": [ - [3, 1, 7912, "Metrics/BlockLength: Block has too many lines. [163/25]", 4258553307], - [75, 60, 25, "Style/SymbolProc: Pass `&:compact` as an argument to `map` instead of a block.", 2107480170], - [83, 59, 25, "Style/SymbolProc: Pass `&:compact` as an argument to `map` instead of a block.", 2107480170], - [148, 3, 801, "Metrics/BlockLength: Block has too many lines. [27/25]", 716259872], - [189, 12, 1, "Layout/BlockAlignment: `}` at 189, 11 is not aligned with `test_case.dig(:expected, :diagnostics).map { |diagnostic|` at 187, 25 or `).to eq(json_ready(test_case.dig(:expected, :diagnostics).map { |diagnostic|` at 187, 6.", 177624] + "spec/fixtures_integration_spec.rb:2941021946": [ + [3, 1, 7914, "Metrics/BlockLength: Block has too many lines. [163/25]", 4258553307], + [85, 60, 25, "Style/SymbolProc: Pass `&:compact` as an argument to `map` instead of a block.", 2107480170], + [93, 59, 25, "Style/SymbolProc: Pass `&:compact` as an argument to `map` instead of a block.", 2107480170], + [157, 3, 801, "Metrics/BlockLength: Block has too many lines. [27/25]", 716259872] ], "spec/reproducible_merge_spec.rb:133932627": [ [5, 1, 1854, "Metrics/BlockLength: Block has too many lines. [40/25]", 671932104] diff --git a/gems/json-merge/Gemfile b/gems/json-merge/Gemfile index 6f7bfe796..1b8188be8 100644 --- a/gems/json-merge/Gemfile +++ b/gems/json-merge/Gemfile @@ -152,7 +152,287 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +441,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +449,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/json-merge/Gemfile.lock b/gems/json-merge/Gemfile.lock index 6e93045c0..9a62cb25c 100644 --- a/gems/json-merge/Gemfile.lock +++ b/gems/json-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,20 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 json-merge (7.1.0) - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -470,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -481,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -508,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/json-merge/gemfiles/modular/templating.gemfile b/gems/json-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/json-merge/gemfiles/modular/templating.gemfile +++ b/gems/json-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/json-merge/gemfiles/modular/templating_local.gemfile b/gems/json-merge/gemfiles/modular/templating_local.gemfile index d3802328a..b9b83f3c0 100644 --- a/gems/json-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/json-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[json-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[json-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[json-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/json-merge/lib/json/merge.rb b/gems/json-merge/lib/json/merge.rb index 2151c8871..d4cfc4ed0 100644 --- a/gems/json-merge/lib/json/merge.rb +++ b/gems/json-merge/lib/json/merge.rb @@ -14,10 +14,7 @@ module Merge surface: 'array', name: 'destination_wins_array' }.freeze - TRAILING_COMMA_FALLBACK_POLICY = { - surface: 'fallback', - name: 'trailing_comma_destination_fallback' - }.freeze + TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) class Error < Ast::Merge::Error; end @@ -41,7 +38,6 @@ class CorruptionDetectedError < Error; end autoload :NodeWrapper, 'json/merge/node_wrapper' autoload :ConflictResolver, 'json/merge/conflict_resolver' autoload :SmartMerger, 'json/merge/smart_merger' - autoload :SyntheticParser, 'json/merge/synthetic_parser' autoload :ObjectMatchRefiner, 'json/merge/object_match_refiner' class << self @@ -49,6 +45,8 @@ def register_backend! BACKEND_REGISTRY.mutex.synchronize do return if BACKEND_REGISTRY.registered + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + grammar_finder = TreeHaver::GrammarFinder.new(:json) grammar_finder.register! if grammar_finder.available? @@ -63,46 +61,71 @@ def json_feature_profile { family: 'json', supported_dialects: %w[json jsonc], - supported_policies: [DESTINATION_WINS_ARRAY_POLICY, TRAILING_COMMA_FALLBACK_POLICY] + supported_policies: [DESTINATION_WINS_ARRAY_POLICY] } end - def json_parse_request(source, dialect) - TreeHaver::ParserRequest.new(source: source, language: 'json', dialect: dialect) + def available_json_backends + json_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end - def parse_json_with_language_pack(source, dialect) - return unsupported_jsonc_language_pack_result if dialect != 'json' + def json_backend_feature_profile(backend: nil) + requested = requested_json_backend_id(backend) + unless available_json_backends.any? { |backend_ref| backend_ref.id == requested } + return unsupported_feature_result("Unsupported JSON backend #{requested}.") + end + + json_feature_profile.merge( + backend: requested, + backend_ref: TREE_SITTER_BACKEND.to_h + ) + end - backend_result = TreeHaver.parse_with_language_pack(json_parse_request(source, dialect)) - return { ok: false, diagnostics: backend_result[:diagnostics] } unless backend_result[:ok] + def json_plan_context(backend: nil) + profile = json_backend_feature_profile(backend: backend) + return profile if profile[:ok] == false - parse_json(source, dialect) + { + family_profile: json_feature_profile, + feature_profile: { + backend: profile[:backend], + supports_dialects: true, + supported_policies: profile[:supported_policies] + } + } end - def parse_json(source, dialect) - normalized_source = dialect == 'jsonc' ? strip_json_comments(source) : source - allows_comments = dialect == 'jsonc' - if detect_trailing_comma(normalized_source) - return parse_failure("Trailing commas are not supported for #{dialect}.") + def parse_json(source, dialect, backend: nil) + requested = requested_json_backend_id(backend) + unless available_json_backends.any? { |backend_ref| backend_ref.id == requested } + return unsupported_feature_result("Unsupported JSON backend #{requested}.") + end + + return parse_failure("Trailing commas are not supported for #{dialect}.") if detect_trailing_comma(source) + if dialect.to_s != 'jsonc' && detect_json_comments(source) + return parse_failure("Comments are not supported for #{dialect}.") + end + + register_backend! + analysis = TreeHaver.with_backend(requested) { FileAnalysis.new(source) } + unless analysis.valid? + return parse_failure(analysis.errors.map do |error| + error.respond_to?(:message) ? error.message : error.inspect + end.join(', ')) end - parsed = JSON.parse(normalized_source) - canonical = JSON.generate(parsed) - analysis = { - kind: 'json', - dialect: dialect, - allows_comments: allows_comments, - normalized_source: canonical, - root_kind: json_root_kind(parsed), - owners: collect_json_owners(parsed) - } { ok: true, diagnostics: [], - analysis: analysis + analysis: { + dialect: dialect, + allows_comments: dialect == 'jsonc', + root_kind: json_analysis_root_kind(analysis), + owners: collect_file_analysis_owners(analysis) + }, + policies: [] } - rescue JSON::ParserError => e + rescue TreeHaver::Error, StandardError => e parse_failure(e.message) end @@ -110,35 +133,25 @@ def match_json_owners(template, destination) Ast::Merge::OwnerSelection.match_by_path(template, destination) end - def merge_json(template_source, destination_source, dialect) - template_result = parse_json(template_source, dialect) + def merge_json(template_source, destination_source, dialect, backend: nil) + requested = requested_json_backend_id(backend) + unless available_json_backends.any? { |backend_ref| backend_ref.id == requested } + return unsupported_feature_result("Unsupported JSON backend #{requested}.") + end + + template_result = parse_json(template_source, dialect, backend: requested) return { ok: false, diagnostics: template_result[:diagnostics] } unless template_result[:ok] - destination_result = parse_json(destination_source, dialect) + destination_result = parse_json(destination_source, dialect, backend: requested) if destination_result[:ok] return { ok: true, diagnostics: [], - output: merge_json_sources(template_source, destination_source), + output: TreeHaver.with_backend(requested) { merge_json_sources(template_source, destination_source) }, policies: [DESTINATION_WINS_ARRAY_POLICY] } end - fallback_source = try_destination_trailing_comma_fallback(destination_source) - if fallback_source - retried = parse_json(fallback_source, dialect) - if retried[:ok] - return { - ok: true, - diagnostics: [ - fallback_applied('stripped trailing commas from destination before retrying json merge.') - ], - output: merge_json_sources(template_source, fallback_source), - policies: [DESTINATION_WINS_ARRAY_POLICY, TRAILING_COMMA_FALLBACK_POLICY] - } - end - end - { ok: false, diagnostics: destination_result[:diagnostics].map do |diagnostic| @@ -158,6 +171,82 @@ def merge_json_sources(template_source, destination_source) end private_class_method :merge_json_sources + def json_value_for_source(source, dialect: 'json', backend: nil) + requested = requested_json_backend_id(backend) + unless available_json_backends.any? { |backend_ref| backend_ref.id == requested } + raise ParseError, "Unsupported JSON backend #{requested}." + end + + raise ParseError, "Trailing commas are not supported for #{dialect}." if detect_trailing_comma(source) + if dialect.to_s != 'jsonc' && detect_json_comments(source) + raise ParseError, "Comments are not supported for #{dialect}." + end + + register_backend! + analysis = TreeHaver.with_backend(requested) { FileAnalysis.new(source) } + unless analysis.valid? + message = analysis.errors.map { |error| error.respond_to?(:message) ? error.message : error.inspect }.join(', ') + raise ParseError, message + end + + json_value_for_node(analysis.root_node) + end + + def json_value_for_node(node) + case node.type.to_s + when 'document' + child = node.semantic_children.first + child ? json_value_for_node(NodeWrapper.new(child, lines: node.lines, source: node.source)) : nil + when 'object' + node.pairs.each_with_object({}) do |pair, object| + key = pair.key_name + next unless key + + object[key] = json_value_for_node(pair.value_node) + end + when 'array' + node.elements.map { |element| json_value_for_node(element) } + when 'string' + decode_json_string_literal(node.text) + when 'number' + parse_json_number(node.text) + when 'true' + true + when 'false' + false + when 'null' + nil + end + end + + def decode_json_string_literal(text) + literal = text.to_s + literal = literal[1...-1] if literal.start_with?('"') && literal.end_with?('"') + literal.gsub(%r{\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4})}) do |escape| + case escape + when '\\"' then '"' + when '\\\\' then '\\' + when '\\/' then '/' + when '\\b' then "\b" + when '\\f' then "\f" + when '\\n' then "\n" + when '\\r' then "\r" + when '\\t' then "\t" + else + [escape[2..].to_i(16)].pack('U') + end + end + end + private_class_method :decode_json_string_literal + + def parse_json_number(text) + number = text.to_s + return number.to_f if number.match?(/[.eE]/) + + number.to_i + end + private_class_method :parse_json_number + def parse_failure(message) { ok: false, @@ -166,15 +255,29 @@ def parse_failure(message) end private_class_method :parse_failure - def unsupported_jsonc_language_pack_result - { - ok: false, - diagnostics: [ - unsupported_feature('tree-sitter-language-pack json parsing currently supports only the json dialect.') - ] - } + def requested_json_backend_id(backend) + return backend.to_s unless backend.to_s.empty? + + current = TreeHaver.current_backend_id + return current if json_backend_available_for_analysis?(current) + + available_json_backends.find do |backend_ref| + json_backend_available_for_analysis?(backend_ref.id) + end&.id || TREE_SITTER_BACKEND.id end - private_class_method :unsupported_jsonc_language_pack_result + private_class_method :requested_json_backend_id + + def json_backend_available_for_analysis?(backend_id) + register_backend! + registrations = TreeHaver.registered_languages(:json) + case backend_id.to_s + when TREE_SITTER_BACKEND.id + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + else + false + end + end + private_class_method :json_backend_available_for_analysis? def parse_error(message) { severity: 'error', category: 'parse_error', message: message } @@ -186,57 +289,51 @@ def unsupported_feature(message) end private_class_method :unsupported_feature - def fallback_applied(message) - { severity: 'warning', category: 'fallback_applied', message: message } + def unsupported_feature_result(message) + { ok: false, diagnostics: [unsupported_feature(message)], policies: [] } end - private_class_method :fallback_applied + private_class_method :unsupported_feature_result - def json_root_kind(value) - return 'object' if value.is_a?(Hash) - return 'array' if value.is_a?(Array) + def json_analysis_root_kind(analysis) + root = analysis.root_object || analysis.root_node + return 'object' if root&.object? + return 'array' if root&.array? 'scalar' end - private_class_method :json_root_kind + private_class_method :json_analysis_root_kind + + def collect_file_analysis_owners(analysis) + root = analysis.root_object || analysis.root_node + return [] unless root - def collect_json_owners(value, path = '') - if value.is_a?(Hash) - value.keys.sort.flat_map do |key| - next_path = "#{path}/#{key}" - [{ path: next_path, owner_kind: 'member', match_key: key }] + collect_json_owners(value[key], next_path) + collect_json_node_owners(root, '') + .sort_by { |owner| owner.fetch(:path) } + end + private_class_method :collect_file_analysis_owners + + def collect_json_node_owners(node, path) + if node.object? + node.pairs.flat_map do |pair| + key = pair.key_name + next [] unless key + + owner_path = "#{path}/#{key}" + value = pair.value_node + [{ path: owner_path, owner_kind: 'member', match_key: key }] + + (value ? collect_json_node_owners(value, owner_path) : []) end - elsif value.is_a?(Array) - value.each_with_index.flat_map do |item, index| - next_path = "#{path}/#{index}" - [{ path: next_path, owner_kind: 'element' }] + collect_json_owners(item, next_path) + elsif node.array? + node.elements.each_with_index.flat_map do |element, index| + owner_path = "#{path}/#{index}" + [{ path: owner_path, owner_kind: 'element' }] + + collect_json_node_owners(element, owner_path) end else [] end end - private_class_method :collect_json_owners - - def merge_json_values(template, destination) - if template.is_a?(Hash) && destination.is_a?(Hash) - ordered_merge_keys(template, destination).each_with_object({}) do |key, merged| - merged[key] = if !template.key?(key) - destination[key] - elsif !destination.key?(key) - template[key] - else - merge_json_values(template[key], destination[key]) - end - end - else - destination - end - end - private_class_method :merge_json_values - - def ordered_merge_keys(template, destination) - template.keys + destination.keys.reject { |key| template.key?(key) } - end - private_class_method :ordered_merge_keys + private_class_method :collect_json_node_owners def detect_trailing_comma(source) state = scanner_state @@ -257,142 +354,17 @@ def detect_trailing_comma(source) end private_class_method :detect_trailing_comma - def strip_json_comments(source) - result = +'' - state = scanner_state - index = 0 - while index < source.length - char = source[index] - next_char = source[index + 1] - - if state[:in_line_comment] - if char == "\n" - state[:in_line_comment] = false - result << "\n" - end - index += 1 - next - end - - if state[:in_block_comment] - if char == '*' && next_char == '/' - state[:in_block_comment] = false - index += 2 - next - end - index += 1 - next - end - - if state[:in_string] - result << char - if state[:escaped] - state[:escaped] = false - elsif char == '\\' - state[:escaped] = true - elsif char == '"' - state[:in_string] = false - end - index += 1 - next - end - - if char == '"' - state[:in_string] = true - result << char - index += 1 - next - end - - if char == '/' && next_char == '/' - state[:in_line_comment] = true - index += 2 - next - end - - if char == '/' && next_char == '*' - state[:in_block_comment] = true - index += 2 - next - end - - result << char - index += 1 - end - result - end - private_class_method :strip_json_comments - - def try_destination_trailing_comma_fallback(source) - stripped = strip_trailing_commas(source) - return nil if stripped == source - - stripped - end - private_class_method :try_destination_trailing_comma_fallback - - def strip_trailing_commas(source) - result = +'' + def detect_json_comments(source) state = scanner_state source.each_char.with_index do |char, index| next_char = source[index + 1] + return true if !state[:in_string] && char == '/' && %w[/ *].include?(next_char) - if state[:in_line_comment] - result << char - state[:in_line_comment] = false if char == "\n" - next - end - - if state[:in_block_comment] - result << char - if char == '*' && next_char == '/' - result << next_char - state[:in_block_comment] = false - end - next - end - - if state[:in_string] - result << char - if state[:escaped] - state[:escaped] = false - elsif char == '\\' - state[:escaped] = true - elsif char == '"' - state[:in_string] = false - end - next - end - - if char == '"' - state[:in_string] = true - result << char - next - end - - if char == '/' && next_char == '/' - state[:in_line_comment] = true - result << char - next - end - - if char == '/' && next_char == '*' - state[:in_block_comment] = true - result << char - next - end - - if char == ',' - lookahead = source[(index + 1)..] - trimmed = lookahead&.lstrip - next if trimmed&.start_with?(']', '}') - end - - result << char + advance_scanner_state(state, char, next_char) end - result + false end - private_class_method :strip_trailing_commas + private_class_method :detect_json_comments def scanner_state { diff --git a/gems/json-merge/lib/json/merge/file_analysis.rb b/gems/json-merge/lib/json/merge/file_analysis.rb index 2f0a07a14..81cad85b6 100644 --- a/gems/json-merge/lib/json/merge/file_analysis.rb +++ b/gems/json-merge/lib/json/merge/file_analysis.rb @@ -22,7 +22,7 @@ def initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: @lines = source.lines.map(&:chomp) @freeze_token = freeze_token @signature_generator = signature_generator - @parser_path = parser_path || self.class.find_parser_path + @parser_path = parser_path @errors = [] @comment_tracker = CommentTracker.new(source) @@ -202,30 +202,27 @@ def root_merge_node def parse_json # TreeHaver handles backend selection against the grammar Json::Merge # has already registered during bootstrap. - parser = TreeHaver.parser_for(:json, library_path: @parser_path) + parser = if @parser_path + TreeHaver.parser_for(:json, library_path: @parser_path) + else + TreeHaver.parser_for(:json) + end @ast = parser.parse(@source) collect_parse_errors(@ast.root_node) if @ast&.root_node - parse_synthetic_json(@errors.dup) unless @errors.empty? rescue TreeHaver::Error => e - parse_synthetic_json(e) + @errors << e + @ast = nil rescue StandardError => e - parse_synthetic_json(e) - end - - def parse_synthetic_json(original_error) - normalized = Json::Merge.send(:strip_json_comments, @source) - JSON.parse(Json::Merge.send(:strip_trailing_commas, normalized)) - @errors = [] - @ast = SyntheticParser.new(@source).parse - rescue StandardError - @errors.concat(Array(original_error)) + @errors << e @ast = nil end def collect_parse_errors(node, found_errors = []) - if node.type.to_s == 'ERROR' || (node.respond_to?(:missing?) && node.missing?) + if node.type.to_s == 'ERROR' || + (node.respond_to?(:has_error?) && node.has_error?) || + (node.respond_to?(:missing?) && node.missing?) found_errors << { type: node.type.to_s, start_point: node.respond_to?(:start_point) ? node.start_point : nil, diff --git a/gems/json-merge/lib/json/merge/node_wrapper.rb b/gems/json-merge/lib/json/merge/node_wrapper.rb index 9ee8d23b4..d1fdde691 100644 --- a/gems/json-merge/lib/json/merge/node_wrapper.rb +++ b/gems/json-merge/lib/json/merge/node_wrapper.rb @@ -40,7 +40,7 @@ def comment? def key_name return unless pair? - key_node = find_child_by_field('key') + key_node = find_child_by_field('key') || semantic_children.first return unless key_node node_text(key_node)&.gsub(/\A"|"\z/, '') @@ -49,7 +49,7 @@ def key_name def value_node return unless pair? - value = find_child_by_field('value') + value = find_child_by_field('value') || semantic_children[1] return unless value NodeWrapper.new(value, lines: @lines, source: @source) @@ -153,6 +153,17 @@ def find_child_by_type(type_name) nil end + def semantic_children + return [] unless @node.respond_to?(:each) + + @node.each.filter_map do |child| + child_type = child.type.to_s + next if %w[comment , : { } [ ]].include?(child_type) + + child + end + end + protected def wrap_child(child) diff --git a/gems/json-merge/lib/json/merge/synthetic_parser.rb b/gems/json-merge/lib/json/merge/synthetic_parser.rb deleted file mode 100644 index 7f7c35d07..000000000 --- a/gems/json-merge/lib/json/merge/synthetic_parser.rb +++ /dev/null @@ -1,223 +0,0 @@ -# frozen_string_literal: true - -module Json - module Merge - class SyntheticParser - Point = Struct.new(:row, :column, keyword_init: true) do - def [](key) - public_send(key) - end - end - - class Tree - attr_reader :root_node - - def initialize(root_node) - @root_node = root_node - end - end - - class Node - attr_reader :type, :start_byte, :end_byte, :source - attr_accessor :parent - - def initialize(type, start_byte:, end_byte:, source:, children: [], fields: {}) - @type = type.to_s - @start_byte = start_byte - @end_byte = end_byte - @source = source - @children = children - @fields = fields - @children.each { |child| child.parent = self } - @fields.each_value { |child| child.parent = self } - end - - def each(&block) - return @children.each unless block - - @children.each(&block) - end - - def child_by_field_name(name) - @fields[name.to_s] - end - - def text - @source.byteslice(@start_byte...@end_byte).to_s - end - alias to_s text - - def start_point - point_for(@start_byte) - end - - def end_point - point_for(@end_byte) - end - - def missing? - false - end - - def has_error? - false - end - - private - - def point_for(byte) - prefix = @source.byteslice(0...byte).to_s - lines = prefix.split("\n", -1) - Point.new(row: lines.length - 1, column: lines.last.to_s.bytesize) - end - end - - def initialize(source) - @source = source - @index = 0 - end - - def parse - skip_ignored - value = parse_value - skip_ignored - Tree.new(Node.new('document', start_byte: 0, end_byte: @source.bytesize, source: @source, children: [value])) - end - - private - - def parse_value - skip_ignored - case current_char - when '{' - parse_object - when '[' - parse_array - when '"' - parse_string - when 't' - parse_literal('true') - when 'f' - parse_literal('false') - when 'n' - parse_literal('null') - else - parse_number - end - end - - def parse_object - start = @index - @index += 1 - pairs = [] - loop do - skip_ignored - break if consume?('}') - - pairs << parse_pair - skip_ignored - consume?(',') - end - Node.new('object', start_byte: start, end_byte: @index, source: @source, children: pairs) - end - - def parse_pair - start = @index - key = parse_string - skip_ignored - consume?(':') - value = parse_value - Node.new( - 'pair', - start_byte: start, - end_byte: value.end_byte, - source: @source, - children: [key, value], - fields: { 'key' => key, 'value' => value } - ) - end - - def parse_array - start = @index - @index += 1 - elements = [] - loop do - skip_ignored - break if consume?(']') - - elements << parse_value - skip_ignored - consume?(',') - end - Node.new('array', start_byte: start, end_byte: @index, source: @source, children: elements) - end - - def parse_string - start = @index - @index += 1 - escaped = false - while @index < @source.bytesize - char = current_char - @index += 1 - if escaped - escaped = false - elsif char == '\\' - escaped = true - elsif char == '"' - break - end - end - Node.new('string', start_byte: start, end_byte: @index, source: @source) - end - - def parse_number - start = @index - @index += 1 while @index < @source.bytesize && current_char.match?(/[0-9eE+\-.]/) - Node.new('number', start_byte: start, end_byte: @index, source: @source) - end - - def parse_literal(literal) - start = @index - @index += literal.bytesize - Node.new(literal, start_byte: start, end_byte: @index, source: @source) - end - - def skip_ignored - loop do - skip_whitespace - if current_char == '/' && peek_char == '/' - @index += 2 - @index += 1 while @index < @source.bytesize && current_char != "\n" - next - end - if current_char == '/' && peek_char == '*' - @index += 2 - @index += 1 while @index < @source.bytesize && !(current_char == '*' && peek_char == '/') - @index += 2 if @index < @source.bytesize - next - end - break - end - end - - def skip_whitespace - @index += 1 while @index < @source.bytesize && current_char.match?(/\s/) - end - - def consume?(char) - return false unless current_char == char - - @index += 1 - true - end - - def current_char - @source.byteslice(@index, 1) - end - - def peek_char - @source.byteslice(@index + 1, 1) - end - end - end -end diff --git a/gems/json-merge/spec/fixtures_integration_spec.rb b/gems/json-merge/spec/fixtures_integration_spec.rb index 8196ce0bd..f17bce414 100644 --- a/gems/json-merge/spec/fixtures_integration_spec.rb +++ b/gems/json-merge/spec/fixtures_integration_spec.rb @@ -47,7 +47,47 @@ def json_ready(value) expect(json_ready(result[:diagnostics])).to eq(json_ready(fixture.dig(:expected, :diagnostics))) end - it 'analyzes devcontainer-style JSONC with comments and trailing commas through the synthetic fallback' do + it 'exposes JSON TreeHaver backend availability and plan context' do + expect(json_ready(described_class.available_json_backends.map(&:to_h))).to eq( + [{ 'id' => 'kreuzberg-language-pack', 'family' => 'tree-sitter' }] + ) + + profile = described_class.json_backend_feature_profile + expect(profile[:backend]).to eq('kreuzberg-language-pack') + expect(json_ready(profile[:backend_ref])).to eq( + { 'id' => 'kreuzberg-language-pack', 'family' => 'tree-sitter' } + ) + + expect(json_ready(described_class.json_plan_context.dig(:feature_profile))).to include( + 'backend' => 'kreuzberg-language-pack', + 'supports_dialects' => true + ) + end + + it 'parses through an explicit JSON TreeHaver backend and rejects unsupported backends' do + fixture = json_fixture('structure_json') + result = described_class.parse_json( + fixture[:source], + fixture[:dialect], + backend: 'kreuzberg-language-pack' + ) + unsupported = described_class.parse_json(fixture[:source], fixture[:dialect], backend: :direct_json) + + expect(result[:ok]).to be(true) + expect(unsupported[:ok]).to be(false) + expect(unsupported.dig(:diagnostics, 0, :category)).to eq('unsupported_feature') + end + + it 'rejects comments in strict JSON without rejecting comment-like string content' do + strict_result = described_class.parse_json("{\n // nope\n \"name\": \"Ruby\"\n}\n", 'json') + string_result = described_class.parse_json("{\"url\":\"https://example.test/path\"}\n", 'json') + + expect(strict_result[:ok]).to be(false) + expect(strict_result.dig(:diagnostics, 0, :message)).to eq('Comments are not supported for json.') + expect(string_result[:ok]).to be(true) + end + + it 'fails closed for JSONC analysis when no TreeHaver JSON backend is available' do source = <<~JSON { // devcontainer files commonly use JSONC comments. @@ -62,8 +102,9 @@ def json_ready(value) analysis = described_class::FileAnalysis.new(source) - expect(analysis).to be_valid - expect(analysis.root_object).not_to be_nil + expect(analysis).not_to be_valid + expect(analysis.root_object).to be_nil + expect(analysis.errors).not_to be_empty end it 'conforms to the structure fixtures' do @@ -121,11 +162,10 @@ def json_ready(value) fallback_fixture = json_fixture('fallback') fallback_result = described_class.merge_json(fallback_fixture[:template], fallback_fixture[:destination], 'json') - expect(fallback_result[:ok]).to eq(fallback_fixture.dig(:expected, :ok)) - expect(fallback_result[:output]).to eq(fallback_fixture.dig(:expected, :output)) + expect(fallback_result[:ok]).to be(false) expect( json_ready(fallback_result[:diagnostics].map { |diagnostic| diagnostic.slice(:severity, :category) }) - ).to eq(json_ready(fallback_fixture.dig(:expected, :diagnostics))) + ).to eq(json_ready([{ severity: 'error', category: 'destination_parse_error' }])) end it 'records emitter source provenance line metadata for raw source rendering' do @@ -177,18 +217,11 @@ def json_ready(value) JSON end - it 'conforms to the language-pack adapter fixture and shared family feature profile fixture' do - adapter_fixture = json_fixture('tree_sitter_adapter') - adapter_fixture[:cases].each do |test_case| - result = described_class.parse_json_with_language_pack(test_case[:source], test_case[:dialect]) - expect(result[:ok]).to eq(test_case.dig(:expected, :ok)) - expect( - json_ready(Array(result[:diagnostics]).map { |diagnostic| diagnostic.slice(:severity, :category) }) - ).to eq(json_ready(test_case.dig(:expected, :diagnostics).map { |diagnostic| - diagnostic.slice(:severity, :category) - })) - end + it 'conforms to the shared family feature profile fixture' do + expected_profile = family_profile_fixture[:feature_profile].dup + expected_profile[:supported_policies] = + expected_profile[:supported_policies].reject { |policy| policy[:surface] == 'fallback' } - expect(json_ready(described_class.json_feature_profile)).to eq(json_ready(family_profile_fixture[:feature_profile])) + expect(json_ready(described_class.json_feature_profile)).to eq(json_ready(expected_profile)) end end diff --git a/gems/kettle-jem/.github/workflows/coverage.yml b/gems/kettle-jem/.github/workflows/coverage.yml index 18002d709..e974040b9 100644 --- a/gems/kettle-jem/.github/workflows/coverage.yml +++ b/gems/kettle-jem/.github/workflows/coverage.yml @@ -79,6 +79,16 @@ jobs: if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }}@current via ${{ matrix.exec_cmd }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.github/workflows/current.yml b/gems/kettle-jem/.github/workflows/current.yml index bfb959ac7..ff24160f1 100644 --- a/gems/kettle-jem/.github/workflows/current.yml +++ b/gems/kettle-jem/.github/workflows/current.yml @@ -70,5 +70,15 @@ jobs: if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.github/workflows/dep-heads.yml b/gems/kettle-jem/.github/workflows/dep-heads.yml index 7f5dc90d1..d632a147a 100644 --- a/gems/kettle-jem/.github/workflows/dep-heads.yml +++ b/gems/kettle-jem/.github/workflows/dep-heads.yml @@ -76,6 +76,16 @@ jobs: if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via Appraisal and ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} @@ -115,6 +125,16 @@ jobs: bundler: ${{ matrix.bundler }} bundler-cache: true + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec ${{ matrix.exec_cmd }} @@ -164,6 +184,16 @@ jobs: if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via Appraisal and ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.github/workflows/heads.yml b/gems/kettle-jem/.github/workflows/heads.yml index 1deb50f66..95b0f24a4 100644 --- a/gems/kettle-jem/.github/workflows/heads.yml +++ b/gems/kettle-jem/.github/workflows/heads.yml @@ -75,6 +75,16 @@ jobs: if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} @@ -123,6 +133,16 @@ jobs: if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} @@ -171,6 +191,16 @@ jobs: if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.github/workflows/jruby.yml b/gems/kettle-jem/.github/workflows/jruby.yml index 0accd9f85..c92a3d1d7 100644 --- a/gems/kettle-jem/.github/workflows/jruby.yml +++ b/gems/kettle-jem/.github/workflows/jruby.yml @@ -27,7 +27,7 @@ concurrency: jobs: test: - if: "github.event_name != 'push' || (!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')) && (github.event_name != 'pull_request' || startsWith(github.head_ref, 'engines/') || startsWith(github.head_ref, 'jruby/'))" + if: "(github.event_name != 'push' || (!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]'))) && (github.event_name != 'pull_request' || startsWith(github.head_ref, 'engines/') || startsWith(github.head_ref, 'jruby/'))" name: Specs ${{ matrix.ruby }}@${{ matrix.appraisal }} runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} @@ -74,6 +74,16 @@ jobs: if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' && !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-jruby-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-jruby-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-jruby-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.github/workflows/truffle.yml b/gems/kettle-jem/.github/workflows/truffle.yml index 99e175c5f..b41ba5a5b 100644 --- a/gems/kettle-jem/.github/workflows/truffle.yml +++ b/gems/kettle-jem/.github/workflows/truffle.yml @@ -27,7 +27,7 @@ concurrency: jobs: test: - if: "github.event_name != 'push' || (!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')) && (github.event_name != 'pull_request' || startsWith(github.head_ref, 'engines/') || startsWith(github.head_ref, 'truffleruby/'))" + if: "(github.event_name != 'push' || (!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]'))) && (github.event_name != 'pull_request' || startsWith(github.head_ref, 'engines/') || startsWith(github.head_ref, 'truffleruby/'))" name: Specs ${{ matrix.ruby }}@${{ matrix.appraisal }} runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} @@ -74,6 +74,16 @@ jobs: if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' && !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} install + - name: Restore RSpec status log + if: "${{!env.ACT}}" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .rspec_status + key: rspec-status-truffle-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}} + restore-keys: | + rspec-status-truffle-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}- + rspec-status-truffle-${{matrix.ruby}}-${{matrix.appraisal}}- + - name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }} if: ${{ !env.ACT }} run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }} diff --git a/gems/kettle-jem/.kettle-drift.lock b/gems/kettle-jem/.kettle-drift.lock index ac6ca38b0..bc1265c3c 100644 --- a/gems/kettle-jem/.kettle-drift.lock +++ b/gems/kettle-jem/.kettle-drift.lock @@ -1,11 +1,40 @@ { + "[[profiles.textconv-normalized.attributes]]\ndiff = \"smorg-json-textconv\"": [ + { + "file": ".structuredmerge/git-drivers.toml", + "lines": [ + 19, + 22, + 34, + 37 + ] + } + ], + "[[profiles.textconv-normalized.attributes]]\ndiff = \"smorg-toml-textconv\"": [ + { + "file": ".structuredmerge/git-drivers.toml", + "lines": [ + 31, + 40 + ] + } + ], + "[[profiles.textconv-normalized.attributes]]\ndiff = \"smorg-yaml-textconv\"": [ + { + "file": ".structuredmerge/git-drivers.toml", + "lines": [ + 25, + 28 + ] + } + ], "appraisal: \"dep-heads\"\nexec_cmd: \"kettle-test\"": [ { "file": ".github/workflows/dep-heads.yml", "lines": [ 44, - 95, - 134 + 105, + 154 ] } ], @@ -14,8 +43,8 @@ "file": ".github/workflows/heads.yml", "lines": [ 43, - 94, - 142 + 104, + 162 ] } ], @@ -24,26 +53,27 @@ "file": ".github/workflows/heads.yml", "lines": [ 44, - 95, - 143 + 105, + 163 ] } ], - "if: ${{ !env.ACT }}\nuses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0": [ + "scope = \"global\"\nvalue = \"true\"": [ { - "file": ".github/workflows/dep-heads.yml", + "file": ".structuredmerge/git-drivers.toml", "lines": [ - 51, - 104, - 142 + 49, + 57, + 65 ] - }, + } + ], + "value = \"true\"\n[[profiles.textconv-normalized.git_config]]": [ { - "file": ".github/workflows/heads.yml", + "file": ".structuredmerge/git-drivers.toml", "lines": [ 50, - 101, - 149 + 58 ] } ] diff --git a/gems/kettle-jem/.rubocop_gradual.lock b/gems/kettle-jem/.rubocop_gradual.lock index b09c227c5..0334d6fb6 100644 --- a/gems/kettle-jem/.rubocop_gradual.lock +++ b/gems/kettle-jem/.rubocop_gradual.lock @@ -1,5 +1,5 @@ { - "kettle-jem.gemspec:1783780734": [ + "kettle-jem.gemspec:1742431759": [ [19, 32, 10, "Gemspec/RequiredRubyVersion: `required_ruby_version` and `TargetRubyVersion` (3.2, which may be specified in .rubocop.yml) should be equal.", 3888670706], [90, 3, 70, "Gemspec/DependencyVersion: Dependency version specification is required.", 4023754366], [91, 3, 65, "Gemspec/DependencyVersion: Dependency version specification is required.", 1638532368], diff --git a/gems/kettle-jem/.structuredmerge/git-drivers.toml b/gems/kettle-jem/.structuredmerge/git-drivers.toml index 07ef3a40f..5eabc7c79 100644 --- a/gems/kettle-jem/.structuredmerge/git-drivers.toml +++ b/gems/kettle-jem/.structuredmerge/git-drivers.toml @@ -1,86 +1,66 @@ -version = 1 driver_namespace = "smorg" - +version = 1 [profiles.builtin-diff] description = "Use Git built-in hunk and word-diff drivers where available." - [[profiles.builtin-diff.attributes]] -pattern = "*.rb" diff = "ruby" - +pattern = "*.rb" [profiles.semantic-diff] description = "Use StructuredMerge external diff drivers for local CLI diffs." - [[profiles.semantic-diff.attributes]] -pattern = "*.rb" diff = "smorg-rb" - +pattern = "*.rb" [[profiles.semantic-diff.git_config]] -scope = "global" key = "diff.smorg-rb.command" +scope = "global" value = "smorg-rb diff-driver" - [profiles.textconv-normalized] description = "Use one-way normalized text projections for package/config review." - [[profiles.textconv-normalized.attributes]] -pattern = "*.json" diff = "smorg-json-textconv" - +pattern = "*.json" [[profiles.textconv-normalized.attributes]] -pattern = "*.jsonc" diff = "smorg-json-textconv" - +pattern = "*.jsonc" [[profiles.textconv-normalized.attributes]] -pattern = "*.yml" diff = "smorg-yaml-textconv" - +pattern = "*.yml" [[profiles.textconv-normalized.attributes]] -pattern = "*.yaml" diff = "smorg-yaml-textconv" - +pattern = "*.yaml" [[profiles.textconv-normalized.attributes]] -pattern = "*.toml" diff = "smorg-toml-textconv" - +pattern = "*.toml" [[profiles.textconv-normalized.attributes]] -pattern = "package.json" diff = "smorg-json-textconv" - +pattern = "package.json" [[profiles.textconv-normalized.attributes]] -pattern = "package-lock.json" diff = "smorg-json-textconv" - +pattern = "package-lock.json" [[profiles.textconv-normalized.attributes]] -pattern = "Cargo.toml" diff = "smorg-toml-textconv" - +pattern = "Cargo.toml" [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-json-textconv.textconv" +scope = "global" value = "smorg-rb textconv --format json" - [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-json-textconv.cachetextconv" +scope = "global" value = "true" - [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-yaml-textconv.textconv" +scope = "global" value = "smorg-rb textconv --format yaml" - [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-yaml-textconv.cachetextconv" +scope = "global" value = "true" - [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-toml-textconv.textconv" +scope = "global" value = "smorg-rb textconv --format toml" - [[profiles.textconv-normalized.git_config]] -scope = "global" key = "diff.smorg-toml-textconv.cachetextconv" +scope = "global" value = "true" diff --git a/gems/kettle-jem/CHANGELOG.md b/gems/kettle-jem/CHANGELOG.md index 515eb2c91..d92efeab4 100644 --- a/gems/kettle-jem/CHANGELOG.md +++ b/gems/kettle-jem/CHANGELOG.md @@ -38,6 +38,10 @@ Please file a bug if you notice a violation of semantic versioning. - Added the repo-local `bin/kettle-jem-workflow-pins` maintenance script to update the GitHub Actions SHA pin index used by generated workflow templates via `kettle-gha-sha-pins`. +- Generated local Gemfile templates now document why `nomono` is explicitly + activated before requiring `nomono/bundler`. +- Added the repo-local `bin/kettle-jem-deps-floor` maintenance script to scan + dependency-bearing kettle-jem templates and update their dependency floors. - `kettle-jem install` now generates a curated `bin/appraisal` binstub for the `appraisal2` executable. - Added a default-off `readme.badges.fossa` template option for managed FOSSA @@ -231,7 +235,7 @@ Please file a bug if you notice a violation of semantic versioning. - Generated main Gemfiles now require `nomono` >= 1.0.6. - Generated templating local Gemfiles now only use `TSLP_DEV` for local `tree_sitter_language_pack` path overrides and no longer derive that path - from `SMORG_RB_DEV`. + from `STRUCTUREDMERGE_DEV`. - Generated gemspecs now require `version_gem` >= 1.1.14. - Generated gemspecs now require `gitmoji-regex` >= 2.0.4. - Generated documentation Gemfiles now require `yaml-converter` >= 0.2.3. @@ -790,7 +794,7 @@ Please file a bug if you notice a violation of semantic versioning. without requiring unreleased `kettle-drift` in every generated gemspec. - Added `kettle-drift` to generated templating Gemfiles, resolved remotely in templating mode and via `KETTLE_RB_DEV` locally, separate from the - `SMORG_RB_DEV` StructuredMerge local gem set. + `STRUCTUREDMERGE_DEV` StructuredMerge local gem set. - Refreshed generated README metadata blocks after template README merging so version-derived gemspec metadata such as `source_code_uri` does not stay stale. - Added `yard-yaml` to generated local documentation Gemfiles so local diff --git a/gems/kettle-jem/CONTRIBUTING.md b/gems/kettle-jem/CONTRIBUTING.md index 3267ae435..6ce65e81f 100644 --- a/gems/kettle-jem/CONTRIBUTING.md +++ b/gems/kettle-jem/CONTRIBUTING.md @@ -30,6 +30,20 @@ Follow these instructions: 8. Create new Pull Request. 9. Announce it in the channel for this org in the [Discord][✉️discord-invite]! +## Ruby engine CI branches + +Pull requests run MRI workflows by default. JRuby and TruffleRuby workflows are +available by branch naming convention so ordinary PRs do not spend CI time on +alternate Ruby engines. + +- Use a branch named `jruby/*` to run JRuby workflows for a pull request. +- Use a branch named `truffleruby/*` to run TruffleRuby workflows for a pull + request. +- Use a branch named `engines/*` to run both JRuby and TruffleRuby workflows for + a pull request. + +Pushes to the default branch continue to run the configured engine workflows. + ## Executables vs Rake tasks Executables shipped by dependencies, such as kettle-dev, and stone_checksums, are available diff --git a/gems/kettle-jem/Gemfile b/gems/kettle-jem/Gemfile index a1579321e..c7b6554af 100644 --- a/gems/kettle-jem/Gemfile +++ b/gems/kettle-jem/Gemfile @@ -92,7 +92,7 @@ if direct_sibling_gems.any? && end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? # Debugging diff --git a/gems/kettle-jem/Gemfile.lock b/gems/kettle-jem/Gemfile.lock index ad7a65291..bd7918522 100644 --- a/gems/kettle-jem/Gemfile.lock +++ b/gems/kettle-jem/Gemfile.lock @@ -40,7 +40,23 @@ PATH specs: ast-crispr-ruby-prism (7.1.0) ast-crispr (= 7.1.0) - prism (>= 1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) PATH @@ -52,6 +68,13 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge specs: @@ -60,6 +83,13 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge specs: @@ -84,6 +114,14 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge specs: @@ -116,6 +154,22 @@ PATH markly (~> 0.9) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge specs: @@ -150,6 +204,27 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge specs: @@ -167,6 +242,14 @@ PATH tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + PATH remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge specs: @@ -175,25 +258,35 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) - appraisal2-rubocop (0.2.3) + appraisal2-rubocop (1.0.0) appraisal2 (>= 3.1.4) rubocop (>= 1.0) - version_gem (~> 1.1, >= 1.1.13) + version_gem (~> 1.1, >= 1.1.14) ast (2.4.3) - ast-crispr (7.1.0) - ast-merge (= 7.1.0) - service_actor (~> 3.9) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -261,7 +354,7 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) @@ -269,7 +362,7 @@ GEM kettle-drift (1.0.5) version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) - kettle-soup-cover (3.0.0) + kettle-soup-cover (3.0.1) simplecov (>= 1.0) simplecov-cobertura (>= 4.0) simplecov-console (~> 0.9, >= 0.9.5) @@ -318,6 +411,9 @@ GEM racc (1.8.1) rainbow (3.1.1) rake (13.4.2) + rake-compiler-dock (1.12.0) + rb_sys (0.9.127) + rake-compiler-dock (= 1.12.0) rbs (4.0.3) logger prism (>= 1.6.0) @@ -453,7 +549,7 @@ GEM silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) - simplecov (1.0.1) + simplecov (1.0.2) simplecov-cobertura (4.0.0) rexml simplecov (~> 1.0) @@ -504,13 +600,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) toml-rb (4.2.0) citrus (~> 3.0, > 3.0) racc (~> 1.7) - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) - sorbet-runtime (~> 0.5) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -536,7 +632,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -548,35 +644,42 @@ PLATFORMS x86_64-linux DEPENDENCIES - appraisal2 (~> 3.1, >= 3.1.4) - appraisal2-rubocop (~> 0.2, >= 0.2.3) + appraisal2 (~> 3.2, >= 3.2.0) + appraisal2-rubocop (~> 1.0, >= 1.0.0) + ast-crispr! ast-crispr-markdown-markly! ast-crispr-ruby-prism! ast-merge! + ast-merge-git! + ast-template! bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) cgi (~> 0.5) citrus-toml-merge! commonmarker-merge! debug (>= 1.1) dotenv-merge! - erb (~> 6.0, >= 6.0.4) + erb (~> 6.0, >= 6.0.5) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.4) + go-merge! irb (~> 1.17) json-merge! kettle-drift (~> 1.0, >= 1.0.5) kettle-jem! - kettle-soup-cover (~> 3.0, >= 3.0.0) + kettle-soup-cover (~> 3.0, >= 3.0.1) kettle-test (~> 2.0, >= 2.0.11) - kramdown (~> 2.5, >= 2.5.1) + kramdown (~> 2.5, >= 2.5.2) kramdown-merge! kramdown-parser-gfm (~> 1.1) markdown-merge! markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! prism-merge! psych-merge! rake (~> 13.0) @@ -586,43 +689,51 @@ DEPENDENCIES require_bench (~> 1.0, >= 1.0.4) rubocop-gradual (~> 0.4, >= 0.4.0) rubocop-lts (~> 24.2, >= 24.2.1) - rubocop-lts-rspec (~> 1.0, >= 1.0.4) - rubocop-minitest (~> 0.38, >= 0.38.1) + rubocop-lts-rspec (~> 1.0, >= 1.0.5) + rubocop-minitest (~> 0.39, >= 0.39.1) rubocop-on-rbs (~> 2.0, >= 2.0.0) rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-ruby3_2 (~> 3.0, >= 3.0.6) ruby-merge! ruby-progressbar (~> 1.13) - standard (~> 1.54, >= 1.54.0) + rust-merge! + smorg-rb! + standard (~> 1.56, >= 1.56.0) stone_checksums (~> 1.0, >= 1.0.6) stringio (>= 3.0) toml-merge! tree_haver! - turbo_tests2 (~> 3.1, >= 3.1.14) + tree_sitter_language_pack! + turbo_tests2 (~> 3.2, >= 3.2.0) + typescript-merge! webrick (~> 1.9) yaml-converter (~> 0.2, >= 0.2.3) yaml-merge! - yard (~> 0.9, >= 0.9.44) + yard (~> 0.9, >= 0.9.45) yard-fence (~> 0.9, >= 0.9.6) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) - yard-timekeeper (~> 0.2, >= 0.2.3) + yard-timekeeper (~> 0.2, >= 0.2.4) yard-yaml (~> 0.2, >= 0.2.3) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 - appraisal2-rubocop (0.2.3) sha256=06fd36e7d4e88742193e38d48c196b8d96cff37168bf789405c08a7d771abc2c + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f + appraisal2-rubocop (1.0.0) sha256=b71410fbb014befda5340605a605b7f6f3f012739baf0acc5b4351b592c3258d ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) ast-crispr-markdown-markly (7.1.0) ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 cgi (0.5.2) sha256=61ca30298171190fd4fa0d8018e57ada456eae9b7a2b78526debf7f0a0e6f8bb citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 @@ -649,16 +760,17 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 json-merge (7.1.0) - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae - kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 - kettle-soup-cover (3.0.0) sha256=4d3ed6c714cb88cf148f65934c6a96c976b2281abb3ae443ad0ddf6ac0da875b + kettle-soup-cover (3.0.1) sha256=83ebe2aa099f15781e4796b5faef0dc2720fba48f6b9d34808670b91baf271e4 kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa kramdown-merge (7.1.0) @@ -678,6 +790,8 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 @@ -688,6 +802,8 @@ CHECKSUMS racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rake-compiler-dock (1.12.0) + rb_sys (0.9.127) rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 @@ -728,13 +844,15 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 - simplecov (1.0.1) sha256=419d93c40484159d20b40e26e9a83cdd4c3afa2f3fd443bb8946c301cd658d75 + simplecov (1.0.2) sha256=c6459434efe4b948b46477cc2df2faa73ab365f83a33c7c17f81262f4f7f1244 simplecov-cobertura (4.0.0) sha256=e4fb3159b1ecea545b44f5452a8611305323e78ad23eae8aed35924d072e01ea simplecov-console (0.9.5) sha256=b1108bcfff5f210143e2b8301698c367b01586f20d25a73e95475a5df6fc6ff6 simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_lcov_formatter (0.9.0) sha256=4c1839bb31dcf7a8f7a6474c94ed228aa03b994e9dd5e1965e58b4121b049bed + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -749,12 +867,14 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) toml-merge (7.1.0) toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) sha256=ad6743a373eeac954c1b659b17af3aff1c82918b3ce9c9dc572a7c70ff843cdd + tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 @@ -765,9 +885,10 @@ CHECKSUMS yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/kettle-jem/Rakefile b/gems/kettle-jem/Rakefile index 721ea8c9d..c9b733eba 100644 --- a/gems/kettle-jem/Rakefile +++ b/gems/kettle-jem/Rakefile @@ -6,7 +6,7 @@ # kettle-jem will then preserve content between those markers across template runs. # kettle-jem:unfreeze -# kettle-jem Rakefile v7.1.0 - 2026-07-17 +# kettle-jem Rakefile v7.1.0 - 2026-07-19 # Ruby 2.3 (Safe Navigation) or higher required # # See LICENSE.md for license information. diff --git a/gems/kettle-jem/bin/kettle-jem-deps-floor b/gems/kettle-jem/bin/kettle-jem-deps-floor new file mode 100755 index 000000000..73b744c5f --- /dev/null +++ b/gems/kettle-jem/bin/kettle-jem-deps-floor @@ -0,0 +1,350 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "json" +require "optparse" +require "pathname" + +require_relative "../lib/kettle/jem" + +# Repository-local maintenance tool for updating dependency floors owned by +# kettle-jem templates. +class KettleJemDepsFloor + VALID_UPGRADE_LEVELS = %w[major minor patch].freeze + DEFAULT_UPGRADE_LEVEL = "major" + DEFAULT_PROJECT_ROOT = File.expand_path("..", __dir__) + + SOURCE_GLOBS = [ + "lib/kettle/jem/templates/Appraisal.root.gemfile.example", + "lib/kettle/jem/templates/Appraisals.example", + "lib/kettle/jem/templates/Gemfile.example", + "lib/kettle/jem/templates/gem.gemspec.example", + "lib/kettle/jem/templates/gemfiles/**/*.gemfile.example", + "lib/kettle/jem/templates/shim/Gemfile.example", + "lib/kettle/jem/templates/shim/gem.gemspec.example" + ].freeze + EXTRA_SOURCE_FILES = [ + "lib/kettle/jem.rb" + ].freeze + + def initialize(project_root:, resolver: Kettle::Jem::RubyGemsResolver.new, options: {}) + @project_root = File.expand_path(project_root) + @resolver = resolver + @options = { + write: false, + check: false, + json: false, + upgrade: DEFAULT_UPGRADE_LEVEL + }.merge(options.transform_keys(&:to_sym)) + end + + def self.run(argv = ARGV, out: $stdout, err: $stderr) + options = parse_options(argv) + result = new(project_root: options.delete(:project_root), options: options).run + if options[:json] + out.puts(JSON.pretty_generate(result)) + else + out.puts("deps-floor: #{result.fetch(:updates)} update#{"s" unless result.fetch(:updates) == 1}") + result.fetch(:planned_changes, []).each do |change| + out.puts( + " #{change.fetch(:name)} #{change.fetch(:relative_path)} " \ + "#{change.fetch(:current_pessimistic)}, >= #{change.fetch(:current_floor)} -> " \ + "#{change.fetch(:new_pessimistic)}, >= #{change.fetch(:new_floor)}" + ) + end + end + 0 + rescue OptionParser::ParseError, ArgumentError => error + err.puts(error.message) + err.puts(parser) + 2 + rescue => error + err.puts("#{error.class}: #{error.message}") + 1 + end + + def self.parse_options(argv) + options = { + project_root: DEFAULT_PROJECT_ROOT, + write: false, + check: false, + json: false, + upgrade: DEFAULT_UPGRADE_LEVEL + } + parser.parse!(argv, into: options) + options[:project_root] = argv.shift || DEFAULT_PROJECT_ROOT + raise OptionParser::InvalidArgument, "Expected at most one PROJECT_ROOT" unless argv.empty? + + options + end + + def self.parser + OptionParser.new do |opts| + opts.banner = "Usage: bin/kettle-jem-deps-floor [PROJECT_ROOT] [--json] [--write] [--check] [--upgrade LEVEL]" + opts.on("-w", "--write", "Write updates to kettle-jem template sources.") { |value| value } + opts.on("--check", "Fail when managed dependency floors are stale.") { |value| value } + opts.on("--json", "Print the machine-readable report as JSON.") { |value| value } + opts.on("--upgrade LEVEL", "Upgrade strategy: major, minor, patch (default: #{DEFAULT_UPGRADE_LEVEL})") { |value| value } + end + end + + def run + upgrade = @options.fetch(:upgrade, DEFAULT_UPGRADE_LEVEL).to_s + unless VALID_UPGRADE_LEVELS.include?(upgrade) + raise ArgumentError, "Invalid --upgrade value #{upgrade.inspect}; use one of: #{VALID_UPGRADE_LEVELS.join(", ")}" + end + + records = dependency_records + planned_changes = planned_dependency_changes(records, upgrade) + apply_changes(planned_changes) if @options[:write] && planned_changes.any? + + if @options[:check] && planned_changes.any? + raise "Managed dependency floors are stale; run bin/kettle-jem-deps-floor --write --upgrade #{upgrade}" + end + + { + mode: @options[:write] ? "write" : "dry-run", + check: !!@options[:check], + upgrade: upgrade, + discovered_dependencies: records.map { |record| record.fetch(:name) }.uniq.sort, + updates: planned_changes.length, + updated_dependencies: planned_changes.map { |change| change.fetch(:name) }.uniq.sort, + planned_changes: planned_changes.map { |change| serializable_change(change) } + } + end + + private + + attr_reader :project_root, :resolver + + def dependency_records + dedupe_records(dependency_source_paths.flat_map { |relative_path| dependency_records_for_path(relative_path) }) + end + + def dependency_source_paths + paths = self.class::SOURCE_GLOBS.flat_map do |pattern| + Dir.glob(File.join(project_root, pattern), File::FNM_DOTMATCH).select { |path| File.file?(path) } + end + paths.concat(self.class::EXTRA_SOURCE_FILES.map { |relative_path| File.join(project_root, relative_path) }) + paths.uniq.sort.map { |path| Pathname(path).relative_path_from(Pathname(project_root)).to_s } + end + + def dependency_records_for_path(relative_path) + path = File.join(project_root, relative_path) + content = File.read(path) + [ + *ruby_dependency_records(content, relative_path), + *text_dependency_records(content, relative_path) + ] + end + + def ruby_dependency_records(content, relative_path) + [ + *ruby_call_dependency_records(content, relative_path), + *ruby_requirement_assignment_records(content, relative_path) + ] + end + + def ruby_call_dependency_records(content, relative_path) + Kettle::Jem.ruby_call_records(content, nil).filter_map do |call| + next unless ruby_dependency_call?(call) + + name = Kettle::Jem.ruby_string_argument(call) + next unless real_gem_name?(name) + + requirement_arguments = Array(call.arguments&.arguments).drop(1).select do |argument| + argument.is_a?(::Prism::StringNode) + end + record_from_arguments(relative_path, name, requirement_arguments, source_kind: "ruby") + end + end + + def ruby_dependency_call?(call) + return true if call.receiver.nil? && call.name == :gem + return true if %i[add_dependency add_runtime_dependency add_development_dependency].include?(call.name) + + false + end + + def ruby_requirement_assignment_records(content, relative_path) + result = Kettle::Jem.prism_parse_success(content) + return [] unless result + + result.value.breadth_first_search_all do |node| + node.is_a?(::Prism::LocalVariableWriteNode) && + %i[nomono_requirements nomono_activation_requirements].include?(node.name) + end.filter_map do |node| + values = Array(node.value&.elements).select { |element| element.is_a?(::Prism::StringNode) } + record_from_arguments(relative_path, "nomono", values, source_kind: "ruby") + end + end + + def record_from_arguments(relative_path, name, arguments, source_kind:) + return unless real_gem_name?(name) + + pessimistic = arguments.find { |argument| Kettle::Jem.ruby_static_string_value(argument).to_s.start_with?("~>") } + floor = arguments.find { |argument| Kettle::Jem.ruby_static_string_value(argument).to_s.start_with?(">=") } + return unless pessimistic && floor + + { + relative_path: relative_path, + name: name, + source_kind: source_kind, + current_pessimistic: Kettle::Jem.ruby_static_string_value(pessimistic), + current_floor: Kettle::Jem.ruby_static_string_value(floor), + pessimistic_range: range_for(pessimistic), + floor_range: range_for(floor) + } + end + + def range_for(node) + { + start_offset: node.location.start_offset, + end_offset: node.location.end_offset + } + end + + def text_dependency_records(content, relative_path) + lines = content.lines + lines.each_with_index.filter_map do |line, index| + name = text_dependency_name(line) + next unless real_gem_name?(name) + + current_pessimistic, pessimistic_range = text_requirement_record(content, lines, index, line, "~>") + current_floor, floor_range = text_requirement_record(content, lines, index, line, ">=") + next unless current_pessimistic && current_floor + + { + relative_path: relative_path, + name: name, + source_kind: "text", + current_pessimistic: current_pessimistic, + current_floor: current_floor, + pessimistic_range: pessimistic_range, + floor_range: floor_range + } + end + end + + def text_dependency_name(line) + stripped = line.lstrip + return if stripped.start_with?("#") + return "nomono" if stripped.start_with?("nomono_requirements =", "nomono_activation_requirements =") + + match = stripped.match(/\A(?:gem|spec\.add_dependency|spec\.add_runtime_dependency|spec\.add_development_dependency)\(?\s*"([^"]+)"/) + return match[1] if match + + match = stripped.match(/source:\s*%\(gem "([^"]+)"/) + match && match[1] + end + + def real_gem_name?(name) + name.to_s.match?(/\A[a-zA-Z0-9_.-]+\z/) + end + + def text_requirement_record(content, lines, index, line, operator) + match = line.match(/"#{Regexp.escape(operator)} [^"]+"/) + return unless match + + line_start = lines.take(index).join.bytesize + value = match[0][1...-1] + [ + value, + { + start_offset: line_start + match.begin(0), + end_offset: line_start + match.end(0) + } + ] + end + + def dedupe_records(records) + seen = {} + records.select do |record| + key = [ + record.fetch(:relative_path), + record.fetch(:name), + record.fetch(:pessimistic_range).fetch(:start_offset), + record.fetch(:floor_range).fetch(:start_offset) + ] + next false if seen.include?(key) + + seen[key] = true + true + end + end + + def planned_dependency_changes(records, upgrade) + records.filter_map do |record| + current_floor = floor_version(record.fetch(:current_floor)) + latest = latest_version_for(record.fetch(:name), current_floor, upgrade) + next unless latest && latest > current_floor + + { + **record, + current_floor_version: current_floor, + new_floor_version: latest, + new_pessimistic: pessimistic_requirement_for(latest) + } + end + end + + def latest_version_for(name, current_floor, upgrade) + resolver.versions(name, requirements: requirement_for_upgrade(current_floor, upgrade)).map do |entry| + Gem::Version.new((entry[:number] || entry["number"]).to_s) + end.max + end + + def requirement_for_upgrade(current_floor, upgrade) + major = current_floor.segments.fetch(0) + minor = current_floor.segments.fetch(1, 0) + case upgrade + when "patch" + [">= #{current_floor}", "~> #{major}.#{minor}.0"] + when "minor" + [">= #{current_floor}", "~> #{major}.0"] + else + [">= #{current_floor}"] + end + end + + def floor_version(requirement) + parsed = Gem::Requirement.new(requirement).requirements.find { |operator, _version| operator == ">=" } + raise ArgumentError, "Expected >= requirement, got #{requirement.inspect}" unless parsed + + parsed.last + end + + def pessimistic_requirement_for(version) + segments = version.segments + "~> #{segments.fetch(0)}.#{segments.fetch(1, 0)}" + end + + def apply_changes(changes) + changes.group_by { |change| change.fetch(:relative_path) }.each do |relative_path, path_changes| + path = File.join(project_root, relative_path) + replacements = path_changes.flat_map do |change| + [ + change.fetch(:pessimistic_range).merge(replacement: JSON.generate(change.fetch(:new_pessimistic))), + change.fetch(:floor_range).merge(replacement: JSON.generate(">= #{change.fetch(:new_floor_version)}")) + ] + end + original = File.read(path) + updated = Kettle::Jem.replace_source_offsets(original, replacements) + File.write(path, updated) if updated != original + end + end + + def serializable_change(change) + { + name: change.fetch(:name), + relative_path: change.fetch(:relative_path), + source_kind: change.fetch(:source_kind), + current_pessimistic: change.fetch(:current_pessimistic), + new_pessimistic: change.fetch(:new_pessimistic), + current_floor: change.fetch(:current_floor_version).to_s, + new_floor: change.fetch(:new_floor_version).to_s + } + end +end + +exit(KettleJemDepsFloor.run(ARGV, out: $stdout, err: $stderr)) if $PROGRAM_NAME == __FILE__ diff --git a/gems/kettle-jem/bin/kettle-jem-workflow-pins b/gems/kettle-jem/bin/kettle-jem-workflow-pins index 937b7e433..f27dc1ebf 100755 --- a/gems/kettle-jem/bin/kettle-jem-workflow-pins +++ b/gems/kettle-jem/bin/kettle-jem-workflow-pins @@ -14,7 +14,7 @@ class KettleJemWorkflowPins VALID_UPGRADE_LEVELS = %w[major minor patch].freeze DEFAULT_UPGRADE_LEVEL = "major" DEFAULT_PROJECT_ROOT = File.expand_path("..", __dir__) - PIN_PATTERN = %r{(([-\w.]+/[-\w.]+(?:/[-\w.]+)*)@[0-9a-f]{40}\s*#\s*\S+)} + PIN_PATTERN = %r{(([-\w.]+/[-\w.]+(?:/[-\w.]+)*)@[0-9a-f]{40}[ \t]*#[ \t]*[^\s"',]+)} def initialize(project_root:, env: ENV, options: {}) @project_root = File.expand_path(project_root) diff --git a/gems/kettle-jem/docs/Kettle/Jem/Tasks/InstallTask.html b/gems/kettle-jem/docs/Kettle/Jem/Tasks/InstallTask.html index 7f01e3838..e0fdd8a19 100644 --- a/gems/kettle-jem/docs/Kettle/Jem/Tasks/InstallTask.html +++ b/gems/kettle-jem/docs/Kettle/Jem/Tasks/InstallTask.html @@ -5,9 +5,9 @@ Module: Kettle::Jem::Tasks::InstallTask - + — Documentation by YARD 0.9.44 - + @@ -37,16 +37,16 @@

Module: Kettle::Jem::Tasks::InstallTask - - - + + +

- - - - - - - - + + + + + + + +
Defined in:
lib/kettle/jem/tasks/install_task.rb
- +
- +

Constant Summary collapse

- +
CURATED_BINSTUB_GEMS = - +
%w[appraisal2 rake rbs rspec-core yard kettle-dev kettle-test kettle-soup-cover stone_checksums].freeze
- +
CURATED_BINSTUB_DISCRETE_EXECUTABLES = - +
%w[
   kettle-drift
   yard
 ].freeze
- +
DEFAULT_GIT_DRIVER_DEFINITIONS = - +
[
   {
@@ -137,23 +137,22 @@ 

merge_command: "smorg-rs merge-driver %O %A %B %P" } ].freeze

- +
GIT_DRIVER_LANGUAGE_REGISTRY = - +
DEFAULT_GIT_DRIVER_DEFINITIONS.to_h { |definition| [definition.fetch(:language), definition] }.freeze
- +
BUILTIN_GIT_DIFF_ATTRIBUTES = - +
[
   {path: ".gitattributes", pattern: "*.rb", attributes: {"diff" => "ruby"}},
   {path: ".gitattributes", pattern: "*.go", attributes: {"diff" => "golang"}},
   {path: ".gitattributes", pattern: "*.rs", attributes: {"diff" => "rust"}}
 ].freeze
- +
- @@ -161,2310 +160,2311 @@

- + +

Class Method Summary collapse

- - + +

Class Method Details

- +

- - .bin_setup_command(project_root, quiet:) ⇒ Object - - + .bin_setup_command(project_root, quiet:) ⇒ Object + + + + -

@@ -2489,16 +2489,16 @@

- +

- - .binstub_files(bin_dir) ⇒ Object - - + .binstub_files(bin_dir) ⇒ Object + + + + -

@@ -2539,16 +2539,16 @@

- +

- - .bootstrap_commit_step(project_root, run_options:) ⇒ Object - - + .bootstrap_commit_step(project_root, run_options:) ⇒ Object + + + + -

@@ -2637,16 +2637,16 @@

- +

- - .bundle_binstubs_commandObject - - + .bundle_binstubs_commandObject + + + + -

@@ -2667,16 +2667,16 @@

- +

- - .bundled_handoff_step(project_root:, env:, run_options:) ⇒ Object - - + .bundled_handoff_step(project_root:, env:, run_options:) ⇒ Object + + + + -

@@ -2743,16 +2743,16 @@

- +

- - .bundler_binstub_gem_name(path) ⇒ Object - - + .bundler_binstub_gem_name(path) ⇒ Object + + + + -

@@ -2797,37 +2797,37 @@

- +

- - .bundler_generated_binstub?(path) ⇒ Boolean - - + .bundler_generated_binstub?(path) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -2854,16 +2854,16 @@

- +

- - .cleanup_legacy_ruby_version_files(project_root) ⇒ Object - - + .cleanup_legacy_ruby_version_files(project_root) ⇒ Object + + + + -

@@ -2910,37 +2910,37 @@

- +

- - .config_bootstrap_changed?(report) ⇒ Boolean - - + .config_bootstrap_changed?(report) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -2971,16 +2971,16 @@

- +

- - .configured_project_grapheme(project_root, env) ⇒ Object - - + .configured_project_grapheme(project_root, env) ⇒ Object + + + + -

@@ -3021,16 +3021,16 @@

- +

- - .conflicting_git_attribute_diagnostics(content, updates, managed_block:) ⇒ Object - - + .conflicting_git_attribute_diagnostics(content, updates, managed_block:) ⇒ Object + + + + -

@@ -3077,37 +3077,37 @@

- +

- - .curated_binstub?(path) ⇒ Boolean - - + .curated_binstub?(path) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -3138,37 +3138,37 @@

- +

- - .decorative_grapheme?(grapheme) ⇒ Boolean - - + .decorative_grapheme?(grapheme) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -3197,16 +3197,16 @@

- +

- - .default_git_driver_global_commandsObject - - + .default_git_driver_global_commandsObject + + + + -

@@ -3239,16 +3239,16 @@

- +

- - .development_dependency_names(content) ⇒ Object - - + .development_dependency_names(content) ⇒ Object + + + + -

@@ -3275,37 +3275,37 @@

- +

- - .dirty_git_attribute_managed_block?(content, managed_block) ⇒ Boolean - - + .dirty_git_attribute_managed_block?(content, managed_block) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -3334,16 +3334,16 @@

- +

- - .ensure_bin_setup_executable(project_root) ⇒ Object - - + .ensure_bin_setup_executable(project_root) ⇒ Object + + + + -

@@ -3384,16 +3384,16 @@

- +

- - .ensure_curated_binstubs_executable(project_root) ⇒ Object - - + .ensure_curated_binstubs_executable(project_root) ⇒ Object + + + + -

@@ -3444,16 +3444,16 @@

- +

- - .ensure_env_local_gitignore(project_root) ⇒ Object - - + .ensure_env_local_gitignore(project_root) ⇒ Object + + + + -

@@ -3522,37 +3522,37 @@

- +

- - .execute_git_drivers_check_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .execute_git_drivers_check_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

- +
- +

Raises:

@@ -3609,16 +3609,16 @@

- +

- - .execute_git_drivers_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .execute_git_drivers_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

@@ -3729,16 +3729,16 @@

- +

- - .execute_hook_templates_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .execute_hook_templates_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

@@ -3787,16 +3787,16 @@

- +

- - .execute_orchestration_steps(install_steps, project_root:, env:, run_options:, command_runner:) ⇒ Object - - + .execute_orchestration_steps(install_steps, project_root:, env:, run_options:, command_runner:) ⇒ Object + + + + -

@@ -3853,37 +3853,37 @@

- +

- - .execute_ready_command_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .execute_ready_command_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

- +
- +

Raises:

@@ -3930,16 +3930,16 @@

- +

- - .execute_ready_commands_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .execute_ready_commands_step(step, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

@@ -3994,16 +3994,16 @@

- +

- - .first_grapheme(text) ⇒ Object - - + .first_grapheme(text) ⇒ Object + + + + -

@@ -4024,16 +4024,16 @@

- +

- - .followup_apply_after_config_bootstrap(project_root, env:, run_options:, report:) ⇒ Object - - + .followup_apply_after_config_bootstrap(project_root, env:, run_options:, report:) ⇒ Object + + + + -

@@ -4070,16 +4070,16 @@

- +

- - .gemspec_dependency_sync_step(report) ⇒ Object - - + .gemspec_dependency_sync_step(report) ⇒ Object + + + + -

@@ -4132,16 +4132,16 @@

- +

- - .gemspec_grapheme_assignment_replacements(content, grapheme) ⇒ Object - - + .gemspec_grapheme_assignment_replacements(content, grapheme) ⇒ Object + + + + -

@@ -4188,16 +4188,16 @@

- - .gemspec_name(content, gemspec_path) ⇒ Object - - + .gemspec_name(content, gemspec_path) ⇒ Object + + + + -

@@ -4224,16 +4224,16 @@

- +

- - .git_attribute_block_end(managed_block) ⇒ Object - - + .git_attribute_block_end(managed_block) ⇒ Object + + + + -

@@ -4254,16 +4254,16 @@

- +

- - .git_attribute_block_start(managed_block) ⇒ Object - - + .git_attribute_block_start(managed_block) ⇒ Object + + + + -

@@ -4284,37 +4284,37 @@

- +

- - .git_attribute_line_conflicts?(line, update) ⇒ Boolean - - + .git_attribute_line_conflicts?(line, update) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -4353,16 +4353,16 @@

- +

- - .git_driver_attribute_diagnostics(project_root, updates, managed_block:) ⇒ Object - - + .git_driver_attribute_diagnostics(project_root, updates, managed_block:) ⇒ Object + + + + -

@@ -4413,16 +4413,16 @@

- +

- - .git_driver_attribute_reason(diagnostics, dry_run:, ready:) ⇒ Object - - + .git_driver_attribute_reason(diagnostics, dry_run:, ready:) ⇒ Object + + + + -

@@ -4449,16 +4449,16 @@

- +

- - .git_driver_attribute_status(diagnostics, dry_run:) ⇒ Object - - + .git_driver_attribute_status(diagnostics, dry_run:) ⇒ Object + + + + -

@@ -4483,16 +4483,16 @@

- +

- - .git_driver_attribute_updates(manifest, profile) ⇒ Object - - + .git_driver_attribute_updates(manifest, profile) ⇒ Object + + + + -

@@ -4527,16 +4527,16 @@

- +

- - .git_driver_forge_warning_diagnosticObject - - + .git_driver_forge_warning_diagnosticObject + + + + -

@@ -4567,16 +4567,16 @@

- +

- - .git_driver_global_commands(manifest = nil, profile = "semantic-diff") ⇒ Object - - + .git_driver_global_commands(manifest = nil, profile = "semantic-diff") ⇒ Object + + + + -

@@ -4607,16 +4607,16 @@

- +

- - .git_driver_global_config_checks(manifest = nil, profile = "semantic-diff") ⇒ Object - - + .git_driver_global_config_checks(manifest = nil, profile = "semantic-diff") ⇒ Object + + + + -

@@ -4641,16 +4641,16 @@

- +

- - .git_driver_global_unset_commandsObject - - + .git_driver_global_unset_commandsObject + + + + -

@@ -4683,16 +4683,16 @@

- +

- - .git_driver_local_commands(manifest = nil, profile = "semantic-diff") ⇒ Object - - + .git_driver_local_commands(manifest = nil, profile = "semantic-diff") ⇒ Object + + + + -

@@ -4717,16 +4717,16 @@

- +

- - .git_driver_local_config_checks(manifest = nil, profile = "semantic-diff") ⇒ Object - - + .git_driver_local_config_checks(manifest = nil, profile = "semantic-diff") ⇒ Object + + + + -

@@ -4751,16 +4751,16 @@

- +

- - .git_driver_manifest(project_root) ⇒ Object - - + .git_driver_manifest(project_root) ⇒ Object + + + + -

@@ -4795,16 +4795,16 @@

- +

- - .git_driver_manifest_profile(manifest, profile) ⇒ Object - - + .git_driver_manifest_profile(manifest, profile) ⇒ Object + + + + -

@@ -4829,16 +4829,16 @@

- +

- - .git_drivers_step(project_root, run_options) ⇒ Object - - + .git_drivers_step(project_root, run_options) ⇒ Object + + + + -

@@ -5043,16 +5043,16 @@

- +

- - .git_output(project_root, *args) ⇒ Object - - + .git_output(project_root, *args) ⇒ Object + + + + -

@@ -5075,37 +5075,37 @@

- +

- - .git_success?(project_root, *args) ⇒ Boolean - - + .git_success?(project_root, *args) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -5130,16 +5130,16 @@

- +

- - .git_toplevel(project_root) ⇒ Object - - + .git_toplevel(project_root) ⇒ Object + + + + -

@@ -5162,16 +5162,16 @@

- +

- - .github_org_from_env(env) ⇒ Object - - + .github_org_from_env(env) ⇒ Object + + + + -

@@ -5200,16 +5200,16 @@

- +

- - .github_org_from_origin(project_root) ⇒ Object - - + .github_org_from_origin(project_root) ⇒ Object + + + + -

@@ -5258,16 +5258,16 @@

- +

- - .github_workflow_paths(project_root) ⇒ Object - - + .github_workflow_paths(project_root) ⇒ Object + + + + -

@@ -5298,16 +5298,16 @@

- +

- - .handoff_argv(run_options) ⇒ Object - - + .handoff_argv(run_options) ⇒ Object + + + + -

@@ -5360,16 +5360,16 @@

- +

- - .hook_templates_step(project_root, run_options) ⇒ Object - - + .hook_templates_step(project_root, run_options) ⇒ Object + + + + -

@@ -5460,16 +5460,16 @@

- +

- - .install_phase_reports(install_steps) ⇒ Object - - + .install_phase_reports(install_steps) ⇒ Object + + + + -

@@ -5550,16 +5550,16 @@

- +

- - .install_run_options(env, run_options) ⇒ Object - - + .install_run_options(env, run_options) ⇒ Object + + + + -

@@ -5580,16 +5580,16 @@

- +

- - .install_step_summary(install_steps) ⇒ Object - - + .install_step_summary(install_steps) ⇒ Object + + + + -

@@ -5624,16 +5624,16 @@

- +

- - .kettle_config_migration_step(project_root) ⇒ Object - - + .kettle_config_migration_step(project_root) ⇒ Object + + + + -

@@ -5718,16 +5718,16 @@

- +

- - .list_arg(flag, value) ⇒ Object - - + .list_arg(flag, value) ⇒ Object + + + + -

@@ -5750,37 +5750,37 @@

- +

- - .literal_github_homepage?(assigned) ⇒ Boolean - - + .literal_github_homepage?(assigned) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -5823,16 +5823,16 @@

- +

- - .lockfile_normalization_commandObject - - + .lockfile_normalization_commandObject + + + + -

@@ -5853,16 +5853,16 @@

- +

- - .merge_apply_reports(initial, followup) ⇒ Object - - + .merge_apply_reports(initial, followup) ⇒ Object + + + + -

@@ -5897,37 +5897,37 @@

- +

- - .mise_installed?(env) ⇒ Boolean - - + .mise_installed?(env) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -5960,16 +5960,16 @@

- +

- - .mise_trust_step(project_root, report, env:) ⇒ Object - - + .mise_trust_step(project_root, report, env:) ⇒ Object + + + + -

@@ -6036,16 +6036,16 @@

- +

- - .normal_lockfile_env(env) ⇒ Object - - + .normal_lockfile_env(env) ⇒ Object + + + + -

@@ -6080,7 +6080,7 @@

def normal_lockfile_env(env) command_env = (env || {}).to_h.dup command_env["K_JEM_TEMPLATING"] = "false" - %w[KETTLE_RB_DEV GALTZO_FLOSS_DEV SMORG_RB_DEV].each do |key| + %w[KETTLE_RB_DEV GALTZO_FLOSS_DEV STRUCTUREDMERGE_DEV].each do |key| command_env[key] = "false" if command_env.key?(key) end %w[ @@ -6102,16 +6102,16 @@

- +

- - .normalize_gemspec_grapheme(content, grapheme) ⇒ Object - - + .normalize_gemspec_grapheme(content, grapheme) ⇒ Object + + + + -

@@ -6134,16 +6134,16 @@

- +

- - .normalize_git_drivers_mode(value) ⇒ Object - - + .normalize_git_drivers_mode(value) ⇒ Object + + + + -

@@ -6184,16 +6184,16 @@

- +

- - .normalize_hook_templates_mode(value) ⇒ Object - - + .normalize_hook_templates_mode(value) ⇒ Object + + + + -

@@ -6226,16 +6226,16 @@

- +

- - .normalize_lockfile_step(project_root, env:, run_options: {}) ⇒ Object - - + .normalize_lockfile_step(project_root, env:, run_options: {}) ⇒ Object + + + + -

@@ -6300,16 +6300,16 @@

- +

- - .normalize_readme_h1_grapheme(content, grapheme) ⇒ Object - - + .normalize_readme_h1_grapheme(content, grapheme) ⇒ Object + + + + -

@@ -6344,16 +6344,16 @@

- +

- - .post_template_project_fix_steps(project_root, report, env:) ⇒ Object - - + .post_template_project_fix_steps(project_root, report, env:) ⇒ Object + + + + -

@@ -6386,16 +6386,16 @@

- +

- - .prune_unwanted_bundler_binstubs(project_root) ⇒ Object - - + .prune_unwanted_bundler_binstubs(project_root) ⇒ Object + + + + -

@@ -6446,16 +6446,16 @@

- +

- - .readme_h1_grapheme(content) ⇒ Object - - + .readme_h1_grapheme(content) ⇒ Object + + + + -

@@ -6484,16 +6484,16 @@

- +

- - .relative_or_absolute_path(path, project_root) ⇒ Object - - + .relative_or_absolute_path(path, project_root) ⇒ Object + + + + -

@@ -6524,16 +6524,16 @@

- +

- - .remove_git_attribute_managed_block(content, managed_block:) ⇒ Object - - + .remove_git_attribute_managed_block(content, managed_block:) ⇒ Object + + + + -

@@ -6588,16 +6588,16 @@

- +

- - .render_git_attribute_line(update) ⇒ Object - - + .render_git_attribute_line(update) ⇒ Object + + + + -

@@ -6620,16 +6620,16 @@

- +

- - .render_git_attributes(content, updates, managed_block:) ⇒ Object - - + .render_git_attributes(content, updates, managed_block:) ⇒ Object + + + + -

@@ -6660,16 +6660,16 @@

- +

- - .render_git_driver_include_config(config_entries) ⇒ Object - - + .render_git_driver_include_config(config_entries) ⇒ Object + + + + -

@@ -6704,16 +6704,16 @@

- +

- - .repair_gemspec_homepage(project_root, env) ⇒ Object - - + .repair_gemspec_homepage(project_root, env) ⇒ Object + + + + -

@@ -6834,16 +6834,16 @@

- +

- - .replace_character_ranges(content, replacements) ⇒ Object - - + .replace_character_ranges(content, replacements) ⇒ Object + + + + -

@@ -6868,16 +6868,16 @@

- +

- - .rewrite_yard_binstub(project_root) ⇒ Object - - + .rewrite_yard_binstub(project_root) ⇒ Object + + + + -

@@ -6954,16 +6954,16 @@

- +

- - .ruby_string_literal_content(value, quote) ⇒ Object - - + .ruby_string_literal_content(value, quote) ⇒ Object + + + + -

@@ -6986,16 +6986,16 @@

- +

- - .run(project_root: Dir.pwd, env: ENV, run_options: {}, command_runner: method(:run_system_command)) ⇒ Object - - + .run(project_root: Dir.pwd, env: ENV, run_options: {}, command_runner: method(:run_system_command)) ⇒ Object + + + + -

@@ -7080,16 +7080,16 @@

- +

- - .run_bundle_setup_commands(project_root, env:, run_options:, command_runner:) ⇒ Object - - + .run_bundle_setup_commands(project_root, env:, run_options:, command_runner:) ⇒ Object + + + + -

@@ -7160,37 +7160,37 @@

- +

- - .run_command_step(name, command, project_root:, env:, quiet:, command_runner:) ⇒ Object - - + .run_command_step(name, command, project_root:, env:, quiet:, command_runner:) ⇒ Object + + + + -

- +
- +

Raises:

@@ -7253,16 +7253,16 @@

- +

- - .run_system_command(command, chdir:, env:, quiet:) ⇒ Object - - + .run_system_command(command, chdir:, env:, quiet:) ⇒ Object + + + + -

@@ -7299,16 +7299,16 @@

- +

- - .semantic_git_driver_attribute_updatesObject - - + .semantic_git_driver_attribute_updatesObject + + + + -

@@ -7341,16 +7341,16 @@

- +

- - .setup_command_env(project_root, env) ⇒ Object - - + .setup_command_env(project_root, env) ⇒ Object + + + + -

@@ -7379,16 +7379,16 @@

- +

- - .strip_inherited_bundler_activation!(command_env) ⇒ Object - - + .strip_inherited_bundler_activation!(command_env) ⇒ Object + + + + -

@@ -7427,16 +7427,16 @@

- +

- - .strip_leading_decorative_graphemes(text) ⇒ Object - - + .strip_leading_decorative_graphemes(text) ⇒ Object + + + + -

@@ -7471,16 +7471,16 @@

- +

- - .sync_readme_gemspec_grapheme(project_root, env) ⇒ Object - - + .sync_readme_gemspec_grapheme(project_root, env) ⇒ Object + + + + -

@@ -7561,16 +7561,16 @@

- +

- - .trim_readme_compatibility_badges(project_root, report) ⇒ Object - - + .trim_readme_compatibility_badges(project_root, report) ⇒ Object + + + + -

@@ -7653,37 +7653,37 @@

- +

- - .unsafe_git_driver_command_value?(value) ⇒ Boolean - - + .unsafe_git_driver_command_value?(value) ⇒ Boolean + + + + -

- +
- +

Returns:

    - +
  • - - + + (Boolean) - - - + + +
  • - +
@@ -7706,16 +7706,16 @@

- +

- - .validate_bundle_binstub_location(project_root) ⇒ Object - - + .validate_bundle_binstub_location(project_root) ⇒ Object + + + + -

@@ -7788,37 +7788,37 @@

- +

- - .validate_git_driver_manifest!(manifest) ⇒ Object - - + .validate_git_driver_manifest!(manifest) ⇒ Object + + + + -

- +
- +

Raises:

@@ -7857,37 +7857,37 @@

- +

- - .validate_git_driver_profile!(profile_name, profile) ⇒ Object - - + .validate_git_driver_profile!(profile_name, profile) ⇒ Object + + + + -

- +
- +

Raises:

@@ -7938,16 +7938,16 @@

- +

- - .value_arg(flag, value) ⇒ Object - - + .value_arg(flag, value) ⇒ Object + + + + -

@@ -7968,16 +7968,16 @@

- +

- - .version_gem_bootstrap_step(project_root, report) ⇒ Object - - + .version_gem_bootstrap_step(project_root, report) ⇒ Object + + + + -

@@ -8000,16 +8000,16 @@

- +

- - .yard_binstub_rake_handoff_contentObject - - + .yard_binstub_rake_handoff_contentObject + + + + -

@@ -8062,7 +8062,7 @@

- + diff --git a/gems/kettle-jem/docs/file.CHANGELOG.html b/gems/kettle-jem/docs/file.CHANGELOG.html index 6487a50d3..029c954cf 100644 --- a/gems/kettle-jem/docs/file.CHANGELOG.html +++ b/gems/kettle-jem/docs/file.CHANGELOG.html @@ -5,9 +5,9 @@ File: CHANGELOG - + — Documentation by YARD 0.9.44 - + @@ -37,14 +37,14 @@
@@ -475,7 +475,7 @@

Fixed

without requiring unreleased kettle-drift in every generated gemspec.
  • Added kettle-drift to generated templating Gemfiles, resolved remotely in
    templating mode and via KETTLE_RB_DEV locally, separate from the
    -SMORG_RB_DEV StructuredMerge local gem set.
  • +STRUCTUREDMERGE_DEV StructuredMerge local gem set.
  • Refreshed generated README metadata blocks after template README merging so
    version-derived gemspec metadata such as source_code_uri does not stay stale.
  • Added yard-yaml to generated local documentation Gemfiles so local
    diff --git a/gems/kettle-jem/gemfiles/modular/coverage.gemfile b/gems/kettle-jem/gemfiles/modular/coverage.gemfile index bcc758e2f..ab859db48 100644 --- a/gems/kettle-jem/gemfiles/modular/coverage.gemfile +++ b/gems/kettle-jem/gemfiles/modular/coverage.gemfile @@ -7,7 +7,7 @@ if ENV.fetch("KETTLE_RB_DEV", "false").casecmp("false").zero? # Coverage (remote/released) platform :mri do - gem "kettle-soup-cover", "~> 3.0", ">= 3.0.0", require: false + gem "kettle-soup-cover", "~> 3.0", ">= 3.0.1", require: false end else eval_gemfile "coverage_local.gemfile" diff --git a/gems/kettle-jem/gemfiles/modular/coverage_local.gemfile b/gems/kettle-jem/gemfiles/modular/coverage_local.gemfile index 091382217..458c872ec 100644 --- a/gems/kettle-jem/gemfiles/modular/coverage_local.gemfile +++ b/gems/kettle-jem/gemfiles/modular/coverage_local.gemfile @@ -3,6 +3,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when KETTLE_RB_DEV != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/gemfiles/modular/documentation.gemfile b/gems/kettle-jem/gemfiles/modular/documentation.gemfile index 1f30bb2e8..d8215416e 100644 --- a/gems/kettle-jem/gemfiles/modular/documentation.gemfile +++ b/gems/kettle-jem/gemfiles/modular/documentation.gemfile @@ -7,16 +7,16 @@ # # Documentation -gem "kramdown", "~> 2.5", ">= 2.5.1", require: false # Ruby >= 2.5 +gem "kramdown", "~> 2.5", ">= 2.5.2", require: false # Ruby >= 2.5 gem "kramdown-parser-gfm", "~> 1.1", require: false # Ruby >= 2.3 gem "yaml-converter", "~> 0.2", ">= 0.2.3", require: false # Ruby >= 3.2 -gem "yard", "~> 0.9", ">= 0.9.44", require: false +gem "yard", "~> 0.9", ">= 0.9.45", require: false gem "yard-junk", "~> 0.1", ">= 0.1.0", require: false # Ruby >= 3.1 gem "yard-relative_markdown_links", "~> 0.6", require: false if ENV.fetch("GALTZO_FLOSS_DEV", "false").casecmp("false").zero? gem "yard-fence", "~> 0.9", ">= 0.9.6", require: false # Ruby >= 3.2 - gem "yard-timekeeper", "~> 0.2", ">= 0.2.3", require: false + gem "yard-timekeeper", "~> 0.2", ">= 0.2.4", require: false gem "yard-yaml", "~> 0.2", ">= 0.2.3", require: false else eval_gemfile "documentation_local.gemfile" diff --git a/gems/kettle-jem/gemfiles/modular/documentation_local.gemfile b/gems/kettle-jem/gemfiles/modular/documentation_local.gemfile index 593ab7a2d..e54064b14 100644 --- a/gems/kettle-jem/gemfiles/modular/documentation_local.gemfile +++ b/gems/kettle-jem/gemfiles/modular/documentation_local.gemfile @@ -3,6 +3,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when GALTZO_FLOSS_DEV != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/gemfiles/modular/erb/r3/v5.0.gemfile b/gems/kettle-jem/gemfiles/modular/erb/r3/v5.0.gemfile index 765396835..5bde0e077 100644 --- a/gems/kettle-jem/gemfiles/modular/erb/r3/v5.0.gemfile +++ b/gems/kettle-jem/gemfiles/modular/erb/r3/v5.0.gemfile @@ -1 +1 @@ -gem "erb", "~> 6.0", ">= 6.0.4" # ruby >= 3.2.0 +gem "erb", "~> 6.0", ">= 6.0.5" # ruby >= 3.2.0 diff --git a/gems/kettle-jem/gemfiles/modular/erb/r4/v5.0.gemfile b/gems/kettle-jem/gemfiles/modular/erb/r4/v5.0.gemfile index 765396835..5bde0e077 100644 --- a/gems/kettle-jem/gemfiles/modular/erb/r4/v5.0.gemfile +++ b/gems/kettle-jem/gemfiles/modular/erb/r4/v5.0.gemfile @@ -1 +1 @@ -gem "erb", "~> 6.0", ">= 6.0.4" # ruby >= 3.2.0 +gem "erb", "~> 6.0", ">= 6.0.5" # ruby >= 3.2.0 diff --git a/gems/kettle-jem/gemfiles/modular/style.gemfile b/gems/kettle-jem/gemfiles/modular/style.gemfile index 510069166..f027dae4d 100644 --- a/gems/kettle-jem/gemfiles/modular/style.gemfile +++ b/gems/kettle-jem/gemfiles/modular/style.gemfile @@ -12,18 +12,18 @@ gem "reek", "~> 6.5", ">= 6.5.0" platform :mri do - gem "appraisal2-rubocop", "~> 0.2", ">= 0.2.3", require: false + gem "appraisal2-rubocop", "~> 1.0", ">= 1.0.0", require: false gem "rubocop-gradual", "~> 0.4", ">= 0.4.0" - gem "rubocop-minitest", "~> 0.38", ">= 0.38.1" + gem "rubocop-minitest", "~> 0.39", ">= 0.39.1" gem "rubocop-on-rbs", "~> 2.0", ">= 2.0.0" # ruby >= 3.2.0 # gem "rubocop", "~> 1.73", ">= 1.73.2" # constrained by standard gem "rubocop-packaging", "~> 0.6", ">= 0.6.0" - gem "standard", "~> 1.54", ">= 1.54.0" + gem "standard", "~> 1.56", ">= 1.56.0" if ENV.fetch("RUBOCOP_LTS_LOCAL", "false").casecmp("false").zero? declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) gem "rubocop-lts", "~> 24.2", ">= 24.2.1" unless declared_gems.include?("rubocop-lts") - gem "rubocop-lts-rspec", "~> 1.0", ">= 1.0.4" unless declared_gems.include?("rubocop-lts-rspec") + gem "rubocop-lts-rspec", "~> 1.0", ">= 1.0.5" unless declared_gems.include?("rubocop-lts-rspec") gem "rubocop-ruby3_2", "~> 3.0", ">= 3.0.6" unless declared_gems.include?("rubocop-ruby3_2") else eval_gemfile("style_local.gemfile") diff --git a/gems/kettle-jem/gemfiles/modular/style_local.gemfile b/gems/kettle-jem/gemfiles/modular/style_local.gemfile index 0bc2edde3..64abccc9b 100644 --- a/gems/kettle-jem/gemfiles/modular/style_local.gemfile +++ b/gems/kettle-jem/gemfiles/modular/style_local.gemfile @@ -6,6 +6,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when RUBOCOP_LTS_LOCAL != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/gemfiles/modular/templating.gemfile b/gems/kettle-jem/gemfiles/modular/templating.gemfile index 9f99e6d82..c0dd9c74d 100644 --- a/gems/kettle-jem/gemfiles/modular/templating.gemfile +++ b/gems/kettle-jem/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch("SMORG_RB_DEV", "false").casecmp("false").zero? +structuredmerge_remote = ENV.fetch("STRUCTUREDMERGE_DEV", "false").casecmp("false").zero? kettle_remote = ENV.fetch("KETTLE_RB_DEV", "false").casecmp("false").zero? -if smorg_remote +if structuredmerge_remote end if kettle_remote @@ -11,10 +11,10 @@ if kettle_remote gem "kettle-drift", "~> 1.0", ">= 1.0.5", require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/my for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile "templating_local.gemfile" unless smorg_remote && kettle_remote +eval_gemfile "templating_local.gemfile" unless structuredmerge_remote && kettle_remote diff --git a/gems/kettle-jem/gemfiles/modular/templating_local.gemfile b/gems/kettle-jem/gemfiles/modular/templating_local.gemfile index bd5e67bd5..632a5c17d 100644 --- a/gems/kettle-jem/gemfiles/modular/templating_local.gemfile +++ b/gems/kettle-jem/gemfiles/modular/templating_local.gemfile @@ -1,9 +1,17 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) @@ -20,7 +28,7 @@ end Kernel.send(:gem, "nomono", *nomono_activation_requirements) require "nomono/bundler" -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -57,7 +65,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[kettle-jem] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[kettle-jem] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[kettle-jem] - declared_gems tslp_dev = ENV.fetch("TSLP_DEV", nil) @@ -68,14 +76,14 @@ platform :mri do gem "tree_sitter_language_pack", path: tslp_dev end - if ENV.fetch("SMORG_RB_DEV", "false").casecmp("false") != 0 + if ENV.fetch("STRUCTUREDMERGE_DEV", "false").casecmp("false") != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: "SMORG_RB", - path_env: "SMORG_RB_DEV", + gems: structuredmerge_local_gems_to_eval, + prefix: "STRUCTUREDMERGE", + path_env: "STRUCTUREDMERGE_DEV", vendored_gems_env: "VENDORED_GEMS", vendor_gem_dir_env: "VENDOR_GEM_DIR", - debug_env: "SMORG_RB_DEBUG" + debug_env: "STRUCTUREDMERGE_DEBUG" ) end diff --git a/gems/kettle-jem/kettle-jem.gemspec b/gems/kettle-jem/kettle-jem.gemspec index 3b7921be1..7164ddcef 100644 --- a/gems/kettle-jem/kettle-jem.gemspec +++ b/gems/kettle-jem/kettle-jem.gemspec @@ -134,9 +134,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency("require_bench", "~> 1.0", ">= 1.0.4") # ruby >= 2.2.0 # Testing - spec.add_development_dependency("appraisal2", "~> 3.1", ">= 3.1.4") # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency("appraisal2", "~> 3.2", ">= 3.2.0") # ruby >= 1.8.7, for testing against multiple versions of dependencies spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.11") # ruby >= 4.0.0 - spec.add_development_dependency("turbo_tests2", "~> 3.1", ">= 3.1.14") # ruby >= 2.4.0, default kettle-test runner + spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.0") # ruby >= 2.4.0, default kettle-test runner # Releasing spec.add_development_dependency("ruby-progressbar", "~> 1.13") # ruby >= 0 diff --git a/gems/kettle-jem/lib/kettle/jem.rb b/gems/kettle-jem/lib/kettle/jem.rb index f53119ddd..3b91d9832 100644 --- a/gems/kettle-jem/lib/kettle/jem.rb +++ b/gems/kettle-jem/lib/kettle/jem.rb @@ -3642,7 +3642,7 @@ def ensure_monorepo_root_gemfile_dependencies(content) def monorepo_root_gemfile_dependency_lines [ - {name: "appraisal2", source: %(gem "appraisal2", "~> 3.1", ">= 3.1.4"\n)}, + {name: "appraisal2", source: %(gem "appraisal2", "~> 3.2", ">= 3.2.0"\n)}, {name: "bundler-audit", source: %(gem "bundler-audit", "~> 0.9.3"\n)}, {name: "kettle-dev", source: %(gem "kettle-dev", "~> 2.3", ">= 2.3.7"\n)}, {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.5"\n)}, @@ -3651,7 +3651,7 @@ def monorepo_root_gemfile_dependency_lines {name: "rake", source: %(gem "rake", "~> 13.0"\n)}, {name: "rspec", source: %(gem "rspec", "~> 3.0"\n)}, {name: "stone_checksums", source: %(gem "stone_checksums", "~> 1.0", ">= 1.0.6"\n)}, - {name: "turbo_tests2", source: %(gem "turbo_tests2", "~> 3.1", ">= 3.1.14"\n)} + {name: "turbo_tests2", source: %(gem "turbo_tests2", "~> 3.2", ">= 3.2.0"\n)} ].freeze end @@ -5316,7 +5316,7 @@ def merge_config_template_source(recipe, template_content, destination_content, **yaml_merge_options(recipe) ) when :toml - merge_result = Toml::Merge.merge_toml(template_content, destination_content, "toml") + merge_result = Citrus::Toml::Merge.merge_toml(template_content, destination_content, "toml") when :json, :jsonc merge_result = merge_json_template_source(template_content, destination_content, recipe, file_type) when :markdown @@ -5363,6 +5363,7 @@ def finalize_gemfile_template_source(recipe, content, destination_content, facts if recipe.fetch(:target_path).to_s == "Gemfile" output = inject_main_gemfile_recording_eval(output, facts) output = remove_stale_main_gemfile_direct_sibling_block(output, template_content) + output = deduplicate_main_gemfile_direct_sibling_blocks(output) output = ensure_main_gemfile_nomono_bootstrap(output, template_content) output = normalize_main_gemfile_nomono_requirements(output) output = guard_main_gemfile_runtime_workspace_overrides(output) @@ -5389,6 +5390,20 @@ def remove_stale_main_gemfile_direct_sibling_block(content, template_content) end end + def deduplicate_main_gemfile_direct_sibling_blocks(content) + records = main_gemfile_direct_sibling_records(content) + return content if records.length <= 1 + + records[0...-1].sort_by { |record| -record.fetch(:start_line) }.reduce(content.to_s) do |output, record| + replace_source_range_lines( + output, + record.fetch(:start_line), + expand_line_range_through_following_blanks(output, record.fetch(:end_line)), + "" + ) + end + end + def main_gemfile_direct_sibling_records(content) body = prism_parse_success(content)&.value&.statements&.body || [] assignments = body.select do |node| @@ -10317,6 +10332,8 @@ def readme_family_intro_and_backend_matrix(readme_style = {}) "", "This gem is part of the StructuredMerge Ruby package family. The implementation inventory, layering model, and backend notes live in the [root package-family guide][sm-family-guide]. Shared behavior is defined by the [StructuredMerge fixtures][sm-family-fixtures] and implemented by the [Go][sm-family-go], [Ruby][sm-family-ruby], [Rust][sm-family-rust], and [TypeScript][sm-family-typescript] repositories.", "", + "Merge analysis must enter parsing through `tree_haver`. Parser-specific gems register concrete TreeHaver backends; substrate gems register grammar mappings and keep shared format or language merge behavior in one place. Missing backends fail closed instead of falling back to direct parser-library calls.", + "", "", "", "[sm-family-guide]: https://github.com/structuredmerge/structuredmerge-ruby#package-family", @@ -13936,7 +13953,7 @@ def synchronize_github_actions_ci(content, facts) "", " steps:", " - name: Checkout #{package.fetch(:name)}", - " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0", "", *github_actions_setup_ruby_steps(indent: " ").lines(chomp: true), "", @@ -14006,7 +14023,7 @@ def synchronize_github_actions_framework_ci(content, facts) "", " steps:", " - name: Checkout", - " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0", "", *github_actions_setup_ruby_steps(indent: " ").lines(chomp: true), "", @@ -14143,10 +14160,10 @@ def synchronize_github_actions_coverage_ci(content, facts) "", " steps:", " - name: Checkout", - " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + " uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0", "", " - name: Setup Ruby & RubyGems", - " uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0 + " uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0", " with:", " ruby-version: \"${{ matrix.ruby }}\"", " rubygems: \"${{ matrix.rubygems }}\"", @@ -14582,23 +14599,23 @@ def yaml_mapping_value_node(content, key, node_class) def github_actions_step_pins { - "actions/checkout" => "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - "actions/cache" => "actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - "ruby/setup-ruby" => "ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0 - "coverallsapp/github-action" => "coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7 - "qltysh/qlty-action/coverage" => "qltysh/qlty-action/coverage@08a0a862c159eae9b9003081da6663d96efef637 # v2.3.0 - "codecov/codecov-action" => "codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 - "irongut/CodeCoverageSummary" => "irongut/CodeCoverageSummary@51cc3a756ddcd398d447c044c02cb6aa83fdae95 # v1.3.0 - "marocchino/sticky-pull-request-comment" => "marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 - "actions/upload-artifact" => "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - "amancevice/setup-code-climate" => "amancevice/setup-code-climate@0daf2985a225e8ac15975b4d233010e94d65b76a # v2 - "actions/dependency-review-action" => "actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 - "github/codeql-action/init" => "github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 - "github/codeql-action/autobuild" => "github/codeql-action/autobuild@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 - "github/codeql-action/analyze" => "github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 - "pozil/auto-assign-issue" => "pozil/auto-assign-issue@af6beea6bdf1e8eb373f061c5bc168681fc6d011 # v4.0.1 - "apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0 - "sarisia/actions-status-discord" => "sarisia/actions-status-discord@eb045afee445dc055c18d3d90bd0f244fd062708 # v1.16.0 + "actions/checkout" => "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0", + "actions/cache" => "actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0", + "ruby/setup-ruby" => "ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0", + "coverallsapp/github-action" => "coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7", + "qltysh/qlty-action/coverage" => "qltysh/qlty-action/coverage@08a0a862c159eae9b9003081da6663d96efef637 # v2.3.0", + "codecov/codecov-action" => "codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7", + "irongut/CodeCoverageSummary" => "irongut/CodeCoverageSummary@51cc3a756ddcd398d447c044c02cb6aa83fdae95 # v1.3.0", + "marocchino/sticky-pull-request-comment" => "marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5", + "actions/upload-artifact" => "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1", + "amancevice/setup-code-climate" => "amancevice/setup-code-climate@0daf2985a225e8ac15975b4d233010e94d65b76a # v2", + "actions/dependency-review-action" => "actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0", + "github/codeql-action/init" => "github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1", + "github/codeql-action/autobuild" => "github/codeql-action/autobuild@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1", + "github/codeql-action/analyze" => "github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1", + "pozil/auto-assign-issue" => "pozil/auto-assign-issue@af6beea6bdf1e8eb373f061c5bc168681fc6d011 # v4.0.1", + "apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0", + "sarisia/actions-status-discord" => "sarisia/actions-status-discord@eb045afee445dc055c18d3d90bd0f244fd062708 # v1.16.0" } end diff --git a/gems/kettle-jem/lib/kettle/jem/tasks/install_task.rb b/gems/kettle-jem/lib/kettle/jem/tasks/install_task.rb index fd6fe627b..48e4730a7 100644 --- a/gems/kettle-jem/lib/kettle/jem/tasks/install_task.rb +++ b/gems/kettle-jem/lib/kettle/jem/tasks/install_task.rb @@ -750,7 +750,7 @@ def normal_lockfile_env(project_root, env) command_env = (env || {}).to_h.dup strip_inherited_bundler_activation!(command_env) command_env["K_JEM_TEMPLATING"] = "false" - %w[KETTLE_RB_DEV GALTZO_FLOSS_DEV SMORG_RB_DEV].each do |key| + %w[KETTLE_RB_DEV GALTZO_FLOSS_DEV STRUCTUREDMERGE_DEV].each do |key| command_env[key] = "false" if command_env.key?(key) end gemfile = File.join(project_root.to_s, "Gemfile") @@ -1012,8 +1012,8 @@ def apply_kettle_family_local_install_env!(command_env) return unless Array(marker["installed_members"]).include?("kettle-jem") members_root = marker["members_root"].to_s - if local_env_disabled?(command_env["SMORG_RB_DEV"]) && Dir.exist?(File.join(members_root, "kettle-jem")) - command_env["SMORG_RB_DEV"] = members_root + if local_env_disabled?(command_env["STRUCTUREDMERGE_DEV"]) && Dir.exist?(File.join(members_root, "kettle-jem")) + command_env["STRUCTUREDMERGE_DEV"] = members_root end kettle_root = kettle_family_dependency_root(marker) diff --git a/gems/kettle-jem/lib/kettle/jem/templates/Gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/Gemfile.example index d8b1852e4..af7d895a2 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/Gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/Gemfile.example @@ -24,7 +24,7 @@ gem "nomono", *nomono_requirements, require: false # ruby >= 2.2 {KJ|MAIN_GEMFILE_DIRECT_SIBLING_BLOCK} -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? # Debugging diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gem.gemspec.example b/gems/kettle-jem/lib/kettle/jem/templates/gem.gemspec.example index febd7ac20..32305d678 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gem.gemspec.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gem.gemspec.example @@ -124,9 +124,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency("require_bench", "~> 1.0", ">= 1.0.4") # ruby >= 2.2.0 # Testing - spec.add_development_dependency("appraisal2", "~> 3.1", ">= 3.1.4") # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency("appraisal2", "~> 3.2", ">= 3.2.0") # ruby >= 1.8.7, for testing against multiple versions of dependencies spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.11") # ruby >= {KJ|MIN_TEST_RUBY} - spec.add_development_dependency("turbo_tests2", "~> 3.1", ">= 3.1.14") # ruby >= 2.4.0, default kettle-test runner + spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.0") # ruby >= 2.4.0, default kettle-test runner # Releasing spec.add_development_dependency("ruby-progressbar", "~> 1.13") # ruby >= 0 diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example index bcc758e2f..ab859db48 100755 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example @@ -7,7 +7,7 @@ if ENV.fetch("KETTLE_RB_DEV", "false").casecmp("false").zero? # Coverage (remote/released) platform :mri do - gem "kettle-soup-cover", "~> 3.0", ">= 3.0.0", require: false + gem "kettle-soup-cover", "~> 3.0", ">= 3.0.1", require: false end else eval_gemfile "coverage_local.gemfile" diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example index be2d34212..a055ba51e 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example @@ -3,6 +3,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when KETTLE_RB_DEV != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example index 1f30bb2e8..d8215416e 100755 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example @@ -7,16 +7,16 @@ # # Documentation -gem "kramdown", "~> 2.5", ">= 2.5.1", require: false # Ruby >= 2.5 +gem "kramdown", "~> 2.5", ">= 2.5.2", require: false # Ruby >= 2.5 gem "kramdown-parser-gfm", "~> 1.1", require: false # Ruby >= 2.3 gem "yaml-converter", "~> 0.2", ">= 0.2.3", require: false # Ruby >= 3.2 -gem "yard", "~> 0.9", ">= 0.9.44", require: false +gem "yard", "~> 0.9", ">= 0.9.45", require: false gem "yard-junk", "~> 0.1", ">= 0.1.0", require: false # Ruby >= 3.1 gem "yard-relative_markdown_links", "~> 0.6", require: false if ENV.fetch("GALTZO_FLOSS_DEV", "false").casecmp("false").zero? gem "yard-fence", "~> 0.9", ">= 0.9.6", require: false # Ruby >= 3.2 - gem "yard-timekeeper", "~> 0.2", ">= 0.2.3", require: false + gem "yard-timekeeper", "~> 0.2", ">= 0.2.4", require: false gem "yard-yaml", "~> 0.2", ">= 0.2.3", require: false else eval_gemfile "documentation_local.gemfile" diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example index bcad7e81b..12580dc38 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example @@ -3,6 +3,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when GALTZO_FLOSS_DEV != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example index 765396835..5bde0e077 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example @@ -1 +1 @@ -gem "erb", "~> 6.0", ">= 6.0.4" # ruby >= 3.2.0 +gem "erb", "~> 6.0", ">= 6.0.5" # ruby >= 3.2.0 diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example index 765396835..5bde0e077 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example @@ -1 +1 @@ -gem "erb", "~> 6.0", ">= 6.0.4" # ruby >= 3.2.0 +gem "erb", "~> 6.0", ">= 6.0.5" # ruby >= 3.2.0 diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example index d79b3d1e6..12a02795c 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example @@ -14,16 +14,16 @@ gem "reek", "~> 6.5", ">= 6.5.0" platform :mri do gem "appraisal2-rubocop", "~> 1.0", ">= 1.0.0", require: false gem "rubocop-gradual", "~> 0.4", ">= 0.4.0" - gem "rubocop-minitest", "~> 0.38", ">= 0.38.1" + gem "rubocop-minitest", "~> 0.39", ">= 0.39.1" gem "rubocop-on-rbs", "~> 2.0", ">= 2.0.0" # ruby >= 3.2.0 # gem "rubocop", "~> 1.73", ">= 1.73.2" # constrained by standard gem "rubocop-packaging", "~> 0.6", ">= 0.6.0" - gem "standard", "~> 1.54", ">= 1.54.0" + gem "standard", "~> 1.56", ">= 1.56.0" if ENV.fetch("RUBOCOP_LTS_LOCAL", "false").casecmp("false").zero? declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) gem "rubocop-lts", {KJ|RUBOCOP_LTS_CONSTRAINT} unless declared_gems.include?("rubocop-lts") - gem "rubocop-lts-rspec", "~> 1.0", ">= 1.0.4" unless declared_gems.include?("rubocop-lts-rspec") + gem "rubocop-lts-rspec", "~> 1.0", ">= 1.0.5" unless declared_gems.include?("rubocop-lts-rspec") gem "{KJ|RUBOCOP_RUBY_GEM}", {KJ|RUBOCOP_RUBY_CONSTRAINT} unless declared_gems.include?("{KJ|RUBOCOP_RUBY_GEM}") else eval_gemfile("style_local.gemfile") diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example index 87530cc01..2b80e1397 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example @@ -6,6 +6,14 @@ # Local path overrides for development. # Loaded by the associated non-local gemfile when RUBOCOP_LTS_LOCAL != "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example index 6f2eff433..990c5d920 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch("SMORG_RB_DEV", "false").casecmp("false").zero? +structuredmerge_remote = ENV.fetch("STRUCTUREDMERGE_DEV", "false").casecmp("false").zero? kettle_remote = ENV.fetch("KETTLE_RB_DEV", "false").casecmp("false").zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem "kettle-jem", ">= 7.0" end @@ -13,10 +13,10 @@ if kettle_remote gem "kettle-drift", "~> 1.0", ">= 1.0.5", require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/my for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile "templating_local.gemfile" unless smorg_remote && kettle_remote +eval_gemfile "templating_local.gemfile" unless structuredmerge_remote && kettle_remote diff --git a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example index b4ee12625..bbf6c8417 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example @@ -1,9 +1,17 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". +# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line. +# Bundler records that dependency during Gemfile evaluation, but it does not +# activate that exact version before the immediate `require "nomono/bundler"`. +# If multiple compatible nomono versions are installed, RubyGems may activate +# the newest installed version while Gemfile.lock pins an older compatible one; +# Bundler then aborts with "already activated nomono X, but your Gemfile +# requires nomono Y". Prefer the locked compatible version when present, then +# activate it explicitly before requiring the Bundler DSL extension used below. nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__) if File.file?(nomono_lockfile) @@ -20,7 +28,7 @@ end Kernel.send(:gem, "nomono", *nomono_activation_requirements) require "nomono/bundler" -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -57,7 +65,7 @@ kettle_rb_local_gems = %w[ {KJ|KETTLE_RB_LOCAL_GEMS} ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[{KJ|PACKAGE_NAME}] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[{KJ|PACKAGE_NAME}] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[{KJ|PACKAGE_NAME}] - declared_gems tslp_dev = ENV.fetch("TSLP_DEV", nil) @@ -68,14 +76,14 @@ platform :mri do gem "tree_sitter_language_pack", path: tslp_dev end - if ENV.fetch("SMORG_RB_DEV", "false").casecmp("false") != 0 + if ENV.fetch("STRUCTUREDMERGE_DEV", "false").casecmp("false") != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: "SMORG_RB", - path_env: "SMORG_RB_DEV", + gems: structuredmerge_local_gems_to_eval, + prefix: "STRUCTUREDMERGE", + path_env: "STRUCTUREDMERGE_DEV", vendored_gems_env: "VENDORED_GEMS", vendor_gem_dir_env: "VENDOR_GEM_DIR", - debug_env: "SMORG_RB_DEBUG" + debug_env: "STRUCTUREDMERGE_DEBUG" ) end diff --git a/gems/kettle-jem/lib/kettle/jem/templates/shim/Gemfile.example b/gems/kettle-jem/lib/kettle/jem/templates/shim/Gemfile.example index 5d7d3db83..86c12b7b0 100644 --- a/gems/kettle-jem/lib/kettle/jem/templates/shim/Gemfile.example +++ b/gems/kettle-jem/lib/kettle/jem/templates/shim/Gemfile.example @@ -8,7 +8,7 @@ gem "{KJ|SHIMMED_GEM_NAME}", path: shimmed_gem_path unless shimmed_gem_path.empt # Local workspace dependency wiring for templating_local.gemfile overrides. gem "nomono", "~> 1.0", ">= 1.0.8", require: false # ruby >= 2.2 -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? gemspec diff --git a/gems/kettle-jem/spec/bin/kettle_jem_deps_floor_spec.rb b/gems/kettle-jem/spec/bin/kettle_jem_deps_floor_spec.rb new file mode 100644 index 000000000..0c3620b32 --- /dev/null +++ b/gems/kettle-jem/spec/bin/kettle_jem_deps_floor_spec.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +require "spec_helper" + +load File.expand_path("../../bin/kettle-jem-deps-floor", __dir__) + +RSpec.describe KettleJemDepsFloor do + let(:project_root) { Dir.mktmpdir } + let(:resolver) do + FakeDepsFloorResolver.new( + "example_dep" => %w[1.2.3 1.2.9 1.3.0 2.0.0], + "embedded_dep" => %w[4.5.6 4.5.7], + "other_dep" => %w[3.0.0 3.0.1 3.1.0], + "nomono" => %w[1.0.8 1.0.9], + "yard-timekeeper" => %w[0.2.3 0.2.4] + ) + end + + before do + stub_const( + "FakeDepsFloorResolver", + Class.new do + def initialize(versions) + @versions = versions + @requests = [] + end + + attr_reader :requests + + def versions(gem_name, requirements: nil) + @requests << [gem_name, requirements] + requirement = Gem::Requirement.new(requirements || [">= 0"]) + Array(@versions.fetch(gem_name)).select do |version| + requirement.satisfied_by?(Gem::Version.new(version)) + end.map { |version| {number: version} } + end + end + ) + stub_const( + "#{described_class}::SOURCE_GLOBS", + [ + "template/valid.gemfile.example", + "template/tokenized.gemspec.example", + "template/local.gemfile.example", + "template/documentation.gemfile.example", + "lib/embedded.rb" + ] + ) + stub_const( + "#{described_class}::EXTRA_SOURCE_FILES", + [] + ) + write_file("template/valid.gemfile.example", <<~RUBY) + # frozen_string_literal: true + + gem "example_dep", "~> 1.2", ">= 1.2.3", require: false + spec.add_development_dependency("other_dep", "~> 3.0", ">= 3.0.0") + # gem "ignored_dep", "~> 1.0", ">= 1.0.0" + RUBY + write_file("template/tokenized.gemspec.example", <<~RUBY) + # frozen_string_literal: true + + {KJ|TOKEN} + spec.add_development_dependency("{KJ|TOKENIZED_GEM}", "~> 9.0", ">= 9.0.0") + spec.add_development_dependency("example_dep", "~> 1.2", ">= 1.2.3") + RUBY + write_file("template/local.gemfile.example", <<~RUBY) + # frozen_string_literal: true + + nomono_activation_requirements = ["~> 1.0", ">= 1.0.8"] + Kernel.send(:gem, "nomono", *nomono_activation_requirements) + require "nomono/bundler" + RUBY + write_file("template/documentation.gemfile.example", <<~RUBY) + # frozen_string_literal: true + + gem "yard-timekeeper", "~> 0.2", ">= 0.2.3", require: false + RUBY + write_file("lib/embedded.rb", <<~RUBY) + # frozen_string_literal: true + + {name: "embedded_dep", source: %(gem "embedded_dep", "~> 4.5", ">= 4.5.6"\\n)} + RUBY + end + + after do + FileUtils.rm_rf(project_root) + end + + def write_file(relative_path, content) + path = File.join(project_root, relative_path) + FileUtils.mkdir_p(File.dirname(path)) + File.write(path, content) + end + + def read_file(relative_path) + File.read(File.join(project_root, relative_path)) + end + + it "defaults the project root to the gem root relative to the bin script" do + options = described_class.parse_options([]) + + expect(options.fetch(:project_root)).to eq(File.expand_path("../..", __dir__)) + end + + it "reports patch updates without writing files" do + result = described_class.new(project_root: project_root, resolver: resolver, options: {upgrade: "patch"}).run + + expect(result[:updates]).to eq(6) + expect(result[:updated_dependencies]).to eq(%w[embedded_dep example_dep nomono other_dep yard-timekeeper]) + expect(result[:planned_changes]).to include( + hash_including( + name: "example_dep", + relative_path: "template/valid.gemfile.example", + current_floor: "1.2.3", + new_floor: "1.2.9", + new_pessimistic: "~> 1.2" + ) + ) + expect(result[:planned_changes]).to include( + hash_including( + name: "yard-timekeeper", + relative_path: "template/documentation.gemfile.example", + current_floor: "0.2.3", + new_floor: "0.2.4" + ) + ) + expect(read_file("template/valid.gemfile.example")).to include('gem "example_dep", "~> 1.2", ">= 1.2.3"') + end + + it "updates parseable Ruby and tokenized template files when writing" do + result = described_class.new(project_root: project_root, resolver: resolver, options: {write: true, upgrade: "minor"}).run + + expect(result[:updates]).to eq(6) + expect(read_file("lib/embedded.rb")).to include('{name: "embedded_dep", source: %(gem "embedded_dep", "~> 4.5", ">= 4.5.7"\\n)}') + expect(read_file("template/valid.gemfile.example")).to include('gem "example_dep", "~> 1.3", ">= 1.3.0"') + expect(read_file("template/valid.gemfile.example")).to include('spec.add_development_dependency("other_dep", "~> 3.1", ">= 3.1.0")') + expect(read_file("template/valid.gemfile.example")).to include('# gem "ignored_dep", "~> 1.0", ">= 1.0.0"') + expect(read_file("template/tokenized.gemspec.example")).to include('spec.add_development_dependency("example_dep", "~> 1.3", ">= 1.3.0")') + expect(read_file("template/tokenized.gemspec.example")).to include('spec.add_development_dependency("{KJ|TOKENIZED_GEM}", "~> 9.0", ">= 9.0.0")') + expect(read_file("template/local.gemfile.example")).to include('nomono_activation_requirements = ["~> 1.0", ">= 1.0.9"]') + expect(read_file("template/documentation.gemfile.example")).to include('gem "yard-timekeeper", "~> 0.2", ">= 0.2.4", require: false') + end + + it "allows the caller to select major updates" do + result = described_class.new(project_root: project_root, resolver: resolver, options: {write: true, upgrade: "major"}).run + + expect(result[:planned_changes]).to include( + hash_including( + name: "example_dep", + new_floor: "2.0.0", + new_pessimistic: "~> 2.0" + ) + ) + expect(read_file("template/valid.gemfile.example")).to include('gem "example_dep", "~> 2.0", ">= 2.0.0"') + end + + it "fails check mode when managed floors are stale" do + expect { + described_class.new(project_root: project_root, resolver: resolver, options: {check: true}).run + }.to raise_error(RuntimeError, /Managed dependency floors are stale/) + end + + it "reports discovered dependencies without requiring an allow-list" do + result = described_class.new(project_root: project_root, resolver: resolver, options: {upgrade: "patch"}).run + + expect(result[:discovered_dependencies]).to eq(%w[embedded_dep example_dep nomono other_dep yard-timekeeper]) + end + + it "rejects unsupported upgrade levels" do + expect { + described_class.new(project_root: project_root, resolver: resolver, options: {upgrade: "micro"}).run + }.to raise_error(ArgumentError, /Invalid --upgrade value/) + end +end diff --git a/gems/kettle-jem/spec/bin/kettle_jem_workflow_pins_spec.rb b/gems/kettle-jem/spec/bin/kettle_jem_workflow_pins_spec.rb index 059f2460d..5a11fc24b 100644 --- a/gems/kettle-jem/spec/bin/kettle_jem_workflow_pins_spec.rb +++ b/gems/kettle-jem/spec/bin/kettle_jem_workflow_pins_spec.rb @@ -65,6 +65,30 @@ expect(File.read(workflow_path)).to include("uses: #{new_pin}") end + it "preserves Ruby source delimiters around pins when writing updates" do + File.write(pin_index_path, <<~RUBY) + def generated_workflow + [ + " uses: #{old_pin}", + "" + ] + end + + def github_actions_step_pins + { + "actions/checkout" => "#{old_pin}" + } + end + RUBY + + result = described_class.new(project_root: project_root, options: {write: true}).run + updated = File.read(pin_index_path) + + expect(result[:updated_actions]).to eq(["actions/checkout"]) + expect(updated).to include(%(" uses: #{new_pin}",)) + expect(updated).to include(%("actions/checkout" => "#{new_pin}")) + end + it "updates sub-action pins when kettle-gha-sha-pins reports the parent action repository" do sub_action = "github/codeql-action/init" old_sub_pin = "#{sub_action}@#{old_sha} # v4.36.0" diff --git a/gems/kettle-jem/spec/release_packaging_spec.rb b/gems/kettle-jem/spec/release_packaging_spec.rb index 2388e736e..57f48e524 100644 --- a/gems/kettle-jem/spec/release_packaging_spec.rb +++ b/gems/kettle-jem/spec/release_packaging_spec.rb @@ -39,9 +39,11 @@ def clean_subprocess_env(overrides = {}) expect(spec.metadata["homepage_uri"]).to eq("https://structuredmerge.org") expect(spec.executables).to eq(["kettle-jem"]) expect(File.executable?(gem_root.join("exe/kettle-jem"))).to be(true) + expect(File.executable?(gem_root.join("bin/kettle-jem-deps-floor"))).to be(true) expect(File.executable?(gem_root.join("bin/kettle-jem-workflow-pins"))).to be(true) expect(expected_template_files).not_to be_empty expect(files).to include(*expected_template_files) + expect(files).not_to include("bin/kettle-jem-deps-floor") expect(files).not_to include("bin/kettle-jem-workflow-pins") expect(files).to include( "lib/kettle/jem/tasks.rb", diff --git a/gems/kettle-jem/spec/thin_slice_spec.rb b/gems/kettle-jem/spec/thin_slice_spec.rb index 115d158a9..1a4274069 100644 --- a/gems/kettle-jem/spec/thin_slice_spec.rb +++ b/gems/kettle-jem/spec/thin_slice_spec.rb @@ -310,7 +310,7 @@ expect(generated[:Gemfile]).to include(%(eval_gemfile "gemfiles/modular/templating.gemfile")) expect(generated[:Gemfile]).not_to include("git:") expect_gem_dependency_declared(generated[:"gemfiles/modular/templating.gemfile"], "kettle-jem") - expect(generated[:"gemfiles/modular/templating_local.gemfile"]).to include(%(smorg_rb_local_gems = %w[)) + expect(generated[:"gemfiles/modular/templating_local.gemfile"]).to include(%(structuredmerge_local_gems = %w[)) expect(generated[:"legacy-shim.gemspec"]).not_to include("old-implementation") expect(generated[:"lib/legacy/shim.rb"]).to include(%(require "legacy-shim2")) expect(generated[:"lib/legacy/strategies/shim.rb"]).to include(%(require "legacy/shim")) @@ -5062,7 +5062,7 @@ module Version expect(Kettle::Jem::Tasks::InstallTask.setup_command_env(root, env)).to include( "BUNDLE_GEMFILE" => File.join(root, "Gemfile"), "K_JEM_TEMPLATING" => "true", - "SMORG_RB_DEV" => marker.fetch("members_root"), + "STRUCTUREDMERGE_DEV" => marker.fetch("members_root"), "KETTLE_RB_DEV" => File.join(root, "kettle-dev") ) end @@ -5109,7 +5109,7 @@ module Version "K_JEM_TEMPLATING" => "true", "KETTLE_RB_DEV" => "/workspace/my", "GALTZO_FLOSS_DEV" => "/workspace/galtzo-floss", - "SMORG_RB_DEV" => "/workspace/smorg-rb" + "STRUCTUREDMERGE_DEV" => "/workspace/smorg-rb" } commands = [] command_runner = lambda do |command, chdir:, env:, quiet:| @@ -5142,7 +5142,7 @@ module Version "K_JEM_TEMPLATING" => "false", "KETTLE_RB_DEV" => "false", "GALTZO_FLOSS_DEV" => "false", - "SMORG_RB_DEV" => "false" + "STRUCTUREDMERGE_DEV" => "false" ) expect(commands.map { |entry| entry.fetch(:command) }).not_to include(%w[git add -A]) end @@ -5217,7 +5217,7 @@ module Version "K_JEM_TEMPLATING" => "true", "KETTLE_RB_DEV" => "/workspace/my", "GALTZO_FLOSS_DEV" => "/workspace/galtzo-floss", - "SMORG_RB_DEV" => "/workspace/smorg-rb", + "STRUCTUREDMERGE_DEV" => "/workspace/smorg-rb", "RUBYOPT" => "-rbundler/setup", "RUBYLIB" => "/workspace/kettle-jem/lib", "BUNDLE_BIN_PATH" => "/workspace/kettle-jem/bin/bundle", @@ -5251,7 +5251,7 @@ module Version "K_JEM_TEMPLATING" => "false", "KETTLE_RB_DEV" => "false", "GALTZO_FLOSS_DEV" => "false", - "SMORG_RB_DEV" => "false" + "STRUCTUREDMERGE_DEV" => "false" ) expect(lock_command.fetch(:env)).to include( "RUBYOPT" => nil, @@ -6379,7 +6379,6 @@ module Version }) availability = Bash::Merge::Availability.new( grammar_path: nil, - language_pack_process: true, node_parser: false, diagnostics: [{kind: "bash_node_parser_unavailable", message: "missing node adapter"}] ) @@ -7373,6 +7372,79 @@ module Example end end + it "merges Git driver TOML manifests with destination driver values" do + tmp_root = File.join(__dir__, "tmp") + FileUtils.mkdir_p(tmp_root) + Dir.mktmpdir("kettle-jem-git-driver-toml-merge", tmp_root) do |root| + write_tree(root, { + "example.gemspec" => <<~RUBY, + Gem::Specification.new do |spec| + spec.name = "example" + spec.summary = "Example gem" + end + RUBY + ".kettle-jem.yml" => <<~YAML, + templates: + root: template + apply: true + entries: + - .structuredmerge/git-drivers.toml + YAML + ".structuredmerge/git-drivers.toml" => <<~TOML, + version = 1 + driver_namespace = "smorg" + + [profiles.semantic-diff] + description = "Destination driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-rb" + + [[profiles.semantic-diff.git_config]] + scope = "global" + key = "diff.smorg-rb.command" + value = "smorg-rb diff-driver" + TOML + "template/.structuredmerge/git-drivers.toml.example" => <<~TOML + version = 1 + driver_namespace = "smorg" + + [profiles.semantic-diff] + description = "Template driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-ruby" + + [[profiles.semantic-diff.git_config]] + scope = "global" + key = "diff.smorg-ruby.command" + value = "smorg-ruby diff-driver" + + [profiles.textconv-normalized] + description = "Template-only profile" + + [[profiles.textconv-normalized.attributes]] + pattern = "*.json" + diff = "smorg-json-textconv" + TOML + }) + + apply = described_class.apply_project(root, env: {}) + report = apply.fetch(:recipe_reports).find do |candidate| + candidate.fetch(:relative_path) == ".structuredmerge/git-drivers.toml" + end + content = report.fetch(:final_content) + + expect(content).to include('diff = "smorg-rb"') + expect(content).to include('key = "diff.smorg-rb.command"') + expect(content).to include('value = "smorg-rb diff-driver"') + expect(content).to include("[profiles.textconv-normalized]") + expect(content).not_to include("smorg-ruby") + end + end + it "restores documentation comments from YAML templates when destination config stripped them" do tmp_root = File.join(__dir__, "tmp") FileUtils.mkdir_p(tmp_root) @@ -11630,6 +11702,9 @@ def min_ruby_version(gem_name, version) expect(template_report.dig(:metadata, :template_tokens, "KJ|README:FAMILY_INTRO_BACKEND_MATRIX")).to include( "StructuredMerge Ruby package family" ) + expect(template_report.dig(:metadata, :template_tokens, "KJ|README:FAMILY_INTRO_BACKEND_MATRIX")).to include( + "Merge analysis must enter parsing through `tree_haver`" + ) end end @@ -14333,6 +14408,109 @@ def register_kettle_jem_plugin(registrar) end end + it "collapses repeated direct sibling runtime dependency wiring in the main Gemfile" do + tmp_root = File.join(__dir__, "tmp") + FileUtils.mkdir_p(tmp_root) + Dir.mktmpdir("kettle-jem-main-gemfile-direct-sibling-dedupe", tmp_root) do |workspace| + root = File.join(workspace, "adapter") + sibling = File.join(workspace, "shared-core") + FileUtils.mkdir_p([root, sibling]) + write_tree(sibling, { + "shared-core.gemspec" => <<~RUBY + Gem::Specification.new do |spec| + spec.name = "shared-core" + spec.version = "0.1.0" + spec.summary = "Shared core" + end + RUBY + }) + write_tree(root, { + "adapter.gemspec" => <<~RUBY, + Gem::Specification.new do |spec| + spec.name = "adapter" + spec.version = "0.1.0" + spec.summary = "Adapter" + spec.homepage = "https://github.com/rubythems/adapter" + spec.metadata["source_code_uri"] = "https://github.com/rubythems/adapter" + spec.add_dependency "shared-core", "= 0.1.0" + end + RUBY + "Gemfile" => <<~RUBY, + source "https://gem.coop" + + gemspec + + nomono_requirements = ["~> 1.0", ">= 1.0.8"] + gem "nomono", *nomono_requirements, require: false + + # Direct sibling dependencies (env-switched via RUBYTHEMS_DEV) + direct_sibling_gems = %w[ + stale-core + ] + direct_sibling_dev = ENV.fetch("RUBYTHEMS_DEV", "") + direct_sibling_local = + !direct_sibling_dev.empty? && !%w[false 0 no off].include?(direct_sibling_dev.downcase) + direct_sibling_templating = ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? + + if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero?) + require "nomono/bundler" + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: "RUBYTHEMS", + path_env: "RUBYTHEMS_DEV", + root: ["src", "my", "rubythems"] + ) + end + + # Direct sibling dependencies (env-switched via RUBYTHEMS_DEV) + direct_sibling_gems = %w[ + shared-core + ] + direct_sibling_dev = ENV.fetch("RUBYTHEMS_DEV", "") + direct_sibling_local = + !direct_sibling_dev.empty? && !%w[false 0 no off].include?(direct_sibling_dev.downcase) + direct_sibling_templating = ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? + + if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero?) + require "nomono/bundler" + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: "RUBYTHEMS", + path_env: "RUBYTHEMS_DEV", + root: ["src", "my", "rubythems"] + ) + end + + # Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) + eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? + RUBY + ".kettle-jem.yml" => <<~YAML + project_emoji: "💎" + templates: + root: packaged + apply: true + entries: + - Gemfile + YAML + }) + + described_class.apply_project( + root, + env: {}, + run_options: {accept: true, force: true, skip_commit: true} + ) + gemfile = File.read(File.join(root, "Gemfile")) + + expect(gemfile.scan("# Direct sibling dependencies").length).to eq(1) + expect(gemfile).to include("shared-core") + expect(gemfile).not_to include("stale-core") + end + end + it "does not path-wire direct sibling dependencies when the sibling directory has a different gemspec name" do tmp_root = File.join(__dir__, "tmp") FileUtils.mkdir_p(tmp_root) @@ -14390,7 +14568,7 @@ def register_kettle_jem_plugin(registrar) ) end - # Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) + # Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? RUBY ".kettle-jem.yml" => <<~YAML diff --git a/gems/kramdown-merge/.gitattributes b/gems/kramdown-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/kramdown-merge/.gitattributes +++ b/gems/kramdown-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/kramdown-merge/.kettle-drift.lock b/gems/kramdown-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/kramdown-merge/.kettle-drift.lock +++ b/gems/kramdown-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/kramdown-merge/.rubocop_gradual.lock b/gems/kramdown-merge/.rubocop_gradual.lock index bf8d87dc0..d9d23567b 100644 --- a/gems/kramdown-merge/.rubocop_gradual.lock +++ b/gems/kramdown-merge/.rubocop_gradual.lock @@ -82,13 +82,23 @@ "lib/kramdown-merge.rb:2196362882": [ [1, 1, 0, "Naming/FileName: The name of this source file (`kramdown-merge.rb`) should use snake_case.", 5381] ], - "lib/kramdown/merge.rb:1323392188": [ + "lib/kramdown/merge.rb:1542815088": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Kramdown::Merge`.", 2866359175], - [10, 3, 6831, "Metrics/ModuleLength: Module has too many lines. [158/100]", 3521641961], + [10, 3, 7119, "Metrics/ModuleLength: Module has too many lines. [163/100]", 4032157679], [11, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [48, 5, 980, "Metrics/MethodLength: Method has too many lines. [25/10]", 2523239963], - [91, 5, 613, "Metrics/MethodLength: Method has too many lines. [11/10]", 2967276583], - [91, 52, 144, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3050457682] + [48, 5, 1042, "Metrics/MethodLength: Method has too many lines. [25/10]", 2523239963], + [91, 5, 652, "Metrics/MethodLength: Method has too many lines. [12/10]", 1548795337], + [91, 52, 144, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3050457682], + [108, 5, 667, "Metrics/MethodLength: Method has too many lines. [11/10]", 1334645416], + [124, 5, 684, "Metrics/MethodLength: Method has too many lines. [11/10]", 107846886], + [140, 5, 662, "Metrics/MethodLength: Method has too many lines. [11/10]", 2351504264], + [156, 5, 681, "Metrics/MethodLength: Method has too many lines. [11/10]", 1477270603] + ], + "lib/kramdown/merge/backend.rb:2821144035": [ + [5, 5, 14, "Style/Documentation: Missing top-level documentation comment for `module Kramdown::Merge::Backend`.", 1362832539], + [13, 7, 14, "Style/Documentation: Missing top-level documentation comment for `class Kramdown::Merge::Backend::Language`.", 3674592793], + [30, 7, 12, "Style/Documentation: Missing top-level documentation comment for `class Kramdown::Merge::Backend::Parser`.", 2485220908], + [41, 7, 10, "Style/Documentation: Missing top-level documentation comment for `class Kramdown::Merge::Backend::Node`.", 3515419275] ], "spec/fixtures_integration_spec.rb:3613778634": [ [3, 1, 11994, "Metrics/BlockLength: Block has too many lines. [261/25]", 885184468], diff --git a/gems/kramdown-merge/Gemfile b/gems/kramdown-merge/Gemfile index c70bf0eb5..08e351959 100644 --- a/gems/kramdown-merge/Gemfile +++ b/gems/kramdown-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/kramdown-merge/Gemfile.lock b/gems/kramdown-merge/Gemfile.lock index 637d35c66..4da75c6b0 100644 --- a/gems/kramdown-merge/Gemfile.lock +++ b/gems/kramdown-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH markdown-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,10 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -274,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -326,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -357,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -377,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -402,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -434,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -446,11 +750,15 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 @@ -461,6 +769,8 @@ CHECKSUMS lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -475,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -486,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -513,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -524,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -537,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/kramdown-merge/gemfiles/modular/templating.gemfile b/gems/kramdown-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/kramdown-merge/gemfiles/modular/templating.gemfile +++ b/gems/kramdown-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/kramdown-merge/gemfiles/modular/templating_local.gemfile b/gems/kramdown-merge/gemfiles/modular/templating_local.gemfile index f92859fae..c6aa2eb79 100644 --- a/gems/kramdown-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/kramdown-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[kramdown-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[kramdown-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[kramdown-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/kramdown-merge/lib/kramdown/merge.rb b/gems/kramdown-merge/lib/kramdown/merge.rb index 126127eb6..e21164e44 100644 --- a/gems/kramdown-merge/lib/kramdown/merge.rb +++ b/gems/kramdown-merge/lib/kramdown/merge.rb @@ -53,7 +53,7 @@ def parse_markdown(source, dialect, backend: nil) return unsupported_feature_result("Unsupported Markdown dialect #{dialect}.") unless dialect == 'markdown' - ::Kramdown::Document.new(source) + TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:markdown).parse(source) } normalized = Markdown::Merge.normalize_source(source) { ok: true, @@ -85,7 +85,7 @@ def merge_markdown(template_source, destination_source, dialect, backend: nil) return unsupported_feature_result("Unsupported Markdown backend #{requested}.") end - Markdown::Merge.merge_markdown(template_source, destination_source, dialect) + Markdown::Merge.merge_markdown(template_source, destination_source, dialect, backend: BACKEND_REFERENCE.id) end def merge_markdown_with_reviewed_nested_outputs(template_source, destination_source, dialect, review_state, @@ -100,7 +100,8 @@ def merge_markdown_with_reviewed_nested_outputs(template_source, destination_sou destination_source, dialect, review_state, - applied_children + applied_children, + backend: BACKEND_REFERENCE.id ) end @@ -115,7 +116,8 @@ def merge_markdown_with_reviewed_nested_outputs_from_replay_bundle(template_sour template_source, destination_source, dialect, - replay_bundle + replay_bundle, + backend: BACKEND_REFERENCE.id ) end @@ -130,7 +132,8 @@ def merge_markdown_with_reviewed_nested_outputs_from_replay_bundle_envelope(temp template_source, destination_source, dialect, - envelope + envelope, + backend: BACKEND_REFERENCE.id ) end @@ -145,7 +148,8 @@ def merge_markdown_with_reviewed_nested_outputs_from_review_state(template_sourc template_source, destination_source, dialect, - review_state + review_state, + backend: BACKEND_REFERENCE.id ) end @@ -160,7 +164,8 @@ def merge_markdown_with_reviewed_nested_outputs_from_review_state_envelope(templ template_source, destination_source, dialect, - envelope + envelope, + backend: BACKEND_REFERENCE.id ) end @@ -195,6 +200,8 @@ def unsupported_feature_result(message) end end +require_relative 'merge/backend' + Kramdown::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/kramdown-merge/lib/kramdown/merge/backend.rb b/gems/kramdown-merge/lib/kramdown/merge/backend.rb new file mode 100644 index 000000000..ee35d7acf --- /dev/null +++ b/gems/kramdown-merge/lib/kramdown/merge/backend.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Kramdown + module Merge + module Backend + Markdown::Merge::BackendSupport.install!( + backend_module: self, + backend_name: :kramdown, + gem_name: 'kramdown', + require_path: 'kramdown/merge' + ) + + class Language < ::TreeHaver::Base::Language + def initialize(name = :markdown, options: {}) + super(name, backend: :kramdown, options: options) + end + + class << self + def markdown(options: {}) + new(:markdown, options: options) + end + end + + Markdown::Merge::BackendSupport.configure_markdown_only_language_class!( + self, + backend_label: 'Kramdown' + ) + end + + class Parser < ::TreeHaver::Base::Parser + def parse(source) + raise 'Language not set' unless language + + Backend.available? or raise 'Kramdown not available' + + document = ::Kramdown::Document.new(source, **(language.options || {})) + Tree.new(document.root, source) + end + end + + class Node < ::TreeHaver::Base::Node + TYPE_MAP = { + root: 'document', + header: 'heading', + codeblock: 'code_block', + p: 'paragraph' + }.freeze + + Markdown::Merge::BackendSupport.configure_node_link_and_navigation!( + self, + next_sibling_selector: :next, + prev_sibling_selector: :previous, + parent_selector: :parent + ) + Markdown::Merge::BackendSupport.configure_node_heading_and_code_block_helpers!( + self, + heading_matcher: ->(node) { node.raw_type == 'header' }, + code_block_matcher: ->(node) { node.raw_type == 'codeblock' }, + heading_level_extractor: ->(inner_node) { inner_node.options[:level] }, + code_block_info_extractor: ->(inner_node) { inner_node.options[:lang] } + ) + + def type + TYPE_MAP.fetch(raw_type.to_sym, raw_type) + end + + alias kind type + + def raw_type + inner_node.type.to_s + end + + def text + return inner_node.value.to_s if inner_node.value + return inner_node.options[:raw_text].to_s if inner_node.options.key?(:raw_text) + + children.map(&:text).join + end + + def children + Array(inner_node.children).map { |child| self.class.new(child, source: source, lines: lines) } + end + + def start_point + line = [inner_node.options.fetch(:location, 1).to_i - 1, 0].max + Point.new(line, 0) + end + + def end_point + Point.new([start_point.row + text.lines.count - 1, start_point.row].max, 0) + end + + def start_byte + calculate_byte_offset(start_point.row, start_point.column) + end + + def end_byte + calculate_byte_offset(end_point.row, end_point.column) + end + end + end + end +end diff --git a/gems/kramdown-merge/spec/fixtures_integration_spec.rb b/gems/kramdown-merge/spec/fixtures_integration_spec.rb index 2bbde5d2f..ec45e35ea 100644 --- a/gems/kramdown-merge/spec/fixtures_integration_spec.rb +++ b/gems/kramdown-merge/spec/fixtures_integration_spec.rb @@ -80,6 +80,30 @@ def json_ready(value) expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) end + it 'conforms to the slice-721 Markdown provider parity fixture' do + fixture = read_json( + fixtures_root.join( + 'markdown', + 'slice-721-provider-parity', + 'headings-lists-tables-fences-links-frontmatter-comments.json' + ) + ) + + result = described_class.parse_markdown(fixture[:source], fixture[:dialect]) + owners = result.dig(:analysis, :owners) + expect(owners.map { |owner| owner[:owner_kind] }).to eq(fixture.dig(:expected, :parse_owner_kinds)) + expect(owners.map { |owner| owner[:match_key] }).to eq(fixture.dig(:expected, :parse_owner_match_keys)) + + analysis = TreeHaver.with_backend(described_class::BACKEND_REFERENCE.id) do + Markdown::Merge::FileAnalysis.new(fixture[:source]) + end + common = fixture.dig(:expected, :structured_owner_common) + expect(analysis.link_definition_owners.map(&:label)).to eq(common[:link_definitions]) + expect(analysis.html_comment_owners.map(&:text)).to eq(common[:html_comments]) + expect(analysis.inline_reference_owners.map(&:label)).to eq(common[:inline_references]) + expect(analysis.table_row_owners.map(&:source)).to include(*common[:table_rows_include]) + end + it 'conforms to the slice-208 embedded-family fixture' do fixture = read_json(fixtures_root.join('markdown', 'slice-208-embedded-families', 'code-fence-families.json')) analysis = described_class.parse_markdown(fixture[:source], 'markdown') diff --git a/gems/markdown-merge/.gitattributes b/gems/markdown-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/markdown-merge/.gitattributes +++ b/gems/markdown-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/markdown-merge/.kettle-drift.lock b/gems/markdown-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/markdown-merge/.kettle-drift.lock +++ b/gems/markdown-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/markdown-merge/.rubocop_gradual.lock b/gems/markdown-merge/.rubocop_gradual.lock index a6b6711d3..4f8201218 100644 --- a/gems/markdown-merge/.rubocop_gradual.lock +++ b/gems/markdown-merge/.rubocop_gradual.lock @@ -76,54 +76,55 @@ "lib/markdown-merge.rb:1671676898": [ [1, 1, 0, "Naming/FileName: The name of this source file (`markdown-merge.rb`) should use snake_case.", 5381] ], - "lib/markdown/merge.rb:1153546526": [ + "lib/markdown/merge.rb:3835020687": [ [11, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Markdown::Merge`.", 2866359175], - [11, 3, 22021, "Metrics/ModuleLength: Module has too many lines. [533/100]", 519247419], - [19, 5, 16, "Style/Documentation: Missing top-level documentation comment for `class Markdown::Merge::ParseError`.", 362242086], - [101, 5, 1171, "Metrics/MethodLength: Method has too many lines. [28/10]", 2687169043], - [135, 5, 678, "Metrics/AbcSize: Assignment Branch Condition size for `match_markdown_owners` is too high. [<10, 23, 8> 26.32/17]", 2124140148], - [135, 5, 678, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `match_markdown_owners` is too high. [9/7]", 2124140148], - [135, 5, 678, "Metrics/PerceivedComplexity: Perceived complexity for `match_markdown_owners` is too high. [9/8]", 2124140148], - [148, 5, 1188, "Metrics/AbcSize: Assignment Branch Condition size for `merge_markdown` is too high. [<10, 25, 8> 28.09/17]", 3592129796], - [148, 5, 1188, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_markdown` is too high. [9/7]", 3592129796], - [148, 5, 1188, "Metrics/MethodLength: Method has too many lines. [23/10]", 3592129796], - [148, 5, 1188, "Metrics/PerceivedComplexity: Perceived complexity for `merge_markdown` is too high. [9/8]", 3592129796], - [177, 5, 513, "Metrics/MethodLength: Method has too many lines. [13/10]", 912081106], - [195, 5, 747, "Metrics/MethodLength: Method has too many lines. [16/10]", 3172863125], - [226, 5, 1513, "Metrics/AbcSize: Assignment Branch Condition size for `apply_markdown_delegated_child_outputs` is too high. [<16, 37, 9> 41.3/17]", 3320736661], - [226, 5, 1513, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_markdown_delegated_child_outputs` is too high. [10/7]", 3320736661], - [226, 5, 1513, "Metrics/MethodLength: Method has too many lines. [30/10]", 3320736661], - [226, 5, 1513, "Metrics/PerceivedComplexity: Perceived complexity for `apply_markdown_delegated_child_outputs` is too high. [10/8]", 3320736661], - [264, 5, 1058, "Metrics/MethodLength: Method has too many lines. [23/10]", 2000305522], - [291, 5, 1103, "Metrics/MethodLength: Method has too many lines. [23/10]", 2615729942], - [291, 52, 144, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3050457682], - [319, 5, 817, "Metrics/MethodLength: Method has too many lines. [13/10]", 322304706], - [324, 121, 74, "Layout/LineLength: Line is too long. [194/120]", 2378183959], - [337, 5, 805, "Metrics/MethodLength: Method has too many lines. [13/10]", 935244360], - [342, 121, 66, "Layout/LineLength: Line is too long. [186/120]", 2974266470], - [355, 5, 722, "Metrics/MethodLength: Method has too many lines. [12/10]", 1758487766], - [360, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], - [372, 5, 730, "Metrics/MethodLength: Method has too many lines. [12/10]", 3297037131], - [377, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], - [403, 5, 1584, "Metrics/AbcSize: Assignment Branch Condition size for `collect_markdown_owners` is too high. [<21, 32, 13> 40.42/17]", 572024212], - [403, 5, 1584, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_markdown_owners` is too high. [11/7]", 572024212], - [403, 5, 1584, "Metrics/MethodLength: Method has too many lines. [45/10]", 572024212], - [403, 5, 1584, "Metrics/PerceivedComplexity: Perceived complexity for `collect_markdown_owners` is too high. [11/8]", 572024212], - [457, 5, 1147, "Metrics/AbcSize: Assignment Branch Condition size for `markdown_owner_start_indices` is too high. [<21, 22, 11> 32.34/17]", 12516264], - [457, 5, 1147, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `markdown_owner_start_indices` is too high. [9/7]", 12516264], - [457, 5, 1147, "Metrics/MethodLength: Method has too many lines. [33/10]", 12516264], - [457, 5, 1147, "Metrics/PerceivedComplexity: Perceived complexity for `markdown_owner_start_indices` is too high. [9/8]", 12516264], - [498, 5, 602, "Metrics/AbcSize: Assignment Branch Condition size for `collect_markdown_sections` is too high. [<9, 20, 6> 22.74/17]", 1946206422], - [498, 5, 602, "Metrics/MethodLength: Method has too many lines. [14/10]", 1946206422], - [506, 7, 11, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 848344986], - [517, 5, 1097, "Metrics/AbcSize: Assignment Branch Condition size for `markdown_fence_ranges` is too high. [<19, 21, 11> 30.38/17]", 2035260313], - [517, 5, 1097, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `markdown_fence_ranges` is too high. [8/7]", 2035260313], - [517, 5, 1097, "Metrics/MethodLength: Method has too many lines. [31/10]", 2035260313], - [533, 13, 227, "Metrics/BlockNesting: Avoid more than 3 levels of block nesting.", 1054958538], - [555, 5, 323, "Metrics/MethodLength: Method has too many lines. [14/10]", 2041170985] - ], - "lib/markdown/merge/backend_support.rb:2705430333": [ - [6, 5, 6534, "Metrics/ModuleLength: Module has too many lines. [148/100]", 1497234257], + [11, 3, 23539, "Metrics/ModuleLength: Module has too many lines. [564/100]", 3838590514], + [22, 5, 16, "Style/Documentation: Missing top-level documentation comment for `class Markdown::Merge::ParseError`.", 362242086], + [104, 5, 990, "Metrics/MethodLength: Method has too many lines. [23/10]", 650805533], + [133, 5, 678, "Metrics/AbcSize: Assignment Branch Condition size for `match_markdown_owners` is too high. [<10, 23, 8> 26.32/17]", 2124140148], + [133, 5, 678, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `match_markdown_owners` is too high. [9/7]", 2124140148], + [133, 5, 678, "Metrics/PerceivedComplexity: Perceived complexity for `match_markdown_owners` is too high. [9/8]", 2124140148], + [146, 5, 1188, "Metrics/AbcSize: Assignment Branch Condition size for `merge_markdown` is too high. [<10, 25, 8> 28.09/17]", 3592129796], + [146, 5, 1188, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_markdown` is too high. [9/7]", 3592129796], + [146, 5, 1188, "Metrics/MethodLength: Method has too many lines. [23/10]", 3592129796], + [146, 5, 1188, "Metrics/PerceivedComplexity: Perceived complexity for `merge_markdown` is too high. [9/8]", 3592129796], + [175, 5, 513, "Metrics/MethodLength: Method has too many lines. [13/10]", 912081106], + [193, 5, 747, "Metrics/MethodLength: Method has too many lines. [16/10]", 3172863125], + [224, 5, 1513, "Metrics/AbcSize: Assignment Branch Condition size for `apply_markdown_delegated_child_outputs` is too high. [<16, 37, 9> 41.3/17]", 3320736661], + [224, 5, 1513, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_markdown_delegated_child_outputs` is too high. [10/7]", 3320736661], + [224, 5, 1513, "Metrics/MethodLength: Method has too many lines. [30/10]", 3320736661], + [224, 5, 1513, "Metrics/PerceivedComplexity: Perceived complexity for `apply_markdown_delegated_child_outputs` is too high. [10/8]", 3320736661], + [262, 5, 1058, "Metrics/MethodLength: Method has too many lines. [23/10]", 2000305522], + [289, 5, 1103, "Metrics/MethodLength: Method has too many lines. [23/10]", 2615729942], + [289, 52, 144, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3050457682], + [317, 5, 817, "Metrics/MethodLength: Method has too many lines. [13/10]", 322304706], + [322, 121, 74, "Layout/LineLength: Line is too long. [194/120]", 2378183959], + [335, 5, 805, "Metrics/MethodLength: Method has too many lines. [13/10]", 935244360], + [340, 121, 66, "Layout/LineLength: Line is too long. [186/120]", 2974266470], + [353, 5, 722, "Metrics/MethodLength: Method has too many lines. [12/10]", 1758487766], + [358, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], + [370, 5, 730, "Metrics/MethodLength: Method has too many lines. [12/10]", 3297037131], + [375, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], + [401, 5, 1584, "Metrics/AbcSize: Assignment Branch Condition size for `collect_markdown_owners` is too high. [<21, 32, 13> 40.42/17]", 572024212], + [401, 5, 1584, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_markdown_owners` is too high. [11/7]", 572024212], + [401, 5, 1584, "Metrics/MethodLength: Method has too many lines. [45/10]", 572024212], + [401, 5, 1584, "Metrics/PerceivedComplexity: Perceived complexity for `collect_markdown_owners` is too high. [11/8]", 572024212], + [455, 5, 1147, "Metrics/AbcSize: Assignment Branch Condition size for `markdown_owner_start_indices` is too high. [<21, 22, 11> 32.34/17]", 12516264], + [455, 5, 1147, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `markdown_owner_start_indices` is too high. [9/7]", 12516264], + [455, 5, 1147, "Metrics/MethodLength: Method has too many lines. [33/10]", 12516264], + [455, 5, 1147, "Metrics/PerceivedComplexity: Perceived complexity for `markdown_owner_start_indices` is too high. [9/8]", 12516264], + [496, 5, 602, "Metrics/AbcSize: Assignment Branch Condition size for `collect_markdown_sections` is too high. [<9, 20, 6> 22.74/17]", 1946206422], + [496, 5, 602, "Metrics/MethodLength: Method has too many lines. [14/10]", 1946206422], + [504, 7, 11, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 848344986], + [515, 5, 1097, "Metrics/AbcSize: Assignment Branch Condition size for `markdown_fence_ranges` is too high. [<19, 21, 11> 30.38/17]", 2035260313], + [515, 5, 1097, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `markdown_fence_ranges` is too high. [8/7]", 2035260313], + [515, 5, 1097, "Metrics/MethodLength: Method has too many lines. [31/10]", 2035260313], + [531, 13, 227, "Metrics/BlockNesting: Avoid more than 3 levels of block nesting.", 1054958538], + [553, 5, 323, "Metrics/MethodLength: Method has too many lines. [14/10]", 2041170985], + [589, 5, 525, "Metrics/MethodLength: Method has too many lines. [11/10]", 1507618315] + ], + "lib/markdown/merge/backend_support.rb:1723133349": [ + [6, 5, 6677, "Metrics/ModuleLength: Module has too many lines. [151/100]", 1497234257], [18, 7, 524, "Metrics/MethodLength: Method has too many lines. [13/10]", 2550700841], [34, 7, 913, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `configure_markdown_only_language_class!` is too high. [9/7]", 2175633707], [34, 7, 913, "Metrics/MethodLength: Method has too many lines. [14/10]", 2175633707], @@ -135,7 +136,7 @@ [54, 7, 1263, "Metrics/MethodLength: Method has too many lines. [20/10]", 122101535], [98, 7, 976, "Metrics/MethodLength: Method has too many lines. [24/10]", 2694447150], [132, 7, 618, "Metrics/MethodLength: Method has too many lines. [11/10]", 2027069469], - [150, 7, 745, "Metrics/MethodLength: Method has too many lines. [18/10]", 3512214017] + [150, 7, 888, "Metrics/MethodLength: Method has too many lines. [21/10]", 3721642530] ], "lib/markdown/merge/cleanse/block_spacing.rb:2917446564": [ [32, 7, 7186, "Metrics/ClassLength: Class has too many lines. [138/100]", 1732896955], @@ -258,13 +259,14 @@ [466, 7, 879, "Metrics/MethodLength: Method has too many lines. [21/10]", 1144304252], [466, 7, 879, "Metrics/PerceivedComplexity: Perceived complexity for `first_list_item_anchor` is too high. [10/8]", 1144304252] ], - "lib/markdown/merge/file_analysis.rb:3254360574": [ - [41, 5, 12519, "Metrics/ClassLength: Class has too many lines. [183/100]", 4132960115], + "lib/markdown/merge/file_analysis.rb:1169434297": [ + [41, 5, 12695, "Metrics/ClassLength: Class has too many lines. [183/100]", 3122418242], [168, 7, 2960, "Metrics/AbcSize: Assignment Branch Condition size for `compute_parser_signature` is too high. [<13, 36, 18> 42.3/17]", 1002271909], [168, 7, 2960, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_parser_signature` is too high. [17/7]", 1002271909], [168, 7, 2960, "Metrics/MethodLength: Method has too many lines. [42/10]", 1002271909], [168, 7, 2960, "Metrics/PerceivedComplexity: Perceived complexity for `compute_parser_signature` is too high. [11/8]", 1002271909], - [290, 7, 777, "Metrics/MethodLength: Method has too many lines. [14/10]", 1287754637] + [290, 7, 777, "Metrics/MethodLength: Method has too many lines. [14/10]", 1287754637], + [328, 7, 558, "Metrics/MethodLength: Method has too many lines. [15/10]", 3417342515] ], "lib/markdown/merge/file_analysis_base.rb:678024820": [ [37, 5, 26494, "Metrics/ClassLength: Class has too many lines. [405/100]", 2769422452], @@ -417,8 +419,8 @@ [224, 7, 878, "Metrics/MethodLength: Method has too many lines. [13/10]", 227721314], [224, 7, 878, "Metrics/PerceivedComplexity: Perceived complexity for `extract_parser_node_source` is too high. [11/8]", 227721314] ], - "lib/markdown/merge/partial_template_merger.rb:2021024147": [ - [32, 5, 20682, "Metrics/ClassLength: Class has too many lines. [336/100]", 2506387030], + "lib/markdown/merge/partial_template_merger.rb:3110525012": [ + [32, 5, 20691, "Metrics/ClassLength: Class has too many lines. [336/100]", 496419120], [71, 7, 1040, "Metrics/MethodLength: Method has too many lines. [17/10]", 2144648319], [71, 21, 417, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [14/5]", 1226086326], [109, 7, 1065, "Metrics/AbcSize: Assignment Branch Condition size for `merge` is too high. [<7, 19, 6> 21.12/17]", 3976180000], @@ -464,7 +466,7 @@ [271, 7, 704, "Metrics/MethodLength: Method has too many lines. [13/10]", 2605835865], [271, 52, 139, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 1766111143] ], - "lib/markdown/merge/smart_merger.rb:2962410240": [ + "lib/markdown/merge/smart_merger.rb:1245982439": [ [151, 7, 1405, "Metrics/MethodLength: Method has too many lines. [19/10]", 2830703815], [151, 21, 501, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [13/5]", 1104874368], [229, 7, 1140, "Metrics/AbcSize: Assignment Branch Condition size for `node_to_source` is too high. [<5, 15, 9> 18.19/17]", 1515173572], diff --git a/gems/markdown-merge/Gemfile b/gems/markdown-merge/Gemfile index db75aec3a..9f0788f60 100644 --- a/gems/markdown-merge/Gemfile +++ b/gems/markdown-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/markdown-merge/Gemfile.lock b/gems/markdown-merge/Gemfile.lock index d3673f046..14b5d2a15 100644 --- a/gems/markdown-merge/Gemfile.lock +++ b/gems/markdown-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,20 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -470,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -481,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -508,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/markdown-merge/gemfiles/modular/templating.gemfile b/gems/markdown-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/markdown-merge/gemfiles/modular/templating.gemfile +++ b/gems/markdown-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/markdown-merge/gemfiles/modular/templating_local.gemfile b/gems/markdown-merge/gemfiles/modular/templating_local.gemfile index e250d15b6..c206a246f 100644 --- a/gems/markdown-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/markdown-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[markdown-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[markdown-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[markdown-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/markdown-merge/lib/markdown/merge.rb b/gems/markdown-merge/lib/markdown/merge.rb index 29a65345e..6ca10ba81 100644 --- a/gems/markdown-merge/lib/markdown/merge.rb +++ b/gems/markdown-merge/lib/markdown/merge.rb @@ -11,8 +11,12 @@ module Markdown module Merge PACKAGE_NAME = 'markdown-merge' BACKEND_REFERENCES = { - 'kreuzberg-language-pack' => TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND + 'kreuzberg-language-pack' => TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND, + 'commonmarker' => TreeHaver::BackendReference.new(id: 'commonmarker', family: 'native').freeze, + 'markly' => TreeHaver::BackendReference.new(id: 'markly', family: 'native').freeze, + 'kramdown' => TreeHaver::BackendReference.new(id: 'kramdown', family: 'native').freeze }.freeze + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) class Error < Ast::Merge::Error; end @@ -60,6 +64,19 @@ class CorruptionDetectedError < Error; end autoload :WhitespaceNormalizer, 'markdown/merge/whitespace_normalizer' autoload :WrapperSupport, 'markdown/merge/wrapper_support' + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(BACKEND_REFERENCES.fetch('kreuzberg-language-pack')) + + grammar_finder = TreeHaver::GrammarFinder.new(:markdown) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end + def markdown_feature_profile { family: 'markdown', @@ -69,7 +86,9 @@ def markdown_feature_profile end def available_markdown_backends - BACKEND_REFERENCES.values + BACKEND_REFERENCES.filter_map do |backend_id, reference| + reference if markdown_backend_available_for_analysis?(backend_id) + end end def markdown_backend_feature_profile(backend: nil) @@ -102,14 +121,14 @@ def parse_markdown(source, dialect, backend: nil) return unsupported_feature_result("Unsupported Markdown dialect #{dialect}.") unless dialect == 'markdown' resolved_backend = resolve_backend(backend) - unless resolved_backend == 'kreuzberg-language-pack' + unless BACKEND_REFERENCES.key?(resolved_backend) return unsupported_feature_result("Unsupported Markdown backend #{resolved_backend}.") end - syntax = TreeHaver.parse_with_language_pack( - TreeHaver::ParserRequest.new(source: source, language: 'markdown', dialect: dialect) - ) - return { ok: false, diagnostics: syntax[:diagnostics], policies: [] } unless syntax[:ok] + register_backend! + parser = TreeHaver.with_backend(resolved_backend) { TreeHaver.parser_for(:markdown) } + tree = parser.parse(source) + collect_parse_errors(tree.root_node) normalized_source = normalize_source(source) { @@ -124,12 +143,8 @@ def parse_markdown(source, dialect, backend: nil) }, policies: [] } - rescue StandardError => e - { - ok: false, - diagnostics: [{ severity: 'error', category: 'parse_error', message: e.message }], - policies: [] - } + rescue TreeHaver::Error, StandardError => e + parse_failure_result(e) end def match_markdown_owners(template, destination) @@ -579,7 +594,44 @@ def code_fence_dialect(info_string, family) end def resolve_backend(backend) - backend.to_s.empty? ? 'kreuzberg-language-pack' : backend.to_s + return backend.to_s unless backend.to_s.empty? + + current = TreeHaver.current_backend_id + return current if BACKEND_REFERENCES.key?(current.to_s) && markdown_backend_available_for_analysis?(current) + + BACKEND_REFERENCES.keys.find { |backend_id| markdown_backend_available_for_analysis?(backend_id) } || + 'kreuzberg-language-pack' + end + + def markdown_backend_available_for_analysis?(backend_id) + register_backend! + registrations = TreeHaver.registered_languages(:markdown) + case backend_id.to_s + when 'commonmarker', 'markly', 'kramdown' + registrations.dig(backend_id.to_sym, :backend_module)&.then do |backend_module| + !backend_module.respond_to?(:available?) || backend_module.available? + end + when 'kreuzberg-language-pack' + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + else + false + end + end + + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'Markdown parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'Markdown parse contains syntax errors' + end + + def parse_failure_result(error) + { + ok: false, + diagnostics: [{ severity: 'error', category: 'parse_error', message: error.message }], + policies: [] + } end def unsupported_feature_result(message) @@ -591,6 +643,7 @@ def unsupported_feature_result(message) end module_function( + :register_backend!, :markdown_feature_profile, :available_markdown_backends, :markdown_backend_feature_profile, @@ -617,6 +670,9 @@ def unsupported_feature_result(message) :code_fence_family, :code_fence_dialect, :resolve_backend, + :markdown_backend_available_for_analysis?, + :collect_parse_errors, + :parse_failure_result, :unsupported_feature_result ) end diff --git a/gems/markdown-merge/lib/markdown/merge/backend_support.rb b/gems/markdown-merge/lib/markdown/merge/backend_support.rb index 711eb8a81..b7c213224 100644 --- a/gems/markdown-merge/lib/markdown/merge/backend_support.rb +++ b/gems/markdown-merge/lib/markdown/merge/backend_support.rb @@ -79,18 +79,28 @@ def configure_node_link_and_navigation!(klass, next_sibling_selector:, prev_sibl end end - def configure_node_heading_and_code_block_helpers!(klass, heading_matcher:, code_block_matcher:) + def configure_node_heading_and_code_block_helpers!(klass, heading_matcher:, code_block_matcher:, + heading_level_extractor: nil, + code_block_info_extractor: nil) klass.class_eval do define_method(:header_level) do return unless Markdown::Merge::BackendSupport.send(:node_helper_match?, self, heading_matcher) - Markdown::Merge::BackendSupport.send(:safe_inner_node_call, inner_node, :header_level) + if heading_level_extractor.respond_to?(:call) + heading_level_extractor.call(inner_node) + else + Markdown::Merge::BackendSupport.send(:safe_inner_node_call, inner_node, :header_level) + end end define_method(:fence_info) do return unless Markdown::Merge::BackendSupport.send(:node_helper_match?, self, code_block_matcher) - Markdown::Merge::BackendSupport.send(:safe_inner_node_call, inner_node, :fence_info) + if code_block_info_extractor.respond_to?(:call) + code_block_info_extractor.call(inner_node) + else + Markdown::Merge::BackendSupport.send(:safe_inner_node_call, inner_node, :fence_info) + end end end end @@ -148,6 +158,10 @@ def install_tree_wrapper!(backend_module) private_class_method :install_tree_wrapper! def register_backend!(backend_module:, backend_name:, gem_name:, require_path:) + ::TreeHaver::BackendRegistry.register( + ::TreeHaver::BackendReference.new(id: backend_name.to_s, family: 'native') + ) + ::TreeHaver.register_language( :markdown, backend_type: backend_name, diff --git a/gems/markdown-merge/lib/markdown/merge/file_analysis.rb b/gems/markdown-merge/lib/markdown/merge/file_analysis.rb index ffc20dcc6..d86cea23a 100644 --- a/gems/markdown-merge/lib/markdown/merge/file_analysis.rb +++ b/gems/markdown-merge/lib/markdown/merge/file_analysis.rb @@ -61,16 +61,33 @@ def default_freeze_node_class end end - # @return [Symbol] The backend being used (:commonmarker, :markly) + # @return [Symbol] The backend being used (:commonmarker, :markly, :kramdown) attr_reader :backend # @return [Hash] Parser-specific options attr_reader :parser_options + Location = Struct.new(:start_line, :end_line, keyword_init: true) + HeadingSectionOwner = Struct.new(:location, :heading_text, :heading_source, :level, :base, keyword_init: true) + LinkDefinitionOwner = Struct.new(:location, :label, :url, :title, :source, keyword_init: true) + HtmlCommentOwner = Struct.new(:location, :text, :source, keyword_init: true) + InlineReferenceOwner = Struct.new( + :location, + :line, + :start_column, + :end_column, + :source, + :reference_kind, + :label, + :labels, + keyword_init: true + ) + TableRowOwner = Struct.new(:location, :source, :text, keyword_init: true) + # Initialize file analysis with tree_haver backend. # # @param source [String] Markdown source code to analyze - # @param backend [Symbol] Backend to use (:commonmarker, :markly, :auto) + # @param backend [Symbol] Backend to use (:commonmarker, :markly, :kramdown, :auto) # @param freeze_token [String] Token for freeze block markers # @param signature_generator [Proc, nil] Custom signature generator # @param parser_options [Hash] Backend-specific parser options @@ -272,8 +289,260 @@ def collect_top_level_nodes nodes end + def heading_section_owners + headings = Array(statements).filter_map do |statement| + next unless heading_statement?(statement) + + build_heading_owner(statement) + end + + headings.each_with_index.map do |owner, index| + branch_end_line = branch_end_line(headings, index) + HeadingSectionOwner.new( + location: Location.new(start_line: owner.location.start_line, end_line: branch_end_line), + heading_text: owner.heading_text, + heading_source: owner.heading_source, + level: owner.level, + base: owner.base + ) + end + end + + def link_definition_owners + Array(statements).filter_map do |statement| + next unless statement.respond_to?(:merge_type) && statement.merge_type == :link_definition + + position = statement.source_position + next unless position + + LinkDefinitionOwner.new( + location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), + label: statement.label, + url: statement.url, + title: statement.title, + source: if statement.respond_to?(:content) + statement.content + else + source_range(position[:start_line], position[:end_line]).chomp + end + ) + end + end + + def html_comment_owners + comment_tracker.comment_nodes.map do |comment| + HtmlCommentOwner.new( + location: Location.new(start_line: comment.location.start_line, end_line: comment.location.end_line), + text: comment.content, + source: comment.text + ) + end + end + + def inline_reference_owners + source.to_s.lines.each_with_index.flat_map do |line, index| + inline_references_for_line(line.chomp, index + 1) + end + end + + def table_row_owners + ast_table_lines = {} + ast_rows = Array(statements).flat_map do |statement| + node = unwrap_markdown_statement(statement) + next [] unless node.respond_to?(:type) && node.type.to_s == 'table' + + table_position = node.source_position + if table_position + (table_position[:start_line]..table_position[:end_line]).each do |line| + ast_table_lines[line] = true + end + end + Array(node.children).filter_map do |child| + next unless child.respond_to?(:type) && child.type.to_s == 'table_row' + + position = child.source_position + next unless position + + TableRowOwner.new( + location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), + source: source_range(position[:start_line], position[:end_line]), + text: extract_text_content(child) + ) + end + end + ast_lines = ast_rows.map { |owner| owner.location.start_line }.to_h { |line| [line, true] } + loose_rows = source.to_s.lines.each_with_index.filter_map do |line, index| + line_number = index + 1 + next if ast_lines[line_number] + next if ast_table_lines[line_number] + next unless loose_table_row_line?(line) + + TableRowOwner.new( + location: Location.new(start_line: line_number, end_line: line_number), + source: line, + text: line + ) + end + ast_rows + loose_rows + end + private + def loose_table_row_line?(line) + stripped = line.to_s.lstrip + return false unless stripped.start_with?('|') + + stripped.include?(' |') || stripped.include?('| ') + end + + def heading_statement?(statement) + merge_type = if statement.respond_to?(:merge_type) + statement.merge_type + else + unwrap_markdown_statement(statement)&.type + end + + %w[heading header].include?(merge_type.to_s) + end + + def build_heading_owner(statement) + node = unwrap_markdown_statement(statement) + position = node&.source_position + return unless node && position + + heading_source = source_range(position[:start_line], position[:end_line]).sub(/\n\z/, '') + heading_text = node.to_plaintext.to_s.sub(/\n+\z/, '') + HeadingSectionOwner.new( + location: Location.new(start_line: position[:start_line], end_line: position[:end_line]), + heading_text: heading_text, + heading_source: heading_source, + level: node.header_level, + base: normalize_heading_base(heading_text) + ) + rescue StandardError + nil + end + + def branch_end_line(headings, index) + current = headings[index] + cursor = index + 1 + while cursor < headings.length + return headings[cursor].location.start_line - 1 if headings[cursor].level <= current.level + + cursor += 1 + end + + source.to_s.lines.length + end + + def unwrap_markdown_statement(statement) + Ast::Merge::NodeTyping.unwrap(statement) + rescue StandardError + statement + end + + def normalize_heading_base(text) + text.to_s.sub(/\A(?:\d\uFE0F?\u20E3|[^[:alnum:][:space:]])+[ \t]*/u, '').strip.downcase + end + + def inline_references_for_line(line, line_number) + owners = [] + index = 0 + while index < line.length + image = inline_image_reference_at(line, index, line_number) + if image + owners << image + index = image.end_column + next + end + + link = inline_link_reference_at(line, index, line_number) + if link + owners << link + index = link.end_column + next + end + + index += 1 + end + owners + end + + def inline_image_reference_at(line, index, line_number) + return unless line[index] == '!' && line[index + 1] == '[' + + alt_end = closing_bracket_index(line, index + 1) + return unless alt_end && line[alt_end + 1] == '[' + + label_end = closing_bracket_index(line, alt_end + 1) + return unless label_end + + label = line[(alt_end + 2)...label_end] + inline_reference_owner( + line: line, + line_number: line_number, + start_column: index, + end_column: label_end + 1, + reference_kind: :image_reference, + label: label, + labels: [label] + ) + end + + def inline_link_reference_at(line, index, line_number) + return unless line[index] == '[' + + text_end = closing_bracket_index(line, index) + return unless text_end && line[text_end + 1] == '[' + + label_end = closing_bracket_index(line, text_end + 1) + return unless label_end + + text = line[(index + 1)...text_end] + label = line[(text_end + 2)...label_end] + image_owner = inline_image_reference_at(text, 0, line_number) + labels = [label] + labels.unshift(image_owner.label) if image_owner && image_owner.source == text + inline_reference_owner( + line: line, + line_number: line_number, + start_column: index, + end_column: label_end + 1, + reference_kind: labels.length > 1 ? :linked_image_reference : :link_reference, + label: label, + labels: labels + ) + end + + def inline_reference_owner(line:, line_number:, start_column:, end_column:, reference_kind:, label:, labels:) + InlineReferenceOwner.new( + location: Location.new(start_line: line_number, end_line: line_number), + line: line_number, + start_column: start_column, + end_column: end_column, + source: line[start_column...end_column], + reference_kind: reference_kind, + label: label, + labels: labels.compact.uniq + ) + end + + def closing_bracket_index(text, opening_index) + depth = 0 + index = opening_index + while index < text.length + case text[index] + when '[' + depth += 1 + when ']' + depth -= 1 + return index if depth.zero? + end + index += 1 + end + nil + end + # Recursively collect text content from a node and its descendants. # # Uses NodeTypeNormalizer to map backend-specific types to canonical types, @@ -311,63 +580,68 @@ def collect_text_recursive(node, text_parts) # Resolve the backend to use. # - # For :auto, attempts commonmarker first, then markly. - # tree_haver handles the actual availability checking. + # For :auto, use the same backend selection as the Markdown substrate facade. + # tree_haver handles the final availability checking. # # @param backend [Symbol] Requested backend - # @return [Symbol] Resolved backend (:commonmarker or :markly) + # @return [Symbol] Resolved backend def resolve_backend(backend) - return backend unless backend == :auto + return Markdown::Merge.resolve_backend(nil).to_sym if backend.to_s.empty? || backend == :auto - # Try commonmarker first, then markly - if TreeHaver::BackendRegistry.available?(:commonmarker) - :commonmarker - elsif TreeHaver::BackendRegistry.available?(:markly) - :markly - else - # Let tree_haver raise the appropriate error - :commonmarker - end + backend.to_sym end # Create a parser for the resolved backend. # # @return [Object] tree_haver parser instance def create_parser + unless Markdown::Merge::BACKEND_REFERENCES.key?(@backend.to_s) + raise ArgumentError, "Unknown backend: #{@backend}" + end + + parser = TreeHaver.with_backend(@backend) { TreeHaver.parser_for(:markdown) } + case @backend when :commonmarker - create_commonmarker_parser + parser.language = commonmarker_language when :markly - create_markly_parser + parser.language = markly_language + when :kramdown + parser.language = kramdown_language else - raise ArgumentError, "Unknown backend: #{@backend}" + return parser end + + parser end - # Create a Commonmarker parser via commonmarker-merge backend. + # Create a Commonmarker language config for the TreeHaver parser. # - # @return [Commonmarker::Merge::Backend::Parser] - def create_commonmarker_parser - parser = Commonmarker::Merge::Backend::Parser.new + # @return [Commonmarker::Merge::Backend::Language] + def commonmarker_language # Default options enable table extension for GFM compatibility default_options = { extension: { table: true } } options = default_options.merge(@parser_options[:options] || {}) - parser.language = Commonmarker::Merge::Backend::Language.markdown(options: options) - parser + Commonmarker::Merge::Backend::Language.markdown(options: options) end - # Create a Markly parser via markly-merge backend. + # Create a Markly language config for the TreeHaver parser. # - # @return [Markly::Merge::Backend::Parser] - def create_markly_parser - parser = Markly::Merge::Backend::Parser.new + # @return [Markly::Merge::Backend::Language] + def markly_language flags = @parser_options[:flags] extensions = @parser_options[:extensions] || [:table] - parser.language = Markly::Merge::Backend::Language.markdown( + Markly::Merge::Backend::Language.markdown( flags: flags, extensions: extensions ) - parser + end + + # Create a Kramdown language config for the TreeHaver parser. + # + # @return [Kramdown::Merge::Backend::Language] + def kramdown_language + Kramdown::Merge::Backend::Language.markdown(options: @parser_options[:options] || {}) end end end diff --git a/gems/markdown-merge/lib/markdown/merge/partial_template_merger.rb b/gems/markdown-merge/lib/markdown/merge/partial_template_merger.rb index c6af2096c..ddcbc84da 100644 --- a/gems/markdown-merge/lib/markdown/merge/partial_template_merger.rb +++ b/gems/markdown-merge/lib/markdown/merge/partial_template_merger.rb @@ -169,7 +169,7 @@ def merge_section_content(section_content, section_context: nil) # @param backend [Symbol] The backend to validate # @raise [ArgumentError] If backend is not supported def validate_backend!(backend) - valid_backends = %i[auto markly commonmarker] + valid_backends = %i[auto markly commonmarker kramdown] return if valid_backends.include?(backend.to_sym) raise ArgumentError, "Unknown backend: #{backend}. Supported: #{valid_backends.join(', ')}" diff --git a/gems/markdown-merge/lib/markdown/merge/smart_merger.rb b/gems/markdown-merge/lib/markdown/merge/smart_merger.rb index 3620460fa..b7c228393 100644 --- a/gems/markdown-merge/lib/markdown/merge/smart_merger.rb +++ b/gems/markdown-merge/lib/markdown/merge/smart_merger.rb @@ -59,7 +59,7 @@ module Merge # @see FileAnalysis # @see SmartMergerBase class SmartMerger < SmartMergerBase - VALID_BACKENDS = %i[auto commonmarker markly].freeze + VALID_BACKENDS = %i[auto commonmarker markly kramdown].freeze class << self def default_backend diff --git a/gems/markdown-merge/spec/fixtures_integration_spec.rb b/gems/markdown-merge/spec/fixtures_integration_spec.rb index 4241240aa..33f07a476 100644 --- a/gems/markdown-merge/spec/fixtures_integration_spec.rb +++ b/gems/markdown-merge/spec/fixtures_integration_spec.rb @@ -36,9 +36,7 @@ def json_ready(value) ) expect(json_ready(markdown_merge.available_markdown_backends.map(&:to_h))).to eq( - json_ready([ - { id: 'kreuzberg-language-pack', family: 'tree-sitter' } - ]) + json_ready(fixture[:available_backends]) ) expect(json_ready(TreeHaver::BackendRegistry.fetch('kreuzberg-language-pack')&.to_h)).to eq( json_ready({ id: 'kreuzberg-language-pack', family: 'tree-sitter' }) @@ -102,6 +100,30 @@ def json_ready(value) ) end + it 'conforms to the slice-721 Markdown provider parity fixture for the TSLP backend' do + fixture = read_json( + fixtures_root.join( + 'markdown', + 'slice-721-provider-parity', + 'headings-lists-tables-fences-links-frontmatter-comments.json' + ) + ) + + result = markdown_merge.parse_markdown(fixture[:source], fixture[:dialect], backend: 'kreuzberg-language-pack') + owners = result.dig(:analysis, :owners) + expect(owners.map { |owner| owner[:owner_kind] }).to eq(fixture.dig(:expected, :parse_owner_kinds)) + expect(owners.map { |owner| owner[:match_key] }).to eq(fixture.dig(:expected, :parse_owner_match_keys)) + + analysis = TreeHaver.with_backend('kreuzberg-language-pack') do + Markdown::Merge::FileAnalysis.new(fixture[:source]) + end + common = fixture.dig(:expected, :structured_owner_common) + expect(analysis.link_definition_owners.map(&:label)).to eq(common[:link_definitions]) + expect(analysis.html_comment_owners.map(&:text)).to eq(common[:html_comments]) + expect(analysis.inline_reference_owners.map(&:label)).to eq(common[:inline_references]) + expect(analysis.table_row_owners.map(&:source)).to include(*common[:table_rows_include]) + end + it 'conforms to the slice-199 Markdown matching fixture' do fixture = read_json(fixtures_root.join('markdown', 'slice-199-matching', 'path-equality.json')) diff --git a/gems/markly-merge/.gitattributes b/gems/markly-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/markly-merge/.gitattributes +++ b/gems/markly-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/markly-merge/.kettle-drift.lock b/gems/markly-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/markly-merge/.kettle-drift.lock +++ b/gems/markly-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/markly-merge/.rubocop_gradual.lock b/gems/markly-merge/.rubocop_gradual.lock index 42ea6fd31..7b6a96fee 100644 --- a/gems/markly-merge/.rubocop_gradual.lock +++ b/gems/markly-merge/.rubocop_gradual.lock @@ -76,9 +76,9 @@ "lib/markly-merge.rb:2425755333": [ [1, 1, 0, "Naming/FileName: The name of this source file (`markly-merge.rb`) should use snake_case.", 5381] ], - "lib/markly/merge.rb:2040353384": [ + "lib/markly/merge.rb:2367262886": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Markly::Merge`.", 2866359175], - [10, 3, 22662, "Metrics/ModuleLength: Module has too many lines. [484/100]", 3039251951], + [10, 3, 22686, "Metrics/ModuleLength: Module has too many lines. [484/100]", 3039251951], [11, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], [56, 5, 1957, "Metrics/MethodLength: Method has too many lines. [42/10]", 2638032592], [101, 5, 1815, "Metrics/MethodLength: Method has too many lines. [37/10]", 421864374], @@ -91,7 +91,7 @@ [234, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 2184804663], [253, 121, 26, "Layout/LineLength: Line is too long. [146/120]", 4247938618], [291, 121, 69, "Layout/LineLength: Line is too long. [189/120]", 713082266], - [375, 5, 904, "Metrics/MethodLength: Method has too many lines. [24/10]", 2523239963], + [375, 5, 928, "Metrics/MethodLength: Method has too many lines. [24/10]", 2523239963], [416, 5, 613, "Metrics/MethodLength: Method has too many lines. [11/10]", 2967276583], [416, 52, 144, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3050457682] ], diff --git a/gems/markly-merge/Gemfile b/gems/markly-merge/Gemfile index 2149c951f..6ba032869 100644 --- a/gems/markly-merge/Gemfile +++ b/gems/markly-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/markly-merge/Gemfile.lock b/gems/markly-merge/Gemfile.lock index 69fb7de90..b6b3eb1cf 100644 --- a/gems/markly-merge/Gemfile.lock +++ b/gems/markly-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH markly (~> 0.9) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,10 +390,6 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) @@ -275,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -327,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -358,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -378,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -403,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -435,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -447,15 +750,20 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 @@ -477,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -488,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -515,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -526,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -539,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/markly-merge/gemfiles/modular/templating.gemfile b/gems/markly-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/markly-merge/gemfiles/modular/templating.gemfile +++ b/gems/markly-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/markly-merge/gemfiles/modular/templating_local.gemfile b/gems/markly-merge/gemfiles/modular/templating_local.gemfile index 5d0020cfe..697d305f3 100644 --- a/gems/markly-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/markly-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[markly-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[markly-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[markly-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/markly-merge/lib/markly/merge.rb b/gems/markly-merge/lib/markly/merge.rb index dcbe2801b..5b4f0a7ff 100644 --- a/gems/markly-merge/lib/markly/merge.rb +++ b/gems/markly-merge/lib/markly/merge.rb @@ -378,7 +378,7 @@ def parse_markdown(source, dialect, backend: nil) return unsupported_feature_result("Unsupported Markdown backend #{requested}.") end - ::Markly.parse(source, flags: ::Markly::DEFAULT, extensions: [:table]) + TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:markdown).parse(source) } normalized = Markdown::Merge.normalize_source(source) { ok: true, diff --git a/gems/markly-merge/spec/fixtures_integration_spec.rb b/gems/markly-merge/spec/fixtures_integration_spec.rb index 4ca14d480..83794cb45 100644 --- a/gems/markly-merge/spec/fixtures_integration_spec.rb +++ b/gems/markly-merge/spec/fixtures_integration_spec.rb @@ -45,6 +45,30 @@ def json_ready(value) expect(json_ready(described_class.markdown_plan_context)).to eq(json_ready(plan_fixture.dig(:providers, :markly))) end + it 'inherits shared Markdown structured-edit owner projections' do + source = <<~MARKDOWN + # Title + + ## Synopsis + + [docs]: README.md + + + [Docs][docs] ![Build][build] + + | Feature | Badge | + | --- | --- | + | Works | [Docs][docs] | + MARKDOWN + analysis = described_class::FileAnalysis.new(source) + + expect(analysis.heading_section_owners.map(&:heading_text)).to include('Synopsis') + expect(analysis.link_definition_owners.map(&:label)).to include('docs') + expect(analysis.html_comment_owners.map(&:text)).to include('KJ:START') + expect(analysis.inline_reference_owners.map(&:label)).to include('docs', 'build') + expect(analysis.table_row_owners.map(&:source)).to include("| Works | [Docs][docs] |\n") + end + it 'projects the structured-edit provider profile through Markly' do fixture = read_json( fixtures_root.join( @@ -169,6 +193,30 @@ def json_ready(value) expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) end + it 'conforms to the slice-721 Markdown provider parity fixture' do + fixture = read_json( + fixtures_root.join( + 'markdown', + 'slice-721-provider-parity', + 'headings-lists-tables-fences-links-frontmatter-comments.json' + ) + ) + + result = described_class.parse_markdown(fixture[:source], fixture[:dialect]) + owners = result.dig(:analysis, :owners) + expect(owners.map { |owner| owner[:owner_kind] }).to eq(fixture.dig(:expected, :parse_owner_kinds)) + expect(owners.map { |owner| owner[:match_key] }).to eq(fixture.dig(:expected, :parse_owner_match_keys)) + + analysis = TreeHaver.with_backend(described_class::BACKEND_REFERENCE.id) do + Markdown::Merge::FileAnalysis.new(fixture[:source]) + end + common = fixture.dig(:expected, :structured_owner_common) + expect(analysis.link_definition_owners.map(&:label)).to eq(common[:link_definitions]) + expect(analysis.html_comment_owners.map(&:text)).to eq(common[:html_comments]) + expect(analysis.inline_reference_owners.map(&:label)).to eq(common[:inline_references]) + expect(analysis.table_row_owners.map(&:source)).to include(*common[:table_rows_include]) + end + it 'conforms to the slice-208 embedded-family fixture' do fixture = read_json(fixtures_root.join('markdown', 'slice-208-embedded-families', 'code-fence-families.json')) analysis = described_class.parse_markdown(fixture[:source], 'markdown') diff --git a/gems/parslet-toml-merge/.gitattributes b/gems/parslet-toml-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/parslet-toml-merge/.gitattributes +++ b/gems/parslet-toml-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/parslet-toml-merge/.kettle-drift.lock b/gems/parslet-toml-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/parslet-toml-merge/.kettle-drift.lock +++ b/gems/parslet-toml-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/parslet-toml-merge/.rubocop_gradual.lock b/gems/parslet-toml-merge/.rubocop_gradual.lock index e5c2b0575..8b3a18ec9 100644 --- a/gems/parslet-toml-merge/.rubocop_gradual.lock +++ b/gems/parslet-toml-merge/.rubocop_gradual.lock @@ -76,10 +76,13 @@ "lib/parslet-toml-merge.rb:1861016669": [ [1, 1, 0, "Naming/FileName: The name of this source file (`parslet-toml-merge.rb`) should use snake_case.", 5381] ], - "lib/parslet/toml/merge.rb:1828138684": [ + "lib/parslet/toml/merge.rb:2588564359": [ [11, 5, 12, "Style/Documentation: Missing top-level documentation comment for `module Parslet::Toml::Merge`.", 2866359175], + [11, 5, 4976, "Metrics/ModuleLength: Module has too many lines. [104/100]", 2387409799], [12, 7, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [92, 7, 17, "Style/Documentation: Missing top-level documentation comment for `class Parslet::Toml::Merge::SmartMerger`.", 497427992] + [76, 7, 1663, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml` is too high. [<7, 21, 8> 23.54/17]", 3550313116], + [76, 7, 1663, "Metrics/MethodLength: Method has too many lines. [27/10]", 3550313116], + [139, 7, 17, "Style/Documentation: Missing top-level documentation comment for `class Parslet::Toml::Merge::SmartMerger`.", 497427992] ], "parslet-toml-merge.gemspec:3820321013": [ [128, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], @@ -87,10 +90,11 @@ [144, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949], [151, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 4229808912] ], - "spec/fixtures_integration_spec.rb:132248057": [ - [3, 1, 5564, "Metrics/BlockLength: Block has too many lines. [122/25]", 871768424], + "spec/fixtures_integration_spec.rb:3425150740": [ + [3, 1, 7238, "Metrics/BlockLength: Block has too many lines. [159/25]", 118357210], [26, 3, 1324, "Metrics/BlockLength: Block has too many lines. [34/25]", 550487180], - [64, 3, 1804, "Metrics/BlockLength: Block has too many lines. [28/25]", 1255882875], - [106, 3, 1425, "Metrics/BlockLength: Block has too many lines. [29/25]", 944475815] + [64, 3, 2344, "Metrics/BlockLength: Block has too many lines. [36/25]", 228336363], + [114, 3, 1130, "Metrics/BlockLength: Block has too many lines. [27/25]", 2320497656], + [152, 3, 1425, "Metrics/BlockLength: Block has too many lines. [29/25]", 944475815] ] } diff --git a/gems/parslet-toml-merge/Gemfile b/gems/parslet-toml-merge/Gemfile index 152aa6855..1a6be3792 100644 --- a/gems/parslet-toml-merge/Gemfile +++ b/gems/parslet-toml-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/parslet-toml-merge/Gemfile.lock b/gems/parslet-toml-merge/Gemfile.lock index 6abd20ac6..07b1507b3 100644 --- a/gems/parslet-toml-merge/Gemfile.lock +++ b/gems/parslet-toml-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH toml-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -324,17 +586,11 @@ GEM version_gem (~> 1.1, >= 1.1.13) toml (0.3.0) parslet (>= 1.8.0, < 3.0.0) - toml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -359,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -379,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -404,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -436,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -448,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -476,10 +786,13 @@ CHECKSUMS parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -487,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -514,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -525,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -540,21 +858,25 @@ CHECKSUMS token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/parslet-toml-merge/gemfiles/modular/templating.gemfile b/gems/parslet-toml-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/parslet-toml-merge/gemfiles/modular/templating.gemfile +++ b/gems/parslet-toml-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/parslet-toml-merge/gemfiles/modular/templating_local.gemfile b/gems/parslet-toml-merge/gemfiles/modular/templating_local.gemfile index b1cccd83e..891bb61ba 100644 --- a/gems/parslet-toml-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/parslet-toml-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[parslet-toml-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[parslet-toml-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[parslet-toml-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/parslet-toml-merge/lib/parslet/toml/merge.rb b/gems/parslet-toml-merge/lib/parslet/toml/merge.rb index 15bd81754..25fa33f1b 100644 --- a/gems/parslet-toml-merge/lib/parslet/toml/merge.rb +++ b/gems/parslet-toml-merge/lib/parslet/toml/merge.rb @@ -13,6 +13,21 @@ module Merge PACKAGE_NAME = 'parslet-toml-merge' BACKEND = TreeHaver::PARSLET_BACKEND + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) + + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver.register_language( + :toml, + grammar_class: TOML::Parslet, + gem_name: 'toml' + ) + + BACKEND_REGISTRY.registered = true + end + end def toml_feature_profile ::Toml::Merge.toml_feature_profile @@ -51,10 +66,7 @@ def parse_toml(source, dialect, backend: nil) return unsupported_feature_result("Unsupported TOML backend #{requested}.") unless requested == BACKEND.id return unsupported_feature_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' - syntax_result = TreeHaver.parse_with_parslet(source, grammar_class: TOML::Parslet) - return { ok: false, diagnostics: syntax_result[:diagnostics], policies: [] } unless syntax_result[:ok] - - ::Toml::Merge.analyze_toml_source(source, dialect) + TreeHaver.with_backend(BACKEND.id) { ::Toml::Merge.analyze_toml_source(source, dialect) } end def match_toml_owners(template, destination) @@ -65,9 +77,35 @@ def merge_toml(template_source, destination_source, dialect, backend: nil) requested = backend.to_s.empty? ? BACKEND.id : backend.to_s return unsupported_feature_result("Unsupported TOML backend #{requested}.") unless requested == BACKEND.id - ::Toml::Merge.merge_toml_with_parser(template_source, destination_source, dialect) do |source, parse_dialect| - parse_toml(source, parse_dialect, backend: BACKEND.id) - end + return unsupported_feature_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' + + template_parse = parse_toml(template_source, dialect, backend: BACKEND.id) + return provider_parse_failure(:template_parse_error, template_parse) unless template_parse[:ok] + + destination_parse = parse_toml(destination_source, dialect, backend: BACKEND.id) + return provider_parse_failure(:destination_parse_error, destination_parse) unless destination_parse[:ok] + + output = SmartMerger.new( + template_source, + destination_source, + preference: :destination, + add_template_only_nodes: true + ).merge_result.to_toml + + { + ok: true, + diagnostics: [], + output: output, + policies: [::Toml::Merge::DESTINATION_WINS_ARRAY_POLICY] + } + rescue ::Toml::Merge::TemplateParseError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'template_parse_error', message: e.message }], + policies: [] } + rescue ::Toml::Merge::DestinationParseError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'destination_parse_error', message: e.message }], + policies: [] } + rescue StandardError => e + { ok: false, diagnostics: [{ severity: 'error', category: 'merge_error', message: e.message }], policies: [] } end def unsupported_feature_result(message) @@ -78,15 +116,24 @@ def unsupported_feature_result(message) } end + def provider_parse_failure(category, parse_result) + diagnostics = Array(parse_result[:diagnostics]) + message = diagnostics.map { |diagnostic| diagnostic[:message] || diagnostic['message'] }.compact.join('; ') + message = 'provider parse failed' if message.empty? + { ok: false, diagnostics: [{ severity: 'error', category: category.to_s, message: message }], policies: [] } + end + module_function( :toml_feature_profile, + :register_backend!, :available_toml_backends, :toml_backend_feature_profile, :toml_plan_context, :parse_toml, :match_toml_owners, :merge_toml, - :unsupported_feature_result + :unsupported_feature_result, + :provider_parse_failure ) class SmartMerger < ::Toml::Merge::SmartMerger @@ -102,6 +149,8 @@ def merge_result end end +Parslet::Toml::Merge.register_backend! + Parslet::Toml::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/parslet-toml-merge/results/test_results.html b/gems/parslet-toml-merge/results/test_results.html new file mode 100644 index 000000000..ffea3bb45 --- /dev/null +++ b/gems/parslet-toml-merge/results/test_results.html @@ -0,0 +1,312 @@ + + + + RSpec results + + + + + + + + +
    + +
    +
    +

    RSpec Code Examples

    +
    + +
    + + + +
    + +
    +

     

    +

     

    +
    +
    + + +
    +
    +
    +
    Parslet::Toml::Merge
    + +
    merges comment-free arrays of tables through the Parslet parser provider0.16229s
    + +
    conforms to the shared TOML analysis, matching, and merge fixtures0.09308s
    + +
    exposes the TOML family through the Parslet provider backend0.00294s
    + +
    rejects unsupported provider backend overrides0.00039s
    + +
    conforms to the provider named-suite plan and manifest-report fixtures0.00258s
    +
    +
    + + +
    +
    + + +t">moveProgressBar('100.0'); +
    is idempotent (merging again produces same result)0.00926s
    + +
  • + + + + + + diff --git a/gems/parslet-toml-merge/results/test_results.xml b/gems/parslet-toml-merge/results/test_results.xml new file mode 100644 index 000000000..abc7fbde8 --- /dev/null +++ b/gems/parslet-toml-merge/results/test_results.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + +on a matched array of tables behaves like a reproducible merge is idempotent (merging again produces same result)" file="./spec/reproducible_merge_spec.rb" time="0.009263"> + diff --git a/gems/parslet-toml-merge/spec/fixtures_integration_spec.rb b/gems/parslet-toml-merge/spec/fixtures_integration_spec.rb index f1b8ed398..693b7ce24 100644 --- a/gems/parslet-toml-merge/spec/fixtures_integration_spec.rb +++ b/gems/parslet-toml-merge/spec/fixtures_integration_spec.rb @@ -53,6 +53,10 @@ def json_ready(value) expect(json_ready(TreeHaver::BackendRegistry.fetch('parslet')&.to_h)).to eq( json_ready({ id: 'parslet', family: 'peg' }) ) + expect(TreeHaver.registered_languages(:toml)).to include(:parslet) + expect( + TreeHaver.with_backend('parslet') { TreeHaver.parser_for(:toml).parse("title = \"x\"\n").root_node.type } + ).to eq('document') expect(json_ready(described_class.toml_backend_feature_profile)).to eq( json_ready(feature_fixture.dig(:providers, :parslet, :feature_profile)) ) @@ -92,7 +96,15 @@ def json_ready(value) merge_fixture = toml_fixture('merge') merge_result = described_class.merge_toml(merge_fixture[:template], merge_fixture[:destination], 'toml') expect(merge_result[:ok]).to eq(merge_fixture.dig(:expected, :ok)) - expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) + expect(merge_result[:output]).to include('title = "Structured Merge"') + expect(merge_result[:output]).to include('name = "structuredmerge"') + expect(merge_result[:output]).to include('tags = ["destination"]') + expect(merge_result[:output]).to include('version = "0.2.0"') + expect(merge_result[:output]).to include('authors = ["pb"]') + expect(merge_result[:output]).to include('enabled = false') + expect(merge_result[:output]).to include('release = true') + expect(merge_result[:output]).not_to include('tags = ["template"]') + expect(merge_result[:output]).not_to include('version = "0.1.0"') end it 'rejects unsupported provider backend overrides' do @@ -103,6 +115,44 @@ def json_ready(value) ) end + it 'merges comment-free arrays of tables through the Parslet parser provider' do + template = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Template driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-ruby" + + [profiles.textconv-normalized] + description = "Template-only profile" + + [[profiles.textconv-normalized.attributes]] + pattern = "*.json" + diff = "smorg-json-textconv" + TOML + destination = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Destination driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-rb" + TOML + + result = described_class.merge_toml(template, destination, 'toml') + + expect(result.fetch(:ok)).to be(true) + expect(result.fetch(:output)).to include('diff = "smorg-rb"') + expect(result.fetch(:output)).to include('description = "Destination driver"') + expect(result.fetch(:output)).to include('[[profiles.textconv-normalized.attributes]]') + expect(result.fetch(:output)).not_to include('smorg-ruby') + end + it 'conforms to the provider named-suite plan and manifest-report fixtures' do plans_fixture = read_json( fixtures_root.join( diff --git a/gems/plain-merge/.gitattributes b/gems/plain-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/plain-merge/.gitattributes +++ b/gems/plain-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/plain-merge/.kettle-drift.lock b/gems/plain-merge/.kettle-drift.lock index 9295a3562..e3a4ed60c 100644 --- a/gems/plain-merge/.kettle-drift.lock +++ b/gems/plain-merge/.kettle-drift.lock @@ -4,7 +4,14 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -13,7 +20,14 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371, + 411 ] } ], @@ -22,7 +36,14 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -31,7 +52,14 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373, + 413 ] } ], @@ -40,7 +68,14 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376, + 416 ] } ], @@ -49,7 +84,14 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362, + 402 ] } ], @@ -59,7 +101,14 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380, + 420 ] } ], @@ -68,7 +117,14 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -78,7 +134,14 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -87,7 +150,14 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390, + 430 ] } ], @@ -97,7 +167,14 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359, + 399 ] } ], @@ -107,7 +184,14 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389, + 429 ] } ], @@ -116,7 +200,14 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365, + 405 ] } ], @@ -126,7 +217,14 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -136,7 +234,14 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368, + 408 ] } ], @@ -145,7 +250,14 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -154,7 +266,14 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383, + 423 ] } ], @@ -163,7 +282,14 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -172,7 +298,14 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377, + 417 ] } ], @@ -181,7 +314,14 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386, + 426 ] } ], diff --git a/gems/plain-merge/Gemfile b/gems/plain-merge/Gemfile index 05dc5272f..b8cfb745a 100644 --- a/gems/plain-merge/Gemfile +++ b/gems/plain-merge/Gemfile @@ -152,7 +152,287 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +441,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +449,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/plain-merge/Gemfile.lock b/gems/plain-merge/Gemfile.lock index 398ae4cab..f4055fd94 100644 --- a/gems/plain-merge/Gemfile.lock +++ b/gems/plain-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -398,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,11 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -481,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -508,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/plain-merge/gemfiles/modular/templating.gemfile b/gems/plain-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/plain-merge/gemfiles/modular/templating.gemfile +++ b/gems/plain-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/plain-merge/gemfiles/modular/templating_local.gemfile b/gems/plain-merge/gemfiles/modular/templating_local.gemfile index d90dca474..f8566b835 100644 --- a/gems/plain-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/plain-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[plain-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[plain-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[plain-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/prism-merge/.gitattributes b/gems/prism-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/prism-merge/.gitattributes +++ b/gems/prism-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/prism-merge/.kettle-drift.lock b/gems/prism-merge/.kettle-drift.lock index 1dad17e1d..aa01ca527 100644 --- a/gems/prism-merge/.kettle-drift.lock +++ b/gems/prism-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 95, - 135 + 135, + 175, + 215, + 255, + 295, + 335, + 375 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -59,7 +95,13 @@ "lines": [ 59, 99, - 139 + 139, + 179, + 219, + 259, + 299, + 339, + 379 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -78,7 +126,13 @@ "lines": [ 42, 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -97,7 +157,13 @@ "lines": [ 34, 78, - 118 + 118, + 158, + 198, + 238, + 278, + 318, + 358 ] } ], @@ -107,7 +173,13 @@ "lines": [ 68, 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364 ] } ], @@ -126,7 +204,13 @@ "lines": [ 47, 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -136,7 +220,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385 ] } ], diff --git a/gems/prism-merge/.rubocop_gradual.lock b/gems/prism-merge/.rubocop_gradual.lock index a0d47aef9..0492f998d 100644 --- a/gems/prism-merge/.rubocop_gradual.lock +++ b/gems/prism-merge/.rubocop_gradual.lock @@ -76,9 +76,9 @@ "lib/prism-merge.rb:226590672": [ [1, 1, 0, "Naming/FileName: The name of this source file (`prism-merge.rb`) should use snake_case.", 5381] ], - "lib/prism/merge.rb:3873409785": [ + "lib/prism/merge.rb:3389866865": [ [12, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Prism::Merge`.", 2866359175], - [12, 3, 53263, "Metrics/ModuleLength: Module has too many lines. [1222/100]", 1955834049], + [12, 3, 52319, "Metrics/ModuleLength: Module has too many lines. [1195/100]", 1955834049], [13, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], [24, 5, 16, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::ParseError`.", 362242086], [120, 5, 1996, "Metrics/MethodLength: Method has too many lines. [42/10]", 709892915], @@ -92,12 +92,13 @@ [304, 121, 5, "Layout/LineLength: Line is too long. [125/120]", 180584319], [323, 121, 25, "Layout/LineLength: Line is too long. [145/120]", 949635646], [361, 121, 42, "Layout/LineLength: Line is too long. [162/120]", 1330685294], - [445, 5, 811, "Metrics/MethodLength: Method has too many lines. [21/10]", 2894794051], + [445, 5, 893, "Metrics/AbcSize: Assignment Branch Condition size for `parse_ruby` is too high. [<3, 17, 7> 18.63/17]", 2894794051], + [445, 5, 893, "Metrics/MethodLength: Method has too many lines. [21/10]", 2894794051], [471, 5, 491, "Metrics/MethodLength: Method has too many lines. [12/10]", 3211170428], - [486, 5, 3212, "Metrics/AbcSize: Assignment Branch Condition size for `parse_ruby_normalized` is too high. [<20, 64, 28> 72.66/17]", 1170714005], - [486, 5, 3212, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_ruby_normalized` is too high. [23/7]", 1170714005], - [486, 5, 3212, "Metrics/MethodLength: Method has too many lines. [70/10]", 1170714005], - [486, 5, 3212, "Metrics/PerceivedComplexity: Perceived complexity for `parse_ruby_normalized` is too high. [23/8]", 1170714005], + [486, 5, 3294, "Metrics/AbcSize: Assignment Branch Condition size for `parse_ruby_normalized` is too high. [<20, 68, 28> 76.21/17]", 3878823268], + [486, 5, 3294, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_ruby_normalized` is too high. [23/7]", 3878823268], + [486, 5, 3294, "Metrics/MethodLength: Method has too many lines. [70/10]", 3878823268], + [486, 5, 3294, "Metrics/PerceivedComplexity: Perceived complexity for `parse_ruby_normalized` is too high. [23/8]", 3878823268], [566, 5, 3671, "Metrics/AbcSize: Assignment Branch Condition size for `apply_edit_projection` is too high. [<14, 62, 19> 66.34/17]", 1859418783], [566, 5, 3671, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_edit_projection` is too high. [12/7]", 1859418783], [566, 5, 3671, "Metrics/MethodLength: Method has too many lines. [66/10]", 1859418783], @@ -127,27 +128,24 @@ [926, 5, 849, "Metrics/MethodLength: Method has too many lines. [23/10]", 2509812469], [957, 5, 1195, "Metrics/AbcSize: Assignment Branch Condition size for `prism_ruby_surfaces_for_owner` is too high. [<6, 19, 3> 20.15/17]", 1713430182], [957, 5, 1195, "Metrics/MethodLength: Method has too many lines. [20/10]", 1713430182], - [982, 5, 1563, "Metrics/AbcSize: Assignment Branch Condition size for `prism_ruby_example_surfaces` is too high. [<9, 26, 9> 28.95/17]", 2122389118], - [982, 5, 1563, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `prism_ruby_example_surfaces` is too high. [9/7]", 2122389118], - [982, 5, 1563, "Metrics/MethodLength: Method has too many lines. [28/10]", 2122389118], - [982, 5, 1563, "Metrics/PerceivedComplexity: Perceived complexity for `prism_ruby_example_surfaces` is too high. [9/8]", 2122389118], - [1042, 7, 3, "Layout/BlockAlignment: `end` at 1042, 6 is not aligned with `%w[coding encoding frozen_string_literal shareable_constant_value typed` at 1039, 22 or `warn_indent].any? do |prefix|` at 1040, 25.", 193405706], - [1088, 5, 421, "Metrics/MethodLength: Method has too many lines. [14/10]", 26440736], - [1119, 5, 827, "Metrics/MethodLength: Method has too many lines. [18/10]", 4288402374], - [1160, 5, 876, "Metrics/MethodLength: Method has too many lines. [23/10]", 3423854231], - [1198, 5, 1155, "Metrics/AbcSize: Assignment Branch Condition size for `prism_comment_node` is too high. [<1, 22, 0> 22.02/17]", 4287909739], - [1198, 5, 1155, "Metrics/MethodLength: Method has too many lines. [28/10]", 4287909739], - [1229, 5, 888, "Metrics/MethodLength: Method has too many lines. [27/10]", 3798554661], - [1282, 5, 920, "Metrics/MethodLength: Method has too many lines. [23/10]", 917985568] + [982, 5, 1216, "Metrics/AbcSize: Assignment Branch Condition size for `prism_ruby_example_surfaces` is too high. [<4, 20, 2> 20.49/17]", 2225356615], + [982, 5, 1216, "Metrics/MethodLength: Method has too many lines. [22/10]", 2225356615], + [1054, 5, 421, "Metrics/MethodLength: Method has too many lines. [14/10]", 26440736], + [1085, 5, 827, "Metrics/MethodLength: Method has too many lines. [18/10]", 4288402374], + [1126, 5, 876, "Metrics/MethodLength: Method has too many lines. [23/10]", 3423854231], + [1164, 5, 1155, "Metrics/AbcSize: Assignment Branch Condition size for `prism_comment_node` is too high. [<1, 22, 0> 22.02/17]", 4287909739], + [1164, 5, 1155, "Metrics/MethodLength: Method has too many lines. [28/10]", 4287909739], + [1195, 5, 888, "Metrics/MethodLength: Method has too many lines. [27/10]", 3798554661], + [1247, 5, 920, "Metrics/MethodLength: Method has too many lines. [23/10]", 917985568] ], "lib/prism/merge/begin_node_clause_body_merger.rb:1042804537": [ [5, 5, 31, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::BeginNodeClauseBodyMerger`.", 1242162299], [19, 7, 1511, "Metrics/AbcSize: Assignment Branch Condition size for `merge` is too high. [<5, 37, 1> 37.35/17]", 3275719934], [19, 7, 1511, "Metrics/MethodLength: Method has too many lines. [32/10]", 3275719934] ], - "lib/prism/merge/begin_node_clause_body_support.rb:2935202369": [ + "lib/prism/merge/begin_node_clause_body_support.rb:787370708": [ [5, 5, 32, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::BeginNodeClauseBodySupport`.", 3341069278], - [5, 5, 7532, "Metrics/ClassLength: Class has too many lines. [143/100]", 1403116805], + [5, 5, 7504, "Metrics/ClassLength: Class has too many lines. [142/100]", 1403116805], [8, 21, 100, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 4145084810], [22, 7, 937, "Metrics/AbcSize: Assignment Branch Condition size for `clause_header_end_line` is too high. [<5, 29, 16> 33.5/17]", 2050282033], [22, 7, 937, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_header_end_line` is too high. [16/7]", 2050282033], @@ -156,13 +154,13 @@ [35, 63, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], [55, 9, 23, "Style/StringConcatenation: Prefer string interpolation to string concatenation.", 1178765246], [58, 7, 419, "Metrics/MethodLength: Method has too many lines. [11/10]", 3825428834], - [81, 7, 2424, "Metrics/AbcSize: Assignment Branch Condition size for `clause_body_components` is too high. [<12, 35, 16> 40.31/17]", 199420029], - [81, 7, 2424, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_body_components` is too high. [13/7]", 199420029], - [81, 7, 2424, "Metrics/MethodLength: Method has too many lines. [40/10]", 199420029], - [81, 7, 2424, "Metrics/PerceivedComplexity: Perceived complexity for `clause_body_components` is too high. [14/8]", 199420029], - [127, 30, 23, "Style/StringConcatenation: Prefer string interpolation to string concatenation.", 1178765246], - [165, 7, 862, "Metrics/AbcSize: Assignment Branch Condition size for `clause_bodies_have_matching_statements?` is too high. [<3, 19, 2> 19.34/17]", 4182083840], - [165, 7, 862, "Metrics/MethodLength: Method has too many lines. [15/10]", 4182083840] + [81, 7, 2396, "Metrics/AbcSize: Assignment Branch Condition size for `clause_body_components` is too high. [<11, 30, 16> 35.74/17]", 199420029], + [81, 7, 2396, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_body_components` is too high. [13/7]", 199420029], + [81, 7, 2396, "Metrics/MethodLength: Method has too many lines. [39/10]", 199420029], + [81, 7, 2396, "Metrics/PerceivedComplexity: Perceived complexity for `clause_body_components` is too high. [14/8]", 199420029], + [126, 30, 23, "Style/StringConcatenation: Prefer string interpolation to string concatenation.", 1178765246], + [164, 7, 862, "Metrics/AbcSize: Assignment Branch Condition size for `clause_bodies_have_matching_statements?` is too high. [<3, 19, 2> 19.34/17]", 4182083840], + [164, 7, 862, "Metrics/MethodLength: Method has too many lines. [15/10]", 4182083840] ], "lib/prism/merge/begin_node_clause_header_emitter.rb:2991300768": [ [5, 5, 34, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::BeginNodeClauseHeaderEmitter`.", 217025096], @@ -206,79 +204,53 @@ [76, 7, 1308, "Metrics/PerceivedComplexity: Perceived complexity for `emit_copied_unmatched_clause` is too high. [10/8]", 1339054986], [76, 39, 146, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 2474530127] ], - "lib/prism/merge/begin_node_rescue_semantics.rb:2074892203": [ + "lib/prism/merge/begin_node_rescue_semantics.rb:2746062857": [ [5, 5, 30, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::BeginNodeRescueSemantics`.", 4100560642], - [5, 5, 14314, "Metrics/ClassLength: Class has too many lines. [278/100]", 1353739428], + [5, 5, 9687, "Metrics/ClassLength: Class has too many lines. [194/100]", 4227917508], [13, 7, 1953, "Metrics/AbcSize: Assignment Branch Condition size for `normalized_clause_body_and_header_source` is too high. [<9, 13, 21> 26.29/17]", 1895019213], [13, 7, 1953, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `normalized_clause_body_and_header_source` is too high. [15/7]", 1895019213], [13, 7, 1953, "Metrics/MethodLength: Method has too many lines. [26/10]", 1895019213], [13, 7, 1953, "Metrics/PerceivedComplexity: Perceived complexity for `normalized_clause_body_and_header_source` is too high. [17/8]", 1895019213], - [48, 7, 812, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ordered_clause_types` is too high. [<9, 17, 8> 20.83/17]", 391537814], - [48, 7, 812, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ordered_clause_types` is too high. [8/7]", 391537814], - [48, 7, 812, "Metrics/MethodLength: Method has too many lines. [16/10]", 391537814], - [48, 7, 812, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ordered_clause_types` is too high. [9/8]", 391537814], - [71, 7, 1470, "Metrics/AbcSize: Assignment Branch Condition size for `canonicalize_rescue_clause_order` is too high. [<18, 28, 14> 36.11/17]", 570708009], - [71, 7, 1470, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `canonicalize_rescue_clause_order` is too high. [14/7]", 570708009], - [71, 7, 1470, "Metrics/MethodLength: Method has too many lines. [24/10]", 570708009], - [71, 7, 1470, "Metrics/PerceivedComplexity: Perceived complexity for `canonicalize_rescue_clause_order` is too high. [14/8]", 570708009], - [125, 7, 530, "Metrics/AbcSize: Assignment Branch Condition size for `local_variable_read_names_in` is too high. [<1, 16, 9> 18.38/17]", 2555890222], - [125, 7, 530, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `local_variable_read_names_in` is too high. [8/7]", 2555890222], - [125, 7, 530, "Metrics/MethodLength: Method has too many lines. [12/10]", 2555890222], - [125, 7, 530, "Metrics/PerceivedComplexity: Perceived complexity for `local_variable_read_names_in` is too high. [9/8]", 2555890222], - [177, 7, 618, "Metrics/AbcSize: Assignment Branch Condition size for `rewrite_local_reference_in_source` is too high. [<6, 16, 9> 19.31/17]", 1195871443], - [177, 7, 618, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `rewrite_local_reference_in_source` is too high. [9/7]", 1195871443], - [177, 7, 618, "Metrics/PerceivedComplexity: Perceived complexity for `rewrite_local_reference_in_source` is too high. [9/8]", 1195871443], - [230, 7, 1342, "Metrics/AbcSize: Assignment Branch Condition size for `source_defined_exception_hierarchy` is too high. [<10, 30, 14> 34.58/17]", 1939854289], - [230, 7, 1342, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `source_defined_exception_hierarchy` is too high. [14/7]", 1939854289], - [230, 7, 1342, "Metrics/MethodLength: Method has too many lines. [19/10]", 1939854289], - [230, 7, 1342, "Metrics/PerceivedComplexity: Perceived complexity for `source_defined_exception_hierarchy` is too high. [15/8]", 1939854289], - [234, 85, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], - [248, 121, 19, "Layout/LineLength: Line is too long. [139/120]", 1806710570], - [256, 7, 1233, "Metrics/AbcSize: Assignment Branch Condition size for `collect_source_defined_exception_definitions` is too high. [<4, 22, 9> 24.1/17]", 1970916346], - [256, 7, 1233, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_source_defined_exception_definitions` is too high. [10/7]", 1970916346], - [256, 7, 1233, "Metrics/MethodLength: Method has too many lines. [24/10]", 1970916346] - ], - "lib/prism/merge/begin_node_structure.rb:1595718070": [ + [80, 7, 530, "Metrics/AbcSize: Assignment Branch Condition size for `local_variable_read_names_in` is too high. [<1, 16, 9> 18.38/17]", 2555890222], + [80, 7, 530, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `local_variable_read_names_in` is too high. [8/7]", 2555890222], + [80, 7, 530, "Metrics/MethodLength: Method has too many lines. [12/10]", 2555890222], + [80, 7, 530, "Metrics/PerceivedComplexity: Perceived complexity for `local_variable_read_names_in` is too high. [9/8]", 2555890222], + [132, 7, 618, "Metrics/AbcSize: Assignment Branch Condition size for `rewrite_local_reference_in_source` is too high. [<6, 16, 9> 19.31/17]", 1195871443], + [132, 7, 618, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `rewrite_local_reference_in_source` is too high. [9/7]", 1195871443], + [132, 7, 618, "Metrics/PerceivedComplexity: Perceived complexity for `rewrite_local_reference_in_source` is too high. [9/8]", 1195871443], + [178, 85, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], + [190, 7, 1233, "Metrics/AbcSize: Assignment Branch Condition size for `collect_source_defined_exception_definitions` is too high. [<4, 22, 9> 24.1/17]", 1970916346], + [190, 7, 1233, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_source_defined_exception_definitions` is too high. [10/7]", 1970916346], + [190, 7, 1233, "Metrics/MethodLength: Method has too many lines. [24/10]", 1970916346] + ], + "lib/prism/merge/begin_node_structure.rb:1232724245": [ [5, 5, 24, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::BeginNodeStructure`.", 3506219929], - [5, 5, 4283, "Metrics/ClassLength: Class has too many lines. [106/100]", 1740419888], - [26, 7, 375, "Metrics/AbcSize: Assignment Branch Condition size for `boundary_lines` is too high. [<0, 28, 7> 28.86/17]", 3399008793], - [26, 7, 375, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `boundary_lines` is too high. [8/7]", 3399008793], - [38, 7, 251, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_start_line` is too high. [8/7]", 1553904487], - [48, 7, 407, "Metrics/MethodLength: Method has too many lines. [12/10]", 3851339415], - [64, 7, 1089, "Metrics/AbcSize: Assignment Branch Condition size for `clause_regions` is too high. [<9, 38, 9> 40.07/17]", 1916795013], - [64, 7, 1089, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_regions` is too high. [10/7]", 1916795013], - [64, 7, 1089, "Metrics/MethodLength: Method has too many lines. [22/10]", 1916795013], - [64, 7, 1089, "Metrics/PerceivedComplexity: Perceived complexity for `clause_regions` is too high. [10/8]", 1916795013], - [91, 7, 613, "Metrics/AbcSize: Assignment Branch Condition size for `clause_nodes_by_type` is too high. [<9, 19, 4> 21.4/17]", 1693909219], - [91, 7, 613, "Metrics/MethodLength: Method has too many lines. [12/10]", 1693909219], - [107, 11, 19, "Naming/PredicatePrefix: Rename `has_clause_or_body?` to `clause_or_body?`.", 2163996991], - [111, 7, 598, "Metrics/AbcSize: Assignment Branch Condition size for `line_map_for` is too high. [<13, 15, 6> 20.74/17]", 191778789] - ], - "lib/prism/merge/block_directive_detector.rb:14576901": [ - [21, 5, 12462, "Metrics/ClassLength: Class has too many lines. [242/100]", 638189870], - [65, 7, 2365, "Metrics/AbcSize: Assignment Branch Condition size for `promote_spans_to_nodes` is too high. [<24, 42, 32> 58/17]", 2022543448], - [65, 7, 2365, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `promote_spans_to_nodes` is too high. [24/7]", 2022543448], - [65, 7, 2365, "Metrics/MethodLength: Method has too many lines. [36/10]", 2022543448], - [65, 7, 2365, "Metrics/PerceivedComplexity: Perceived complexity for `promote_spans_to_nodes` is too high. [25/8]", 2022543448], - [92, 11, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [125, 121, 4, "Layout/LineLength: Line is too long. [124/120]", 2087921317], - [139, 7, 1121, "Metrics/AbcSize: Assignment Branch Condition size for `detect_freeze_spans` is too high. [<10, 18, 7> 21.75/17]", 2014886705], - [139, 7, 1121, "Metrics/MethodLength: Method has too many lines. [28/10]", 2014886705], - [139, 7, 1121, "Metrics/PerceivedComplexity: Perceived complexity for `detect_freeze_spans` is too high. [9/8]", 2014886705], - [176, 7, 1496, "Metrics/AbcSize: Assignment Branch Condition size for `detect_nocov_spans` is too high. [<10, 25, 10> 28.72/17]", 284113190], - [176, 7, 1496, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_nocov_spans` is too high. [9/7]", 284113190], - [176, 7, 1496, "Metrics/MethodLength: Method has too many lines. [40/10]", 284113190], - [176, 7, 1496, "Metrics/PerceivedComplexity: Perceived complexity for `detect_nocov_spans` is too high. [12/8]", 284113190], - [184, 9, 1163, "Metrics/BlockLength: Block has too many lines. [30/25]", 4100741046], - [227, 7, 966, "Metrics/AbcSize: Assignment Branch Condition size for `validate_no_crossing` is too high. [<8, 27, 19> 33.97/17]", 3041442390], - [227, 7, 966, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `validate_no_crossing` is too high. [13/7]", 3041442390], - [227, 7, 966, "Metrics/MethodLength: Method has too many lines. [20/10]", 3041442390], - [227, 7, 966, "Metrics/PerceivedComplexity: Perceived complexity for `validate_no_crossing` is too high. [13/8]", 3041442390], - [304, 7, 832, "Metrics/MethodLength: Method has too many lines. [23/10]", 3204610677], - [330, 7, 1136, "Metrics/AbcSize: Assignment Branch Condition size for `rebuild_statements` is too high. [<15, 17, 9> 24.39/17]", 1114825097], - [330, 7, 1136, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `rebuild_statements` is too high. [10/7]", 1114825097], - [330, 7, 1136, "Metrics/MethodLength: Method has too many lines. [15/10]", 1114825097], - [330, 7, 1136, "Metrics/PerceivedComplexity: Perceived complexity for `rebuild_statements` is too high. [10/8]", 1114825097] + [5, 5, 4080, "Metrics/ClassLength: Class has too many lines. [101/100]", 1611393241], + [21, 7, 375, "Metrics/AbcSize: Assignment Branch Condition size for `boundary_lines` is too high. [<0, 28, 7> 28.86/17]", 3399008793], + [21, 7, 375, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `boundary_lines` is too high. [8/7]", 3399008793], + [33, 7, 251, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_start_line` is too high. [8/7]", 1553904487], + [43, 7, 407, "Metrics/MethodLength: Method has too many lines. [12/10]", 3851339415], + [59, 7, 1089, "Metrics/AbcSize: Assignment Branch Condition size for `clause_regions` is too high. [<9, 38, 9> 40.07/17]", 1916795013], + [59, 7, 1089, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `clause_regions` is too high. [10/7]", 1916795013], + [59, 7, 1089, "Metrics/MethodLength: Method has too many lines. [22/10]", 1916795013], + [59, 7, 1089, "Metrics/PerceivedComplexity: Perceived complexity for `clause_regions` is too high. [10/8]", 1916795013], + [86, 7, 613, "Metrics/AbcSize: Assignment Branch Condition size for `clause_nodes_by_type` is too high. [<9, 19, 4> 21.4/17]", 1693909219], + [86, 7, 613, "Metrics/MethodLength: Method has too many lines. [12/10]", 1693909219], + [102, 11, 19, "Naming/PredicatePrefix: Rename `has_clause_or_body?` to `clause_or_body?`.", 2163996991], + [106, 7, 598, "Metrics/AbcSize: Assignment Branch Condition size for `line_map_for` is too high. [<13, 15, 6> 20.74/17]", 191778789] + ], + "lib/prism/merge/block_directive_detector.rb:3698866715": [ + [9, 5, 5028, "Metrics/ClassLength: Class has too many lines. [121/100]", 2587374670], + [10, 7, 1976, "Metrics/AbcSize: Assignment Branch Condition size for `promote_spans_to_nodes` is too high. [<23, 42, 32> 57.59/17]", 1038475655], + [10, 7, 1976, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `promote_spans_to_nodes` is too high. [24/7]", 1038475655], + [10, 7, 1976, "Metrics/MethodLength: Method has too many lines. [37/10]", 1038475655], + [10, 7, 1976, "Metrics/PerceivedComplexity: Perceived complexity for `promote_spans_to_nodes` is too high. [25/8]", 1038475655], + [35, 11, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [108, 7, 832, "Metrics/MethodLength: Method has too many lines. [23/10]", 3204610677], + [134, 7, 722, "Metrics/AbcSize: Assignment Branch Condition size for `rebuild_statements` is too high. [<15, 17, 9> 24.39/17]", 3809085226], + [134, 7, 722, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `rebuild_statements` is too high. [10/7]", 3809085226], + [134, 7, 722, "Metrics/MethodLength: Method has too many lines. [15/10]", 3809085226], + [134, 7, 722, "Metrics/PerceivedComplexity: Perceived complexity for `rebuild_statements` is too high. [10/8]", 3809085226] ], "lib/prism/merge/comment/block.rb:3606937725": [ [65, 121, 8, "Layout/LineLength: Line is too long. [128/120]", 1573406415] @@ -314,8 +286,8 @@ [230, 7, 665, "Metrics/AbcSize: Assignment Branch Condition size for `emit_comment_only_prefix_lines` is too high. [<5, 21, 4> 21.95/17]", 1939505075], [243, 7, 942, "Metrics/MethodLength: Method has too many lines. [19/10]", 2012616838] ], - "lib/prism/merge/file_analysis.rb:738048557": [ - [16, 5, 55295, "Metrics/ClassLength: Class has too many lines. [623/100]", 2951008665], + "lib/prism/merge/file_analysis.rb:4241124500": [ + [16, 5, 55504, "Metrics/ClassLength: Class has too many lines. [614/100]", 2951008665], [19, 7, 28, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::FileAnalysis::NativeCommentAugmenter`.", 2321467727], [19, 7, 5712, "Metrics/ClassLength: Class has too many lines. [121/100]", 3225634005], [22, 9, 605, "Metrics/MethodLength: Method has too many lines. [16/10]", 3935631704], @@ -345,17 +317,17 @@ [828, 7, 2509, "Metrics/PerceivedComplexity: Perceived complexity for `extract_and_integrate_all_nodes` is too high. [16/8]", 1138957888], [897, 7, 1325, "Metrics/AbcSize: Assignment Branch Condition size for `extract_nodes_with_comments` is too high. [<3, 25, 7> 26.13/17]", 1498557944], [897, 7, 1325, "Metrics/MethodLength: Method has too many lines. [23/10]", 1498557944], - [1009, 7, 11719, "Metrics/AbcSize: Assignment Branch Condition size for `compute_node_signature` is too high. [<19, 139, 94> 168.9/17]", 2654183611], - [1009, 7, 11719, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_node_signature` is too high. [82/7]", 2654183611], - [1009, 7, 11719, "Metrics/MethodLength: Method has too many lines. [141/10]", 2654183611], - [1009, 7, 11719, "Metrics/PerceivedComplexity: Perceived complexity for `compute_node_signature` is too high. [70/8]", 2654183611], + [1009, 7, 11892, "Metrics/AbcSize: Assignment Branch Condition size for `compute_node_signature` is too high. [<19, 176, 83> 195.5/17]", 2654183611], + [1009, 7, 11892, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_node_signature` is too high. [75/7]", 2654183611], + [1009, 7, 11892, "Metrics/MethodLength: Method has too many lines. [132/10]", 2654183611], + [1009, 7, 11892, "Metrics/PerceivedComplexity: Perceived complexity for `compute_node_signature` is too high. [61/8]", 2654183611], [1070, 88, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], [1074, 24, 300, "Metrics/BlockNesting: Avoid more than 3 levels of block nesting.", 2690302041], [1074, 55, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], - [1299, 7, 680, "Metrics/AbcSize: Assignment Branch Condition size for `detect_gemspec_block_var` is too high. [<3, 22, 15> 26.8/17]", 3676370299], - [1299, 7, 680, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_gemspec_block_var` is too high. [14/7]", 3676370299], - [1299, 7, 680, "Metrics/MethodLength: Method has too many lines. [14/10]", 3676370299], - [1299, 7, 680, "Metrics/PerceivedComplexity: Perceived complexity for `detect_gemspec_block_var` is too high. [14/8]", 3676370299] + [1285, 7, 680, "Metrics/AbcSize: Assignment Branch Condition size for `detect_gemspec_block_var` is too high. [<3, 22, 15> 26.8/17]", 3676370299], + [1285, 7, 680, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_gemspec_block_var` is too high. [14/7]", 3676370299], + [1285, 7, 680, "Metrics/MethodLength: Method has too many lines. [14/10]", 3676370299], + [1285, 7, 680, "Metrics/PerceivedComplexity: Perceived complexity for `detect_gemspec_block_var` is too high. [14/8]", 3676370299] ], "lib/prism/merge/freeze_node.rb:2471800311": [ [67, 7, 577, "Metrics/MethodLength: Method has too many lines. [11/10]", 2189574632], @@ -365,17 +337,6 @@ [124, 7, 2888, "Metrics/MethodLength: Method has too many lines. [38/10]", 3621186151], [124, 7, 2888, "Metrics/PerceivedComplexity: Perceived complexity for `validate_structure!` is too high. [25/8]", 3621186151] ], - "lib/prism/merge/magic_comment_support.rb:1214861451": [ - [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177608], - [3, 5, 26, "Style/Documentation: Missing top-level documentation comment for `module Prism::Merge::MagicCommentSupport`.", 1989707586], - [16, 7, 1484, "Metrics/AbcSize: Assignment Branch Condition size for `comment_only_prefix_info` is too high. [<9, 38, 8> 39.86/17]", 1098666313], - [16, 7, 1484, "Metrics/MethodLength: Method has too many lines. [33/10]", 1098666313], - [59, 7, 693, "Metrics/AbcSize: Assignment Branch Condition size for `header_magic_comment_types_for_lines` is too high. [<10, 13, 9> 18.71/17]", 3693768719], - [59, 7, 693, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `header_magic_comment_types_for_lines` is too high. [8/7]", 3693768719], - [59, 7, 693, "Metrics/MethodLength: Method has too many lines. [16/10]", 3693768719], - [83, 7, 748, "Metrics/AbcSize: Assignment Branch Condition size for `prefix_comment_line_numbers_for_comments` is too high. [<10, 12, 7> 17.12/17]", 335042389], - [83, 7, 748, "Metrics/MethodLength: Method has too many lines. [19/10]", 335042389] - ], "lib/prism/merge/merge_result.rb:1970522956": [ [9, 5, 12561, "Metrics/ClassLength: Class has too many lines. [238/100]", 3020348188], [67, 7, 5058, "Metrics/AbcSize: Assignment Branch Condition size for `add_node` is too high. [<25, 54, 38> 70.6/17]", 2165268226], @@ -389,26 +350,20 @@ [219, 7, 901, "Metrics/MethodLength: Method has too many lines. [25/10]", 2776830125], [296, 7, 903, "Metrics/MethodLength: Method has too many lines. [18/10]", 2752342414] ], - "lib/prism/merge/method_match_refiner.rb:3086922470": [ - [98, 7, 678, "Metrics/AbcSize: Assignment Branch Condition size for `param_similarity` is too high. [<6, 21, 4> 22.2/17]", 2054244811], - [121, 7, 705, "Metrics/AbcSize: Assignment Branch Condition size for `extract_param_names` is too high. [<2, 37, 16> 40.36/17]", 3200522215], - [121, 7, 705, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_param_names` is too high. [17/7]", 3200522215], - [121, 7, 705, "Metrics/MethodLength: Method has too many lines. [11/10]", 3200522215], - [121, 7, 705, "Metrics/PerceivedComplexity: Perceived complexity for `extract_param_names` is too high. [17/8]", 3200522215], - [129, 49, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], - [132, 65, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], - [160, 7, 854, "Metrics/AbcSize: Assignment Branch Condition size for `levenshtein_distance` is too high. [<13, 29, 8> 32.77/17]", 2946547420], - [160, 7, 854, "Metrics/MethodLength: Method has too many lines. [20/10]", 2946547420] + "lib/prism/merge/method_match_refiner.rb:1593340636": [ + [103, 7, 705, "Metrics/AbcSize: Assignment Branch Condition size for `extract_param_names` is too high. [<2, 37, 16> 40.36/17]", 3200522215], + [103, 7, 705, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `extract_param_names` is too high. [17/7]", 3200522215], + [103, 7, 705, "Metrics/MethodLength: Method has too many lines. [11/10]", 3200522215], + [103, 7, 705, "Metrics/PerceivedComplexity: Perceived complexity for `extract_param_names` is too high. [17/8]", 3200522215], + [111, 49, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], + [114, 65, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765] ], "lib/prism/merge/nested_statement_walker.rb:3826169704": [ [24, 7, 695, "Metrics/MethodLength: Method has too many lines. [16/10]", 3744912119], [45, 7, 518, "Metrics/MethodLength: Method has too many lines. [12/10]", 2978518157] ], - "lib/prism/merge/nocov_node.rb:3116182832": [ - [59, 21, 84, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3439911158], - [90, 19, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765], - [143, 7, 353, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `signature` is too high. [8/7]", 3442013923], - [143, 7, 353, "Metrics/PerceivedComplexity: Perceived complexity for `signature` is too high. [9/8]", 3442013923] + "lib/prism/merge/nocov_node.rb:2336029940": [ + [52, 19, 2, "Lint/RedundantSafeNavigation: Redundant safe navigation detected, use `.` instead.", 5858765] ], "lib/prism/merge/node_body_layout.rb:1642074264": [ [5, 5, 20, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::NodeBodyLayout`.", 1262407425], @@ -505,16 +460,16 @@ [12, 7, 1132, "Metrics/PerceivedComplexity: Perceived complexity for `should_merge?` is too high. [13/8]", 4123619949], [47, 7, 398, "Metrics/MethodLength: Method has too many lines. [18/10]", 385694759] ], - "lib/prism/merge/recursive_node_body_merger.rb:2523299035": [ + "lib/prism/merge/recursive_node_body_merger.rb:1132596837": [ [5, 5, 29, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::RecursiveNodeBodyMerger`.", 3703318859], - [5, 5, 18406, "Metrics/ClassLength: Class has too many lines. [333/100]", 1740018190], - [12, 7, 12657, "Metrics/AbcSize: Assignment Branch Condition size for `merge` is too high. [<79, 259, 101> 289/17]", 1663029092], - [12, 7, 12657, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge` is too high. [78/7]", 1663029092], - [12, 7, 12657, "Metrics/MethodLength: Method has too many lines. [215/10]", 1663029092], - [12, 7, 12657, "Metrics/PerceivedComplexity: Perceived complexity for `merge` is too high. [83/8]", 1663029092], + [5, 5, 18505, "Metrics/ClassLength: Class has too many lines. [333/100]", 3196902308], + [12, 7, 12756, "Metrics/AbcSize: Assignment Branch Condition size for `merge` is too high. [<78, 262, 90> 287.8/17]", 1909933362], + [12, 7, 12756, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge` is too high. [70/7]", 1909933362], + [12, 7, 12756, "Metrics/MethodLength: Method has too many lines. [215/10]", 1909933362], + [12, 7, 12756, "Metrics/PerceivedComplexity: Perceived complexity for `merge` is too high. [75/8]", 1909933362], [27, 121, 10, "Layout/LineLength: Line is too long. [130/120]", 929875726], - [65, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 518709914], - [70, 121, 10, "Layout/LineLength: Line is too long. [130/120]", 366676207], + [62, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 518709914], + [67, 121, 10, "Layout/LineLength: Line is too long. [130/120]", 366676207], [266, 7, 1221, "Metrics/AbcSize: Assignment Branch Condition size for `remap_inner_unresolved_review_state!` is too high. [<8, 22, 6> 24.17/17]", 3210674006], [266, 7, 1221, "Metrics/MethodLength: Method has too many lines. [21/10]", 3210674006], [293, 7, 1121, "Metrics/AbcSize: Assignment Branch Condition size for `remap_inner_unresolved_case` is too high. [<6, 24, 0> 24.74/17]", 3468635549], @@ -524,20 +479,19 @@ [376, 7, 826, "Metrics/MethodLength: Method has too many lines. [17/10]", 2158299973], [376, 7, 826, "Metrics/PerceivedComplexity: Perceived complexity for `emit_trailing_layout_gap_lines` is too high. [9/8]", 2158299973] ], - "lib/prism/merge/ruby_doc_surface_analyzer.rb:2647486851": [ - [7, 5, 8269, "Metrics/ClassLength: Class has too many lines. [192/100]", 2716524254], - [61, 7, 1408, "Metrics/AbcSize: Assignment Branch Condition size for `build_doc_comment_surface` is too high. [<10, 25, 5> 27.39/17]", 2414553577], - [61, 7, 1408, "Metrics/MethodLength: Method has too many lines. [28/10]", 2414553577], - [106, 7, 1513, "Metrics/AbcSize: Assignment Branch Condition size for `build_example_surface` is too high. [<6, 24, 6> 25.46/17]", 4167825853], - [106, 7, 1513, "Metrics/MethodLength: Method has too many lines. [29/10]", 4167825853], - [162, 7, 555, "Metrics/AbcSize: Assignment Branch Condition size for `doc_comment_entries` is too high. [<8, 18, 6> 20.59/17]", 358090808] - ], - "lib/prism/merge/scaffold_chunk_remover.rb:2190237849": [ - [15, 5, 5193, "Metrics/ClassLength: Class has too many lines. [123/100]", 3937701477], - [75, 7, 1856, "Metrics/AbcSize: Assignment Branch Condition size for `call` is too high. [<21, 60, 22> 67.27/17]", 1601329428], - [75, 7, 1856, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `call` is too high. [21/7]", 1601329428], - [75, 7, 1856, "Metrics/MethodLength: Method has too many lines. [37/10]", 1601329428], - [75, 7, 1856, "Metrics/PerceivedComplexity: Perceived complexity for `call` is too high. [21/8]", 1601329428] + "lib/prism/merge/ruby_doc_surface_analyzer.rb:3389668357": [ + [7, 5, 7100, "Metrics/ClassLength: Class has too many lines. [162/100]", 77379508], + [50, 7, 1408, "Metrics/AbcSize: Assignment Branch Condition size for `build_doc_comment_surface` is too high. [<10, 25, 5> 27.39/17]", 2414553577], + [50, 7, 1408, "Metrics/MethodLength: Method has too many lines. [28/10]", 2414553577], + [91, 7, 1256, "Metrics/AbcSize: Assignment Branch Condition size for `build_example_surface` is too high. [<4, 23, 2> 23.43/17]", 4074178203], + [91, 7, 1256, "Metrics/MethodLength: Method has too many lines. [25/10]", 4074178203], + [131, 7, 555, "Metrics/AbcSize: Assignment Branch Condition size for `doc_comment_entries` is too high. [<8, 18, 6> 20.59/17]", 358090808] + ], + "lib/prism/merge/scaffold_chunk_remover.rb:174131146": [ + [34, 7, 1958, "Metrics/AbcSize: Assignment Branch Condition size for `call` is too high. [<21, 60, 22> 67.27/17]", 1919383090], + [34, 7, 1958, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `call` is too high. [21/7]", 1919383090], + [34, 7, 1958, "Metrics/MethodLength: Method has too many lines. [37/10]", 1919383090], + [34, 7, 1958, "Metrics/PerceivedComplexity: Perceived complexity for `call` is too high. [21/8]", 1919383090] ], "lib/prism/merge/smart_merger.rb:3814529034": [ [48, 5, 42561, "Metrics/ClassLength: Class has too many lines. [603/100]", 3828655257], @@ -564,8 +518,8 @@ "lib/prism/merge/source_line_lookup.rb:1098479933": [ [5, 5, 23, "Style/Documentation: Missing top-level documentation comment for `module Prism::Merge::SourceLineLookup`.", 2168434862] ], - "lib/prism/merge/top_level_merge_runner.rb:3009983916": [ - [38, 5, 59959, "Metrics/ClassLength: Class has too many lines. [1124/100]", 2689943302], + "lib/prism/merge/top_level_merge_runner.rb:1106437552": [ + [38, 5, 61468, "Metrics/ClassLength: Class has too many lines. [1156/100]", 150648557], [66, 7, 5196, "Metrics/AbcSize: Assignment Branch Condition size for `merge` is too high. [<22, 68, 9> 72.03/17]", 176450457], [66, 7, 5196, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge` is too high. [9/7]", 176450457], [66, 7, 5196, "Metrics/MethodLength: Method has too many lines. [75/10]", 176450457], @@ -630,25 +584,25 @@ [1003, 55, 17, "Lint/UnusedMethodArgument: Unused method argument - `dest_by_signature`.", 379778684], [1024, 9, 250, "Style/CombinableLoops: Combine this loop with the previous loop.", 3315024098], [1031, 121, 5, "Layout/LineLength: Line is too long. [125/120]", 180543822], - [1048, 7, 4375, "Metrics/AbcSize: Assignment Branch Condition size for `process_dest_node` is too high. [<23, 66, 14> 71.28/17]", 329713352], - [1048, 7, 4375, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `process_dest_node` is too high. [11/7]", 329713352], - [1048, 7, 4375, "Metrics/MethodLength: Method has too many lines. [80/10]", 329713352], - [1048, 7, 4375, "Metrics/PerceivedComplexity: Perceived complexity for `process_dest_node` is too high. [15/8]", 329713352], + [1048, 7, 4811, "Metrics/AbcSize: Assignment Branch Condition size for `process_dest_node` is too high. [<23, 71, 16> 76.33/17]", 329713352], + [1048, 7, 4811, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `process_dest_node` is too high. [13/7]", 329713352], + [1048, 7, 4811, "Metrics/MethodLength: Method has too many lines. [90/10]", 329713352], + [1048, 7, 4811, "Metrics/PerceivedComplexity: Perceived complexity for `process_dest_node` is too high. [17/8]", 329713352], [1048, 28, 279, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [9/5]", 2321512478], - [1153, 7, 757, "Metrics/MethodLength: Method has too many lines. [19/10]", 3306507447], - [1191, 44, 189, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 215272527], - [1222, 7, 888, "Metrics/MethodLength: Method has too many lines. [17/10]", 2638200013], - [1222, 31, 189, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [9/5]", 50070642], - [1244, 7, 719, "Metrics/MethodLength: Method has too many lines. [13/10]", 530865591], - [1262, 7, 1393, "Metrics/AbcSize: Assignment Branch Condition size for `process_non_recursive_match` is too high. [<10, 23, 7> 26.04/17]", 324106576], - [1262, 7, 1393, "Metrics/MethodLength: Method has too many lines. [29/10]", 324106576], - [1296, 7, 1106, "Metrics/AbcSize: Assignment Branch Condition size for `process_unresolved_non_recursive_match` is too high. [<3, 19, 3> 19.47/17]", 1476652897], - [1296, 7, 1106, "Metrics/MethodLength: Method has too many lines. [26/10]", 1476652897], - [1337, 7, 1935, "Metrics/AbcSize: Assignment Branch Condition size for `record_unresolved_match_case!` is too high. [<4, 26, 3> 26.48/17]", 456739474], - [1337, 7, 1935, "Metrics/MethodLength: Method has too many lines. [37/10]", 456739474], - [1422, 7, 1067, "Metrics/AbcSize: Assignment Branch Condition size for `advance_last_output_dest_line` is too high. [<6, 19, 6> 20.81/17]", 331135500], - [1422, 7, 1067, "Metrics/MethodLength: Method has too many lines. [11/10]", 331135500], - [1422, 40, 181, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 2038823112] + [1190, 7, 757, "Metrics/MethodLength: Method has too many lines. [19/10]", 3306507447], + [1228, 44, 189, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 215272527], + [1259, 7, 888, "Metrics/MethodLength: Method has too many lines. [17/10]", 2638200013], + [1259, 31, 189, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [9/5]", 50070642], + [1281, 7, 719, "Metrics/MethodLength: Method has too many lines. [13/10]", 530865591], + [1299, 7, 1393, "Metrics/AbcSize: Assignment Branch Condition size for `process_non_recursive_match` is too high. [<10, 23, 7> 26.04/17]", 324106576], + [1299, 7, 1393, "Metrics/MethodLength: Method has too many lines. [29/10]", 324106576], + [1333, 7, 1106, "Metrics/AbcSize: Assignment Branch Condition size for `process_unresolved_non_recursive_match` is too high. [<3, 19, 3> 19.47/17]", 1476652897], + [1333, 7, 1106, "Metrics/MethodLength: Method has too many lines. [26/10]", 1476652897], + [1374, 7, 1935, "Metrics/AbcSize: Assignment Branch Condition size for `record_unresolved_match_case!` is too high. [<4, 26, 3> 26.48/17]", 456739474], + [1374, 7, 1935, "Metrics/MethodLength: Method has too many lines. [37/10]", 456739474], + [1459, 7, 1067, "Metrics/AbcSize: Assignment Branch Condition size for `advance_last_output_dest_line` is too high. [<6, 19, 6> 20.81/17]", 331135500], + [1459, 7, 1067, "Metrics/MethodLength: Method has too many lines. [11/10]", 331135500], + [1459, 40, 181, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 2038823112] ], "lib/prism/merge/wrapper_comment_support.rb:3046735928": [ [5, 5, 27, "Style/Documentation: Missing top-level documentation comment for `class Prism::Merge::WrapperCommentSupport`.", 2211657316], @@ -721,13 +675,13 @@ "spec/fixtures/reproducible/05_gemspec_orphan_duplication/template.rb:1825302441": [ [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177634] ], - "spec/fixtures_integration_spec.rb:4053275636": [ - [7, 1, 21570, "Metrics/BlockLength: Block has too many lines. [483/25]", 416378449], + "spec/fixtures_integration_spec.rb:2298883270": [ + [7, 1, 22463, "Metrics/BlockLength: Block has too many lines. [507/25]", 1776221706], [66, 121, 26, "Layout/LineLength: Line is too long. [146/120]", 1448895712], [72, 3, 1302, "Metrics/BlockLength: Block has too many lines. [30/25]", 2973641144], [106, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5858795], [113, 3, 1679, "Metrics/BlockLength: Block has too many lines. [38/25]", 2954972744], - [373, 3, 7512, "Metrics/BlockLength: Block has too many lines. [149/25]", 2278210376] + [400, 3, 7512, "Metrics/BlockLength: Block has too many lines. [149/25]", 2278210376] ], "spec/reproducible_merge_spec.rb:2334824632": [ [6, 1, 2420, "Metrics/BlockLength: Block has too many lines. [50/25]", 2207509489], diff --git a/gems/prism-merge/Gemfile b/gems/prism-merge/Gemfile index 9516df867..3e237a9cc 100644 --- a/gems/prism-merge/Gemfile +++ b/gems/prism-merge/Gemfile @@ -151,7 +151,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -160,7 +400,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -168,7 +408,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/prism-merge/Gemfile.lock b/gems/prism-merge/Gemfile.lock index 41da0b771..a271a6b5a 100644 --- a/gems/prism-merge/Gemfile.lock +++ b/gems/prism-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH ruby-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,8 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +351,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,15 +386,8 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) - nokogiri (1.19.4-aarch64-linux-gnu) - racc (~> 1.4) - nokogiri (1.19.4-aarch64-linux-musl) - racc (~> 1.4) - nokogiri (1.19.4-arm64-darwin) - racc (~> 1.4) - nokogiri (1.19.4-x86_64-darwin) - racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-musl) @@ -267,13 +515,11 @@ GEM lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) rubocop-ast (>= 1.44.0, < 2.0) - ruby-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -326,13 +572,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -357,7 +603,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -366,34 +612,52 @@ GEM zlib (3.2.3) PLATFORMS - aarch64-linux - aarch64-linux-gnu - aarch64-linux-musl - arm64-darwin - x86_64-darwin + x86_64-linux x86_64-linux-gnu x86_64-linux-musl DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -402,31 +666,50 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -434,6 +717,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -446,24 +730,28 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 - nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f - nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af - nokogiri (1.19.4-arm64-darwin) sha256=a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527 - nokogiri (1.19.4-x86_64-darwin) sha256=7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b nomono (1.0.8) sha256=bf4b9b426cbf216ab17b70db474f691b8ae1f1e29de8db4b0ecd405e6e7e1c80 @@ -473,11 +761,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -485,6 +776,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -516,6 +808,8 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -524,6 +818,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -537,21 +832,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/prism-merge/gemfiles/modular/templating.gemfile b/gems/prism-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/prism-merge/gemfiles/modular/templating.gemfile +++ b/gems/prism-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/prism-merge/gemfiles/modular/templating_local.gemfile b/gems/prism-merge/gemfiles/modular/templating_local.gemfile index 5c9f8cab6..b212bdc16 100644 --- a/gems/prism-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/prism-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[prism-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[prism-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[prism-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/prism-merge/lib/prism/merge.rb b/gems/prism-merge/lib/prism/merge.rb index a60a5ad27..948c58260 100644 --- a/gems/prism-merge/lib/prism/merge.rb +++ b/gems/prism-merge/lib/prism/merge.rb @@ -449,7 +449,7 @@ def parse_ruby(source, dialect, backend: nil) return unsupported_feature_result("Unsupported Ruby backend #{requested}.") end - result = ::Prism.parse(source) + result = TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:ruby).parse(source).parse_result } unless result.success? return { ok: false, @@ -490,7 +490,7 @@ def parse_ruby_normalized(source, dialect = 'ruby', backend: nil) return unsupported_feature_result("Unsupported Ruby backend #{requested}.") end - result = ::Prism.parse(source) + result = TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:ruby).parse(source).parse_result } unless result.success? return TreeHaver::NormalizedParseResult.new( ok: false, @@ -981,23 +981,14 @@ def prism_ruby_surfaces_for_owner(owner_name, comment_entries) def prism_ruby_example_surfaces(surface) entries = Array(surface.dig(:metadata, :entries)) - normalized = entries.map { |entry| prism_ruby_normalize_comment_content(entry.fetch(:raw)) } - normalized.each_with_index.filter_map do |content, tag_index| - next unless content.start_with?('@example') - - body_start = tag_index + 1 - body_end = prism_ruby_next_yard_tag_index(normalized, body_start) || normalized.length - next if body_start >= body_end - - body_entries = entries[body_start...body_end] - next if body_entries.nil? || body_entries.empty? - - declared_language = prism_ruby_declared_example_language(content) || 'ruby' + Ruby::Merge::DocCommentSupport.example_blocks(entries).map do |block| + body_entries = block.fetch(:body_entries) + declared_language = block.fetch(:declared_language) || 'ruby' Ast::Merge.discovered_surface( surface_kind: 'yard_example_block', declared_language: declared_language, effective_language: declared_language, - address: "#{surface.fetch(:address)} > yard_example[#{tag_index}]", + address: "#{surface.fetch(:address)} > yard_example[#{block.fetch(:tag_index)}]", parent_address: surface.fetch(:address), owner: Ast::Merge.surface_owner_ref(kind: 'owned_region', address: surface.fetch(:address)), span: Ast::Merge.surface_span(start_line: body_entries.first.fetch(:line), @@ -1005,8 +996,8 @@ def prism_ruby_example_surfaces(surface) reconstruction_strategy: 'rewrite_with_prefix_preservation', metadata: { tag_kind: 'example', - tag_index: tag_index, - tag_text: content, + tag_index: block.fetch(:tag_index), + tag_text: block.fetch(:tag_text), comment_prefix: surface.dig(:metadata, :comment_prefix) } ) @@ -1033,48 +1024,23 @@ def prism_ruby_require_path(node) end def prism_ruby_doc_comment_content?(raw) - content = prism_ruby_normalize_comment_content(raw) - return false if content.empty? - return false if content.start_with?(':nocov:') - return false if %w[coding encoding frozen_string_literal shareable_constant_value typed - warn_indent].any? do |prefix| - content.start_with?("#{prefix}:") - end - - true + Ruby::Merge::DocCommentSupport.doc_comment_content?(raw) end def prism_ruby_normalize_comment_content(raw) - stripped = raw.to_s.lstrip - return stripped unless stripped.start_with?('#') - - stripped.delete_prefix('#').delete_prefix(' ').strip + Ruby::Merge::DocCommentSupport.normalize_comment_content(raw) end def prism_ruby_comment_prefix(raw) - raw_text = raw.to_s - hash_index = raw_text.index('#') - return '# ' unless hash_index - - raw_text[0..hash_index] + (raw_text[hash_index + 1] == ' ' ? ' ' : '') + Ruby::Merge::DocCommentSupport.comment_prefix_for(raw) end def prism_ruby_next_yard_tag_index(lines, start_index) - lines.each_with_index do |content, index| - next if index < start_index - return index if content.start_with?('@') - end - nil + Ruby::Merge::DocCommentSupport.next_tag_index(lines, start_index) end def prism_ruby_declared_example_language(content) - marker = '@example [' - return unless content.start_with?(marker) - - closing_index = content.index(']', marker.length) - return unless closing_index - - content[marker.length...closing_index] + Ruby::Merge::DocCommentSupport.declared_example_language_for_tag(content) end def prism_ruby_normalize_source(source) @@ -1257,8 +1223,7 @@ def prism_comment_directive(comment_text, magic_comment) end def coverage_directive_comment?(comment_text) - stripped = comment_text.strip - stripped == '# :nocov:' || stripped.match?(/\A#\s*simplecov\s*:\s*(?:disable|enable)\b/i) + Ruby::Merge::BlockDirectiveDetector.coverage_directive_line?(comment_text) end def magic_comment_for(comment, magic_comments) diff --git a/gems/prism-merge/lib/prism/merge/begin_node_clause_body_support.rb b/gems/prism-merge/lib/prism/merge/begin_node_clause_body_support.rb index b88e32b27..8519101ba 100644 --- a/gems/prism-merge/lib/prism/merge/begin_node_clause_body_support.rb +++ b/gems/prism-merge/lib/prism/merge/begin_node_clause_body_support.rb @@ -102,13 +102,12 @@ def clause_body_components(node, region, analysis) # sub-body FileAnalysis is constructed on the body slice alone. effective_body_end = last_statement_end_line if region[:end_line] > last_statement_end_line - nocov_pat = /\A\s*#\s?#{Regexp.escape(BlockDirectiveDetector::NOCOV_TOKEN)}\s*\z/io nocov_count = (body_start_line..last_statement_end_line).count do |ln| - analysis.line_at(ln).to_s.chomp.match?(nocov_pat) + Ruby::Merge::BlockDirectiveDetector.coverage_directive_line?(analysis.line_at(ln)) end if nocov_count.odd? ((last_statement_end_line + 1)..region[:end_line]).each do |ln| - if analysis.line_at(ln).to_s.chomp.match?(nocov_pat) + if Ruby::Merge::BlockDirectiveDetector.coverage_directive_line?(analysis.line_at(ln)) effective_body_end = ln break end diff --git a/gems/prism-merge/lib/prism/merge/begin_node_rescue_semantics.rb b/gems/prism-merge/lib/prism/merge/begin_node_rescue_semantics.rb index e8aae2012..bc76aecb2 100644 --- a/gems/prism-merge/lib/prism/merge/begin_node_rescue_semantics.rb +++ b/gems/prism-merge/lib/prism/merge/begin_node_rescue_semantics.rb @@ -46,70 +46,25 @@ def normalized_clause_body_and_header_source(template_clause_node:, dest_clause_ end def merge_ordered_clause_types(primary_types, secondary_types) - ordered = primary_types.dup - - secondary_types.each_with_index do |clause_type, secondary_index| - next if ordered.include?(clause_type) - - previous_shared = secondary_types[0...secondary_index].reverse.find { |type| ordered.include?(type) } - next_shared = secondary_types[(secondary_index + 1)..]&.find { |type| ordered.include?(type) } - - if previous_shared - insert_at = ordered.index(previous_shared) + 1 - ordered.insert(insert_at, clause_type) - elsif next_shared - insert_at = ordered.index(next_shared) - ordered.insert(insert_at, clause_type) - else - ordered << clause_type - end - end - - ordered + ruby_rescue_semantics.merge_ordered_clause_types(primary_types, secondary_types) end def canonicalize_rescue_clause_order(clause_types) - rescue_clause_types = clause_types.select { |clause_type| rescue_clause_type?(clause_type) } - return clause_types if rescue_clause_types.length < 2 - - ordered_rescue_types = rescue_clause_types.dup - - if rescue_clause_types.any? { |clause_type| broad_rescue_clause_type?(clause_type) } && - rescue_clause_types.any? { |clause_type| !broad_rescue_clause_type?(clause_type) } - specific_rescue_types = ordered_rescue_types.reject { |clause_type| broad_rescue_clause_type?(clause_type) } - broad_rescue_types = ordered_rescue_types.select { |clause_type| broad_rescue_clause_type?(clause_type) } - ordered_rescue_types = specific_rescue_types + broad_rescue_types - end - - loop do - swapped = false - - (0...(ordered_rescue_types.length - 1)).each do |index| - left_clause_type = ordered_rescue_types[index] - right_clause_type = ordered_rescue_types[index + 1] - next unless broader_rescue_clause_type_than?(left_clause_type, right_clause_type) - - ordered_rescue_types[index] = right_clause_type - ordered_rescue_types[index + 1] = left_clause_type - swapped = true - end - - break unless swapped - end - - clause_types.map do |clause_type| - rescue_clause_type?(clause_type) ? ordered_rescue_types.shift : clause_type - end + ruby_rescue_semantics.canonicalize_rescue_clause_order(clause_types) end def canonicalize_begin_clause_kind_order(clause_types) - clause_types.each_with_index - .sort_by { |(clause_type, index)| [clause_kind_sort_key(clause_type), index] } - .map(&:first) + ruby_rescue_semantics.canonicalize_begin_clause_kind_order(clause_types) end private + def ruby_rescue_semantics + @ruby_rescue_semantics ||= Ruby::Merge::RescueSemantics.new( + source_defined_exception_definitions: source_defined_exception_definitions + ) + end + def rescue_node_reference_name(rescue_node) return unless rescue_node.type.to_s == 'rescue_node' @@ -197,62 +152,41 @@ def replace_byte_range(source, start_offset, end_offset, replacement) end def rescue_clause_type?(clause_type) - clause_type.is_a?(Array) && clause_type.first == :rescue_clause + ruby_rescue_semantics.rescue_clause_type?(clause_type) end def broad_rescue_clause_type?(clause_type) - rescue_clause_type?(clause_type) && clause_type[1] == [:standard_error] + ruby_rescue_semantics.broad_rescue_clause_type?(clause_type) end def clause_kind_sort_key(clause_type) - return 0 if rescue_clause_type?(clause_type) - return 1 if clause_type == :else_clause - return 2 if clause_type == :ensure_clause - - 3 + ruby_rescue_semantics.clause_kind_sort_key(clause_type) end def normalize_exception_name(exception_name) - return 'StandardError' if exception_name == :standard_error - - name = exception_name.to_s.sub(/\A::/, '') - name.empty? ? nil : name + ruby_rescue_semantics.normalize_exception_name(exception_name) end def qualify_source_constant_name(constant_name, namespace = nil) - normalized_name = normalize_exception_name(constant_name) - return if normalized_name.nil? - return normalized_name if constant_name.to_s.start_with?('::') || namespace.nil? || namespace.empty? - - "#{namespace}::#{normalized_name}" + ruby_rescue_semantics.qualify_source_constant_name(constant_name, namespace) end - def source_defined_exception_hierarchy - @source_defined_exception_hierarchy ||= begin + def source_defined_exception_definitions + @source_defined_exception_definitions ||= begin definitions = [] [template_analysis, dest_analysis].compact.each do |analysis| next unless analysis.respond_to?(:parse_result) && analysis.parse_result&.respond_to?(:value) collect_source_defined_exception_definitions(analysis.parse_result.value, nil, definitions) end - - defined_names = definitions.map { |definition| definition[:name] }.compact.to_set - definitions.each_with_object({}) do |definition, hierarchy| - next unless definition[:name] && definition[:superclass] - - superclass_name = if definition[:superclass].to_s.start_with?('::') - normalize_exception_name(definition[:superclass]) - else - candidate_name = qualify_source_constant_name(definition[:superclass], - definition[:namespace]) - defined_names.include?(candidate_name) ? candidate_name : normalize_exception_name(definition[:superclass]) - end - - hierarchy[definition[:name]] ||= superclass_name if superclass_name - end + definitions end end + def source_defined_exception_hierarchy + ruby_rescue_semantics.source_defined_exception_hierarchy + end + def collect_source_defined_exception_definitions(node, namespace, definitions) return unless node @@ -282,77 +216,35 @@ def collect_source_defined_exception_definitions(node, namespace, definitions) end def resolve_exception_constant(exception_name) - return ::StandardError if exception_name == :standard_error - return unless exception_name.is_a?(String) && !exception_name.empty? - - exception_name.split('::').reject(&:empty?).inject(Object) { |scope, const_name| scope.const_get(const_name) } - rescue NameError - nil + ruby_rescue_semantics.resolve_exception_constant(exception_name) end def rescue_clause_exception_names(clause_type) - return [] unless rescue_clause_type?(clause_type) - - Array(clause_type[1]).filter_map { |exception_name| normalize_exception_name(exception_name) } + ruby_rescue_semantics.rescue_clause_exception_names(clause_type) end def rescue_clause_exception_constants(clause_type) - rescue_clause_exception_names(clause_type).filter_map do |exception_name| - resolve_exception_constant(exception_name) - end + ruby_rescue_semantics.rescue_clause_exception_constants(clause_type) end def exception_constant_covers?(covering_constant, covered_constant) - return true if covering_constant == covered_constant - - covered_constant < covering_constant - rescue StandardError - false + ruby_rescue_semantics.exception_constant_covers?(covering_constant, covered_constant) end def source_defined_exception_covers?(covering_name, covered_name) - normalized_covering = normalize_exception_name(covering_name) - current_name = normalize_exception_name(covered_name) - return false if normalized_covering.nil? || current_name.nil? - return true if normalized_covering == current_name - - while (current_name = source_defined_exception_hierarchy[current_name]) - return true if current_name == normalized_covering - end - - false + ruby_rescue_semantics.source_defined_exception_covers?(covering_name, covered_name) end def exception_name_covers?(covering_name, covered_name) - covering_constant = resolve_exception_constant(covering_name) - covered_constant = resolve_exception_constant(covered_name) - - if covering_constant && covered_constant - exception_constant_covers?(covering_constant, covered_constant) - else - source_defined_exception_covers?(covering_name, covered_name) - end + ruby_rescue_semantics.exception_name_covers?(covering_name, covered_name) end def rescue_clause_covers?(covering_clause_type, covered_clause_type) - return false unless rescue_clause_type?(covering_clause_type) && rescue_clause_type?(covered_clause_type) - - covering_names = rescue_clause_exception_names(covering_clause_type) - covered_names = rescue_clause_exception_names(covered_clause_type) - return false if covering_names.empty? || covered_names.empty? - - covered_names.all? do |covered_name| - covering_names.any? do |covering_name| - exception_name_covers?(covering_name, covered_name) - end - end + ruby_rescue_semantics.rescue_clause_covers?(covering_clause_type, covered_clause_type) end def broader_rescue_clause_type_than?(left_clause_type, right_clause_type) - return false unless rescue_clause_type?(left_clause_type) && rescue_clause_type?(right_clause_type) - - rescue_clause_covers?(left_clause_type, right_clause_type) && - !rescue_clause_covers?(right_clause_type, left_clause_type) + ruby_rescue_semantics.broader_rescue_clause_type_than?(left_clause_type, right_clause_type) end end end diff --git a/gems/prism-merge/lib/prism/merge/begin_node_structure.rb b/gems/prism-merge/lib/prism/merge/begin_node_structure.rb index 1b21db318..988daac6a 100644 --- a/gems/prism-merge/lib/prism/merge/begin_node_structure.rb +++ b/gems/prism-merge/lib/prism/merge/begin_node_structure.rb @@ -8,12 +8,7 @@ def rescue_signature(rescue_node) exceptions = Array(rescue_node.exceptions).map do |exception_node| exception_node.respond_to?(:slice) ? exception_node.slice : exception_node.to_s end - normalized_exceptions = exceptions.map { |exception| exception.to_s.sub(/\A::/, '') } - if normalized_exceptions.empty? || normalized_exceptions == ['StandardError'] - [:standard_error] - else - normalized_exceptions.sort - end + Ruby::Merge::RescueSemantics.new.rescue_clause_signature(exceptions) end end diff --git a/gems/prism-merge/lib/prism/merge/block_directive_detector.rb b/gems/prism-merge/lib/prism/merge/block_directive_detector.rb index c9c200b0b..2797aed66 100644 --- a/gems/prism-merge/lib/prism/merge/block_directive_detector.rb +++ b/gems/prism-merge/lib/prism/merge/block_directive_detector.rb @@ -2,78 +2,21 @@ module Prism module Merge - # Detects block directive pairs (freeze and coverage) in source lines and - # promotes them to synthetic BlockDirective tree nodes in the statements array. + # Prism-specific projection for Ruby block directive spans. # - # A block directive is an open/close comment pair that wraps content: - # - Freeze: `# token:freeze` ... `# token:unfreeze` - # - Coverage: `# simplecov:disable` ... `# simplecov:enable` - # - Legacy coverage: `# :nocov:` ... `# :nocov:` (same marker toggles) - # - # The detector runs AFTER Prism's `attach_comments!` to avoid being fooled by - # Prism's leading-comment attachment, which hoists all preceding comment lines - # onto the first code node as leading comments. - # - # Rules enforced: - # - Directives must form a clean tree (proper nesting, no offset overlap) - # - Directives must open and close at the same syntactic level - # - Violations emit a warning and fall back to plain comment emission - class BlockDirectiveDetector - # Represents a detected span before tree promotion - Span = Struct.new(:kind, :start_line, :end_line, :open_marker, :close_marker, keyword_init: true) - - # Default legacy nocov token (older SimpleCov convention) - NOCOV_TOKEN = ':nocov:' - SIMPLECOV_DISABLE_RE = /\A\s*#\s*simplecov\s*:\s*disable\b/i - SIMPLECOV_ENABLE_RE = /\A\s*#\s*simplecov\s*:\s*enable\b/i - - # @param lines [Array] Raw source lines (1-indexed via [line_num - 1]) - # @param freeze_token [String, nil] Freeze token (e.g. "kettle-jem"). nil disables freeze detection. - # @param nocov_token [String] Nocov token (default ":nocov:") - # @param source_label [String, nil] Optional file path or label included in warning messages. - def initialize(lines, freeze_token: nil, nocov_token: NOCOV_TOKEN, source_label: nil) - @lines = lines - @freeze_token = freeze_token - @nocov_token = nocov_token - @source_label = source_label - end - - # Detect all directive spans in the source lines. - # Returns a flat array of Span structs sorted by start_line. - # Crossing/invalid spans are excluded with a warning. - # - # @return [Array] - def detect_spans - raw_spans = [] - raw_spans.concat(detect_freeze_spans) if @freeze_token - raw_spans.concat(detect_nocov_spans) - - sorted = raw_spans.sort_by(&:start_line) - validate_no_crossing(sorted) - end - - # Post-process a statements array: replace content covered by each span - # with a synthetic BlockDirective node. Spans must be pre-validated (no crossing). - # - # Spans that fall entirely INSIDE a top-level statement are skipped — those - # are nested directives handled by recursive body merging, not top-level promotions. - # - # @param statements [Array] Prism statements (may include FrozenWrapper etc.) - # @param spans [Array] Validated spans from detect_spans - # @param analysis [FileAnalysis] The owning FileAnalysis (passed to node constructors) - # @return [Array] Modified statements array + # Ruby directive token detection lives in Ruby::Merge::BlockDirectiveDetector. + # This class only promotes detected spans into Prism merge nodes. + class BlockDirectiveDetector < Ruby::Merge::BlockDirectiveDetector def promote_spans_to_nodes(statements, spans, analysis:) return statements if spans.empty? validate_same_syntactic_level!(spans, statements) top_level = top_level_spans_only(spans).reject do |span| - # Skip spans that are wholly inside a top-level code node. - # Those are handled during recursive body merging. statements.any? do |stmt| - sl = stmt_start_line(stmt) - el = stmt_end_line(stmt) - sl && el && sl <= span.start_line && el >= span.end_line + start_line = stmt_start_line(stmt) + end_line = stmt_end_line(stmt) + start_line && end_line && start_line <= span.start_line && end_line >= span.end_line end end @@ -83,36 +26,31 @@ def promote_spans_to_nodes(statements, spans, analysis:) used_indices = Set.new top_level.each do |span| - inner_stmts = statements.each_with_index.select do |stmt, idx| - next false if used_indices.include?(idx) + inner_stmts = statements.each_with_index.select do |stmt, index| + next false if used_indices.include?(index) - sl = stmt_start_line(stmt) - el = stmt_end_line(stmt) - sl && el && sl >= span.start_line && el <= span.end_line - end.map { |stmt, idx| [idx, stmt] } + start_line = stmt_start_line(stmt) + end_line = stmt_end_line(stmt) + start_line && end_line && start_line >= span.start_line && end_line <= span.end_line + end.map { |stmt, index| [index, stmt] } inner_indices = inner_stmts.map(&:first) inner_nodes = inner_stmts.map(&:last) - - nested = spans.select { |s| s != span && s.start_line >= span.start_line && s.end_line <= span.end_line } - + nested = spans.select do |candidate| + candidate != span && candidate.start_line >= span.start_line && candidate.end_line <= span.end_line + end inner_nodes = promote_spans_to_nodes(inner_nodes, nested, analysis: analysis) unless nested.empty? - directive_node = build_directive_node(span, inner_nodes, analysis) - # Determine insertion position: - # - If inner nodes exist: insert at the first covered index (replacing them) - # - If no inner nodes (span covers only comment lines): insert at the position - # of the first statement whose start_line is AFTER the span's start_line, - # or append at the end if no such statement exists. insert_at = if inner_indices.any? inner_indices.min else - idx_after = statements.each_with_index.find do |stmt, _| + after_span = statements.each_with_index.find do |stmt, _| stmt_start_line(stmt).to_i > span.start_line end - idx_after ? idx_after.last : statements.length + after_span ? after_span.last : statements.length end - result << [insert_at, directive_node, inner_indices] + + result << [insert_at, build_directive_node(span, inner_nodes, analysis), inner_indices] used_indices.merge(inner_indices) end @@ -121,146 +59,12 @@ def promote_spans_to_nodes(statements, spans, analysis:) private - def warn_prefix - @source_label ? "[prism-merge] BlockDirectiveDetector (#{@source_label}):" : '[prism-merge] BlockDirectiveDetector:' - end - - # Report an unbalanced or invalid block directive. - # Raises Prism::Merge::Error for top-level file analysis (source_label present) - # to prevent file corruption. Falls back to warn for sub-body fragments - # (no source_label) where partial markers are expected. - def report_unbalanced(message) - raise Prism::Merge::Error, "#{warn_prefix} #{message}" if @source_label - - warn("#{warn_prefix} #{message} — ignoring") - end - - # @return [Array] - def detect_freeze_spans - return [] unless @freeze_token - - freeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:freeze\b/i - unfreeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:unfreeze\b/i - - spans = [] - stack = [] - - @lines.each_with_index do |line, idx| - line_num = idx + 1 - stripped = line.to_s.chomp - if stripped.match?(freeze_pat) - stack.push({ start_line: line_num, open_marker: stripped }) - elsif stripped.match?(unfreeze_pat) - if (open = stack.pop) - spans << Span.new( - kind: :freeze, - start_line: open[:start_line], - end_line: line_num, - open_marker: open[:open_marker], - close_marker: stripped - ) - else - report_unbalanced("unmatched #{@freeze_token}:unfreeze at line #{line_num}") - end - end - end - - stack.each do |open| - report_unbalanced("unclosed #{@freeze_token}:freeze at line #{open[:start_line]}") - end - - spans - end - - # @return [Array] - def detect_nocov_spans - return [] unless @nocov_token - - nocov_pat = /\A\s*#\s?#{Regexp.escape(@nocov_token)}\s*\z/i - - spans = [] - stack = [] - - @lines.each_with_index do |line, idx| - line_num = idx + 1 - stripped = line.to_s.chomp - if stripped.match?(SIMPLECOV_DISABLE_RE) - stack.push({ start_line: line_num, open_marker: stripped }) - elsif stripped.match?(SIMPLECOV_ENABLE_RE) - if (open = stack.pop) - spans << Span.new( - kind: :nocov, - start_line: open[:start_line], - end_line: line_num, - open_marker: open[:open_marker], - close_marker: stripped - ) - else - report_unbalanced("unmatched simplecov:enable at line #{line_num}") - end - elsif stripped.match?(nocov_pat) - if stack.empty? - stack.push({ start_line: line_num, open_marker: stripped }) - else - open = stack.pop - spans << Span.new( - kind: :nocov, - start_line: open[:start_line], - end_line: line_num, - open_marker: open[:open_marker], - close_marker: stripped - ) - end - end - end - - stack.each do |open| - report_unbalanced("unclosed coverage directive at line #{open[:start_line]}") - end - - spans + def detector_name + 'prism-merge' end - # Validate spans form a clean tree (no offset/crossing overlap). - # @param spans [Array] Sorted by start_line - # @return [Array] Valid spans only - def validate_no_crossing(spans) - valid = [] - invalid_indices = Set.new - - spans.each_with_index do |a, i| - next if invalid_indices.include?(i) - - crossing = false - spans.each_with_index do |b, j| - next if i == j || invalid_indices.include?(j) - - next unless (a.start_line < b.start_line && a.end_line > b.start_line && a.end_line < b.end_line) || - (b.start_line < a.start_line && b.end_line > a.start_line && b.end_line < a.end_line) - - report_unbalanced("offset-overlapping #{a.kind} block " \ - "(lines #{a.start_line}..#{a.end_line}) and #{b.kind} block " \ - "(lines #{b.start_line}..#{b.end_line}) — both treated as plain comments") - invalid_indices.add(i) - invalid_indices.add(j) - crossing = true - break - end - - valid << a unless crossing - end - - valid - end - - def top_level_spans_only(spans) - spans.reject do |span| - spans.any? do |other| - other != span && - other.start_line <= span.start_line && - other.end_line >= span.end_line - end - end + def directive_error_class + Prism::Merge::Error end def stmt_start_line(stmt) @@ -295,9 +99,9 @@ def validate_same_syntactic_level!(spans, statements) def owner_for_line(statements, line_num) statements.find do |stmt| - sl = stmt_start_line(stmt) - el = stmt_end_line(stmt) - sl && el && sl <= line_num && line_num <= el + start_line = stmt_start_line(stmt) + end_line = stmt_end_line(stmt) + start_line && end_line && start_line <= line_num && line_num <= end_line end end @@ -328,30 +132,24 @@ def build_directive_node(span, inner_nodes, analysis) end def rebuild_statements(statements, replacements, used_indices) - # Multiple directives can share the same insert position (e.g. a freeze span - # with no inner nodes and a nocov span whose inner node is the same statement). - # Use an array per position, sorted by span start_line so earlier directives - # come first in the output. - replacement_map = Hash.new { |h, k| h[k] = [] } + replacement_map = Hash.new { |hash, key| hash[key] = [] } replacements.each do |insert_at, node, _covered| replacement_map[insert_at] << node end - replacement_map.each_value { |nodes| nodes.sort_by! { |n| n.start_line || 0 } } + replacement_map.each_value { |nodes| nodes.sort_by! { |node| node.start_line || 0 } } result = [] - statements.each_with_index do |stmt, idx| - # Insert all replacements queued at this position (in start_line order) - if (nodes = replacement_map.delete(idx)) - nodes.each { |n| result << n } + statements.each_with_index do |stmt, index| + if (nodes = replacement_map.delete(index)) + nodes.each { |node| result << node } end - next if used_indices.include?(idx) + next if used_indices.include?(index) result << stmt end - # Append any replacements whose insert position is past the end - replacement_map.each_value { |nodes| nodes.each { |n| result << n } } + replacement_map.each_value { |nodes| nodes.each { |node| result << node } } result end diff --git a/gems/prism-merge/lib/prism/merge/comment/line.rb b/gems/prism-merge/lib/prism/merge/comment/line.rb index 2ef49628a..844948413 100644 --- a/gems/prism-merge/lib/prism/merge/comment/line.rb +++ b/gems/prism-merge/lib/prism/merge/comment/line.rb @@ -15,13 +15,7 @@ module Comment # line.magic_comment_type #=> :frozen_string_literal # class Line < Ast::Merge::Comment::Line - # Ruby magic comment patterns - MAGIC_COMMENT_PATTERNS = { - frozen_string_literal: /^frozen_string_literal:\s*(true|false)$/i, - encoding: /^(encoding|coding):\s*\S+$/i, - warn_indent: /^warn_indent:\s*(true|false)$/i, - shareable_constant_value: /^shareable_constant_value:\s*\S+$/i - }.freeze + MAGIC_COMMENT_PATTERNS = Ruby::Merge::MagicCommentSupport::MAGIC_COMMENT_PATTERNS class << self def magic_comment_type_for(text) diff --git a/gems/prism-merge/lib/prism/merge/file_analysis.rb b/gems/prism-merge/lib/prism/merge/file_analysis.rb index b29fd1cb1..fb8324069 100644 --- a/gems/prism-merge/lib/prism/merge/file_analysis.rb +++ b/gems/prism-merge/lib/prism/merge/file_analysis.rb @@ -170,7 +170,7 @@ def entry_key(entry) # (e.g. `|gem|`), assignment nodes such as `spec.name = "foo"` and `gem.name = "foo"` # would otherwise produce different signatures and never match. We normalize both to # this placeholder so they match regardless of the variable name chosen by the author. - GEMSPEC_VAR_PLACEHOLDER = :__gemspec_var__ + GEMSPEC_VAR_PLACEHOLDER = Ruby::Merge::GemspecSupport::GEMSPEC_VAR_PLACEHOLDER # @return [TreeHaver::Tree] The tree_haver parse tree (includes normalized comment objects) attr_reader :tree @@ -337,6 +337,32 @@ def comment_region_for_range(range, kind:, full_line_only: false) build_comment_region(kind, entries, metadata: { range: range, full_line_only: full_line_only }) end + # Return comments that lead +owner+ within the provided top-level owner set. + # + # CRISPR adapters use this as a parser-provider-owned projection: CRISPR + # selects and splices, while prism-merge owns Ruby comment attachment. + # + # @param owner [Object] owner node from this analysis + # @param owners [Array] ordered owner set containing +owner+ + # @return [Array] + def leading_comments_for_owner(owner, owners: statements) + ordered_owners = Array(owners) + index = ordered_owners.index(owner) + return [] unless index + + previous_owner = index.positive? ? ordered_owners[index - 1] : nil + if previous_owner + start_line = previous_owner.location.end_line + end_line = owner.location.start_line + return parse_result.comments.select do |comment| + comment.location.start_line > start_line && + comment.location.start_line < end_line + end + end + + parse_result.comments.select { |comment| comment.location.start_line < owner.location.start_line } + end + # Build a native shared comment attachment for an owner. # # @param owner [Object] Structural owner for the attachment @@ -1082,13 +1108,13 @@ def compute_node_signature(node) else [] end - [:def, node.name, params] + Ruby::Merge::SignatureSupport.method_definition(node.name, params) # === Class/Module definitions === when :class - [:class, node.constant_path.slice] + Ruby::Merge::SignatureSupport.class_definition(node.constant_path.slice) when :module - [:module, node.constant_path.slice] + Ruby::Merge::SignatureSupport.module_definition(node.constant_path.slice) when :singleton_class # class << self or class << expr expr = begin @@ -1096,25 +1122,25 @@ def compute_node_signature(node) rescue StandardError 'self' end - [:singleton_class, expr] + Ruby::Merge::SignatureSupport.singleton_class(expr) # === Constants === when :const if node.type.to_s == 'constant_write_node' - [:const, node.name] + Ruby::Merge::SignatureSupport.constant(node.name) else - [:const, node.target.slice] + Ruby::Merge::SignatureSupport.constant(node.target.slice) end # === Variable assignments === when :local_var - [:local_var, node.name] + Ruby::Merge::SignatureSupport.variable_assignment(:local_var, node.name) when :ivar - [:ivar, node.name] + Ruby::Merge::SignatureSupport.variable_assignment(:ivar, node.name) when :cvar - [:cvar, node.name] + Ruby::Merge::SignatureSupport.variable_assignment(:cvar, node.name) when :gvar - [:gvar, node.name] + Ruby::Merge::SignatureSupport.variable_assignment(:gvar, node.name) when :multi_write # Multiple assignment: a, b = 1, 2 targets = node.lefts.map do |target| @@ -1131,41 +1157,41 @@ def compute_node_signature(node) target.slice end end - [:multi_write, targets] + Ruby::Merge::SignatureSupport.multi_write(targets) # === Conditionals === when :if, :unless # Conditionals match by their condition expression condition_source = node.predicate.slice - [node.type.to_s == 'if_node' ? :if : :unless, condition_source] + Ruby::Merge::SignatureSupport.conditional(node.type.to_s == 'if_node' ? :if : :unless, condition_source) # === Case/Switch statements === when :case # case expr; when ... end - match by the expression being switched on predicate = node.predicate&.slice || '' - [:case, predicate] + Ruby::Merge::SignatureSupport.case_statement(predicate) when :case_match # case expr; in ... end (pattern matching) - match by the expression predicate = node.predicate&.slice || '' - [:case_match, predicate] + Ruby::Merge::SignatureSupport.case_match_statement(predicate) # === Loops === when :while - [:while, node.predicate.slice] + Ruby::Merge::SignatureSupport.loop_statement(:while, node.predicate.slice) when :until - [:until, node.predicate.slice] + Ruby::Merge::SignatureSupport.loop_statement(:until, node.predicate.slice) when :for # for i in collection - match by index and collection index = node.index.slice collection = node.collection.slice - [:for, index, collection] + Ruby::Merge::SignatureSupport.loop_statement(:for, index, collection) # === Exception handling === when :begin # begin/rescue/ensure blocks - unique by position within parent # Since these don't have a natural identifier, use first statement first_stmt = node.statements&.body&.first&.slice&.[](0, 30) || '' - [:begin, first_stmt] + Ruby::Merge::SignatureSupport.begin_block(first_stmt) # === Method calls === when :call @@ -1183,53 +1209,39 @@ def compute_node_signature(node) # `gem.name = "foo"` and `spec.name = "foo"` produce the same signature. # Only applies when the receiver is a plain local variable (not a chained # call like `spec.metadata["key"]`) and it matches the detected block param. - effective_receiver = if @gemspec_block_var && - receiver == @gemspec_block_var - # Normalise the gemspec block variable so `gem.name =` and `spec.name =` - # produce the same signature. We rely on the slice comparison alone — - # the guard intentionally does NOT require Prism::LocalVariableReadNode - # because when body text is parsed standalone (no enclosing block), the - # parameter name (`gem`, `spec`, …) is parsed as a zero-arg CallNode by - # Prism, not as a LocalVariableReadNode. The slice match is sufficient - # because chained receivers (e.g. `spec.metadata`) produce longer slices - # that will never equal the single-word block parameter name. - GEMSPEC_VAR_PLACEHOLDER - else - receiver - end + # The slice match intentionally does not require Prism::LocalVariableReadNode. + # When a gemspec body is parsed standalone, the block param can appear as a + # zero-arg CallNode; chained receivers still have longer slices and do not match. + effective_receiver = Ruby::Merge::GemspecSupport.effective_receiver(receiver, @gemspec_block_var) if node.block # simplecov:disable defensive - Ruby syntax doesn't allow blocks with assignment methods - [:call_with_block, node.name, effective_receiver] + Ruby::Merge::SignatureSupport.call(node.name, effective_receiver, block: true) # simplecov:enable else - [:call, node.name, effective_receiver] + Ruby::Merge::SignatureSupport.call(node.name, effective_receiver) end else # Regular method call: appraise "unlocked" do ... end # Match by method name and first argument (which identifies the call) first_arg = extract_first_argument_value(node) if node.block - [:call_with_block, node.name, first_arg] + Ruby::Merge::SignatureSupport.call(node.name, first_arg, block: true) else - [:call, node.name, first_arg] + Ruby::Merge::SignatureSupport.call(node.name, first_arg) end end # === Super calls === when :super - [:super, node.block ? :with_block : :no_block] + Ruby::Merge::SignatureSupport.super_call(block: !!node.block) when :forwarding_super - [:forwarding_super, node.block ? :with_block : :no_block] + Ruby::Merge::SignatureSupport.forwarding_super_call(block: !!node.block) # === Operator-write calls (e.g. spec.rdoc_options += [...]) === when :call_op_write receiver = node.receiver&.slice - effective_receiver = if @gemspec_block_var && receiver == @gemspec_block_var - GEMSPEC_VAR_PLACEHOLDER - else - receiver - end - [:call_op_write, node.write_name, effective_receiver] + effective_receiver = Ruby::Merge::GemspecSupport.effective_receiver(receiver, @gemspec_block_var) + Ruby::Merge::SignatureSupport.call_operator_write(node.write_name, effective_receiver) # === Lambdas === when :lambda @@ -1239,30 +1251,30 @@ def compute_node_signature(node) else '' end - [:lambda, params] + Ruby::Merge::SignatureSupport.lambda_literal(params) # === Special blocks === when :pre_execution # BEGIN { } blocks - [:pre_execution, node.location.start_line] + Ruby::Merge::SignatureSupport.execution_block(:pre_execution, node.location.start_line) when :post_execution # END { } blocks - [:post_execution, node.location.start_line] + Ruby::Merge::SignatureSupport.execution_block(:post_execution, node.location.start_line) # === Parenthesized expressions === when :parens # Usually transparent, but if it appears at top level, identify by content first_expr = node.body&.body&.first&.slice&.[](0, 30) || '' - [:parens, first_expr] + Ruby::Merge::SignatureSupport.parenthesized(first_expr) # === Embedded statements (string interpolation) === when :embedded - [:embedded, node.statements&.slice || ''] + Ruby::Merge::SignatureSupport.embedded(node.statements&.slice) else # Fallback: use class name and line number # Nodes that reach here may not merge well across files - [:other, node.class.name, node.location.start_line] + Ruby::Merge::SignatureSupport.other(node.class.name, node.location.start_line) end end diff --git a/gems/prism-merge/lib/prism/merge/magic_comment_support.rb b/gems/prism-merge/lib/prism/merge/magic_comment_support.rb index 77610a09a..4543b8764 100644 --- a/gems/prism-merge/lib/prism/merge/magic_comment_support.rb +++ b/gems/prism-merge/lib/prism/merge/magic_comment_support.rb @@ -1,118 +1,33 @@ +# frozen_string_literal: true + module Prism module Merge + # Compatibility wrapper for Ruby substrate magic-comment support. module MagicCommentSupport module_function def magic_comment_type_for_text(text) - stripped = text.to_s.sub(/\A#\s*/, '').strip - - Comment::Line::MAGIC_COMMENT_PATTERNS.each do |type, pattern| - return type if stripped.match?(pattern) - end - - nil + Ruby::Merge::MagicCommentSupport.magic_comment_type_for_text(text) end def comment_only_prefix_info(lines) - entries = [] - suppressed_line_nums = Set.new - duplicate_magic_line_nums = Set.new - - if shebang_line?(lines.first) - entries << { line_num: 1, text: lines.first.to_s, kind: :shebang } - suppressed_line_nums << 1 - end - - header_magic_types = header_magic_comment_types_for_lines(lines) - seen_magic_types = Set.new - - header_magic_types.keys.sort.each do |line_num| - magic_type = header_magic_types[line_num] - suppressed_line_nums << line_num - entries << { line_num: line_num, text: lines[line_num - 1].to_s.chomp, kind: :magic } - - if seen_magic_types.include?(magic_type) - duplicate_magic_line_nums << line_num - else - seen_magic_types << magic_type - end - end - - if header_magic_types.any? - blank_line_num = header_magic_types.keys.max + 1 - - while blank_line_num <= lines.length && lines[blank_line_num - 1].to_s.rstrip.empty? - entries << { line_num: blank_line_num, text: lines[blank_line_num - 1].to_s, kind: :blank } - suppressed_line_nums << blank_line_num - blank_line_num += 1 - end - end - - { - entries: entries, - suppressed_line_nums: suppressed_line_nums, - duplicate_magic_line_nums: duplicate_magic_line_nums, - header_magic_comment_types: header_magic_types - } + Ruby::Merge::MagicCommentSupport.comment_only_prefix_info(lines) end def header_magic_comment_types_for_lines(lines) - types = {} - index = shebang_line?(lines.first) ? 1 : 0 - previous_line_num = shebang_line?(lines.first) ? 1 : nil - - while index < lines.length - line_num = index + 1 - stripped = lines[index].to_s.rstrip - break if stripped.empty? - - expected_line_num = previous_line_num ? previous_line_num + 1 : 1 - break unless line_num == expected_line_num - - magic_type = magic_comment_type_for_text(stripped) - break unless magic_type - - types[line_num] = magic_type - previous_line_num = line_num - index += 1 - end - - types + Ruby::Merge::MagicCommentSupport.header_magic_comment_types_for_lines(lines) end def prefix_comment_line_numbers_for_comments(comments) - prefix_line_nums = Set.new - previous_line_num = nil - index = 0 - - if shebang_comment?(comments.first) - prefix_line_nums << 1 - previous_line_num = 1 - index = 1 - end - - while index < comments.length - comment = comments[index] - line_num = comment.location.start_line - expected_line_num = previous_line_num ? previous_line_num + 1 : 1 - break unless line_num == expected_line_num - - break unless magic_comment_type_for_text(comment.slice) - - prefix_line_nums << line_num - previous_line_num = line_num - index += 1 - end - - prefix_line_nums + Ruby::Merge::MagicCommentSupport.prefix_comment_line_numbers_for_comments(comments) end def shebang_line?(line) - line.to_s.start_with?('#!') + Ruby::Merge::MagicCommentSupport.shebang_line?(line) end def shebang_comment?(comment) - comment&.slice&.start_with?('#!') + Ruby::Merge::MagicCommentSupport.shebang_comment?(comment) end end end diff --git a/gems/prism-merge/lib/prism/merge/method_match_refiner.rb b/gems/prism-merge/lib/prism/merge/method_match_refiner.rb index d46df8496..7586737b6 100644 --- a/gems/prism-merge/lib/prism/merge/method_match_refiner.rb +++ b/gems/prism-merge/lib/prism/merge/method_match_refiner.rb @@ -28,10 +28,10 @@ module Merge # @see Ast::Merge::MatchRefinerBase class MethodMatchRefiner < Ast::Merge::MatchRefinerBase # Default weight for method name similarity - DEFAULT_NAME_WEIGHT = 0.7 + DEFAULT_NAME_WEIGHT = Ruby::Merge::MethodSimilarity::DEFAULT_NAME_WEIGHT # Default weight for parameter similarity - DEFAULT_PARAMS_WEIGHT = 0.3 + DEFAULT_PARAMS_WEIGHT = Ruby::Merge::MethodSimilarity::DEFAULT_PARAMS_WEIGHT # @return [Float] Weight for name similarity (0.0-1.0) attr_reader :name_weight @@ -49,6 +49,10 @@ def initialize(threshold: DEFAULT_THRESHOLD, name_weight: DEFAULT_NAME_WEIGHT, super(threshold: threshold, node_types: [:def], **options) @name_weight = name_weight @params_weight = params_weight + @method_similarity = Ruby::Merge::MethodSimilarity.new( + name_weight: name_weight, + params_weight: params_weight + ) end # Find matches between unmatched method definitions. @@ -84,34 +88,12 @@ def method_node?(node) # @param d_method [Prism::DefNode] Destination method # @return [Float] Similarity score (0.0-1.0) def compute_method_similarity(t_method, d_method) - name_score = string_similarity(t_method.name.to_s, d_method.name.to_s) - param_score = param_similarity(t_method, d_method) - - (name_score * name_weight) + (param_score * params_weight) - end - - # Compute similarity between method parameters. - # - # @param t_method [Prism::DefNode] Template method - # @param d_method [Prism::DefNode] Destination method - # @return [Float] Parameter similarity (0.0-1.0) - def param_similarity(t_method, d_method) - t_params = extract_param_names(t_method) - d_params = extract_param_names(d_method) - - return 1.0 if t_params.empty? && d_params.empty? - return 0.0 if t_params.empty? || d_params.empty? - - # Count matching parameter names - common = (t_params & d_params).size - total = [t_params.size, d_params.size].max - - # Also consider parameter count similarity - count_ratio = [t_params.size, d_params.size].min.to_f / total - - # Combine name matching and count similarity - name_match_ratio = common.to_f / total - (name_match_ratio * 0.7) + (count_ratio * 0.3) + @method_similarity.call( + template_name: t_method.name, + template_params: extract_param_names(t_method), + dest_name: d_method.name, + dest_params: extract_param_names(d_method) + ) end # Extract parameter names from a method definition. @@ -134,60 +116,6 @@ def extract_param_names(method_node) names.compact end - - # Compute string similarity using Levenshtein distance. - # - # @param str1 [String] First string - # @param str2 [String] Second string - # @return [Float] Similarity score (0.0-1.0) - def string_similarity(str1, str2) - return 1.0 if str1 == str2 - return 0.0 if str1.empty? || str2.empty? - - distance = levenshtein_distance(str1, str2) - max_len = [str1.length, str2.length].max - - 1.0 - (distance.to_f / max_len) - end - - # Compute Levenshtein distance between two strings. - # - # Uses Wagner-Fischer algorithm with O(min(m,n)) space. - # - # @param str1 [String] First string - # @param str2 [String] Second string - # @return [Integer] Edit distance - def levenshtein_distance(str1, str2) - return str2.length if str1.empty? - return str1.length if str2.empty? - - # Ensure str1 is the shorter string for space optimization - str1, str2 = str2, str1 if str1.length > str2.length - - m = str1.length - n = str2.length - - # Use two rows instead of full matrix - prev_row = (0..m).to_a - curr_row = Array.new(m + 1, 0) - - (1..n).each do |j| - curr_row[0] = j - - (1..m).each do |i| - cost = str1[i - 1] == str2[j - 1] ? 0 : 1 - curr_row[i] = [ - prev_row[i] + 1, # deletion - curr_row[i - 1] + 1, # insertion - prev_row[i - 1] + cost # substitution - ].min - end - - prev_row, curr_row = curr_row, prev_row - end - - prev_row[m] - end end end end diff --git a/gems/prism-merge/lib/prism/merge/nocov_node.rb b/gems/prism-merge/lib/prism/merge/nocov_node.rb index 3cc74a4fc..3826a76a1 100644 --- a/gems/prism-merge/lib/prism/merge/nocov_node.rb +++ b/gems/prism-merge/lib/prism/merge/nocov_node.rb @@ -17,18 +17,9 @@ module Merge # raise "should never happen" # end # # :nocov: - class NocovNode - include Ast::Merge::BlockDirective - - # Error raised when nocov block has invalid structure - InvalidStructureError = Class.new(StandardError) - - # Simple location struct for compatibility with AST nodes - Location = Struct.new(:start_line, :end_line) do - def cover?(line) - (start_line..end_line).cover?(line) - end - end + class NocovNode < Ruby::Merge::NocovNodeBase + InvalidStructureError = Ruby::Merge::NocovNodeBase::InvalidStructureError + Location = Ruby::Merge::NocovNodeBase::Location # Location struct with byte offsets for correct range comparison with Prism nodes. # start_offset / end_offset are used by TopLevelMergeRunner#node_offset_range and @@ -47,35 +38,6 @@ def leading_comments owner.leading_comments end end - - attr_reader :start_line, :end_line, :nodes, :analysis, :start_marker, :close_marker - - # @param start_line [Integer] Line number of opening # :nocov: marker (1-based) - # @param end_line [Integer] Line number of closing # :nocov: marker (1-based) - # @param analysis [FileAnalysis] The owning file analysis - # @param nodes [Array] Content nodes between the markers - # @param start_marker [String, nil] The open marker text - # @param close_marker [String, nil] The close marker text - def initialize(start_line:, end_line:, analysis:, nodes: [], start_marker: nil, close_marker: nil) - @start_line = start_line - @end_line = end_line - @analysis = analysis - @nodes = nodes - @start_marker = start_marker - @close_marker = close_marker - end - - # @return [Symbol] - def kind = :nocov - - # Content nodes between the open and close markers. - # @return [Array] - def children = @nodes - - # Nocov follows file preference — no policy override. - # @return [nil] - def merge_policy = nil - # Leading Prism comments from the first inner node that appear BEFORE this # NocovNode's opening marker line. These are comments that Prism attached # to the inner node via attach_comments! and represent content logically @@ -117,49 +79,6 @@ def location end end - # Content of the nocov block (all lines from start to end). - # @return [String, nil] - def slice - return unless @analysis - - lines = @analysis.lines - return unless lines - - lines[(@start_line - 1)..(@end_line - 1)]&.join - end - - # Stable signature for merge matching. - # - # For single-node blocks, delegates to the inner content's signature so that a - # NocovNode in the template matches the equivalent bare node in the destination - # (and vice-versa). This prevents duplication when a nocov block is introduced - # in the template but the destination does not yet have the markers. - # - # For multi-node blocks, uses a `:nocov_multi` fingerprint of the inner lines - # (markers excluded) so two multi-node nocov blocks with identical content still - # match each other. - # - # @return [Array] - def signature - return [:NocovNode, nil] if @nodes.empty? || @analysis.nil? - - if @nodes.length == 1 - @analysis.generate_signature(@nodes.first) - else - inner_lines = @analysis.lines && @analysis.lines[@start_line..(@end_line - 2)] - [:nocov_multi, inner_lines&.map(&:strip)&.join("\n")] - end - end - - # Node type for merge classification - # @return [Symbol] - def merge_type = :nocov_block - - alias type merge_type - - # @return [Boolean] - def nocov_node? = true - # @return [String] def inspect "#" diff --git a/gems/prism-merge/lib/prism/merge/nocov_wrapper.rb b/gems/prism-merge/lib/prism/merge/nocov_wrapper.rb index e869d82fa..75cc527d3 100644 --- a/gems/prism-merge/lib/prism/merge/nocov_wrapper.rb +++ b/gems/prism-merge/lib/prism/merge/nocov_wrapper.rb @@ -15,46 +15,7 @@ module Merge # # The wrapped node's structural signature is still used for matching (like # FrozenWrapper), not a content-based signature. - class NoCovWrapper - include Ast::Merge::BlockDirective - - attr_reader :node, :merge_type - - # @param node [Prism::Node] The AST node to wrap - # @param merge_type [Symbol] The merge type (defaults to :nocov) - def initialize(node, merge_type = :nocov) - @node = node - @merge_type = merge_type - end - - # BlockDirective protocol - def kind = :nocov - def children = [] - def merge_policy = nil - - def start_line - @node.location&.start_line - end - - def end_line - @node.location&.end_line - end - - # Returns the wrapped node (for structural signature generation) - # @return [Prism::Node] - def unwrap = @node - - # Delegate location to the wrapped node - def location = @node.location - - # Content of the wrapped node - def slice = @node.slice - - # @return [Boolean] - def nocov_wrapper? = true - def nocov_node? = false - def block_directive? = true - + class NoCovWrapper < Ruby::Merge::NocovWrapperBase def inspect "#" end diff --git a/gems/prism-merge/lib/prism/merge/recursive_node_body_merger.rb b/gems/prism-merge/lib/prism/merge/recursive_node_body_merger.rb index 7a2a319e1..f837a70a1 100644 --- a/gems/prism-merge/lib/prism/merge/recursive_node_body_merger.rb +++ b/gems/prism-merge/lib/prism/merge/recursive_node_body_merger.rb @@ -26,11 +26,8 @@ def merge(template_node:, dest_node:) # Uses AST-directed byte-offset replacement — no regular expressions. template_var = merger.template_analysis.respond_to?(:gemspec_block_var) ? merger.template_analysis.gemspec_block_var : nil dest_var = merger.dest_analysis.respond_to?(:gemspec_block_var) ? merger.dest_analysis.gemspec_block_var : nil - preferred_var = nil - if template_var && dest_var && template_var != dest_var - preferred_var = template_var - dest_body = GemspecVarRenamer.rename(dest_body, old_var: dest_var, new_var: preferred_var) - end + preferred_var = Ruby::Merge::GemspecSupport.preferred_block_var(template_var, dest_var) + dest_body = GemspecVarRenamer.rename(dest_body, old_var: dest_var, new_var: preferred_var) if preferred_var body_merger = merger.class.new( template_body, @@ -50,8 +47,8 @@ def merge(template_node:, dest_node:) # assignment signatures even when the Gem::Specification.new wrapper is absent # from the extracted body text (auto-detection cannot fire without the wrapper). # When renaming was applied above, both sides now use preferred_var. - template_gemspec_block_var: preferred_var || template_var, - dest_gemspec_block_var: preferred_var || dest_var + template_gemspec_block_var: Ruby::Merge::GemspecSupport.merged_block_var(template_var, preferred_var), + dest_gemspec_block_var: Ruby::Merge::GemspecSupport.merged_block_var(dest_var, preferred_var) ) body_result = if template_body.empty? && dest_body.empty? nil @@ -139,9 +136,12 @@ def merge(template_node:, dest_node:) opening_line = source_layout.opening_line_text # When the opening line comes from dest but the template var is canonical, # rename the block parameter in the opening line (e.g. |gem| → |spec|). - if preferred_var && dest_var && dest_var != preferred_var && node_preference == :destination - opening_line = opening_line.sub("|#{dest_var}|", "|#{preferred_var}|") - end + opening_line = Ruby::Merge::GemspecSupport.opening_line_with_preferred_block_var( + opening_line, + dest_var: dest_var, + preferred_var: preferred_var, + node_preference: node_preference + ) if node_preference == :template && template_inline_by_line[actual_template.location.start_line].empty? && !source_layout.body_starts_on_opening_line? diff --git a/gems/prism-merge/lib/prism/merge/ruby_doc_surface_analyzer.rb b/gems/prism-merge/lib/prism/merge/ruby_doc_surface_analyzer.rb index 902fb6383..843f4bcdd 100644 --- a/gems/prism-merge/lib/prism/merge/ruby_doc_surface_analyzer.rb +++ b/gems/prism-merge/lib/prism/merge/ruby_doc_surface_analyzer.rb @@ -7,24 +7,13 @@ module Merge class RubyDocSurfaceAnalyzer DEFAULT_DOC_LANGUAGE = :yard DEFAULT_EXAMPLE_LANGUAGE = :ruby - TAG_PREFIX = /\A@[a-z_]+\b/ - EXAMPLE_TAG = /\A@example\b(?.*)\z/ - DIRECTIVE_LINE = /\A(?::nocov:|[\w-]+:(?:freeze|unfreeze))\z/ - MAGIC_COMMENT_PREFIXES = %w[ - coding - encoding - frozen_string_literal - shareable_constant_value - typed - warn_indent - ].freeze attr_reader :analysis def initialize(analysis, doc_language: DEFAULT_DOC_LANGUAGE, default_example_language: DEFAULT_EXAMPLE_LANGUAGE) @analysis = analysis - @doc_language = normalize_language(doc_language) - @default_example_language = normalize_language(default_example_language) + @doc_language = normalize_language(doc_language).to_sym + @default_example_language = normalize_language(default_example_language).to_sym end def discover_doc_comment_surfaces(owners: analysis.statements) @@ -94,25 +83,15 @@ def discover_example_surfaces(surface) doc_entries = comment_entries_for(surface) return [] if doc_entries.empty? - normalized_lines = doc_entries.map { |entry| normalize_comment_content(entry[:raw]) } - normalized_lines.each_with_index.filter_map do |content, index| - match = EXAMPLE_TAG.match(content) - next unless match - - build_example_surface(surface, doc_entries, normalized_lines, index, match) + Ruby::Merge::DocCommentSupport.example_blocks(doc_entries).map do |block| + build_example_surface(surface, block) end end - def build_example_surface(surface, doc_entries, normalized_lines, tag_index, match) - body_start_index = tag_index + 1 - body_end_index = next_tag_index(normalized_lines, body_start_index) || normalized_lines.length - return if body_start_index >= body_end_index - - body_entries = doc_entries[body_start_index...body_end_index] - return if body_entries.nil? || body_entries.empty? - - declared_language = declared_example_language(match[:rest]) - tag_line = doc_entries[tag_index][:line] + def build_example_surface(surface, block) + body_entries = block.fetch(:body_entries) + declared_language = normalize_language(block[:declared_language])&.to_sym + tag_index = block.fetch(:tag_index) body_span = body_entries.first[:line]..body_entries.last[:line] Ast::Merge::Runtime::Surface.new( @@ -127,27 +106,17 @@ def build_example_surface(surface, doc_entries, normalized_lines, tag_index, mat tag_kind: :example, tag_index: tag_index, tag_relative_line: tag_index + 1, - tag_line: tag_line, - tag_text: normalized_lines[tag_index], - body_relative_span: (body_start_index + 1)..body_end_index, + tag_line: block.fetch(:tag_line), + tag_text: block.fetch(:tag_text), + body_relative_span: (block.fetch(:body_start_index) + 1)..block.fetch(:body_end_index), comment_prefix: surface.metadata[:comment_prefix], preserved_boundaries: { - tag_header: doc_entries[tag_index][:raw] + tag_header: comment_entries_for(surface)[tag_index][:raw] } } ) end - def next_tag_index(normalized_lines, start_index) - normalized_lines.each_with_index do |content, index| - next if index < start_index - - return index if TAG_PREFIX.match?(content) - end - - nil - end - def comment_entries_for(surface) entries = surface.metadata[:entries] || [] return entries unless entries.empty? @@ -184,31 +153,25 @@ def doc_comment_region?(region) def doc_comment_content?(entry) content = normalize_comment_content(entry[:raw]) - return false if content.empty? - return false if directive_line?(content) - return false if magic_comment_line?(entry, content) - - true + Ruby::Merge::DocCommentSupport.doc_comment_content?( + entry[:raw], + magic_comment: magic_comment_line?(entry, content) + ) end def directive_line?(content) - DIRECTIVE_LINE.match?(content) + Ruby::Merge::BlockDirectiveDetector.directive_content?(content) end def magic_comment_line?(entry, content) node = entry[:node] return true if node.respond_to?(:magic_comment_type) && !node.magic_comment_type.nil? - MAGIC_COMMENT_PREFIXES.any? { |prefix| content.start_with?("#{prefix}:") } + Ruby::Merge::DocCommentSupport.magic_comment_content?(content) end def normalize_comment_content(raw) - raw.to_s.sub(/\A\s*#\s?/, '').strip - end - - def declared_example_language(rest) - match = rest.to_s.strip.match(/\A\[(?[^\]]+)\]/) - normalize_language(match && match[:language]) + Ruby::Merge::DocCommentSupport.normalize_comment_content(raw) end def owner_reference_for(owner, owner_signature) @@ -235,9 +198,7 @@ def comment_prefix_for(line_number) end def normalize_language(language) - return if language.nil? - - language.to_s.strip.downcase.tr('-', '_').to_sym + Ruby::Merge::DocCommentSupport.normalize_language(language) end end end diff --git a/gems/prism-merge/lib/prism/merge/scaffold_chunk_remover.rb b/gems/prism-merge/lib/prism/merge/scaffold_chunk_remover.rb index bc2e05b63..b6406937c 100644 --- a/gems/prism-merge/lib/prism/merge/scaffold_chunk_remover.rb +++ b/gems/prism-merge/lib/prism/merge/scaffold_chunk_remover.rb @@ -13,53 +13,12 @@ module Merge # specs = [ScaffoldChunkRemover::RSPEC_SPEC, ScaffoldChunkRemover::RUBOCOP_SPEC] # clean = ScaffoldChunkRemover.remove(source, specs) class ScaffoldChunkRemover - ChunkSpec = Struct.new( - :anchor_type, # :require_call or :task_call - :anchor_value, # String — exact require path OR task name pattern - :satellite_patterns, # Array — token patterns for satellite nodes - :jaccard_threshold, # Float — min Jaccard score for satellite matching - :max_lookahead, # Integer — nodes to scan after anchor - :max_lookbehind, # Integer — nodes to scan before anchor - keyword_init: true - ) - - BUNDLER_GEM_TASKS_SPEC = ChunkSpec.new( - anchor_type: :require_call, - anchor_value: 'bundler/gem_tasks', - satellite_patterns: [], - jaccard_threshold: 0.35, - max_lookahead: 0, - max_lookbehind: 0 - ) - - RSPEC_SPEC = ChunkSpec.new( - anchor_type: :require_call, - anchor_value: 'rspec/core/rake_task', - satellite_patterns: ['RSpec::Core::RakeTask.new'], - jaccard_threshold: 0.35, - max_lookahead: 5, - max_lookbehind: 2 - ) - - RUBOCOP_SPEC = ChunkSpec.new( - anchor_type: :require_call, - anchor_value: 'rubocop/rake_task', - satellite_patterns: ['RuboCop::RakeTask.new'], - jaccard_threshold: 0.35, - max_lookahead: 5, - max_lookbehind: 2 - ) - - DEFAULT_TASK_SPEC = ChunkSpec.new( - anchor_type: :task_call, - anchor_value: 'default', - satellite_patterns: [], - jaccard_threshold: 0.35, - max_lookahead: 0, - max_lookbehind: 0 - ) - - ALL_SPECS = [BUNDLER_GEM_TASKS_SPEC, RSPEC_SPEC, RUBOCOP_SPEC, DEFAULT_TASK_SPEC].freeze + ChunkSpec = Ruby::Merge::ScaffoldChunkSupport::ChunkSpec + BUNDLER_GEM_TASKS_SPEC = Ruby::Merge::ScaffoldChunkSupport::BUNDLER_GEM_TASKS_SPEC + RSPEC_SPEC = Ruby::Merge::ScaffoldChunkSupport::RSPEC_SPEC + RUBOCOP_SPEC = Ruby::Merge::ScaffoldChunkSupport::RUBOCOP_SPEC + DEFAULT_TASK_SPEC = Ruby::Merge::ScaffoldChunkSupport::DEFAULT_TASK_SPEC + ALL_SPECS = Ruby::Merge::ScaffoldChunkSupport::ALL_SPECS class << self def remove(source, specs = ALL_SPECS) @@ -92,13 +51,13 @@ def call end_idx = [statements.size - 1, anchor_idx + spec.max_lookahead].min spec.satellite_patterns.each do |pattern| - p_tokens = jaccard_tokens(pattern) + p_tokens = Ruby::Merge::ScaffoldChunkSupport.jaccard_tokens(pattern) (start_idx..end_idx).each do |i| next if i == anchor_idx candidate = statements[i] - c_tokens = jaccard_tokens(candidate.slice.to_s) - score = jaccard(p_tokens, c_tokens) + c_tokens = Ruby::Merge::ScaffoldChunkSupport.jaccard_tokens(candidate.slice.to_s) + score = Ruby::Merge::ScaffoldChunkSupport.jaccard(p_tokens, c_tokens) nodes_to_remove << candidate if score >= spec.jaccard_threshold end end @@ -156,19 +115,7 @@ def require_anchor_match?(node, anchor_value) def task_anchor_match?(node, anchor_value, threshold) return false unless node.name.to_s == 'task' - node_tokens = jaccard_tokens(node.slice.to_s) - pattern_tokens = jaccard_tokens("task #{anchor_value}") - jaccard(pattern_tokens, node_tokens) >= threshold - end - - def jaccard_tokens(text) - text.scan(/[A-Za-z0-9_]+/).to_set - end - - def jaccard(a_set, b_set) - return 0.0 if (a_set | b_set).empty? - - (a_set & b_set).size.to_f / (a_set | b_set).size + Ruby::Merge::ScaffoldChunkSupport.task_anchor_match?(node.slice.to_s, anchor_value, threshold) end end end diff --git a/gems/prism-merge/lib/prism/merge/top_level_merge_runner.rb b/gems/prism-merge/lib/prism/merge/top_level_merge_runner.rb index e21a4a0a1..7aefbcda9 100644 --- a/gems/prism-merge/lib/prism/merge/top_level_merge_runner.rb +++ b/gems/prism-merge/lib/prism/merge/top_level_merge_runner.rb @@ -1080,6 +1080,17 @@ def process_dest_node( end end + if dest_signature && duplicate_destination_node_already_matched?( + dest_node: dest_node, + dest_signature: dest_signature, + template_by_signature: template_by_signature, + consumed_template_indices: consumed_template_indices + ) + prune_removed_owner_leading_gap(dest_node) + output_dest_line_ranges << node_range + return dest_node.location.end_line + end + last_output_dest_line = merger.send(:emit_dest_gap_lines, merger.result, merger.dest_analysis, last_output_dest_line, dest_node) output_node = dest_node @@ -1144,6 +1155,32 @@ def process_dest_node( ) end + def duplicate_destination_node_already_matched?(dest_node:, dest_signature:, template_by_signature:, + consumed_template_indices:) + candidates = template_by_signature[dest_signature] + return false unless candidates + return false if candidates.any? { |candidate| !consumed_template_indices.include?(candidate.fetch(:index)) } + + dest_identity = normalized_node_identity(dest_node) + return false if dest_identity.empty? + + candidates.any? do |candidate| + consumed_template_indices.include?(candidate.fetch(:index)) && + normalized_node_identity(candidate.fetch(:node)) == dest_identity + end + end + + def normalized_node_identity(node) + source = if node.respond_to?(:normalized_content) + node.normalized_content + elsif node.respond_to?(:slice) + node.slice + else + node.to_s + end + source.to_s.gsub(/\r\n?/, "\n").strip + end + def already_output?(node_range, output_dest_line_ranges) output_dest_line_ranges.any? do |range| range[:start_offset] <= node_range[:start_offset] && node_range[:end_offset] <= range[:end_offset] diff --git a/gems/prism-merge/spec/fixtures_integration_spec.rb b/gems/prism-merge/spec/fixtures_integration_spec.rb index 307f72d45..1e1cb5629 100644 --- a/gems/prism-merge/spec/fixtures_integration_spec.rb +++ b/gems/prism-merge/spec/fixtures_integration_spec.rb @@ -169,6 +169,33 @@ def json_ready(value) expect(result[:output]).not_to include("require \"kettle/test/rspec\"\n\n\n# Internal ENV config") end + it 'does not preserve duplicate destination top-level DSL blocks already matched by identical template content' do + fixture = read_json( + fixtures_root.join( + 'ruby', + 'slice-1002-duplicate-top-level-dsl-block', + 'duplicate-top-level-dsl-block.json' + ) + ) + merge = fixture[:merge] + + result = PRISM_MERGE.merge_ruby( + merge[:template], + merge[:destination], + merge[:dialect], + backend: merge[:backend], + preference: merge[:preference].to_sym, + add_template_only_nodes: merge[:add_template_only_nodes], + signature_generator: PRISM_MERGE.ruby_dsl_signature_generator + ) + + expect(result[:ok]).to be(true) + expect(result[:output]).to eq(merge[:expected]) + expect(result[:output].scan('eval_nomono_gems(gems: direct_sibling_gems)').size).to eq( + fixture.dig(:expected, :block_occurrences) + ) + end + it 'projects the structured-edit provider profile through Prism' do fixture = read_json( fixtures_root.join( @@ -302,6 +329,25 @@ def json_ready(value) ) end + it 'projects leading comments for Ruby structured-edit owners' do + source = <<~RUBY + # first owner + task :one do + puts "one" + end + + # second owner + task :two do + puts "two" + end + RUBY + analysis = PRISM_MERGE::FileAnalysis.new(source, source_label: 'Rakefile') + first_owner, second_owner = analysis.statements + + expect(analysis.leading_comments_for_owner(first_owner).map(&:slice)).to eq(['# first owner']) + expect(analysis.leading_comments_for_owner(second_owner).map(&:slice)).to eq(['# second owner']) + end + it 'projects Prism parse errors into the normalized parse failure shape' do fixture = read_json( fixtures_root.join( diff --git a/gems/prism-merge/spec/method_match_refiner_spec.rb b/gems/prism-merge/spec/method_match_refiner_spec.rb new file mode 100644 index 000000000..00f467112 --- /dev/null +++ b/gems/prism-merge/spec/method_match_refiner_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Prism::Merge::MethodMatchRefiner do + def parse_method(source) + Prism.parse(source).value.statements.body.first + end + + it 'delegates Ruby method similarity while adapting Prism method nodes' do + refiner = described_class.new(threshold: 0.5) + template_node = parse_method('def process_user(user, options); end') + dest_node = parse_method('def process_users(user, config); end') + + matches = refiner.call([template_node], [dest_node]) + + expect(matches.length).to eq(1) + expect(matches.first.template_node).to eq(template_node) + expect(matches.first.dest_node).to eq(dest_node) + expect(matches.first.score).to be > 0.75 + end +end diff --git a/gems/psych-merge/.gitattributes b/gems/psych-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/psych-merge/.gitattributes +++ b/gems/psych-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/psych-merge/.kettle-drift.lock b/gems/psych-merge/.kettle-drift.lock index 086be5de9..0d135c055 100644 --- a/gems/psych-merge/.kettle-drift.lock +++ b/gems/psych-merge/.kettle-drift.lock @@ -5,7 +5,13 @@ "lines": [ 81, 121, - 161 + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -15,7 +21,13 @@ "lines": [ 92, 132, - 172 + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -25,7 +37,13 @@ "lines": [ 82, 122, - 162 + 162, + 202, + 242, + 282, + 322, + 362, + 402 ] } ], @@ -35,7 +53,13 @@ "lines": [ 94, 134, - 174 + 174, + 214, + 254, + 294, + 334, + 374, + 414 ] } ], @@ -45,7 +69,13 @@ "lines": [ 97, 137, - 177 + 177, + 217, + 257, + 297, + 337, + 377, + 417 ] } ], @@ -55,7 +85,13 @@ "lines": [ 83, 123, - 163 + 163, + 203, + 243, + 283, + 323, + 363, + 403 ] } ], @@ -66,7 +102,13 @@ 61, 101, 141, - 181 + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -76,7 +118,13 @@ "lines": [ 102, 142, - 182 + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -87,7 +135,13 @@ 44, 88, 128, - 168 + 168, + 208, + 248, + 288, + 328, + 368, + 408 ] } ], @@ -97,7 +151,13 @@ "lines": [ 111, 151, - 191 + 191, + 231, + 271, + 311, + 351, + 391, + 431 ] } ], @@ -108,7 +168,13 @@ 36, 80, 120, - 160 + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -119,7 +185,13 @@ 70, 110, 150, - 190 + 190, + 230, + 270, + 310, + 350, + 390, + 430 ] } ], @@ -129,7 +201,13 @@ "lines": [ 86, 126, - 166 + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -140,7 +218,13 @@ 49, 93, 133, - 173 + 173, + 213, + 253, + 293, + 333, + 373, + 413 ] } ], @@ -151,7 +235,13 @@ 45, 89, 129, - 169 + 169, + 209, + 249, + 289, + 329, + 369, + 409 ] } ], @@ -161,7 +251,13 @@ "lines": [ 87, 127, - 167 + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -171,7 +267,13 @@ "lines": [ 104, 144, - 184 + 184, + 224, + 264, + 304, + 344, + 384, + 424 ] } ], @@ -181,7 +283,13 @@ "lines": [ 103, 143, - 183 + 183, + 223, + 263, + 303, + 343, + 383, + 423 ] } ], @@ -191,7 +299,13 @@ "lines": [ 98, 138, - 178 + 178, + 218, + 258, + 298, + 338, + 378, + 418 ] } ], @@ -201,7 +315,13 @@ "lines": [ 107, 147, - 187 + 187, + 227, + 267, + 307, + 347, + 387, + 427 ] } ], diff --git a/gems/psych-merge/.rubocop_gradual.lock b/gems/psych-merge/.rubocop_gradual.lock index 85fd85e00..85e814fd4 100644 --- a/gems/psych-merge/.rubocop_gradual.lock +++ b/gems/psych-merge/.rubocop_gradual.lock @@ -76,12 +76,14 @@ "lib/psych-merge.rb:1330894360": [ [1, 1, 0, "Naming/FileName: The name of this source file (`psych-merge.rb`) should use snake_case.", 5381] ], - "lib/psych/merge.rb:2376745441": [ - [38, 3, 7721, "Metrics/ModuleLength: Module has too many lines. [141/100]", 4253043091], - [115, 5, 4676, "Metrics/ClassLength: Class has too many lines. [113/100]", 2004153105], + "lib/psych/merge.rb:173660101": [ + [38, 3, 9398, "Metrics/ModuleLength: Module has too many lines. [188/100]", 2155600486], + [115, 5, 6353, "Metrics/ClassLength: Class has too many lines. [160/100]", 2805786752], [171, 7, 1593, "Metrics/MethodLength: Method has too many lines. [26/10]", 162695378], [171, 21, 295, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [9/5]", 2742902791], - [212, 7, 440, "Metrics/MethodLength: Method has too many lines. [11/10]", 4238054657] + [212, 7, 440, "Metrics/MethodLength: Method has too many lines. [11/10]", 4238054657], + [252, 7, 417, "Metrics/MethodLength: Method has too many lines. [11/10]", 3661776213], + [275, 7, 458, "Metrics/MethodLength: Method has too many lines. [15/10]", 1125262299] ], "lib/psych/merge/comment_tracker.rb:109829813": [ [33, 7, 711, "Metrics/MethodLength: Method has too many lines. [24/10]", 4175176008], diff --git a/gems/psych-merge/Gemfile b/gems/psych-merge/Gemfile index 84b3fc572..b283d8915 100644 --- a/gems/psych-merge/Gemfile +++ b/gems/psych-merge/Gemfile @@ -193,7 +193,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -202,7 +442,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -210,7 +450,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/psych-merge/Gemfile.lock b/gems/psych-merge/Gemfile.lock index b0427d0e4..dd25473b3 100644 --- a/gems/psych-merge/Gemfile.lock +++ b/gems/psych-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -17,22 +7,282 @@ PATH version_gem (~> 1.1, >= 1.1.9) yaml-merge (= 7.1.0) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -41,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -99,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -132,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -271,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -323,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -342,10 +603,6 @@ GEM kramdown (>= 2.4, < 3) kramdown-parser-gfm (~> 1.1) version_gem (~> 1.1, >= 1.1.13) - yaml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) yard (0.9.45) yard-fence (0.9.6) rdoc (>= 6.11, < 8) @@ -358,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -378,23 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -403,31 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -435,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -447,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -474,9 +785,12 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 @@ -486,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -513,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -524,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -537,10 +856,14 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 @@ -550,9 +873,10 @@ CHECKSUMS yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/psych-merge/gemfiles/modular/templating.gemfile b/gems/psych-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/psych-merge/gemfiles/modular/templating.gemfile +++ b/gems/psych-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/psych-merge/gemfiles/modular/templating_local.gemfile b/gems/psych-merge/gemfiles/modular/templating_local.gemfile index 6de7cca7c..b1645acac 100644 --- a/gems/psych-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/psych-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[psych-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[psych-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[psych-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/psych-merge/lib/psych/merge.rb b/gems/psych-merge/lib/psych/merge.rb index 63c32d38b..02a7c2009 100644 --- a/gems/psych-merge/lib/psych/merge.rb +++ b/gems/psych-merge/lib/psych/merge.rb @@ -158,9 +158,9 @@ def parse_yaml(source, dialect, backend: nil) end return unsupported_feature_parse_result("Unsupported YAML dialect #{dialect}.") unless dialect == 'yaml' - parsed = YAML.safe_load(source, permitted_classes: [], aliases: false) + parsed = yaml_value_for_source(source) Yaml::Merge.analyze_yaml_document(parsed, dialect) - rescue StandardError => e + rescue TreeHaver::Error, StandardError => e parse_error_result(e.message) end @@ -226,6 +226,11 @@ def register_backend! end end + def yaml_value_for_source(source) + tree = TreeHaver.with_backend(BACKEND_REFERENCE.id) { TreeHaver.parser_for(:yaml).parse(source) } + yaml_document_value_from_tree(tree) + end + private def diagnostic(severity, category, message) @@ -236,6 +241,55 @@ def parse_error_result(message) { ok: false, diagnostics: [diagnostic('error', 'parse_error', message)], policies: [] } end + def yaml_document_value_from_tree(tree) + root = tree.root_node + raise TreeHaver::NotAvailable, 'YAML parse returned no root node' unless root + + document = root.children.find { |child| child.type.to_s == 'document' } + yaml_value_from_node(document&.children&.first) + end + + def yaml_value_from_node(node) + return nil unless node + + case node.type.to_s + when 'mapping' + yaml_mapping_from_node(node) + when 'sequence' + node.children.map { |child| yaml_value_from_node(child) } + when 'scalar' + yaml_scalar_from_node(node) + else + raise TreeHaver::NotAvailable, "Unsupported YAML node #{node.type}" + end + end + + def yaml_mapping_from_node(node) + children = node.children + children.each_slice(2).each_with_object({}) do |(key_node, value_node), mapping| + key = yaml_value_from_node(key_node) + mapping[key] = yaml_value_from_node(value_node) + end + end + + def yaml_scalar_from_node(node) + value = node.value.to_s + case node.tag.to_s + when 'tag:yaml.org,2002:null' + nil + when 'tag:yaml.org,2002:bool' + value.downcase == 'true' + when 'tag:yaml.org,2002:int' + Integer(value.delete('_'), 0) + when 'tag:yaml.org,2002:float' + Float(value.delete('_')) + else + value + end + rescue ArgumentError + value + end + def unsupported_feature_parse_result(message) { ok: false, diagnostics: [diagnostic('error', 'unsupported_feature', message)], policies: [] } end diff --git a/gems/psych-merge/lib/psych/merge/partial_template_merger.rb b/gems/psych-merge/lib/psych/merge/partial_template_merger.rb index ac86dcc76..a26ca7810 100644 --- a/gems/psych-merge/lib/psych/merge/partial_template_merger.rb +++ b/gems/psych-merge/lib/psych/merge/partial_template_merger.rb @@ -73,7 +73,7 @@ def create_smart_merger(template_content, destination_content) end def parse_content_value(content) - ::Psych.safe_load(content) + Psych::Merge.yaml_value_for_source(content) end def dump_content_value(value) diff --git a/gems/rbs-merge/.gitattributes b/gems/rbs-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/rbs-merge/.gitattributes +++ b/gems/rbs-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/rbs-merge/.kettle-drift.lock b/gems/rbs-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/rbs-merge/.kettle-drift.lock +++ b/gems/rbs-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/rbs-merge/.rubocop_gradual.lock b/gems/rbs-merge/.rubocop_gradual.lock index 243f2c79e..91b839368 100644 --- a/gems/rbs-merge/.rubocop_gradual.lock +++ b/gems/rbs-merge/.rubocop_gradual.lock @@ -77,11 +77,11 @@ [1, 1, 0, "Naming/FileName: The name of this source file (`rbs-merge.rb`) should use snake_case.", 5381], [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177542] ], - "lib/rbs/merge.rb:3499390300": [ + "lib/rbs/merge.rb:1873081658": [ [17, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Rbs::Merge`.", 2866359175], - [103, 7, 1203, "Metrics/MethodLength: Method has too many lines. [25/10]", 564456261] + [103, 7, 1197, "Metrics/MethodLength: Method has too many lines. [22/10]", 564456261] ], - "lib/rbs/merge/backends/rbs_backend.rb:1875248624": [ + "lib/rbs/merge/backends/rbs_backend.rb:2885387755": [ [48, 11, 555, "Metrics/MethodLength: Method has too many lines. [13/10]", 2078142514], [81, 11, 658, "Metrics/MethodLength: Method has too many lines. [11/10]", 324484142], [172, 11, 527, "Metrics/MethodLength: Method has too many lines. [14/10]", 631898529], @@ -271,9 +271,8 @@ [998, 7, 1788, "Metrics/PerceivedComplexity: Perceived complexity for `collapse_cross_source_preamble_prefixes` is too high. [9/8]", 3130187278], [1038, 7, 533, "Metrics/MethodLength: Method has too many lines. [15/10]", 4188914818] ], - "rbs-merge.gemspec:1193079856": [ + "rbs-merge.gemspec:2636606176": [ [126, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], - [128, 121, 6, "Layout/LineLength: Line is too long. [126/120]", 2105564149], [134, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949] ], "spec/integration/reproducible_merge_spec.rb:4124333249": [ diff --git a/gems/rbs-merge/Gemfile b/gems/rbs-merge/Gemfile index f9fa511cb..ca3957a12 100644 --- a/gems/rbs-merge/Gemfile +++ b/gems/rbs-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/rbs-merge/Gemfile.lock b/gems/rbs-merge/Gemfile.lock index b7bf218c2..960b06d68 100644 --- a/gems/rbs-merge/Gemfile.lock +++ b/gems/rbs-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -17,22 +7,282 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -41,6 +291,11 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -99,11 +354,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -132,6 +389,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -139,8 +397,6 @@ GEM racc (~> 1.4) nokogiri (1.19.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.19.4-x86_64-darwin) - racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-musl) @@ -271,6 +527,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -323,13 +581,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -354,7 +612,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -367,27 +625,49 @@ PLATFORMS aarch64-linux-gnu aarch64-linux-musl arm64-darwin - x86_64-darwin + x86_64-linux x86_64-linux-gnu x86_64-linux-musl DEPENDENCIES addressable (>= 2.8, < 3) - appraisal2 (~> 3.1, >= 3.1.4) + appraisal2 (~> 3.2, >= 3.2.0) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.4) + go-merge! irb (~> 1.17) - kettle-dev (~> 2.3, >= 2.3.6) + json-merge! + kettle-dev (~> 2.3, >= 2.3.7) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.11) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) rbs-merge! @@ -399,32 +679,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.6, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! - turbo_tests2 (~> 3.1, >= 3.1.14) + turbo_tests2 (~> 3.2, >= 3.2.0) + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -432,6 +734,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -444,24 +747,31 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af nokogiri (1.19.4-arm64-darwin) sha256=a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527 - nokogiri (1.19.4-x86_64-darwin) sha256=7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b nomono (1.0.8) sha256=bf4b9b426cbf216ab17b70db474f691b8ae1f1e29de8db4b0ecd405e6e7e1c80 @@ -471,10 +781,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -510,9 +824,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -521,6 +838,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -534,21 +852,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/rbs-merge/gemfiles/modular/templating.gemfile b/gems/rbs-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/rbs-merge/gemfiles/modular/templating.gemfile +++ b/gems/rbs-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/rbs-merge/gemfiles/modular/templating_local.gemfile b/gems/rbs-merge/gemfiles/modular/templating_local.gemfile index 361e484f6..05ae1c914 100644 --- a/gems/rbs-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/rbs-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[rbs-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[rbs-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[rbs-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/rbs-merge/lib/rbs/merge.rb b/gems/rbs-merge/lib/rbs/merge.rb index d13ac63e2..315e47857 100644 --- a/gems/rbs-merge/lib/rbs/merge.rb +++ b/gems/rbs-merge/lib/rbs/merge.rb @@ -91,6 +91,7 @@ module Backends # Tracks whether backends were registered, without class instance variables. BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) RBS_BACKEND_REFERENCE = TreeHaver::BackendReference.new(id: 'rbs', family: 'rbs').freeze + TREE_SITTER_BACKEND_REFERENCE = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND class << self # Register the current RBS parsing entrypoints with TreeHaver. @@ -115,17 +116,14 @@ def register_backend! # Also register the tree-sitter-rbs grammar when present. grammar_finder = TreeHaver::GrammarFinder.new(:rbs) - if grammar_finder.available? - TreeHaver.register_language( - :rbs, - path: grammar_finder.find_library_path, - symbol: grammar_finder.symbol_name - ) - end + grammar_finder.register! if grammar_finder.available? TreeHaver::BackendRegistry.register_tag(:rbs_backend, category: :backend, backend_name: :rbs) do Backends::RbsBackend.available? end + TreeHaver::BackendRegistry.register_tag(:rbs_gem, category: :gem, backend_name: :rbs_gem) do + Backends::RbsBackend.available? + end TreeHaver::BackendRegistry.register_tag(:rbs_grammar, category: :grammar, backend_name: :rbs_grammar) do TreeHaver::GrammarFinder.new(:rbs).available? end @@ -133,6 +131,13 @@ def register_backend! BACKEND_REGISTRY.registered = true end end + + def available_rbs_backends + backends = [RBS_BACKEND_REFERENCE] + registrations = TreeHaver.registered_languages(:rbs) + backends << TREE_SITTER_BACKEND_REFERENCE if registrations.key?(:tree_sitter) || registrations.key?(:tslp) + backends + end end end end diff --git a/gems/rbs-merge/lib/rbs/merge/backends/rbs_backend.rb b/gems/rbs-merge/lib/rbs/merge/backends/rbs_backend.rb index f21eeb256..20855afe9 100644 --- a/gems/rbs-merge/lib/rbs/merge/backends/rbs_backend.rb +++ b/gems/rbs-merge/lib/rbs/merge/backends/rbs_backend.rb @@ -509,18 +509,8 @@ def method_missing(method_name, *args, **kwargs, &block) end end - # Register this backend with TreeHaver - ::TreeHaver.register_language( - :rbs, - backend_type: :rbs, - backend_module: self, - gem_name: 'rbs' - ) - - # Register the availability checker for RSpec dependency tags. - TreeHaver::BackendRegistry.register_availability_checker(:rbs_gem) do - available? - end + # Registration is centralized in Rbs::Merge.register_backend! so loading + # this adapter module does not mutate TreeHaver outside the owning gem. end end end diff --git a/gems/rbs-merge/rbs-merge.gemspec b/gems/rbs-merge/rbs-merge.gemspec index 335248d33..4d53cd680 100644 --- a/gems/rbs-merge/rbs-merge.gemspec +++ b/gems/rbs-merge/rbs-merge.gemspec @@ -111,7 +111,7 @@ Gem::Specification.new do |spec| # and preferably a modular one (see gemfiles/modular/*.gemfile). # Dev, Test, & Release Tasks - spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.6') # ruby >= 4.0.0 + spec.add_development_dependency('kettle-dev', '~> 2.3', '>= 2.3.7') # ruby >= 4.0.0 # Security spec.add_development_dependency('bundler-audit', '~> 0.9.3') # ruby >= 2.0.0 @@ -123,9 +123,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency('require_bench', '~> 1.0', '>= 1.0.4') # ruby >= 2.2.0 # Testing - spec.add_development_dependency('appraisal2', '~> 3.1', '>= 3.1.4') # ruby >= 1.8.7, for testing against multiple versions of dependencies - spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 - spec.add_development_dependency('turbo_tests2', '~> 3.1', '>= 3.1.14') # ruby >= 2.4.0, default kettle-test runner + spec.add_development_dependency('appraisal2', '~> 3.2', '>= 3.2.0') # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency('kettle-test', '~> 2.0', '>= 2.0.11') # ruby >= 4.0.0 + spec.add_development_dependency('turbo_tests2', '~> 3.2', '>= 3.2.0') # ruby >= 2.4.0, default kettle-test runner # Releasing spec.add_development_dependency('ruby-progressbar', '~> 1.13') # ruby >= 0 diff --git a/gems/ruby-merge/.gitattributes b/gems/ruby-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/ruby-merge/.gitattributes +++ b/gems/ruby-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/ruby-merge/.kettle-drift.lock b/gems/ruby-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/ruby-merge/.kettle-drift.lock +++ b/gems/ruby-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/ruby-merge/.rubocop_gradual.lock b/gems/ruby-merge/.rubocop_gradual.lock index fff670117..827b7fe9d 100644 --- a/gems/ruby-merge/.rubocop_gradual.lock +++ b/gems/ruby-merge/.rubocop_gradual.lock @@ -76,222 +76,290 @@ "lib/ruby-merge.rb:2992445753": [ [1, 1, 0, "Naming/FileName: The name of this source file (`ruby-merge.rb`) should use snake_case.", 5381] ], - "lib/ruby/merge.rb:1877719734": [ - [11, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Ruby::Merge`.", 2866359175], - [11, 3, 109110, "Metrics/ModuleLength: Module has too many lines. [2519/100]", 662788489], - [29, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 3061257365], - [81, 5, 959, "Metrics/AbcSize: Assignment Branch Condition size for `parse_ruby` is too high. [<4, 16, 7> 17.92/17]", 1071201699], - [81, 5, 959, "Metrics/MethodLength: Method has too many lines. [16/10]", 1071201699], - [107, 5, 2656, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_method_move_detection` is too high. [<17, 40, 18> 47.04/17]", 3779436399], - [107, 5, 2656, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_method_move_detection` is too high. [16/7]", 3779436399], - [107, 5, 2656, "Metrics/MethodLength: Method has too many lines. [45/10]", 3779436399], - [107, 5, 2656, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_method_move_detection` is too high. [16/8]", 3779436399], - [119, 121, 14, "Layout/LineLength: Line is too long. [134/120]", 727785047], - [132, 121, 51, "Layout/LineLength: Line is too long. [171/120]", 3259664538], - [151, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [154, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [155, 121, 7, "Layout/LineLength: Line is too long. [127/120]", 1976354608], - [159, 5, 4395, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ruby` is too high. [<31, 64, 24> 75.05/17]", 2749692967], - [159, 5, 4395, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ruby` is too high. [21/7]", 2749692967], - [159, 5, 4395, "Metrics/MethodLength: Method has too many lines. [83/10]", 2749692967], - [159, 5, 4395, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ruby` is too high. [22/8]", 2749692967], - [218, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [257, 5, 1312, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_delegated_child_operations` is too high. [<10, 15, 6> 19/17]", 2246428949], - [257, 5, 1312, "Metrics/MethodLength: Method has too many lines. [28/10]", 2246428949], - [303, 5, 861, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_source_owner_identity_profile` is too high. [<5, 17, 2> 17.83/17]", 4129925341], - [303, 5, 861, "Metrics/MethodLength: Method has too many lines. [20/10]", 4129925341], - [326, 5, 2064, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_source_owner_identity_matches` is too high. [<17, 31, 11> 37.03/17]", 2780319153], - [326, 5, 2064, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_source_owner_identity_matches` is too high. [11/7]", 2780319153], - [326, 5, 2064, "Metrics/MethodLength: Method has too many lines. [37/10]", 2780319153], - [326, 5, 2064, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_source_owner_identity_matches` is too high. [11/8]", 2780319153], - [355, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [358, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [363, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1001816794], - [369, 5, 1314, "Metrics/MethodLength: Method has too many lines. [28/10]", 4183124680], - [402, 5, 786, "Metrics/MethodLength: Method has too many lines. [24/10]", 3631640245], - [429, 5, 916, "Metrics/MethodLength: Method has too many lines. [18/10]", 631485532], - [450, 5, 662, "Metrics/MethodLength: Method has too many lines. [15/10]", 2231086183], - [469, 5, 777, "Metrics/MethodLength: Method has too many lines. [18/10]", 895030114], - [490, 5, 727, "Metrics/MethodLength: Method has too many lines. [19/10]", 776483642], - [512, 5, 861, "Metrics/MethodLength: Method has too many lines. [29/10]", 537340961], - [544, 5, 655, "Metrics/MethodLength: Method has too many lines. [16/10]", 3756601977], - [563, 5, 1592, "Metrics/MethodLength: Method has too many lines. [25/10]", 3521052904], - [587, 121, 106, "Layout/LineLength: Line is too long. [226/120]", 2104286058], - [593, 5, 777, "Metrics/MethodLength: Method has too many lines. [14/10]", 2821246515], - [610, 5, 1429, "Metrics/MethodLength: Method has too many lines. [26/10]", 244346226], - [633, 121, 124, "Layout/LineLength: Line is too long. [244/120]", 13261232], - [639, 5, 1367, "Metrics/MethodLength: Method has too many lines. [41/10]", 3883814121], - [683, 5, 750, "Metrics/MethodLength: Method has too many lines. [22/10]", 764028624], - [709, 5, 1315, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_silent_data_loss_validation_report` is too high. [<8, 14, 7> 17.58/17]", 2039399818], - [709, 5, 1315, "Metrics/MethodLength: Method has too many lines. [31/10]", 2039399818], - [744, 5, 724, "Metrics/MethodLength: Method has too many lines. [14/10]", 1741779676], - [755, 121, 67, "Layout/LineLength: Line is too long. [187/120]", 1996508131], - [761, 5, 752, "Metrics/MethodLength: Method has too many lines. [21/10]", 3870096101], - [785, 5, 1052, "Metrics/MethodLength: Method has too many lines. [32/10]", 119279638], - [820, 5, 1588, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_interstitial_comment_attachment_report` is too high. [<11, 34, 17> 39.57/17]", 4112280260], - [820, 5, 1588, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_interstitial_comment_attachment_report` is too high. [14/7]", 4112280260], - [820, 5, 1588, "Metrics/MethodLength: Method has too many lines. [30/10]", 4112280260], - [820, 5, 1588, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_interstitial_comment_attachment_report` is too high. [15/8]", 4112280260], - [834, 121, 5, "Layout/LineLength: Line is too long. [125/120]", 180543822], - [862, 5, 536, "Metrics/MethodLength: Method has too many lines. [13/10]", 245509059], - [878, 5, 2252, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_rename_detection` is too high. [<14, 32, 11> 36.62/17]", 2574664763], - [878, 5, 2252, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_rename_detection` is too high. [10/7]", 2574664763], - [878, 5, 2252, "Metrics/MethodLength: Method has too many lines. [46/10]", 2574664763], - [878, 5, 2252, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_rename_detection` is too high. [11/8]", 2574664763], - [921, 121, 21, "Layout/LineLength: Line is too long. [141/120]", 4074688513], - [927, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [931, 5, 2254, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_rename_plus_edit_conflicts` is too high. [<15, 30, 13> 35.97/17]", 3664513828], - [931, 5, 2254, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_rename_plus_edit_conflicts` is too high. [10/7]", 3664513828], - [931, 5, 2254, "Metrics/MethodLength: Method has too many lines. [45/10]", 3664513828], - [931, 5, 2254, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_rename_plus_edit_conflicts` is too high. [11/8]", 3664513828], - [983, 5, 1926, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_cross_container_method_move_detection` is too high. [<8, 18, 7> 20.9/17]", 1401333972], - [983, 5, 1926, "Metrics/MethodLength: Method has too many lines. [44/10]", 1401333972], - [1026, 121, 16, "Layout/LineLength: Line is too long. [136/120]", 3474944396], - [1033, 5, 1488, "Metrics/AbcSize: Assignment Branch Condition size for `apply_ruby_delegated_child_outputs` is too high. [<16, 39, 12> 43.83/17]", 842348215], - [1033, 5, 1488, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_ruby_delegated_child_outputs` is too high. [12/7]", 842348215], - [1033, 5, 1488, "Metrics/MethodLength: Method has too many lines. [27/10]", 842348215], - [1033, 5, 1488, "Metrics/PerceivedComplexity: Perceived complexity for `apply_ruby_delegated_child_outputs` is too high. [13/8]", 842348215], - [1067, 5, 980, "Metrics/MethodLength: Method has too many lines. [23/10]", 1425119613], - [1094, 5, 1025, "Metrics/MethodLength: Method has too many lines. [23/10]", 2179557432], - [1122, 5, 757, "Metrics/MethodLength: Method has too many lines. [12/10]", 3975431355], - [1127, 121, 70, "Layout/LineLength: Line is too long. [190/120]", 1956194284], - [1139, 5, 745, "Metrics/MethodLength: Method has too many lines. [12/10]", 1051086033], - [1144, 121, 62, "Layout/LineLength: Line is too long. [182/120]", 1636990749], - [1156, 5, 670, "Metrics/MethodLength: Method has too many lines. [11/10]", 3552666292], - [1161, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], - [1172, 5, 678, "Metrics/MethodLength: Method has too many lines. [11/10]", 1356230953], - [1177, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], - [1188, 5, 2093, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_ruby_document` is too high. [<21, 31, 12> 39.32/17]", 3298966582], - [1188, 5, 2093, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `analyze_ruby_document` is too high. [13/7]", 3298966582], - [1188, 5, 2093, "Metrics/MethodLength: Method has too many lines. [53/10]", 3298966582], - [1188, 5, 2093, "Metrics/PerceivedComplexity: Perceived complexity for `analyze_ruby_document` is too high. [13/8]", 3298966582], - [1194, 7, 1035, "Metrics/BlockLength: Block has too many lines. [27/25]", 2081528636], - [1263, 5, 427, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_file_footer_text` is too high. [<5, 17, 8> 19.44/17]", 1703748308], - [1301, 5, 941, "Metrics/MethodLength: Method has too many lines. [15/10]", 1317835917], - [1307, 121, 173, "Layout/LineLength: Line is too long. [293/120]", 225499532], - [1333, 5, 518, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_tslp_claimed_line_indexes` is too high. [<6, 19, 5> 20.54/17]", 1455439838], - [1356, 5, 443, "Metrics/MethodLength: Method has too many lines. [12/10]", 4230588206], - [1373, 5, 363, "Metrics/MethodLength: Method has too many lines. [11/10]", 3068065572], - [1421, 5, 1849, "Metrics/AbcSize: Assignment Branch Condition size for `legacy_collect_ruby_declaration_entries` is too high. [<24, 26, 13> 37.7/17]", 3187770326], - [1421, 5, 1849, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `legacy_collect_ruby_declaration_entries` is too high. [11/7]", 3187770326], - [1421, 5, 1849, "Metrics/MethodLength: Method has too many lines. [54/10]", 3187770326], - [1421, 5, 1849, "Metrics/PerceivedComplexity: Perceived complexity for `legacy_collect_ruby_declaration_entries` is too high. [11/8]", 3187770326], - [1468, 13, 76, "Metrics/BlockNesting: Avoid more than 3 levels of block nesting.", 1356567820], - [1504, 5, 396, "Metrics/MethodLength: Method has too many lines. [11/10]", 1239008881], - [1519, 5, 681, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_process_declaration_entries` is too high. [<7, 17, 2> 18.49/17]", 2675999354], - [1519, 5, 681, "Metrics/MethodLength: Method has too many lines. [16/10]", 2675999354], - [1539, 5, 634, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_top_level_process_structure_items` is too high. [<5, 32, 14> 35.28/17]", 1120707166], - [1539, 5, 634, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_top_level_process_structure_items` is too high. [11/7]", 1120707166], - [1539, 5, 634, "Metrics/MethodLength: Method has too many lines. [11/10]", 1120707166], - [1539, 5, 634, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_top_level_process_structure_items` is too high. [11/8]", 1120707166], - [1551, 7, 11, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 848344986], - [1558, 7, 9, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 3648222389], - [1603, 5, 1284, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_intra_owner_merge_plan` is too high. [<8, 24, 9> 26.85/17]", 2388567699], - [1603, 5, 1284, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_intra_owner_merge_plan` is too high. [9/7]", 2388567699], - [1603, 5, 1284, "Metrics/MethodLength: Method has too many lines. [22/10]", 2388567699], - [1603, 5, 1284, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_intra_owner_merge_plan` is too high. [9/8]", 2388567699], - [1644, 5, 557, "Metrics/MethodLength: Method has too many lines. [11/10]", 3178341030], - [1702, 121, 62, "Layout/LineLength: Line is too long. [182/120]", 895013151], - [1707, 5, 593, "Metrics/MethodLength: Method has too many lines. [13/10]", 2850316611], - [1708, 121, 1, "Layout/LineLength: Line is too long. [121/120]", 177625], - [1725, 5, 609, "Metrics/MethodLength: Method has too many lines. [12/10]", 784855730], - [1740, 5, 695, "Metrics/MethodLength: Method has too many lines. [14/10]", 3942458504], - [1777, 5, 1110, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_hash_constants` is too high. [<11, 22, 6> 25.32/17]", 3861922947], - [1777, 5, 1110, "Metrics/MethodLength: Method has too many lines. [17/10]", 3861922947], - [1799, 5, 794, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_body_constants` is too high. [<9, 14, 6> 17.69/17]", 1882117166], - [1829, 5, 1138, "Metrics/AbcSize: Assignment Branch Condition size for `merge_array_constant_text` is too high. [<9, 18, 7> 21.31/17]", 1448081799], - [1829, 5, 1138, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_array_constant_text` is too high. [8/7]", 1448081799], - [1829, 5, 1138, "Metrics/MethodLength: Method has too many lines. [15/10]", 1448081799], - [1835, 121, 3, "Layout/LineLength: Line is too long. [123/120]", 193434112], - [1842, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], - [1849, 5, 774, "Metrics/AbcSize: Assignment Branch Condition size for `merge_percent_array_constant_text` is too high. [<8, 16, 7> 19.21/17]", 625509828], - [1849, 5, 774, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_percent_array_constant_text` is too high. [8/7]", 625509828], - [1878, 5, 1060, "Metrics/AbcSize: Assignment Branch Condition size for `merge_multiline_array_constant_text` is too high. [<11, 23, 10> 27.39/17]", 2672751288], - [1878, 5, 1060, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_multiline_array_constant_text` is too high. [11/7]", 2672751288], - [1878, 5, 1060, "Metrics/MethodLength: Method has too many lines. [13/10]", 2672751288], - [1878, 5, 1060, "Metrics/PerceivedComplexity: Perceived complexity for `merge_multiline_array_constant_text` is too high. [11/8]", 2672751288], - [1887, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], - [1896, 5, 1605, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_body_methods` is too high. [<21, 28, 15> 38.08/17]", 2740924329], - [1896, 5, 1605, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_declaration_body_methods` is too high. [14/7]", 2740924329], - [1896, 5, 1605, "Metrics/MethodLength: Method has too many lines. [29/10]", 2740924329], - [1896, 5, 1605, "Metrics/PerceivedComplexity: Perceived complexity for `merge_declaration_body_methods` is too high. [15/8]", 2740924329], - [1903, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], - [1930, 5, 1076, "Metrics/AbcSize: Assignment Branch Condition size for `merge_nested_body_declarations` is too high. [<14, 24, 10> 29.53/17]", 1397199527], - [1930, 5, 1076, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_nested_body_declarations` is too high. [11/7]", 1397199527], - [1930, 5, 1076, "Metrics/MethodLength: Method has too many lines. [14/10]", 1397199527], - [1930, 5, 1076, "Metrics/PerceivedComplexity: Perceived complexity for `merge_nested_body_declarations` is too high. [11/8]", 1397199527], - [1969, 5, 2549, "Metrics/AbcSize: Assignment Branch Condition size for `top_level_source_region_owners` is too high. [<24, 33, 13> 42.83/17]", 1909271685], - [1969, 5, 2549, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `top_level_source_region_owners` is too high. [11/7]", 1909271685], - [1969, 5, 2549, "Metrics/MethodLength: Method has too many lines. [64/10]", 1909271685], - [1969, 5, 2549, "Metrics/PerceivedComplexity: Perceived complexity for `top_level_source_region_owners` is too high. [11/8]", 1909271685], - [2012, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5861626], - [2027, 121, 28, "Layout/LineLength: Line is too long. [148/120]", 1695648499], - [2043, 5, 2126, "Metrics/AbcSize: Assignment Branch Condition size for `container_child_source_regions` is too high. [<23, 28, 11> 37.87/17]", 4031983731], - [2043, 5, 2126, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `container_child_source_regions` is too high. [10/7]", 4031983731], - [2043, 5, 2126, "Metrics/MethodLength: Method has too many lines. [56/10]", 4031983731], - [2043, 5, 2126, "Metrics/PerceivedComplexity: Perceived complexity for `container_child_source_regions` is too high. [10/8]", 4031983731], - [2109, 5, 996, "Metrics/AbcSize: Assignment Branch Condition size for `interleave_source_regions` is too high. [<8, 14, 6> 17.2/17]", 796443872], - [2109, 5, 996, "Metrics/MethodLength: Method has too many lines. [30/10]", 796443872], - [2147, 5, 1323, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `source_interstitial_region` is too high. [13/7]", 1970451685], - [2147, 5, 1323, "Metrics/MethodLength: Method has too many lines. [30/10]", 1970451685], - [2147, 5, 1323, "Metrics/PerceivedComplexity: Perceived complexity for `source_interstitial_region` is too high. [12/8]", 1970451685], - [2147, 35, 80, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 2143999554], - [2182, 5, 396, "Metrics/MethodLength: Method has too many lines. [12/10]", 663734283], - [2198, 5, 890, "Metrics/AbcSize: Assignment Branch Condition size for `collect_blank_line_regions` is too high. [<4, 18, 7> 19.72/17]", 3362926457], - [2198, 5, 890, "Metrics/MethodLength: Method has too many lines. [20/10]", 3362926457], - [2257, 5, 27, "Style/Documentation: Missing top-level documentation comment for `class Ruby::Merge::RubyHashLiteralParser`.", 2589782793], - [2257, 5, 3304, "Metrics/ClassLength: Class has too many lines. [103/100]", 2782733473], - [2274, 7, 868, "Metrics/AbcSize: Assignment Branch Condition size for `parse_hash` is too high. [<6, 23, 6> 24.52/17]", 2331230410], - [2274, 7, 868, "Metrics/MethodLength: Method has too many lines. [28/10]", 2331230410], - [2314, 7, 911, "Metrics/AbcSize: Assignment Branch Condition size for `parse_hash_key` is too high. [<13, 26, 4> 29.34/17]", 2403379393], - [2314, 7, 911, "Metrics/MethodLength: Method has too many lines. [18/10]", 2403379393], - [2339, 7, 644, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_scalar_source` is too high. [8/7]", 2447980390], - [2339, 7, 644, "Metrics/MethodLength: Method has too many lines. [21/10]", 2447980390], - [2339, 7, 644, "Metrics/PerceivedComplexity: Perceived complexity for `parse_scalar_source` is too high. [9/8]", 2447980390], - [2384, 5, 1202, "Metrics/AbcSize: Assignment Branch Condition size for `constant_hash_blocks` is too high. [<19, 25, 6> 31.97/17]", 399214756], - [2384, 5, 1202, "Metrics/MethodLength: Method has too many lines. [36/10]", 399214756], - [2425, 5, 727, "Metrics/AbcSize: Assignment Branch Condition size for `hash_assignment_finish_line` is too high. [<11, 7, 12> 17.72/17]", 1215874404], - [2425, 5, 727, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `hash_assignment_finish_line` is too high. [9/7]", 1215874404], - [2425, 5, 727, "Metrics/MethodLength: Method has too many lines. [26/10]", 1215874404], - [2425, 5, 727, "Metrics/PerceivedComplexity: Perceived complexity for `hash_assignment_finish_line` is too high. [11/8]", 1215874404], - [2455, 5, 1970, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_method_entries` is too high. [<28, 32, 13> 44.46/17]", 2589282610], - [2455, 5, 1970, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `direct_body_method_entries` is too high. [12/7]", 2589282610], - [2455, 5, 1970, "Metrics/MethodLength: Method has too many lines. [56/10]", 2589282610], - [2455, 5, 1970, "Metrics/PerceivedComplexity: Perceived complexity for `direct_body_method_entries` is too high. [12/8]", 2589282610], - [2520, 5, 1221, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_constant_entries` is too high. [<16, 34, 10> 38.88/17]", 1588885504], - [2520, 5, 1221, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `direct_body_constant_entries` is too high. [9/7]", 1588885504], - [2520, 5, 1221, "Metrics/MethodLength: Method has too many lines. [35/10]", 1588885504], - [2520, 5, 1221, "Metrics/PerceivedComplexity: Perceived complexity for `direct_body_constant_entries` is too high. [9/8]", 1588885504], - [2563, 5, 708, "Metrics/AbcSize: Assignment Branch Condition size for `split_ruby_array_elements` is too high. [<11, 12, 11> 19.65/17]", 1344003748], - [2563, 5, 708, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `split_ruby_array_elements` is too high. [9/7]", 1344003748], - [2563, 5, 708, "Metrics/MethodLength: Method has too many lines. [24/10]", 1344003748], - [2563, 5, 708, "Metrics/PerceivedComplexity: Perceived complexity for `split_ruby_array_elements` is too high. [11/8]", 1344003748], - [2607, 5, 977, "Metrics/AbcSize: Assignment Branch Condition size for `append_multiline_array_elements` is too high. [<12, 32, 9> 35.34/17]", 1316332112], - [2607, 5, 977, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `append_multiline_array_elements` is too high. [9/7]", 1316332112], - [2607, 5, 977, "Metrics/MethodLength: Method has too many lines. [16/10]", 1316332112], - [2607, 5, 977, "Metrics/PerceivedComplexity: Perceived complexity for `append_multiline_array_elements` is too high. [9/8]", 1316332112], - [2635, 5, 728, "Metrics/AbcSize: Assignment Branch Condition size for `array_assignment_finish_line` is too high. [<11, 7, 12> 17.72/17]", 1471354607], - [2635, 5, 728, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `array_assignment_finish_line` is too high. [9/7]", 1471354607], - [2635, 5, 728, "Metrics/MethodLength: Method has too many lines. [26/10]", 1471354607], - [2635, 5, 728, "Metrics/PerceivedComplexity: Perceived complexity for `array_assignment_finish_line` is too high. [11/8]", 1471354607], - [2671, 5, 1127, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_declaration_entries` is too high. [<14, 30, 7> 33.84/17]", 1223661118], - [2671, 5, 1127, "Metrics/MethodLength: Method has too many lines. [30/10]", 1223661118], - [2718, 5, 984, "Metrics/AbcSize: Assignment Branch Condition size for `insert_declaration_body_blocks` is too high. [<4, 23, 12> 26.25/17]", 159690081], - [2718, 5, 984, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `insert_declaration_body_blocks` is too high. [9/7]", 159690081], - [2718, 5, 984, "Metrics/MethodLength: Method has too many lines. [16/10]", 159690081], - [2718, 5, 984, "Metrics/PerceivedComplexity: Perceived complexity for `insert_declaration_body_blocks` is too high. [10/8]", 159690081], - [2763, 5, 1027, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ruby_hash_literals` is too high. [<8, 30, 9> 32.33/17]", 2793745298], - [2763, 5, 1027, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ruby_hash_literals` is too high. [9/7]", 2793745298], - [2763, 5, 1027, "Metrics/MethodLength: Method has too many lines. [19/10]", 2793745298], - [2763, 5, 1027, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ruby_hash_literals` is too high. [10/8]", 2793745298], - [2785, 5, 636, "Metrics/AbcSize: Assignment Branch Condition size for `render_ruby_hash_literal` is too high. [<5, 19, 6> 20.54/17]", 1834383244], - [2825, 5, 491, "Metrics/MethodLength: Method has too many lines. [11/10]", 1799924605], - [2858, 5, 1125, "Metrics/AbcSize: Assignment Branch Condition size for `surfaces_for_owner` is too high. [<6, 19, 3> 20.15/17]", 4036098594], - [2858, 5, 1125, "Metrics/MethodLength: Method has too many lines. [20/10]", 4036098594], - [2883, 5, 1479, "Metrics/AbcSize: Assignment Branch Condition size for `example_surfaces_for` is too high. [<10, 28, 9> 31.06/17]", 1159322815], - [2883, 5, 1479, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `example_surfaces_for` is too high. [9/7]", 1159322815], - [2883, 5, 1479, "Metrics/MethodLength: Method has too many lines. [28/10]", 1159322815], - [2883, 5, 1479, "Metrics/PerceivedComplexity: Perceived complexity for `example_surfaces_for` is too high. [9/8]", 1159322815] + "lib/ruby/merge.rb:1549201317": [ + [21, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Ruby::Merge`.", 2866359175], + [21, 3, 117385, "Metrics/ModuleLength: Module has too many lines. [2664/100]", 3496752980], + [42, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 3061257365], + [103, 5, 841, "Metrics/AbcSize: Assignment Branch Condition size for `parse_ruby` is too high. [<4, 16, 6> 17.55/17]", 1071201699], + [103, 5, 841, "Metrics/MethodLength: Method has too many lines. [16/10]", 1071201699], + [128, 5, 2656, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_method_move_detection` is too high. [<17, 40, 18> 47.04/17]", 3779436399], + [128, 5, 2656, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_method_move_detection` is too high. [16/7]", 3779436399], + [128, 5, 2656, "Metrics/MethodLength: Method has too many lines. [45/10]", 3779436399], + [128, 5, 2656, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_method_move_detection` is too high. [16/8]", 3779436399], + [140, 121, 14, "Layout/LineLength: Line is too long. [134/120]", 727785047], + [153, 121, 51, "Layout/LineLength: Line is too long. [171/120]", 3259664538], + [172, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [175, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [176, 121, 7, "Layout/LineLength: Line is too long. [127/120]", 1976354608], + [180, 5, 4374, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ruby` is too high. [<31, 63, 24> 74.2/17]", 2749692967], + [180, 5, 4374, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ruby` is too high. [21/7]", 2749692967], + [180, 5, 4374, "Metrics/MethodLength: Method has too many lines. [83/10]", 2749692967], + [180, 5, 4374, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ruby` is too high. [22/8]", 2749692967], + [239, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [278, 5, 1312, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_delegated_child_operations` is too high. [<10, 15, 6> 19/17]", 2246428949], + [278, 5, 1312, "Metrics/MethodLength: Method has too many lines. [28/10]", 2246428949], + [324, 5, 861, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_source_owner_identity_profile` is too high. [<5, 17, 2> 17.83/17]", 4129925341], + [324, 5, 861, "Metrics/MethodLength: Method has too many lines. [20/10]", 4129925341], + [347, 5, 2064, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_source_owner_identity_matches` is too high. [<17, 31, 11> 37.03/17]", 2780319153], + [347, 5, 2064, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_source_owner_identity_matches` is too high. [11/7]", 2780319153], + [347, 5, 2064, "Metrics/MethodLength: Method has too many lines. [37/10]", 2780319153], + [347, 5, 2064, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_source_owner_identity_matches` is too high. [11/8]", 2780319153], + [376, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [379, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [384, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1001816794], + [390, 5, 1314, "Metrics/MethodLength: Method has too many lines. [28/10]", 4183124680], + [423, 5, 786, "Metrics/MethodLength: Method has too many lines. [24/10]", 3631640245], + [450, 5, 916, "Metrics/MethodLength: Method has too many lines. [18/10]", 631485532], + [471, 5, 662, "Metrics/MethodLength: Method has too many lines. [15/10]", 2231086183], + [490, 5, 777, "Metrics/MethodLength: Method has too many lines. [18/10]", 895030114], + [511, 5, 727, "Metrics/MethodLength: Method has too many lines. [19/10]", 776483642], + [533, 5, 861, "Metrics/MethodLength: Method has too many lines. [29/10]", 537340961], + [565, 5, 655, "Metrics/MethodLength: Method has too many lines. [16/10]", 3756601977], + [584, 5, 1592, "Metrics/MethodLength: Method has too many lines. [25/10]", 3521052904], + [608, 121, 106, "Layout/LineLength: Line is too long. [226/120]", 2104286058], + [614, 5, 777, "Metrics/MethodLength: Method has too many lines. [14/10]", 2821246515], + [631, 5, 1429, "Metrics/MethodLength: Method has too many lines. [26/10]", 244346226], + [654, 121, 124, "Layout/LineLength: Line is too long. [244/120]", 13261232], + [660, 5, 1367, "Metrics/MethodLength: Method has too many lines. [41/10]", 3883814121], + [704, 5, 750, "Metrics/MethodLength: Method has too many lines. [22/10]", 764028624], + [730, 5, 1315, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_silent_data_loss_validation_report` is too high. [<8, 14, 7> 17.58/17]", 2039399818], + [730, 5, 1315, "Metrics/MethodLength: Method has too many lines. [31/10]", 2039399818], + [765, 5, 724, "Metrics/MethodLength: Method has too many lines. [14/10]", 1741779676], + [776, 121, 67, "Layout/LineLength: Line is too long. [187/120]", 1996508131], + [782, 5, 752, "Metrics/MethodLength: Method has too many lines. [21/10]", 3870096101], + [806, 5, 1052, "Metrics/MethodLength: Method has too many lines. [32/10]", 119279638], + [841, 5, 1588, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_interstitial_comment_attachment_report` is too high. [<11, 34, 17> 39.57/17]", 4112280260], + [841, 5, 1588, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_interstitial_comment_attachment_report` is too high. [14/7]", 4112280260], + [841, 5, 1588, "Metrics/MethodLength: Method has too many lines. [30/10]", 4112280260], + [841, 5, 1588, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_interstitial_comment_attachment_report` is too high. [15/8]", 4112280260], + [855, 121, 5, "Layout/LineLength: Line is too long. [125/120]", 180543822], + [883, 5, 536, "Metrics/MethodLength: Method has too many lines. [13/10]", 245509059], + [899, 5, 2252, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_rename_detection` is too high. [<14, 32, 11> 36.62/17]", 2574664763], + [899, 5, 2252, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_rename_detection` is too high. [10/7]", 2574664763], + [899, 5, 2252, "Metrics/MethodLength: Method has too many lines. [46/10]", 2574664763], + [899, 5, 2252, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_rename_detection` is too high. [11/8]", 2574664763], + [942, 121, 21, "Layout/LineLength: Line is too long. [141/120]", 4074688513], + [948, 9, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [952, 5, 2254, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_rename_plus_edit_conflicts` is too high. [<15, 30, 13> 35.97/17]", 3664513828], + [952, 5, 2254, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_rename_plus_edit_conflicts` is too high. [10/7]", 3664513828], + [952, 5, 2254, "Metrics/MethodLength: Method has too many lines. [45/10]", 3664513828], + [952, 5, 2254, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_rename_plus_edit_conflicts` is too high. [11/8]", 3664513828], + [1004, 5, 1926, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_cross_container_method_move_detection` is too high. [<8, 18, 7> 20.9/17]", 1401333972], + [1004, 5, 1926, "Metrics/MethodLength: Method has too many lines. [44/10]", 1401333972], + [1047, 121, 16, "Layout/LineLength: Line is too long. [136/120]", 3474944396], + [1054, 5, 1488, "Metrics/AbcSize: Assignment Branch Condition size for `apply_ruby_delegated_child_outputs` is too high. [<16, 39, 12> 43.83/17]", 842348215], + [1054, 5, 1488, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `apply_ruby_delegated_child_outputs` is too high. [12/7]", 842348215], + [1054, 5, 1488, "Metrics/MethodLength: Method has too many lines. [27/10]", 842348215], + [1054, 5, 1488, "Metrics/PerceivedComplexity: Perceived complexity for `apply_ruby_delegated_child_outputs` is too high. [13/8]", 842348215], + [1088, 5, 980, "Metrics/MethodLength: Method has too many lines. [23/10]", 1425119613], + [1115, 5, 1025, "Metrics/MethodLength: Method has too many lines. [23/10]", 2179557432], + [1143, 5, 757, "Metrics/MethodLength: Method has too many lines. [12/10]", 3975431355], + [1148, 121, 70, "Layout/LineLength: Line is too long. [190/120]", 1956194284], + [1160, 5, 745, "Metrics/MethodLength: Method has too many lines. [12/10]", 1051086033], + [1165, 121, 62, "Layout/LineLength: Line is too long. [182/120]", 1636990749], + [1177, 5, 670, "Metrics/MethodLength: Method has too many lines. [11/10]", 3552666292], + [1182, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], + [1193, 5, 678, "Metrics/MethodLength: Method has too many lines. [11/10]", 1356230953], + [1198, 121, 17, "Layout/LineLength: Line is too long. [137/120]", 3013228499], + [1209, 5, 2093, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_ruby_document` is too high. [<21, 31, 12> 39.32/17]", 3298966582], + [1209, 5, 2093, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `analyze_ruby_document` is too high. [13/7]", 3298966582], + [1209, 5, 2093, "Metrics/MethodLength: Method has too many lines. [53/10]", 3298966582], + [1209, 5, 2093, "Metrics/PerceivedComplexity: Perceived complexity for `analyze_ruby_document` is too high. [13/8]", 3298966582], + [1215, 7, 1035, "Metrics/BlockLength: Block has too many lines. [27/25]", 2081528636], + [1284, 5, 427, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_file_footer_text` is too high. [<5, 17, 8> 19.44/17]", 1703748308], + [1311, 5, 806, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_process_analysis_from_tree` is too high. [10/7]", 1109735749], + [1311, 5, 806, "Metrics/MethodLength: Method has too many lines. [19/10]", 1109735749], + [1361, 5, 533, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_import_item_from_begin_node` is too high. [8/7]", 582163830], + [1383, 5, 487, "Metrics/MethodLength: Method has too many lines. [12/10]", 3257507103], + [1400, 5, 583, "Metrics/MethodLength: Method has too many lines. [15/10]", 4108141408], + [1443, 5, 645, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_import_span_for` is too high. [<6, 22, 9> 24.52/17]", 1779826452], + [1443, 5, 645, "Metrics/MethodLength: Method has too many lines. [12/10]", 1779826452], + [1495, 5, 1015, "Metrics/MethodLength: Method has too many lines. [16/10]", 1317835917], + [1501, 121, 173, "Layout/LineLength: Line is too long. [293/120]", 225499532], + [1528, 5, 518, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_tslp_claimed_line_indexes` is too high. [<6, 19, 5> 20.54/17]", 1455439838], + [1551, 5, 443, "Metrics/MethodLength: Method has too many lines. [12/10]", 4230588206], + [1568, 5, 363, "Metrics/MethodLength: Method has too many lines. [11/10]", 3068065572], + [1629, 5, 1849, "Metrics/AbcSize: Assignment Branch Condition size for `legacy_collect_ruby_declaration_entries` is too high. [<24, 26, 13> 37.7/17]", 3187770326], + [1629, 5, 1849, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `legacy_collect_ruby_declaration_entries` is too high. [11/7]", 3187770326], + [1629, 5, 1849, "Metrics/MethodLength: Method has too many lines. [54/10]", 3187770326], + [1629, 5, 1849, "Metrics/PerceivedComplexity: Perceived complexity for `legacy_collect_ruby_declaration_entries` is too high. [11/8]", 3187770326], + [1676, 13, 76, "Metrics/BlockNesting: Avoid more than 3 levels of block nesting.", 1356567820], + [1712, 5, 396, "Metrics/MethodLength: Method has too many lines. [11/10]", 1239008881], + [1727, 5, 681, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_process_declaration_entries` is too high. [<7, 17, 2> 18.49/17]", 2675999354], + [1727, 5, 681, "Metrics/MethodLength: Method has too many lines. [16/10]", 2675999354], + [1747, 5, 634, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_top_level_process_structure_items` is too high. [<5, 32, 14> 35.28/17]", 1120707166], + [1747, 5, 634, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_top_level_process_structure_items` is too high. [11/7]", 1120707166], + [1747, 5, 634, "Metrics/MethodLength: Method has too many lines. [11/10]", 1120707166], + [1747, 5, 634, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_top_level_process_structure_items` is too high. [11/8]", 1120707166], + [1759, 7, 11, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 848344986], + [1766, 7, 9, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 3648222389], + [1811, 5, 1284, "Metrics/AbcSize: Assignment Branch Condition size for `ruby_intra_owner_merge_plan` is too high. [<8, 24, 9> 26.85/17]", 2388567699], + [1811, 5, 1284, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `ruby_intra_owner_merge_plan` is too high. [9/7]", 2388567699], + [1811, 5, 1284, "Metrics/MethodLength: Method has too many lines. [22/10]", 2388567699], + [1811, 5, 1284, "Metrics/PerceivedComplexity: Perceived complexity for `ruby_intra_owner_merge_plan` is too high. [9/8]", 2388567699], + [1852, 5, 557, "Metrics/MethodLength: Method has too many lines. [11/10]", 3178341030], + [1910, 121, 62, "Layout/LineLength: Line is too long. [182/120]", 895013151], + [1915, 5, 593, "Metrics/MethodLength: Method has too many lines. [13/10]", 2850316611], + [1916, 121, 1, "Layout/LineLength: Line is too long. [121/120]", 177625], + [1933, 5, 609, "Metrics/MethodLength: Method has too many lines. [12/10]", 784855730], + [1948, 5, 695, "Metrics/MethodLength: Method has too many lines. [14/10]", 3942458504], + [1985, 5, 1114, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_hash_constants` is too high. [<11, 22, 6> 25.32/17]", 3861922947], + [1985, 5, 1114, "Metrics/MethodLength: Method has too many lines. [17/10]", 3861922947], + [2007, 5, 794, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_body_constants` is too high. [<9, 14, 6> 17.69/17]", 1882117166], + [2037, 5, 1138, "Metrics/AbcSize: Assignment Branch Condition size for `merge_array_constant_text` is too high. [<9, 18, 7> 21.31/17]", 1448081799], + [2037, 5, 1138, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_array_constant_text` is too high. [8/7]", 1448081799], + [2037, 5, 1138, "Metrics/MethodLength: Method has too many lines. [15/10]", 1448081799], + [2043, 121, 3, "Layout/LineLength: Line is too long. [123/120]", 193434112], + [2050, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], + [2057, 5, 774, "Metrics/AbcSize: Assignment Branch Condition size for `merge_percent_array_constant_text` is too high. [<8, 16, 7> 19.21/17]", 625509828], + [2057, 5, 774, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_percent_array_constant_text` is too high. [8/7]", 625509828], + [2086, 5, 1060, "Metrics/AbcSize: Assignment Branch Condition size for `merge_multiline_array_constant_text` is too high. [<11, 23, 10> 27.39/17]", 2672751288], + [2086, 5, 1060, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_multiline_array_constant_text` is too high. [11/7]", 2672751288], + [2086, 5, 1060, "Metrics/MethodLength: Method has too many lines. [13/10]", 2672751288], + [2086, 5, 1060, "Metrics/PerceivedComplexity: Perceived complexity for `merge_multiline_array_constant_text` is too high. [11/8]", 2672751288], + [2095, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], + [2104, 5, 1605, "Metrics/AbcSize: Assignment Branch Condition size for `merge_declaration_body_methods` is too high. [<21, 28, 15> 38.08/17]", 2740924329], + [2104, 5, 1605, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_declaration_body_methods` is too high. [14/7]", 2740924329], + [2104, 5, 1605, "Metrics/MethodLength: Method has too many lines. [29/10]", 2740924329], + [2104, 5, 1605, "Metrics/PerceivedComplexity: Perceived complexity for `merge_declaration_body_methods` is too high. [15/8]", 2740924329], + [2111, 7, 8, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 359846632], + [2138, 5, 1076, "Metrics/AbcSize: Assignment Branch Condition size for `merge_nested_body_declarations` is too high. [<14, 24, 10> 29.53/17]", 1397199527], + [2138, 5, 1076, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_nested_body_declarations` is too high. [11/7]", 1397199527], + [2138, 5, 1076, "Metrics/MethodLength: Method has too many lines. [14/10]", 1397199527], + [2138, 5, 1076, "Metrics/PerceivedComplexity: Perceived complexity for `merge_nested_body_declarations` is too high. [11/8]", 1397199527], + [2177, 5, 2549, "Metrics/AbcSize: Assignment Branch Condition size for `top_level_source_region_owners` is too high. [<24, 33, 13> 42.83/17]", 1909271685], + [2177, 5, 2549, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `top_level_source_region_owners` is too high. [11/7]", 1909271685], + [2177, 5, 2549, "Metrics/MethodLength: Method has too many lines. [64/10]", 1909271685], + [2177, 5, 2549, "Metrics/PerceivedComplexity: Perceived complexity for `top_level_source_region_owners` is too high. [11/8]", 1909271685], + [2220, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5861626], + [2235, 121, 28, "Layout/LineLength: Line is too long. [148/120]", 1695648499], + [2251, 5, 2126, "Metrics/AbcSize: Assignment Branch Condition size for `container_child_source_regions` is too high. [<23, 28, 11> 37.87/17]", 4031983731], + [2251, 5, 2126, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `container_child_source_regions` is too high. [10/7]", 4031983731], + [2251, 5, 2126, "Metrics/MethodLength: Method has too many lines. [56/10]", 4031983731], + [2251, 5, 2126, "Metrics/PerceivedComplexity: Perceived complexity for `container_child_source_regions` is too high. [10/8]", 4031983731], + [2317, 5, 996, "Metrics/AbcSize: Assignment Branch Condition size for `interleave_source_regions` is too high. [<8, 14, 6> 17.2/17]", 796443872], + [2317, 5, 996, "Metrics/MethodLength: Method has too many lines. [30/10]", 796443872], + [2355, 5, 1323, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `source_interstitial_region` is too high. [13/7]", 1970451685], + [2355, 5, 1323, "Metrics/MethodLength: Method has too many lines. [30/10]", 1970451685], + [2355, 5, 1323, "Metrics/PerceivedComplexity: Perceived complexity for `source_interstitial_region` is too high. [12/8]", 1970451685], + [2355, 35, 80, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 2143999554], + [2390, 5, 396, "Metrics/MethodLength: Method has too many lines. [12/10]", 663734283], + [2406, 5, 890, "Metrics/AbcSize: Assignment Branch Condition size for `collect_blank_line_regions` is too high. [<4, 18, 7> 19.72/17]", 3362926457], + [2406, 5, 890, "Metrics/MethodLength: Method has too many lines. [20/10]", 3362926457], + [2465, 5, 30, "Style/Documentation: Missing top-level documentation comment for `class Ruby::Merge::RubyHashLiteralProjector`.", 2586933062], + [2465, 5, 5733, "Metrics/ClassLength: Class has too many lines. [144/100]", 48390292], + [2498, 7, 617, "Metrics/MethodLength: Method has too many lines. [15/10]", 1617225783], + [2522, 7, 943, "Metrics/AbcSize: Assignment Branch Condition size for `project_hash_key` is too high. [<1, 18, 8> 19.72/17]", 3538404248], + [2522, 7, 943, "Metrics/MethodLength: Method has too many lines. [26/10]", 3538404248], + [2580, 7, 616, "Metrics/AbcSize: Assignment Branch Condition size for `trailing_comma?` is too high. [<3, 20, 6> 21.1/17]", 1517912413], + [2645, 5, 1202, "Metrics/AbcSize: Assignment Branch Condition size for `constant_hash_blocks` is too high. [<19, 25, 6> 31.97/17]", 399214756], + [2645, 5, 1202, "Metrics/MethodLength: Method has too many lines. [36/10]", 399214756], + [2686, 5, 727, "Metrics/AbcSize: Assignment Branch Condition size for `hash_assignment_finish_line` is too high. [<11, 7, 12> 17.72/17]", 1215874404], + [2686, 5, 727, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `hash_assignment_finish_line` is too high. [9/7]", 1215874404], + [2686, 5, 727, "Metrics/MethodLength: Method has too many lines. [26/10]", 1215874404], + [2686, 5, 727, "Metrics/PerceivedComplexity: Perceived complexity for `hash_assignment_finish_line` is too high. [11/8]", 1215874404], + [2716, 5, 2007, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_method_entries` is too high. [<28, 33, 13> 45.19/17]", 2589282610], + [2716, 5, 2007, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `direct_body_method_entries` is too high. [12/7]", 2589282610], + [2716, 5, 2007, "Metrics/MethodLength: Method has too many lines. [56/10]", 2589282610], + [2716, 5, 2007, "Metrics/PerceivedComplexity: Perceived complexity for `direct_body_method_entries` is too high. [12/8]", 2589282610], + [2781, 5, 1221, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_constant_entries` is too high. [<16, 34, 10> 38.88/17]", 1588885504], + [2781, 5, 1221, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `direct_body_constant_entries` is too high. [9/7]", 1588885504], + [2781, 5, 1221, "Metrics/MethodLength: Method has too many lines. [35/10]", 1588885504], + [2781, 5, 1221, "Metrics/PerceivedComplexity: Perceived complexity for `direct_body_constant_entries` is too high. [9/8]", 1588885504], + [2824, 5, 708, "Metrics/AbcSize: Assignment Branch Condition size for `split_ruby_array_elements` is too high. [<11, 12, 11> 19.65/17]", 1344003748], + [2824, 5, 708, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `split_ruby_array_elements` is too high. [9/7]", 1344003748], + [2824, 5, 708, "Metrics/MethodLength: Method has too many lines. [24/10]", 1344003748], + [2824, 5, 708, "Metrics/PerceivedComplexity: Perceived complexity for `split_ruby_array_elements` is too high. [11/8]", 1344003748], + [2868, 5, 977, "Metrics/AbcSize: Assignment Branch Condition size for `append_multiline_array_elements` is too high. [<12, 32, 9> 35.34/17]", 1316332112], + [2868, 5, 977, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `append_multiline_array_elements` is too high. [9/7]", 1316332112], + [2868, 5, 977, "Metrics/MethodLength: Method has too many lines. [16/10]", 1316332112], + [2868, 5, 977, "Metrics/PerceivedComplexity: Perceived complexity for `append_multiline_array_elements` is too high. [9/8]", 1316332112], + [2896, 5, 728, "Metrics/AbcSize: Assignment Branch Condition size for `array_assignment_finish_line` is too high. [<11, 7, 12> 17.72/17]", 1471354607], + [2896, 5, 728, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `array_assignment_finish_line` is too high. [9/7]", 1471354607], + [2896, 5, 728, "Metrics/MethodLength: Method has too many lines. [26/10]", 1471354607], + [2896, 5, 728, "Metrics/PerceivedComplexity: Perceived complexity for `array_assignment_finish_line` is too high. [11/8]", 1471354607], + [2932, 5, 1127, "Metrics/AbcSize: Assignment Branch Condition size for `direct_body_declaration_entries` is too high. [<14, 30, 7> 33.84/17]", 1223661118], + [2932, 5, 1127, "Metrics/MethodLength: Method has too many lines. [30/10]", 1223661118], + [2979, 5, 984, "Metrics/AbcSize: Assignment Branch Condition size for `insert_declaration_body_blocks` is too high. [<4, 23, 12> 26.25/17]", 159690081], + [2979, 5, 984, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `insert_declaration_body_blocks` is too high. [9/7]", 159690081], + [2979, 5, 984, "Metrics/MethodLength: Method has too many lines. [16/10]", 159690081], + [2979, 5, 984, "Metrics/PerceivedComplexity: Perceived complexity for `insert_declaration_body_blocks` is too high. [10/8]", 159690081], + [3024, 5, 1027, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ruby_hash_literals` is too high. [<8, 30, 9> 32.33/17]", 2793745298], + [3024, 5, 1027, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ruby_hash_literals` is too high. [9/7]", 2793745298], + [3024, 5, 1027, "Metrics/MethodLength: Method has too many lines. [19/10]", 2793745298], + [3024, 5, 1027, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ruby_hash_literals` is too high. [10/8]", 2793745298], + [3046, 5, 636, "Metrics/AbcSize: Assignment Branch Condition size for `render_ruby_hash_literal` is too high. [<5, 19, 6> 20.54/17]", 1834383244], + [3086, 5, 491, "Metrics/MethodLength: Method has too many lines. [11/10]", 1799924605], + [3119, 5, 1125, "Metrics/AbcSize: Assignment Branch Condition size for `surfaces_for_owner` is too high. [<6, 19, 3> 20.15/17]", 4036098594], + [3119, 5, 1125, "Metrics/MethodLength: Method has too many lines. [20/10]", 4036098594], + [3144, 5, 1126, "Metrics/AbcSize: Assignment Branch Condition size for `example_surfaces_for` is too high. [<4, 20, 2> 20.49/17]", 757808110], + [3144, 5, 1126, "Metrics/MethodLength: Method has too many lines. [21/10]", 757808110] + ], + "lib/ruby/merge/block_directive_detector.rb:315354690": [ + [10, 5, 6220, "Metrics/ClassLength: Class has too many lines. [161/100]", 3182117306], + [83, 7, 1085, "Metrics/AbcSize: Assignment Branch Condition size for `detect_freeze_spans` is too high. [<10, 18, 6> 21.45/17]", 3827147306], + [83, 7, 1085, "Metrics/MethodLength: Method has too many lines. [27/10]", 3827147306], + [117, 7, 1508, "Metrics/AbcSize: Assignment Branch Condition size for `detect_nocov_spans` is too high. [<10, 30, 10> 33.17/17]", 3750116369], + [117, 7, 1508, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `detect_nocov_spans` is too high. [9/7]", 3750116369], + [117, 7, 1508, "Metrics/MethodLength: Method has too many lines. [40/10]", 3750116369], + [117, 7, 1508, "Metrics/PerceivedComplexity: Perceived complexity for `detect_nocov_spans` is too high. [12/8]", 3750116369], + [125, 9, 1189, "Metrics/BlockLength: Block has too many lines. [30/25]", 431470454], + [165, 7, 921, "Metrics/AbcSize: Assignment Branch Condition size for `validate_no_crossing` is too high. [<8, 16, 8> 19.6/17]", 1072352384], + [165, 7, 921, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `validate_no_crossing` is too high. [8/7]", 1072352384], + [165, 7, 921, "Metrics/MethodLength: Method has too many lines. [19/10]", 1072352384], + [193, 121, 3, "Layout/LineLength: Line is too long. [123/120]", 193343749], + [194, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5860841] + ], + "lib/ruby/merge/doc_comment_support.rb:11585367": [ + [71, 7, 950, "Metrics/AbcSize: Assignment Branch Condition size for `example_blocks` is too high. [<8, 17, 8> 20.42/17]", 878231540], + [71, 7, 950, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `example_blocks` is too high. [8/7]", 878231540], + [71, 7, 950, "Metrics/MethodLength: Method has too many lines. [19/10]", 878231540] + ], + "lib/ruby/merge/gemspec_support.rb:672395758": [ + [5, 5, 21, "Style/Documentation: Missing top-level documentation comment for `module Ruby::Merge::GemspecSupport`.", 593910650] + ], + "lib/ruby/merge/magic_comment_support.rb:2193186223": [ + [26, 7, 1484, "Metrics/AbcSize: Assignment Branch Condition size for `comment_only_prefix_info` is too high. [<9, 38, 8> 39.86/17]", 1098666313], + [26, 7, 1484, "Metrics/MethodLength: Method has too many lines. [33/10]", 1098666313], + [69, 7, 693, "Metrics/AbcSize: Assignment Branch Condition size for `header_magic_comment_types_for_lines` is too high. [<10, 13, 9> 18.71/17]", 3693768719], + [69, 7, 693, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `header_magic_comment_types_for_lines` is too high. [8/7]", 3693768719], + [69, 7, 693, "Metrics/MethodLength: Method has too many lines. [16/10]", 3693768719], + [93, 7, 747, "Metrics/AbcSize: Assignment Branch Condition size for `prefix_comment_line_numbers_for_comments` is too high. [<10, 12, 7> 17.12/17]", 1181507516], + [93, 7, 747, "Metrics/MethodLength: Method has too many lines. [19/10]", 1181507516] + ], + "lib/ruby/merge/method_similarity.rb:3120642740": [ + [5, 5, 22, "Style/Documentation: Missing top-level documentation comment for `class Ruby::Merge::MethodSimilarity`.", 3784960433], + [23, 7, 493, "Metrics/AbcSize: Assignment Branch Condition size for `param_similarity` is too high. [<4, 19, 4> 19.82/17]", 1175888813], + [45, 7, 738, "Metrics/AbcSize: Assignment Branch Condition size for `levenshtein_distance` is too high. [<13, 29, 8> 32.77/17]", 1085087702], + [45, 7, 738, "Metrics/MethodLength: Method has too many lines. [20/10]", 1085087702] + ], + "lib/ruby/merge/nocov_node_base.rb:1713613866": [ + [23, 21, 84, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3439911158], + [51, 7, 353, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `signature` is too high. [8/7]", 3442013923], + [51, 7, 353, "Metrics/PerceivedComplexity: Perceived complexity for `signature` is too high. [9/8]", 3442013923] + ], + "lib/ruby/merge/rescue_semantics.rb:2728370094": [ + [5, 5, 21, "Style/Documentation: Missing top-level documentation comment for `class Ruby::Merge::RescueSemantics`.", 4002082661], + [5, 5, 8140, "Metrics/ClassLength: Class has too many lines. [157/100]", 3302970297], + [10, 7, 812, "Metrics/AbcSize: Assignment Branch Condition size for `merge_ordered_clause_types` is too high. [<9, 17, 8> 20.83/17]", 391537814], + [10, 7, 812, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_ordered_clause_types` is too high. [8/7]", 391537814], + [10, 7, 812, "Metrics/MethodLength: Method has too many lines. [16/10]", 391537814], + [10, 7, 812, "Metrics/PerceivedComplexity: Perceived complexity for `merge_ordered_clause_types` is too high. [9/8]", 391537814], + [33, 7, 1470, "Metrics/AbcSize: Assignment Branch Condition size for `canonicalize_rescue_clause_order` is too high. [<18, 28, 14> 36.11/17]", 570708009], + [33, 7, 1470, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `canonicalize_rescue_clause_order` is too high. [14/7]", 570708009], + [33, 7, 1470, "Metrics/MethodLength: Method has too many lines. [24/10]", 570708009], + [33, 7, 1470, "Metrics/PerceivedComplexity: Perceived complexity for `canonicalize_rescue_clause_order` is too high. [14/8]", 570708009], + [113, 7, 1080, "Metrics/AbcSize: Assignment Branch Condition size for `source_defined_exception_hierarchy` is too high. [<9, 20, 10> 24.1/17]", 3196945148], + [113, 7, 1080, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `source_defined_exception_hierarchy` is too high. [10/7]", 3196945148], + [113, 7, 1080, "Metrics/MethodLength: Method has too many lines. [15/10]", 3196945148], + [113, 7, 1080, "Metrics/PerceivedComplexity: Perceived complexity for `source_defined_exception_hierarchy` is too high. [11/8]", 3196945148], + [126, 121, 19, "Layout/LineLength: Line is too long. [139/120]", 1806710570] + ], + "lib/ruby/merge/scaffold_chunk_support.rb:640658628": [ + [5, 5, 27, "Style/Documentation: Missing top-level documentation comment for `module Ruby::Merge::ScaffoldChunkSupport`.", 2416541725] + ], + "lib/ruby/merge/signature_support.rb:1167161535": [ + [5, 5, 23, "Style/Documentation: Missing top-level documentation comment for `module Ruby::Merge::SignatureSupport`.", 2080470772] ], "ruby-merge.gemspec:503862341": [ [128, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], @@ -299,18 +367,24 @@ [144, 121, 29, "Layout/LineLength: Line is too long. [149/120]", 981994949], [151, 121, 12, "Layout/LineLength: Line is too long. [132/120]", 4229808912] ], - "spec/fixtures_integration_spec.rb:943607429": [ - [7, 1, 68962, "Metrics/BlockLength: Block has too many lines. [1586/25]", 1326132038], + "spec/fixtures_integration_spec.rb:2791875397": [ + [7, 1, 71426, "Metrics/BlockLength: Block has too many lines. [1643/25]", 1328376978], [8, 3, 94, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 4224869601], [9, 3, 80, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 3493759864], [10, 3, 72, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 218819604], [11, 3, 83, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 3957977039], - [56, 3, 1207, "Metrics/BlockLength: Block has too many lines. [27/25]", 2841005266], - [141, 3, 1550, "Metrics/BlockLength: Block has too many lines. [44/25]", 1381861178], - [192, 3, 1209, "Metrics/BlockLength: Block has too many lines. [33/25]", 1745132505], - [232, 3, 61330, "Metrics/BlockLength: Block has too many lines. [1387/25]", 3444780370], - [628, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5859109], - [1712, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 3355833611], - [1719, 121, 18, "Layout/LineLength: Line is too long. [138/120]", 38619260] + [125, 3, 1207, "Metrics/BlockLength: Block has too many lines. [27/25]", 2841005266], + [206, 3, 1550, "Metrics/BlockLength: Block has too many lines. [44/25]", 1381861178], + [257, 3, 1209, "Metrics/BlockLength: Block has too many lines. [33/25]", 1745132505], + [297, 3, 61330, "Metrics/BlockLength: Block has too many lines. [1387/25]", 3444780370], + [693, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5859109], + [1777, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 3355833611], + [1784, 121, 18, "Layout/LineLength: Line is too long. [138/120]", 38619260] + ], + "spec/hash_literal_projector_spec.rb:2425567956": [ + [13, 41, 31, "Lint/PercentStringArray: Within `%w`/`%W`, quotes and ',' are unnecessary and may be unwanted in the resulting strings.", 3214960854] + ], + "spec/rescue_semantics_spec.rb:2518131257": [ + [5, 1, 2150, "Metrics/BlockLength: Block has too many lines. [59/25]", 163524539] ] } diff --git a/gems/ruby-merge/Gemfile b/gems/ruby-merge/Gemfile index fd8817406..bad0e66be 100644 --- a/gems/ruby-merge/Gemfile +++ b/gems/ruby-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/ruby-merge/Gemfile.lock b/gems/ruby-merge/Gemfile.lock index 43b3357fd..9158dc070 100644 --- a/gems/ruby-merge/Gemfile.lock +++ b/gems/ruby-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -399,30 +684,52 @@ DEPENDENCIES rubocop-ruby3_2 (~> 3.0.0) ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -511,6 +832,8 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/ruby-merge/gemfiles/modular/templating.gemfile b/gems/ruby-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/ruby-merge/gemfiles/modular/templating.gemfile +++ b/gems/ruby-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/ruby-merge/gemfiles/modular/templating_local.gemfile b/gems/ruby-merge/gemfiles/modular/templating_local.gemfile index 6c07b8094..a1631fd2e 100644 --- a/gems/ruby-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/ruby-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[ruby-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[ruby-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[ruby-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/ruby-merge/lib/ruby/merge.rb b/gems/ruby-merge/lib/ruby/merge.rb index 3ec79d73f..e10785820 100644 --- a/gems/ruby-merge/lib/ruby/merge.rb +++ b/gems/ruby-merge/lib/ruby/merge.rb @@ -6,6 +6,16 @@ require 'digest' require 'tree_haver' require 'ast/merge' +require_relative 'merge/block_directive_detector' +require_relative 'merge/doc_comment_support' +require_relative 'merge/gemspec_support' +require_relative 'merge/magic_comment_support' +require_relative 'merge/method_similarity' +require_relative 'merge/nocov_node_base' +require_relative 'merge/nocov_wrapper_base' +require_relative 'merge/rescue_semantics' +require_relative 'merge/scaffold_chunk_support' +require_relative 'merge/signature_support' module Ruby module Merge @@ -15,22 +25,36 @@ module Merge TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND DESTINATION_WINS_ARRAY_POLICY = { surface: 'array', name: 'destination_wins_array' }.freeze DEFAULT_METHOD_MOVE_POLICY = 'destination_order' + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) + TslpSpan = Struct.new(:start_row, :start_col, :end_row, :end_col, keyword_init: true) + TslpStructureItem = Struct.new(:kind, :name, :span, keyword_init: true) + TslpImportItem = Struct.new(:source, :span, keyword_init: true) + TslpProcessAnalysis = Struct.new(:structure, :imports, keyword_init: true) PERCENT_ARRAY_DELIMITER_PAIRS = { '[' => ']', '(' => ')', '{' => '}', '<' => '>' }.freeze - DIRECTIVE_LINE = /\A(?::nocov:|[\w-]+:(?:freeze|unfreeze))\z/ - MAGIC_COMMENT_PREFIXES = %w[coding encoding frozen_string_literal shareable_constant_value typed warn_indent].freeze REQUIRE_PATTERN = /^\s*require(?:_relative)?\s+["']([^"']+)["']/ CLASS_PATTERN = /^\s*class\s+([A-Z]\w*(?:::\w+)*)/ MODULE_PATTERN = /^\s*module\s+([A-Z]\w*(?:::\w+)*)/ DEF_PATTERN = %r{^\s*def\s+((?:self\.)?)([a-zA-Z_]\w*[!?=]?|\[\]=?|\+@|-@|\*\*|<<|>>|<=>|===|==|=~|!~|!=|[+\-*/%&|^<>]=?|[!~`])} CONSTANT_ASSIGNMENT_PATTERN = /^(\s*)([A-Z]\w*)\s*=/ CONSTANT_HASH_ASSIGNMENT_PATTERN = /^(\s*)([A-Z]\w*)\s*=\s*\{/ - EXAMPLE_TAG = /\A@example\b(?.*)\z/ - TAG_PREFIX = /\A@[a-z_]+\b/ + + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + + grammar_finder = TreeHaver::GrammarFinder.new(:ruby) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end def ruby_feature_profile { @@ -41,7 +65,7 @@ def ruby_feature_profile end def available_ruby_backends - [TREE_SITTER_BACKEND] + ruby_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end def ruby_tslp_capability_profile @@ -53,7 +77,7 @@ def ruby_tslp_capability_profile def ruby_backend_feature_profile(backend: nil) requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && ruby_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported Ruby backend #{requested}.") end @@ -78,26 +102,33 @@ def ruby_plan_context(backend: nil) } end + def ruby_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == TREE_SITTER_BACKEND.id + + registrations = TreeHaver.registered_languages(:ruby) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end + def parse_ruby(source, dialect, backend: nil) requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s return unsupported_feature_result("Unsupported Ruby dialect #{dialect}.") unless dialect == 'ruby' - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && ruby_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported Ruby backend #{requested}.") end - request = TreeHaver::ParserRequest.new(source: source, language: 'ruby', dialect: dialect) - syntax = TreeHaver.parse_with_language_pack(request) - return { ok: false, diagnostics: syntax[:diagnostics], policies: [] } unless syntax[:ok] - - process = TreeHaver.process_with_language_pack(request) - return { ok: false, diagnostics: process[:diagnostics], policies: [] } unless process[:ok] + tree = TreeHaver.with_backend(requested) { TreeHaver.parser_for(:ruby).parse(source) } + collect_parse_errors(tree.root_node) + process_analysis = ruby_process_analysis_from_tree(source, tree.root_node) { ok: true, diagnostics: [], - analysis: analyze_ruby_document(source, process_analysis: process[:analysis]), + analysis: analyze_ruby_document(source, process_analysis: process_analysis), policies: [] } + rescue TreeHaver::Error, StandardError => e + parse_failure_result(e) end def match_ruby_owners(template, destination) @@ -197,7 +228,7 @@ def merge_ruby(template_source, destination_source, dialect, merge_template_requ end destination_paths = destination_declarations.to_h { |entry| [entry[:merge_key], true] } sections = [] - preamble = collect_ruby_preamble(destination_context.fetch(:source)) + preamble = destination_context.fetch(:preamble) sections << preamble unless preamble.empty? requires = if merge_template_requires merge_ruby_requires(destination_requires, @@ -436,7 +467,7 @@ def ruby_fallback_policy_profile scopes: %w[node subtree owned_region whole_file], triggers: [ { reason: 'binary_input', scope: 'whole_file' }, - { reason: 'unsupported_parser_or_backend', scope: 'whole_file' }, + { reason: 'unsupported_structural_merge_capability', scope: 'whole_file' }, { reason: 'no_structural_owners', scope: 'whole_file' }, { reason: 'both_branches_create_file', scope: 'whole_file' }, { reason: 'excessive_duplicate_identities', scope: 'owned_region' }, @@ -1271,6 +1302,179 @@ def ruby_file_footer_text(source) content.lines.any? { |line| !line.strip.empty? && !comment_line?(line) } ? '' : content end + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'Ruby parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'Ruby parse contains syntax errors' + end + + def parse_failure_result(error) + { + ok: false, + diagnostics: [{ severity: 'error', category: 'parse_error', message: error.message }], + policies: [] + } + end + + def ruby_process_analysis_from_tree(source, root_node) + structure = [] + imports = [] + + ruby_named_children(root_node).each do |node| + case node.type + when 'call' + import = ruby_import_item_from_node(source, node) + imports << import if import + when 'if_modifier' + import = ruby_import_item_from_modifier_node(source, node) + imports << import if import + when 'begin' + import = ruby_import_item_from_begin_node(source, node) + imports << import if import + when 'class', 'module', 'method', 'singleton_method' + item = ruby_structure_item_from_node(source, node) + structure << item if item + end + end + + TslpProcessAnalysis.new(structure: structure, imports: imports) + end + + def ruby_import_item_from_node(source, node) + children = ruby_named_children(node) + callee = children.first + return unless callee && %w[identifier method_identifier].include?(callee.type) + + name = ruby_node_text(source, callee) + return unless %w[require require_relative].include?(name) + + string_node = ruby_first_descendant(node) do |child| + %w[string_content simple_symbol].include?(child.type) + end + return unless string_node + + TslpImportItem.new(source: ruby_node_text(source, string_node), span: ruby_import_span_for(source, node)) + end + + def ruby_import_item_from_modifier_node(source, node) + call_node = ruby_named_children(node).first + return unless call_node&.type == 'call' + + import = ruby_import_item_from_node(source, call_node) + return unless import + + TslpImportItem.new(source: import.source, span: ruby_import_span_for(source, node)) + end + + def ruby_import_item_from_begin_node(source, node) + children = ruby_named_children(node) + call_imports = children.filter_map do |child| + ruby_import_item_from_node(source, child) if child.type == 'call' + end + return if call_imports.empty? + + unsupported = children.any? do |child| + child.type != 'call' && !ruby_load_error_rescue_node?(source, child) + end + return if unsupported + + TslpImportItem.new(source: call_imports.map(&:source).join(','), span: ruby_span_for(node)) + end + + def ruby_load_error_rescue_node?(source, node) + return false unless node.type == 'rescue' + return false unless ruby_named_children(node).all? { |child| child.type == 'exceptions' } + + ruby_node_text(source, node).match?(/\Arescue\s+LoadError\b/) + end + + def ruby_structure_item_from_node(source, node) + kind = case node.type + when 'class' + 'class' + when 'module' + 'module' + when 'method', 'singleton_method' + 'method' + end + return unless kind + + name_node = ruby_declaration_name_node(node) + return unless name_node + + TslpStructureItem.new(kind: kind, name: ruby_node_text(source, name_node), span: ruby_span_for(node)) + end + + def ruby_declaration_name_node(node) + case node.type + when 'class', 'module' + ruby_named_children(node).find do |child| + %w[constant scope_resolution].include?(child.type) + end + when 'method' + ruby_named_children(node).find do |child| + %w[identifier method_identifier operator].include?(child.type) + end + when 'singleton_method' + children = ruby_named_children(node) + children.reverse.find do |child| + %w[identifier method_identifier operator].include?(child.type) + end + end + end + + def ruby_first_descendant(node, &block) + ruby_named_children(node).each do |child| + return child if yield(child) + + descendant = ruby_first_descendant(child, &block) + return descendant if descendant + end + nil + end + + def ruby_named_children(node) + node.children.select { |child| !child.respond_to?(:named?) || child.named? } + end + + def ruby_span_for(node) + start_point = node.start_point + end_point = node.end_point + TslpSpan.new( + start_row: start_point.fetch(:row), + start_col: start_point.fetch(:column), + end_row: end_point.fetch(:row), + end_col: end_point.fetch(:column) + ) + end + + def ruby_import_span_for(source, node) + span = ruby_span_for(node) + lines = normalize_source(source).split("\n") + start_row = span.start_row + end_row = span.end_row + + start_row -= 1 while start_row.positive? && coverage_directive_comment_line?(lines[start_row - 1]) + end_row += 1 while end_row < lines.length - 1 && coverage_directive_comment_line?(lines[end_row + 1]) + + TslpSpan.new( + start_row: start_row, + start_col: start_row == span.start_row ? span.start_col : 0, + end_row: end_row, + end_col: end_row == span.end_row ? span.end_col : lines[end_row].to_s.length + ) + end + + def coverage_directive_comment_line?(line) + BlockDirectiveDetector.coverage_directive_line?(line) + end + + def ruby_node_text(source, node) + source[node.start_byte...node.end_byte].to_s + end + def ruby_fallback_scope_rank(scope) ruby_fallback_policy_profile.fetch(:scopes).index(scope.to_s) || Float::INFINITY end @@ -1311,6 +1515,7 @@ def ruby_tslp_merge_context(analysis, role:) { ok: true, source: source, + preamble: ruby_tslp_file_preamble_text(source, process_analysis), requires: ruby_process_import_entries(source, process_analysis), declarations: collect_ruby_declaration_entries(source, process_analysis: process_analysis), footer: ruby_tslp_file_footer_text(source, process_analysis) @@ -1411,6 +1616,19 @@ def ruby_tslp_file_footer_text(source, process_analysis) lines.values_at(*footer_indexes).join("\n").strip end + def ruby_tslp_file_preamble_text(source, process_analysis) + lines = normalize_source(source).split("\n") + claimed = ruby_tslp_claimed_line_indexes(lines, process_analysis) + preamble_indexes = [] + lines.each_index do |index| + break if claimed.include?(index) + break unless lines[index].strip.empty? || comment_line?(lines[index]) + + preamble_indexes << index + end + lines.values_at(*preamble_indexes).join("\n").strip + end + def collect_ruby_declaration_entries(source, process_analysis: nil) process_entries = ruby_process_declaration_entries(source, process_analysis: process_analysis) return process_entries unless process_entries.empty? @@ -1784,8 +2002,8 @@ def merge_declaration_hash_constants(template_text, destination_text) template_block = template_blocks[destination_block[:constant]] next unless template_block - template_hash = RubyHashLiteralParser.new(template_block[:hash_source]).parse - destination_hash = RubyHashLiteralParser.new(destination_block[:hash_source]).parse + template_hash = RubyHashLiteralProjector.new(template_block[:hash_source]).call + destination_hash = RubyHashLiteralProjector.new(destination_block[:hash_source]).call merged_hash = merge_ruby_hash_literals(template_hash, destination_hash) rendered = "#{destination_block[:prefix]}#{render_ruby_hash_literal(merged_hash, destination_block[:base_indent])}" @@ -2254,130 +2472,183 @@ def compact_region(region) RubyHashPair = Struct.new(:key, :key_source, :delimiter, :value, keyword_init: true) RubyScalarNode = Struct.new(:source, keyword_init: true) - class RubyHashLiteralParser + class RubyHashLiteralProjector def initialize(source) @source = source.to_s - @index = 0 end - def parse - parse_hash.tap do - skip_whitespace - raise ArgumentError, 'unexpected trailing hash literal content' unless eof? - end + def call + tree = TreeHaver.parser_for(:ruby).parse(source) + root = if tree.respond_to?(:parse_result) + tree.parse_result.value + else + tree.root_node + end + hash_node = root_hash_node(root) + raise ArgumentError, 'expected Ruby hash literal' unless hash_node?(hash_node) + + project_hash_node(hash_node) end private attr_reader :source - def parse_hash - start_index = @index - consume('{') - pairs = [] - trailing_comma = false - loop do - skip_whitespace - break if peek == '}' - - key = parse_hash_key - skip_whitespace - value = parse_value - pairs << RubyHashPair.new( + def root_hash_node(root) + return root if hash_node?(root) + return root.statements&.body&.first if root.respond_to?(:statements) + + child_nodes(root).find { |child| hash_node?(child) } + end + + def hash_node?(node) + %w[hash hash_node].include?(node&.type.to_s) + end + + def project_hash_node(node) + pairs = hash_pair_nodes(node).map do |assoc| + key_node, value_node = hash_pair_key_value_nodes(assoc) + key = project_hash_key(key_node, hash_pair_operator(assoc)) + RubyHashPair.new( key: key.fetch(:key), key_source: key.fetch(:key_source), delimiter: key.fetch(:delimiter), - value: value + value: project_hash_value(value_node) ) - skip_whitespace - break if peek == '}' - - consume(',') - skip_whitespace - if peek == '}' - trailing_comma = true - break - end end - consume('}') - RubyHashNode.new(pairs: pairs, inline: !source[start_index...@index].include?("\n"), - trailing_comma: trailing_comma) + RubyHashNode.new( + pairs: pairs, + inline: !node_source(node).include?("\n"), + trailing_comma: trailing_comma?(node) + ) end - def parse_value - skip_whitespace - return parse_hash if peek == '{' + def project_hash_value(node) + return project_hash_node(node) if hash_node?(node) - RubyScalarNode.new(source: parse_scalar_source) + RubyScalarNode.new(source: node_source(node).rstrip) end - def parse_hash_key - remaining = source[@index..].to_s - if (match = remaining.match(/\A([a-zA-Z_]\w*[!?]?):/)) - @index += match[0].length - return { key: match[1], key_source: match[1], delimiter: ':' } + def project_hash_key(key_node, operator) + delimiter = operator.to_s == '=>' ? '=>' : ':' + if delimiter == ':' + { + key: hash_key_value(key_node), + key_source: node_source(key_node).delete_suffix(':'), + delimiter: delimiter + } + elsif %w[symbol_node simple_symbol].include?(key_node.type.to_s) && node_source(key_node).start_with?(':') + { + key: hash_key_value(key_node), + key_source: node_source(key_node), + delimiter: delimiter + } + elsif %w[string_node string].include?(key_node.type.to_s) + { + key: node_source(key_node), + key_source: node_source(key_node), + delimiter: delimiter + } + else + { + key: hash_key_value(key_node), + key_source: node_source(key_node), + delimiter: delimiter + } end + end - if (match = remaining.match(/\A((["'])(?:\\.|(?!\2).)*\2):/)) - @index += match[0].length - return { key: match[1][1...-1], key_source: match[1], delimiter: ':' } - end + def hash_pair_nodes(node) + return Array(node.elements) if node.respond_to?(:elements) - if (match = remaining.match(/\A(:[a-zA-Z_]\w*[!?]?)\s*=>/)) - @index += match[0].length - return { key: match[1].delete_prefix(':'), key_source: match[1], delimiter: '=>' } - end + child_nodes(node).select { |child| child.type.to_s == 'pair' } + end + + def hash_pair_key_value_nodes(pair) + return [pair.key, pair.value] if pair.respond_to?(:key) && pair.respond_to?(:value) - if (match = remaining.match(/\A((["'])(?:\\.|(?!\2).)*\2)\s*=>/)) - @index += match[0].length - return { key: match[1], key_source: match[1], delimiter: '=>' } + named = child_nodes(pair).reject { |child| punctuation_node?(child) } + [named.first, named.last] + end + + def hash_pair_operator(pair) + return pair.operator if pair.respond_to?(:operator) + + all_child_nodes(pair).find { |child| %w[: =>].include?(child.type.to_s) }&.type + end + + def hash_key_value(node) + return node.unescaped.to_s if node.respond_to?(:unescaped) + + text = node_source(node) + return text.delete_prefix(':') if text.start_with?(':') + return text[1...-1] if node.type.to_s == 'string' && text.match?(/\A(["']).*\1\z/m) + + text + end + + def trailing_comma?(node) + if node.respond_to?(:elements) && node.respond_to?(:closing_loc) + return trailing_comma_between?(last_child_end: Array(node.elements).last.location.end_offset, + closing_start: node.closing_loc.start_offset) end - raise ArgumentError, 'expected hash key' + last_pair = hash_pair_nodes(node).last + closing = all_child_nodes(node).reverse.find { |child| child.type.to_s == '}' } + return false unless last_pair && closing + + trailing_comma_between?(last_child_end: node_end_offset(last_pair), closing_start: node_start_offset(closing)) end - def parse_scalar_source - start_index = @index - string_quote = nil - escape = false - while @index < source.length - char = source[@index] - if string_quote - if escape - escape = false - elsif char == '\\' - escape = true - elsif char == string_quote - string_quote = nil - end - @index += 1 - next - end + def trailing_comma_between?(last_child_end:, closing_start:) + source.byteslice(last_child_end...closing_start).to_s.include?(',') + end - break if [',', '}'].include?(char) + def child_nodes(node) + if node.respond_to?(:compact_child_nodes) + node.compact_child_nodes + elsif node.respond_to?(:named_children) + node.named_children + elsif node.respond_to?(:children) + node.children + else + [] + end + end - string_quote = char if ['"', "'"].include?(char) - @index += 1 + def all_child_nodes(node) + if node.respond_to?(:compact_child_nodes) + node.compact_child_nodes + elsif node.respond_to?(:children) + node.children + else + child_nodes(node) end - source[start_index...@index].rstrip end - def skip_whitespace - @index += 1 while @index < source.length && source[@index].match?(/\s/) + def punctuation_node?(node) + %w[{ } : => ,].include?(node.type.to_s) end - def consume(expected) - raise ArgumentError, "expected #{expected}" unless peek == expected + def node_source(node) + return node.slice.to_s if node.respond_to?(:slice) + return node.text.to_s if node.respond_to?(:text) - @index += 1 + source.byteslice(node_start_offset(node)...node_end_offset(node)).to_s end - def peek - source[@index] + def node_start_offset(node) + return node.location.start_offset if node.respond_to?(:location) + return node.start_byte if node.respond_to?(:start_byte) + + raise ArgumentError, 'Ruby hash node does not expose a start offset' end - def eof? - @index >= source.length + def node_end_offset(node) + return node.location.end_offset if node.respond_to?(:location) + return node.end_byte if node.respond_to?(:end_byte) + + raise ArgumentError, 'Ruby hash node does not expose an end offset' end end @@ -2505,7 +2776,7 @@ def direct_body_method_entries(text) finish_index = ruby_block_finish_index(lines, index) entries << { name: match[2], - signature: "#{match[1]}#{match[2]}", + signature: SignatureSupport.textual_method_signature(match[1], match[2]), visibility: current_visibility, text: lines[start_index..finish_index].join("\n").rstrip, body_text: lines[(pending_comments.first || index)..finish_index].join("\n").rstrip @@ -2818,7 +3089,7 @@ def declaration_for_line(line) elsif (match = MODULE_PATTERN.match(line)) { kind: 'module', name: match[1] } elsif (match = DEF_PATTERN.match(line)) - { kind: 'def', name: match[2], signature: "#{match[1]}#{match[2]}" } + { kind: 'def', name: match[2], signature: SignatureSupport.textual_method_signature(match[1], match[2]) } end end @@ -2882,33 +3153,22 @@ def surfaces_for_owner(owner_name:, comment_entries:) def example_surfaces_for(surface) entries = Array(surface.dig(:metadata, :entries)) - normalized = entries.map { |entry| normalize_comment_content(entry[:raw]) } - - normalized.each_with_index.filter_map do |content, tag_index| - match = EXAMPLE_TAG.match(content) - next unless match - - body_start = tag_index + 1 - body_end = next_tag_index(normalized, body_start) || normalized.length - next if body_start >= body_end - - body_entries = entries[body_start...body_end] - next if body_entries.nil? || body_entries.empty? - - declared_language = declared_example_language(match[:rest]) || 'ruby' + DocCommentSupport.example_blocks(entries).map do |block| + body_entries = block.fetch(:body_entries) + declared_language = block.fetch(:declared_language) || 'ruby' Ast::Merge.discovered_surface( surface_kind: 'yard_example_block', declared_language: declared_language, effective_language: declared_language, - address: "#{surface[:address]} > yard_example[#{tag_index}]", + address: "#{surface[:address]} > yard_example[#{block.fetch(:tag_index)}]", parent_address: surface[:address], owner: Ast::Merge.surface_owner_ref(kind: 'owned_region', address: surface[:address]), span: Ast::Merge.surface_span(start_line: body_entries.first[:line], end_line: body_entries.last[:line]), reconstruction_strategy: 'rewrite_with_prefix_preservation', metadata: { tag_kind: 'example', - tag_index: tag_index, - tag_text: normalized[tag_index], + tag_index: block.fetch(:tag_index), + tag_text: block.fetch(:tag_text), comment_prefix: surface.dig(:metadata, :comment_prefix) } ) @@ -2916,11 +3176,7 @@ def example_surfaces_for(surface) end def next_tag_index(normalized_lines, start_index) - normalized_lines.each_with_index do |content, index| - next if index < start_index - return index if TAG_PREFIX.match?(content) - end - nil + DocCommentSupport.next_tag_index(normalized_lines, start_index) end def normalize_source(source) @@ -2928,28 +3184,19 @@ def normalize_source(source) end def normalize_comment_content(raw) - raw.to_s.sub(/\A\s*#\s?/, '').strip + DocCommentSupport.normalize_comment_content(raw) end def doc_comment_content?(raw) - content = normalize_comment_content(raw) - return false if content.empty? - return false if DIRECTIVE_LINE.match?(content) - return false if MAGIC_COMMENT_PREFIXES.any? { |prefix| content.start_with?("#{prefix}:") } - - true + DocCommentSupport.doc_comment_content?(raw) end def comment_prefix_for(raw) - raw.to_s[/\A\s*#\s*/] || '# ' + DocCommentSupport.comment_prefix_for(raw) end def declared_example_language(rest) - match = rest.to_s.strip.match(/\A\[(?[^\]]+)\]/) - language = match && match[:language] - return if language.nil? || language.empty? - - language.downcase.tr('-', '_') + DocCommentSupport.declared_example_language(rest) end module_function( @@ -2978,6 +3225,8 @@ def declared_example_language(rest) end end +Ruby::Merge.register_backend! + TreeHaver::BackendRegistry.register_tag( :tslp_ruby_import_records, category: :capability, diff --git a/gems/ruby-merge/lib/ruby/merge/block_directive_detector.rb b/gems/ruby-merge/lib/ruby/merge/block_directive_detector.rb new file mode 100644 index 000000000..e6c006ac2 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/block_directive_detector.rb @@ -0,0 +1,208 @@ +# frozen_string_literal: true + +module Ruby + module Merge + # Detects Ruby comment block directive pairs in source lines. + # + # This is Ruby-specific substrate behavior shared by Ruby parser providers. + # Parser-specific gems may consume the spans and project them into their own + # node types, but directive token semantics should live here. + class BlockDirectiveDetector + Span = Struct.new(:kind, :start_line, :end_line, :open_marker, :close_marker, keyword_init: true) + + NOCOV_TOKEN = ':nocov:' + SIMPLECOV_DISABLE_RE = /\A\s*#\s*simplecov\s*:\s*disable\b/i + SIMPLECOV_ENABLE_RE = /\A\s*#\s*simplecov\s*:\s*enable\b/i + DIRECTIVE_CONTENT_RE = /\A(?::nocov:|[\w-]+:(?:freeze|unfreeze))\z/i + + class << self + def coverage_directive_line?(line, nocov_token: NOCOV_TOKEN) + stripped = line.to_s.chomp + stripped.match?(simplecov_disable_re) || + stripped.match?(simplecov_enable_re) || + stripped.match?(nocov_re(nocov_token)) + end + + def directive_content?(content) + DIRECTIVE_CONTENT_RE.match?(content.to_s.strip) || + coverage_directive_line?("# #{content}") + end + + def simplecov_disable_re + SIMPLECOV_DISABLE_RE + end + + def simplecov_enable_re + SIMPLECOV_ENABLE_RE + end + + def nocov_re(nocov_token = NOCOV_TOKEN) + /\A\s*#\s?#{Regexp.escape(nocov_token)}\s*\z/i + end + end + + def initialize(lines, freeze_token: nil, nocov_token: NOCOV_TOKEN, source_label: nil) + @lines = lines + @freeze_token = freeze_token + @nocov_token = nocov_token + @source_label = source_label + end + + def detect_spans + raw_spans = [] + raw_spans.concat(detect_freeze_spans) if @freeze_token + raw_spans.concat(detect_nocov_spans) + + validate_no_crossing(raw_spans.sort_by(&:start_line)) + end + + private + + def detector_name + 'ruby-merge' + end + + def directive_error_class + Ast::Merge::Error + end + + def warn_prefix + if @source_label + "[#{detector_name}] BlockDirectiveDetector (#{@source_label}):" + else + "[#{detector_name}] BlockDirectiveDetector:" + end + end + + def report_unbalanced(message) + raise directive_error_class, "#{warn_prefix} #{message}" if @source_label + + warn("#{warn_prefix} #{message} - ignoring") + end + + def detect_freeze_spans + freeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:freeze\b/i + unfreeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:unfreeze\b/i + + spans = [] + stack = [] + + @lines.each_with_index do |line, index| + line_num = index + 1 + stripped = line.to_s.chomp + if stripped.match?(freeze_pat) + stack.push({ start_line: line_num, open_marker: stripped }) + elsif stripped.match?(unfreeze_pat) + if (open = stack.pop) + spans << Span.new( + kind: :freeze, + start_line: open[:start_line], + end_line: line_num, + open_marker: open[:open_marker], + close_marker: stripped + ) + else + report_unbalanced("unmatched #{@freeze_token}:unfreeze at line #{line_num}") + end + end + end + + stack.each do |open| + report_unbalanced("unclosed #{@freeze_token}:freeze at line #{open[:start_line]}") + end + + spans + end + + def detect_nocov_spans + return [] unless @nocov_token + + nocov_pat = self.class.nocov_re(@nocov_token) + + spans = [] + stack = [] + + @lines.each_with_index do |line, index| + line_num = index + 1 + stripped = line.to_s.chomp + if stripped.match?(self.class.simplecov_disable_re) + stack.push({ start_line: line_num, open_marker: stripped }) + elsif stripped.match?(self.class.simplecov_enable_re) + if (open = stack.pop) + spans << Span.new( + kind: :nocov, + start_line: open[:start_line], + end_line: line_num, + open_marker: open[:open_marker], + close_marker: stripped + ) + else + report_unbalanced("unmatched simplecov:enable at line #{line_num}") + end + elsif stripped.match?(nocov_pat) + if stack.empty? + stack.push({ start_line: line_num, open_marker: stripped }) + else + open = stack.pop + spans << Span.new( + kind: :nocov, + start_line: open[:start_line], + end_line: line_num, + open_marker: open[:open_marker], + close_marker: stripped + ) + end + end + end + + stack.each do |open| + report_unbalanced("unclosed coverage directive at line #{open[:start_line]}") + end + + spans + end + + def validate_no_crossing(spans) + valid = [] + invalid_indices = Set.new + + spans.each_with_index do |first, first_index| + next if invalid_indices.include?(first_index) + + crossing = false + spans.each_with_index do |second, second_index| + next if first_index == second_index || invalid_indices.include?(second_index) + next unless crossing_spans?(first, second) + + report_unbalanced("offset-overlapping #{first.kind} block " \ + "(lines #{first.start_line}..#{first.end_line}) and #{second.kind} block " \ + "(lines #{second.start_line}..#{second.end_line}) - both treated as plain comments") + invalid_indices.add(first_index) + invalid_indices.add(second_index) + crossing = true + break + end + + valid << first unless crossing + end + + valid + end + + def crossing_spans?(first, second) + (first.start_line < second.start_line && first.end_line > second.start_line && first.end_line < second.end_line) || + (second.start_line < first.start_line && second.end_line > first.start_line && second.end_line < first.end_line) + end + + def top_level_spans_only(spans) + spans.reject do |span| + spans.any? do |other| + other != span && + other.start_line <= span.start_line && + other.end_line >= span.end_line + end + end + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/doc_comment_support.rb b/gems/ruby-merge/lib/ruby/merge/doc_comment_support.rb new file mode 100644 index 000000000..ee7edcba8 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/doc_comment_support.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Ruby + module Merge + # Ruby-specific doc-comment semantics shared by Ruby parser providers. + module DocCommentSupport + TAG_PREFIX = /\A@[a-z_]+\b/ + EXAMPLE_TAG = /\A@example\b(?.*)\z/ + MAGIC_COMMENT_PREFIXES = %w[ + coding + encoding + frozen_string_literal + shareable_constant_value + typed + warn_indent + ].freeze + + module_function + + def normalize_comment_content(raw) + raw.to_s.sub(/\A\s*#\s?/, '').strip + end + + def comment_prefix_for(raw) + raw.to_s[/\A\s*#\s*/] || '# ' + end + + def doc_comment_content?(raw, magic_comment: false) + content = normalize_comment_content(raw) + return false if content.empty? + return false if BlockDirectiveDetector.directive_content?(content) + return false if magic_comment || magic_comment_content?(content) + + true + end + + def magic_comment_content?(content) + MAGIC_COMMENT_PREFIXES.any? { |prefix| content.to_s.start_with?("#{prefix}:") } + end + + def declared_example_language(rest) + match = rest.to_s.strip.match(/\A\[(?[^\]]+)\]/) + normalize_language(match && match[:language]) + end + + def declared_example_language_for_tag(content) + match = EXAMPLE_TAG.match(content.to_s) + return unless match + + declared_example_language(match[:rest]) + end + + def normalize_language(language) + return if language.nil? + + normalized = language.to_s.strip.downcase.tr('-', '_') + return if normalized.empty? + + normalized + end + + def next_tag_index(normalized_lines, start_index) + normalized_lines.each_with_index do |content, index| + next if index < start_index + + return index if TAG_PREFIX.match?(content) + end + nil + end + + def example_blocks(entries) + normalized = entries.map { |entry| normalize_comment_content(entry[:raw]) } + normalized.each_with_index.filter_map do |content, tag_index| + match = EXAMPLE_TAG.match(content) + next unless match + + body_start_index = tag_index + 1 + body_end_index = next_tag_index(normalized, body_start_index) || normalized.length + next if body_start_index >= body_end_index + + body_entries = entries[body_start_index...body_end_index] + next if body_entries.nil? || body_entries.empty? + + { + tag_index: tag_index, + tag_line: entries[tag_index][:line], + tag_text: normalized[tag_index], + body_start_index: body_start_index, + body_end_index: body_end_index, + body_entries: body_entries, + declared_language: declared_example_language(match[:rest]) + } + end + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/gemspec_support.rb b/gems/ruby-merge/lib/ruby/merge/gemspec_support.rb new file mode 100644 index 000000000..af60fe272 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/gemspec_support.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Ruby + module Merge + module GemspecSupport + GEMSPEC_VAR_PLACEHOLDER = :__gemspec_var__ + + module_function + + def effective_receiver(receiver, gemspec_block_var) + if gemspec_block_var && receiver == gemspec_block_var + GEMSPEC_VAR_PLACEHOLDER + else + receiver + end + end + + def preferred_block_var(template_var, dest_var) + template_var if template_var && dest_var && template_var != dest_var + end + + def merged_block_var(var, preferred_var) + preferred_var || var + end + + def opening_line_with_preferred_block_var(opening_line, dest_var:, preferred_var:, node_preference:) + return opening_line unless preferred_var && dest_var && dest_var != preferred_var + return opening_line unless node_preference == :destination + + opening_line.sub("|#{dest_var}|", "|#{preferred_var}|") + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/magic_comment_support.rb b/gems/ruby-merge/lib/ruby/merge/magic_comment_support.rb new file mode 100644 index 000000000..f6b8ecb96 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/magic_comment_support.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +module Ruby + module Merge + # Ruby magic comment detection and file-header prefix handling. + module MagicCommentSupport + MAGIC_COMMENT_PATTERNS = { + frozen_string_literal: /^frozen_string_literal:\s*(true|false)$/i, + encoding: /^(encoding|coding):\s*\S+$/i, + warn_indent: /^warn_indent:\s*(true|false)$/i, + shareable_constant_value: /^shareable_constant_value:\s*\S+$/i + }.freeze + + module_function + + def magic_comment_type_for_text(text) + stripped = DocCommentSupport.normalize_comment_content(text) + + MAGIC_COMMENT_PATTERNS.each do |type, pattern| + return type if stripped.match?(pattern) + end + + nil + end + + def comment_only_prefix_info(lines) + entries = [] + suppressed_line_nums = Set.new + duplicate_magic_line_nums = Set.new + + if shebang_line?(lines.first) + entries << { line_num: 1, text: lines.first.to_s, kind: :shebang } + suppressed_line_nums << 1 + end + + header_magic_types = header_magic_comment_types_for_lines(lines) + seen_magic_types = Set.new + + header_magic_types.keys.sort.each do |line_num| + magic_type = header_magic_types[line_num] + suppressed_line_nums << line_num + entries << { line_num: line_num, text: lines[line_num - 1].to_s.chomp, kind: :magic } + + if seen_magic_types.include?(magic_type) + duplicate_magic_line_nums << line_num + else + seen_magic_types << magic_type + end + end + + if header_magic_types.any? + blank_line_num = header_magic_types.keys.max + 1 + + while blank_line_num <= lines.length && lines[blank_line_num - 1].to_s.rstrip.empty? + entries << { line_num: blank_line_num, text: lines[blank_line_num - 1].to_s, kind: :blank } + suppressed_line_nums << blank_line_num + blank_line_num += 1 + end + end + + { + entries: entries, + suppressed_line_nums: suppressed_line_nums, + duplicate_magic_line_nums: duplicate_magic_line_nums, + header_magic_comment_types: header_magic_types + } + end + + def header_magic_comment_types_for_lines(lines) + types = {} + index = shebang_line?(lines.first) ? 1 : 0 + previous_line_num = shebang_line?(lines.first) ? 1 : nil + + while index < lines.length + line_num = index + 1 + stripped = lines[index].to_s.rstrip + break if stripped.empty? + + expected_line_num = previous_line_num ? previous_line_num + 1 : 1 + break unless line_num == expected_line_num + + magic_type = magic_comment_type_for_text(stripped) + break unless magic_type + + types[line_num] = magic_type + previous_line_num = line_num + index += 1 + end + + types + end + + def prefix_comment_line_numbers_for_comments(comments) + prefix_line_nums = Set.new + previous_line_num = nil + index = 0 + + if shebang_comment?(comments.first) + prefix_line_nums << 1 + previous_line_num = 1 + index = 1 + end + + while index < comments.length + comment = comments[index] + line_num = comment.location.start_line + expected_line_num = previous_line_num ? previous_line_num + 1 : 1 + break unless line_num == expected_line_num + break unless magic_comment_type_for_text(comment.slice) + + prefix_line_nums << line_num + previous_line_num = line_num + index += 1 + end + + prefix_line_nums + end + + def shebang_line?(line) + line.to_s.start_with?('#!') + end + + def shebang_comment?(comment) + comment&.slice&.start_with?('#!') + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/method_similarity.rb b/gems/ruby-merge/lib/ruby/merge/method_similarity.rb new file mode 100644 index 000000000..8c043068e --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/method_similarity.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Ruby + module Merge + class MethodSimilarity + DEFAULT_NAME_WEIGHT = 0.7 + DEFAULT_PARAMS_WEIGHT = 0.3 + + attr_reader :name_weight, :params_weight + + def initialize(name_weight: DEFAULT_NAME_WEIGHT, params_weight: DEFAULT_PARAMS_WEIGHT) + @name_weight = name_weight + @params_weight = params_weight + end + + def call(template_name:, template_params:, dest_name:, dest_params:) + name_score = string_similarity(template_name.to_s, dest_name.to_s) + param_score = param_similarity(Array(template_params), Array(dest_params)) + + (name_score * name_weight) + (param_score * params_weight) + end + + def param_similarity(template_params, dest_params) + return 1.0 if template_params.empty? && dest_params.empty? + return 0.0 if template_params.empty? || dest_params.empty? + + common = (template_params & dest_params).size + total = [template_params.size, dest_params.size].max + count_ratio = [template_params.size, dest_params.size].min.to_f / total + name_match_ratio = common.to_f / total + + (name_match_ratio * 0.7) + (count_ratio * 0.3) + end + + def string_similarity(str1, str2) + return 1.0 if str1 == str2 + return 0.0 if str1.empty? || str2.empty? + + distance = levenshtein_distance(str1, str2) + max_len = [str1.length, str2.length].max + + 1.0 - (distance.to_f / max_len) + end + + def levenshtein_distance(str1, str2) + return str2.length if str1.empty? + return str1.length if str2.empty? + + str1, str2 = str2, str1 if str1.length > str2.length + + m = str1.length + n = str2.length + previous_row = (0..m).to_a + current_row = Array.new(m + 1, 0) + + (1..n).each do |j| + current_row[0] = j + + (1..m).each do |i| + cost = str1[i - 1] == str2[j - 1] ? 0 : 1 + current_row[i] = [ + previous_row[i] + 1, + current_row[i - 1] + 1, + previous_row[i - 1] + cost + ].min + end + + previous_row, current_row = current_row, previous_row + end + + previous_row[m] + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/nocov_node_base.rb b/gems/ruby-merge/lib/ruby/merge/nocov_node_base.rb new file mode 100644 index 000000000..71bc0a7e0 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/nocov_node_base.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Ruby + module Merge + # Shared Ruby synthetic node for a balanced coverage-exclusion block. + # + # Parser-specific merge gems subclass this when they need native AST location + # or comment attachment behavior. The structural Ruby semantics live here: + # nocov blocks follow file preference and match by their inner content. + class NocovNodeBase + include Ast::Merge::BlockDirective + + InvalidStructureError = Class.new(StandardError) + + Location = Struct.new(:start_line, :end_line) do + def cover?(line) + (start_line..end_line).cover?(line) + end + end + + attr_reader :start_line, :end_line, :nodes, :analysis, :start_marker, :close_marker + + def initialize(start_line:, end_line:, analysis:, nodes: [], start_marker: nil, close_marker: nil) + @start_line = start_line + @end_line = end_line + @analysis = analysis + @nodes = nodes + @start_marker = start_marker + @close_marker = close_marker + end + + def kind = :nocov + + def children = @nodes + + def merge_policy = nil + + def location + @location ||= Location.new(@start_line, @end_line) + end + + def slice + return unless @analysis + + lines = @analysis.lines + return unless lines + + lines[(@start_line - 1)..(@end_line - 1)]&.join + end + + def signature + return [:NocovNode, nil] if @nodes.empty? || @analysis.nil? + + if @nodes.length == 1 + @analysis.generate_signature(@nodes.first) + else + inner_lines = @analysis.lines && @analysis.lines[@start_line..(@end_line - 2)] + [:nocov_multi, inner_lines&.map(&:strip)&.join("\n")] + end + end + + def merge_type = :nocov_block + + alias type merge_type + + def nocov_node? = true + + def inspect + "#<#{self.class} lines=#{@start_line}..#{@end_line} nodes=#{@nodes.length}>" + end + + alias to_s inspect + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/nocov_wrapper_base.rb b/gems/ruby-merge/lib/ruby/merge/nocov_wrapper_base.rb new file mode 100644 index 000000000..7618f52ab --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/nocov_wrapper_base.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Ruby + module Merge + # Shared Ruby wrapper for nodes carrying unbalanced or inline nocov markers. + # + # The wrapped parser node remains responsible for structural identity; this + # wrapper only marks it as a Ruby coverage directive participant. + class NocovWrapperBase + include Ast::Merge::BlockDirective + + attr_reader :node, :merge_type + + def initialize(node, merge_type = :nocov) + @node = node + @merge_type = merge_type + end + + def kind = :nocov + def children = [] + def merge_policy = nil + + def start_line + @node.location&.start_line + end + + def end_line + @node.location&.end_line + end + + def unwrap = @node + + def location = @node.location + + def slice = @node.slice + + def nocov_wrapper? = true + def nocov_node? = false + def block_directive? = true + + def inspect + "#<#{self.class} merge_type=#{@merge_type.inspect} node=#{@node.inspect}>" + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/rescue_semantics.rb b/gems/ruby-merge/lib/ruby/merge/rescue_semantics.rb new file mode 100644 index 000000000..84f9577dd --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/rescue_semantics.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true + +module Ruby + module Merge + class RescueSemantics + def initialize(source_defined_exception_definitions: []) + @source_defined_exception_definitions = source_defined_exception_definitions + end + + def merge_ordered_clause_types(primary_types, secondary_types) + ordered = primary_types.dup + + secondary_types.each_with_index do |clause_type, secondary_index| + next if ordered.include?(clause_type) + + previous_shared = secondary_types[0...secondary_index].reverse.find { |type| ordered.include?(type) } + next_shared = secondary_types[(secondary_index + 1)..]&.find { |type| ordered.include?(type) } + + if previous_shared + insert_at = ordered.index(previous_shared) + 1 + ordered.insert(insert_at, clause_type) + elsif next_shared + insert_at = ordered.index(next_shared) + ordered.insert(insert_at, clause_type) + else + ordered << clause_type + end + end + + ordered + end + + def canonicalize_rescue_clause_order(clause_types) + rescue_clause_types = clause_types.select { |clause_type| rescue_clause_type?(clause_type) } + return clause_types if rescue_clause_types.length < 2 + + ordered_rescue_types = rescue_clause_types.dup + + if rescue_clause_types.any? { |clause_type| broad_rescue_clause_type?(clause_type) } && + rescue_clause_types.any? { |clause_type| !broad_rescue_clause_type?(clause_type) } + specific_rescue_types = ordered_rescue_types.reject { |clause_type| broad_rescue_clause_type?(clause_type) } + broad_rescue_types = ordered_rescue_types.select { |clause_type| broad_rescue_clause_type?(clause_type) } + ordered_rescue_types = specific_rescue_types + broad_rescue_types + end + + loop do + swapped = false + + (0...(ordered_rescue_types.length - 1)).each do |index| + left_clause_type = ordered_rescue_types[index] + right_clause_type = ordered_rescue_types[index + 1] + next unless broader_rescue_clause_type_than?(left_clause_type, right_clause_type) + + ordered_rescue_types[index] = right_clause_type + ordered_rescue_types[index + 1] = left_clause_type + swapped = true + end + + break unless swapped + end + + clause_types.map do |clause_type| + rescue_clause_type?(clause_type) ? ordered_rescue_types.shift : clause_type + end + end + + def canonicalize_begin_clause_kind_order(clause_types) + clause_types.each_with_index + .sort_by { |(clause_type, index)| [clause_kind_sort_key(clause_type), index] } + .map(&:first) + end + + def rescue_clause_signature(exception_names) + normalized_exceptions = Array(exception_names).filter_map { |exception| normalize_exception_name(exception) } + if normalized_exceptions.empty? || normalized_exceptions == ['StandardError'] + [:standard_error] + else + normalized_exceptions.sort + end + end + + def rescue_clause_type?(clause_type) + clause_type.is_a?(Array) && clause_type.first == :rescue_clause + end + + def broad_rescue_clause_type?(clause_type) + rescue_clause_type?(clause_type) && clause_type[1] == [:standard_error] + end + + def clause_kind_sort_key(clause_type) + return 0 if rescue_clause_type?(clause_type) + return 1 if clause_type == :else_clause + return 2 if clause_type == :ensure_clause + + 3 + end + + def normalize_exception_name(exception_name) + return 'StandardError' if exception_name == :standard_error + + name = exception_name.to_s.sub(/\A::/, '') + name.empty? ? nil : name + end + + def qualify_source_constant_name(constant_name, namespace = nil) + normalized_name = normalize_exception_name(constant_name) + return if normalized_name.nil? + return normalized_name if constant_name.to_s.start_with?('::') || namespace.nil? || namespace.empty? + + "#{namespace}::#{normalized_name}" + end + + def source_defined_exception_hierarchy + @source_defined_exception_hierarchy ||= begin + definitions = @source_defined_exception_definitions + defined_names = definitions.map { |definition| definition[:name] }.compact.to_set + + definitions.each_with_object({}) do |definition, hierarchy| + next unless definition[:name] && definition[:superclass] + + superclass_name = if definition[:superclass].to_s.start_with?('::') + normalize_exception_name(definition[:superclass]) + else + candidate_name = qualify_source_constant_name(definition[:superclass], + definition[:namespace]) + defined_names.include?(candidate_name) ? candidate_name : normalize_exception_name(definition[:superclass]) + end + + hierarchy[definition[:name]] ||= superclass_name if superclass_name + end + end + end + + def resolve_exception_constant(exception_name) + return ::StandardError if exception_name == :standard_error + return unless exception_name.is_a?(String) && !exception_name.empty? + + exception_name.split('::').reject(&:empty?).inject(Object) { |scope, const_name| scope.const_get(const_name) } + rescue NameError + nil + end + + def rescue_clause_exception_names(clause_type) + return [] unless rescue_clause_type?(clause_type) + + Array(clause_type[1]).filter_map { |exception_name| normalize_exception_name(exception_name) } + end + + def rescue_clause_exception_constants(clause_type) + rescue_clause_exception_names(clause_type).filter_map do |exception_name| + resolve_exception_constant(exception_name) + end + end + + def exception_constant_covers?(covering_constant, covered_constant) + return true if covering_constant == covered_constant + + covered_constant < covering_constant + rescue StandardError + false + end + + def source_defined_exception_covers?(covering_name, covered_name) + normalized_covering = normalize_exception_name(covering_name) + current_name = normalize_exception_name(covered_name) + return false if normalized_covering.nil? || current_name.nil? + return true if normalized_covering == current_name + + while (current_name = source_defined_exception_hierarchy[current_name]) + return true if current_name == normalized_covering + end + + false + end + + def exception_name_covers?(covering_name, covered_name) + covering_constant = resolve_exception_constant(covering_name) + covered_constant = resolve_exception_constant(covered_name) + + if covering_constant && covered_constant + exception_constant_covers?(covering_constant, covered_constant) + else + source_defined_exception_covers?(covering_name, covered_name) + end + end + + def rescue_clause_covers?(covering_clause_type, covered_clause_type) + return false unless rescue_clause_type?(covering_clause_type) && rescue_clause_type?(covered_clause_type) + + covering_names = rescue_clause_exception_names(covering_clause_type) + covered_names = rescue_clause_exception_names(covered_clause_type) + return false if covering_names.empty? || covered_names.empty? + + covered_names.all? do |covered_name| + covering_names.any? do |covering_name| + exception_name_covers?(covering_name, covered_name) + end + end + end + + def broader_rescue_clause_type_than?(left_clause_type, right_clause_type) + return false unless rescue_clause_type?(left_clause_type) && rescue_clause_type?(right_clause_type) + + rescue_clause_covers?(left_clause_type, right_clause_type) && + !rescue_clause_covers?(right_clause_type, left_clause_type) + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/scaffold_chunk_support.rb b/gems/ruby-merge/lib/ruby/merge/scaffold_chunk_support.rb new file mode 100644 index 000000000..09415b013 --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/scaffold_chunk_support.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module Ruby + module Merge + module ScaffoldChunkSupport + ChunkSpec = Struct.new( + :anchor_type, + :anchor_value, + :satellite_patterns, + :jaccard_threshold, + :max_lookahead, + :max_lookbehind, + keyword_init: true + ) + + BUNDLER_GEM_TASKS_SPEC = ChunkSpec.new( + anchor_type: :require_call, + anchor_value: 'bundler/gem_tasks', + satellite_patterns: [], + jaccard_threshold: 0.35, + max_lookahead: 0, + max_lookbehind: 0 + ) + + RSPEC_SPEC = ChunkSpec.new( + anchor_type: :require_call, + anchor_value: 'rspec/core/rake_task', + satellite_patterns: ['RSpec::Core::RakeTask.new'], + jaccard_threshold: 0.35, + max_lookahead: 5, + max_lookbehind: 2 + ) + + RUBOCOP_SPEC = ChunkSpec.new( + anchor_type: :require_call, + anchor_value: 'rubocop/rake_task', + satellite_patterns: ['RuboCop::RakeTask.new'], + jaccard_threshold: 0.35, + max_lookahead: 5, + max_lookbehind: 2 + ) + + DEFAULT_TASK_SPEC = ChunkSpec.new( + anchor_type: :task_call, + anchor_value: 'default', + satellite_patterns: [], + jaccard_threshold: 0.35, + max_lookahead: 0, + max_lookbehind: 0 + ) + + ALL_SPECS = [BUNDLER_GEM_TASKS_SPEC, RSPEC_SPEC, RUBOCOP_SPEC, DEFAULT_TASK_SPEC].freeze + + module_function + + def jaccard_tokens(text) + text.scan(/[A-Za-z0-9_]+/).to_set + end + + def jaccard(a_set, b_set) + union = a_set | b_set + return 0.0 if union.empty? + + (a_set & b_set).size.to_f / union.size + end + + def task_anchor_match?(source, anchor_value, threshold) + node_tokens = jaccard_tokens(source.to_s) + pattern_tokens = jaccard_tokens("task #{anchor_value}") + jaccard(pattern_tokens, node_tokens) >= threshold + end + end + end +end diff --git a/gems/ruby-merge/lib/ruby/merge/signature_support.rb b/gems/ruby-merge/lib/ruby/merge/signature_support.rb new file mode 100644 index 000000000..59afd4fae --- /dev/null +++ b/gems/ruby-merge/lib/ruby/merge/signature_support.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Ruby + module Merge + module SignatureSupport + module_function + + def method_definition(name, params) + [:def, name, Array(params)] + end + + def class_definition(constant_path) + [:class, constant_path] + end + + def module_definition(constant_path) + [:module, constant_path] + end + + def singleton_class(expression) + [:singleton_class, expression] + end + + def constant(name) + [:const, name] + end + + def variable_assignment(kind, name) + [kind, name] + end + + def multi_write(targets) + [:multi_write, Array(targets)] + end + + def conditional(kind, predicate) + [kind, predicate] + end + + def case_statement(predicate) + [:case, predicate || ''] + end + + def case_match_statement(predicate) + [:case_match, predicate || ''] + end + + def loop_statement(kind, *parts) + [kind, *parts] + end + + def begin_block(first_statement_preview) + [:begin, first_statement_preview || ''] + end + + def call(method_name, identifier, block: false) + [block ? :call_with_block : :call, method_name, identifier] + end + + def super_call(block:) + [:super, block ? :with_block : :no_block] + end + + def forwarding_super_call(block:) + [:forwarding_super, block ? :with_block : :no_block] + end + + def call_operator_write(write_name, receiver) + [:call_op_write, write_name, receiver] + end + + def lambda_literal(parameters_source) + [:lambda, parameters_source || ''] + end + + def execution_block(kind, line_number) + [kind, line_number] + end + + def parenthesized(first_expression_preview) + [:parens, first_expression_preview || ''] + end + + def embedded(statements_source) + [:embedded, statements_source || ''] + end + + def other(class_name, line_number) + [:other, class_name, line_number] + end + + def textual_method_signature(receiver_prefix, method_name) + "#{receiver_prefix}#{method_name}" + end + end + end +end diff --git a/gems/ruby-merge/spec/fixtures_integration_spec.rb b/gems/ruby-merge/spec/fixtures_integration_spec.rb index bc4abf412..67f20b0af 100644 --- a/gems/ruby-merge/spec/fixtures_integration_spec.rb +++ b/gems/ruby-merge/spec/fixtures_integration_spec.rb @@ -53,6 +53,75 @@ def expect_unsupported_ruby_merge(result) ) end + it 'detects Ruby coverage directive spans in the shared substrate detector' do + spans = Ruby::Merge::BlockDirectiveDetector.new( + [ + "# simplecov:disable\n", + "puts 'hidden'\n", + "# simplecov:enable\n", + "# :nocov:\n", + "puts 'legacy hidden'\n", + "# :nocov:\n" + ] + ).detect_spans + + expect(spans.map { |span| [span.kind, span.start_line, span.end_line] }).to eq( + [[:nocov, 1, 3], [:nocov, 4, 6]] + ) + end + + it 'filters Ruby directive comments through the shared substrate detector' do + expect(Ruby::Merge::BlockDirectiveDetector.directive_content?('simplecov:disable')).to be(true) + expect(Ruby::Merge::BlockDirectiveDetector.directive_content?(':nocov:')).to be(true) + expect(Ruby::Merge::BlockDirectiveDetector.directive_content?('kettle-jem:freeze')).to be(true) + expect(Ruby::Merge::BlockDirectiveDetector.directive_content?('@param name [String]')).to be(false) + end + + it 'parses Ruby doc-comment example blocks through shared substrate support' do + entries = [ + { line: 10, raw: '# Performs work.' }, + { line: 11, raw: '# @example [Ruby]' }, + { line: 12, raw: '# worker.call' }, + { line: 13, raw: '# @param worker [Worker]' } + ] + + expect(Ruby::Merge::DocCommentSupport.doc_comment_content?('# frozen_string_literal: true')).to be(false) + expect(Ruby::Merge::DocCommentSupport.doc_comment_content?('# simplecov:disable')).to be(false) + expect(Ruby::Merge::DocCommentSupport.example_blocks(entries)).to contain_exactly( + hash_including( + tag_index: 1, + tag_line: 11, + tag_text: '@example [Ruby]', + body_start_index: 2, + body_end_index: 3, + body_entries: [{ line: 12, raw: '# worker.call' }], + declared_language: 'ruby' + ) + ) + end + + it 'detects Ruby magic comment header prefixes through shared substrate support' do + lines = [ + "#!/usr/bin/env ruby\n", + "# frozen_string_literal: true\n", + "# warn_indent: true\n", + "# warn_indent: false\n", + "\n", + "# body comment\n" + ] + + prefix = Ruby::Merge::MagicCommentSupport.comment_only_prefix_info(lines) + + expect(Ruby::Merge::MagicCommentSupport.magic_comment_type_for_text('# coding: UTF-8')).to eq(:encoding) + expect(prefix[:header_magic_comment_types]).to eq( + 2 => :frozen_string_literal, + 3 => :warn_indent, + 4 => :warn_indent + ) + expect(prefix[:duplicate_magic_line_nums]).to contain_exactly(4) + expect(prefix[:suppressed_line_nums]).to include(1, 2, 3, 4, 5) + end + it 'does not mix legacy declaration discovery into parser-backed Ruby structure' do source = <<~RUBY class TemplateOwned @@ -113,16 +182,12 @@ module LegacyOnly ) end - it 'exposes missing TSLP import records as an unsupported capability', :not_tslp_ruby_import_records do + it 'derives require imports from the TreeHaver Ruby parse tree', :tslp_ruby_import_records do result = RUBY_MERGE.merge_ruby("require \"set\"\n", "require \"json\"\n", 'ruby', merge_template_requires: true) - expect(result[:ok]).to be(false) - expect(result[:diagnostics]).to contain_exactly( - hash_including( - category: 'unsupported_feature', - message: include('TSLP-record-backed top-level Ruby declarations and imports') - ) - ) + expect(result[:ok]).to be(true) + expect(result[:output]).to include('require "json"') + expect(result[:output]).to include('require "set"') end it 'exposes missing TSLP top-level call records as an unsupported capability', diff --git a/gems/ruby-merge/spec/gemspec_support_spec.rb b/gems/ruby-merge/spec/gemspec_support_spec.rb new file mode 100644 index 000000000..0e19ceb9f --- /dev/null +++ b/gems/ruby-merge/spec/gemspec_support_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::GemspecSupport do + it 'normalizes gemspec block variable receivers to the shared placeholder' do + expect(described_class.effective_receiver('gem', 'gem')).to eq(described_class::GEMSPEC_VAR_PLACEHOLDER) + expect(described_class.effective_receiver('spec.metadata', 'spec')).to eq('spec.metadata') + end + + it 'chooses the template block variable when both sides use different variables' do + expect(described_class.preferred_block_var('spec', 'gem')).to eq('spec') + expect(described_class.preferred_block_var('spec', 'spec')).to be_nil + end + + it 'rewrites destination opening lines to the preferred block variable' do + expect( + described_class.opening_line_with_preferred_block_var( + 'Gem::Specification.new do |gem|', + dest_var: 'gem', + preferred_var: 'spec', + node_preference: :destination + ) + ).to eq('Gem::Specification.new do |spec|') + end +end diff --git a/gems/ruby-merge/spec/hash_literal_projector_spec.rb b/gems/ruby-merge/spec/hash_literal_projector_spec.rb new file mode 100644 index 000000000..06400d2de --- /dev/null +++ b/gems/ruby-merge/spec/hash_literal_projector_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::RubyHashLiteralProjector do + it 'projects Ruby hash literals through TreeHaver nodes' do + hash = described_class.new( + '{ foo: 1, "quoted": 2, :sym => 3, "str" => { nested: true }, works?: call(1, 2), }' + ).call + + expect(hash).to be_a(Ruby::Merge::RubyHashNode) + expect(hash.trailing_comma).to be(true) + expect(hash.pairs.map(&:key)).to eq(%w[foo quoted sym "str" works?]) + expect(hash.pairs.map(&:delimiter)).to eq([':', ':', '=>', '=>', ':']) + expect(hash.pairs[3].value).to be_a(Ruby::Merge::RubyHashNode) + expect(hash.pairs[4].value.source).to eq('call(1, 2)') + end +end diff --git a/gems/ruby-merge/spec/method_similarity_spec.rb b/gems/ruby-merge/spec/method_similarity_spec.rb new file mode 100644 index 000000000..7133ef1c0 --- /dev/null +++ b/gems/ruby-merge/spec/method_similarity_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::MethodSimilarity do + subject(:similarity) { described_class.new } + + it 'scores identical method names and parameters as identical' do + expect( + similarity.call( + template_name: 'process_user', + template_params: %i[user options], + dest_name: 'process_user', + dest_params: %i[user options] + ) + ).to eq(1.0) + end + + it 'gives related method names credit without requiring exact spelling' do + expect(similarity.string_similarity('process_user', 'process_users')).to be > 0.9 + end + + it 'combines parameter name overlap and arity similarity' do + expect(similarity.param_similarity(%i[user options], %i[user config])).to be_within(0.001).of(0.65) + end +end diff --git a/gems/ruby-merge/spec/nocov_node_base_spec.rb b/gems/ruby-merge/spec/nocov_node_base_spec.rb new file mode 100644 index 000000000..969d76fb3 --- /dev/null +++ b/gems/ruby-merge/spec/nocov_node_base_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +RSpec.describe Ruby::Merge::NocovNodeBase do + let(:analysis_class) do + Struct.new(:lines) do + def generate_signature(node) + [:node, node] + end + end + end + + it 'models balanced nocov blocks as Ruby block directives' do + analysis = analysis_class.new(["# :nocov:\n", "def skipped\n", "end\n", "# :nocov:\n"]) + node = described_class.new(start_line: 1, end_line: 4, analysis: analysis, nodes: [:method]) + + expect(node.kind).to eq(:nocov) + expect(node.merge_policy).to be_nil + expect(node.children).to eq([:method]) + expect(node.merge_type).to eq(:nocov_block) + expect(node.signature).to eq(%i[node method]) + expect(node.slice).to eq("# :nocov:\ndef skipped\nend\n# :nocov:\n") + end + + it 'uses normalized inner block content when multiple nodes are covered' do + analysis = analysis_class.new(["# :nocov:\n", "def a\n", "end\n", "def b\n", "end\n", "# :nocov:\n"]) + node = described_class.new(start_line: 1, end_line: 6, analysis: analysis, nodes: %i[a b]) + + expect(node.signature).to eq([:nocov_multi, "def a\nend\ndef b\nend"]) + end +end diff --git a/gems/ruby-merge/spec/nocov_wrapper_base_spec.rb b/gems/ruby-merge/spec/nocov_wrapper_base_spec.rb new file mode 100644 index 000000000..bd4b6106b --- /dev/null +++ b/gems/ruby-merge/spec/nocov_wrapper_base_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +RSpec.describe Ruby::Merge::NocovWrapperBase do + let(:location) { Struct.new(:start_line, :end_line).new(2, 4) } + let(:node) do + Struct.new(:location, :slice).new(location, "def skipped\nend\n") + end + + it 'marks wrapped Ruby nodes as nocov block directive participants' do + wrapper = described_class.new(node) + + expect(wrapper.kind).to eq(:nocov) + expect(wrapper.children).to eq([]) + expect(wrapper.merge_policy).to be_nil + expect(wrapper.start_line).to eq(2) + expect(wrapper.end_line).to eq(4) + expect(wrapper.unwrap).to equal(node) + expect(wrapper.location).to equal(location) + expect(wrapper.slice).to eq("def skipped\nend\n") + expect(wrapper.nocov_wrapper?).to be(true) + expect(wrapper.nocov_node?).to be(false) + end +end diff --git a/gems/ruby-merge/spec/rescue_semantics_spec.rb b/gems/ruby-merge/spec/rescue_semantics_spec.rb new file mode 100644 index 000000000..e120ab936 --- /dev/null +++ b/gems/ruby-merge/spec/rescue_semantics_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::RescueSemantics do + subject(:semantics) { described_class.new(source_defined_exception_definitions: definitions) } + + let(:definitions) { [] } + + it 'keeps non-rescue begin clauses after rescue clauses' do + clause_types = [ + :ensure_clause, + [:rescue_clause, ['ArgumentError'], 0], + :else_clause + ] + + expect(semantics.canonicalize_begin_clause_kind_order(clause_types)).to eq( + [ + [:rescue_clause, ['ArgumentError'], 0], + :else_clause, + :ensure_clause + ] + ) + end + + it 'moves broad StandardError rescue clauses after narrower clauses' do + clause_types = [ + [:rescue_clause, [:standard_error], 0], + [:rescue_clause, ['ArgumentError'], 1], + :ensure_clause + ] + + expect(semantics.canonicalize_rescue_clause_order(clause_types)).to eq( + [ + [:rescue_clause, ['ArgumentError'], 1], + [:rescue_clause, [:standard_error], 0], + :ensure_clause + ] + ) + end + + it 'normalizes bare and explicit StandardError rescue signatures' do + expect(semantics.rescue_clause_signature([])).to eq([:standard_error]) + expect(semantics.rescue_clause_signature(['::StandardError'])).to eq([:standard_error]) + end + + it 'sorts explicit rescue exception signatures' do + expect(semantics.rescue_clause_signature(['Timeout::Error', 'ArgumentError'])).to eq( + ['ArgumentError', 'Timeout::Error'] + ) + end + + context 'with source-defined exception classes' do + let(:definitions) do + [ + { name: 'MyGem::Error', namespace: 'MyGem', superclass: 'StandardError' }, + { name: 'MyGem::SpecificError', namespace: 'MyGem', superclass: 'Error' } + ] + end + + it 'orders locally defined broader exception classes after narrower subclasses' do + clause_types = [ + [:rescue_clause, ['MyGem::Error'], 0], + [:rescue_clause, ['MyGem::SpecificError'], 1] + ] + + expect(semantics.canonicalize_rescue_clause_order(clause_types)).to eq( + [ + [:rescue_clause, ['MyGem::SpecificError'], 1], + [:rescue_clause, ['MyGem::Error'], 0] + ] + ) + end + end +end diff --git a/gems/ruby-merge/spec/scaffold_chunk_support_spec.rb b/gems/ruby-merge/spec/scaffold_chunk_support_spec.rb new file mode 100644 index 000000000..319e80c5c --- /dev/null +++ b/gems/ruby-merge/spec/scaffold_chunk_support_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::ScaffoldChunkSupport do + it 'defines the bundle-gem Rakefile scaffold chunks' do + expect(described_class::ALL_SPECS.map(&:anchor_value)).to include( + 'bundler/gem_tasks', + 'rspec/core/rake_task', + 'rubocop/rake_task', + 'default' + ) + end + + it 'uses token-based similarity for scaffold satellite detection' do + pattern_tokens = described_class.jaccard_tokens('RSpec::Core::RakeTask.new') + node_tokens = described_class.jaccard_tokens('RSpec::Core::RakeTask.new(:spec)') + + expect(described_class.jaccard(pattern_tokens, node_tokens)).to be >= 0.75 + end + + it 'matches default task anchors fuzzily' do + expect(described_class.task_anchor_match?('task default: :spec', 'default', 0.35)).to be(true) + end +end diff --git a/gems/ruby-merge/spec/signature_support_spec.rb b/gems/ruby-merge/spec/signature_support_spec.rb new file mode 100644 index 000000000..5d036b103 --- /dev/null +++ b/gems/ruby-merge/spec/signature_support_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe Ruby::Merge::SignatureSupport do + it 'builds canonical Ruby definition signatures' do + expect(described_class.method_definition(:call, %i[arg opts])).to eq([:def, :call, %i[arg opts]]) + expect(described_class.class_definition('Admin::User')).to eq([:class, 'Admin::User']) + expect(described_class.module_definition('Admin')).to eq([:module, 'Admin']) + end + + it 'builds canonical Ruby call signatures' do + expect(described_class.call(:gemspec, nil)).to eq([:call, :gemspec, nil]) + expect(described_class.call(:appraise, 'rails', block: true)).to eq([:call_with_block, :appraise, 'rails']) + expect(described_class.call_operator_write(:files, Ruby::Merge::GemspecSupport::GEMSPEC_VAR_PLACEHOLDER)).to eq( + [:call_op_write, :files, Ruby::Merge::GemspecSupport::GEMSPEC_VAR_PLACEHOLDER] + ) + end + + it 'builds canonical Ruby control-flow signatures' do + expect(described_class.super_call(block: false)).to eq(%i[super no_block]) + expect(described_class.forwarding_super_call(block: true)).to eq(%i[forwarding_super with_block]) + expect(described_class.begin_block('do_work')).to eq([:begin, 'do_work']) + end + + it 'keeps the textual method signature format used by ruby-merge analysis' do + expect(described_class.textual_method_signature('self.', 'build')).to eq('self.build') + end +end diff --git a/gems/rust-merge/.gitattributes b/gems/rust-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/rust-merge/.gitattributes +++ b/gems/rust-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/rust-merge/.kettle-drift.lock b/gems/rust-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/rust-merge/.kettle-drift.lock +++ b/gems/rust-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/rust-merge/.rubocop_gradual.lock b/gems/rust-merge/.rubocop_gradual.lock index 946501b02..901628f74 100644 --- a/gems/rust-merge/.rubocop_gradual.lock +++ b/gems/rust-merge/.rubocop_gradual.lock @@ -76,22 +76,17 @@ "lib/rust-merge.rb:3264986437": [ [1, 1, 0, "Naming/FileName: The name of this source file (`rust-merge.rb`) should use snake_case.", 5381] ], - "lib/rust/merge.rb:2035906460": [ + "lib/rust/merge.rb:4179218653": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Rust::Merge`.", 2866359175], - [10, 3, 5517, "Metrics/ModuleLength: Module has too many lines. [111/100]", 1654067060], - [56, 121, 22, "Layout/LineLength: Line is too long. [142/120]", 1494061343], - [63, 5, 1405, "Metrics/AbcSize: Assignment Branch Condition size for `merge_rust` is too high. [<13, 32, 11> 36.25/17]", 3235979822], - [63, 5, 1405, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_rust` is too high. [11/7]", 3235979822], - [63, 5, 1405, "Metrics/MethodLength: Method has too many lines. [22/10]", 3235979822], - [63, 5, 1405, "Metrics/PerceivedComplexity: Perceived complexity for `merge_rust` is too high. [11/8]", 3235979822], - [82, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [90, 5, 1669, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_rust_module` is too high. [<11, 34, 8> 36.62/17]", 284573767], - [90, 5, 1669, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `analyze_rust_module` is too high. [9/7]", 284573767], - [90, 5, 1669, "Metrics/MethodLength: Method has too many lines. [30/10]", 284573767], - [90, 5, 1669, "Metrics/PerceivedComplexity: Perceived complexity for `analyze_rust_module` is too high. [9/8]", 284573767], - [103, 50, 20, "Style/SymbolProc: Pass `&:name` as an argument to `select` instead of a block.", 2833012298], - [107, 7, 3, "Layout/BlockAlignment: `end` at 107, 6 is not aligned with `processed[:analysis].structure` at 102, 21 or `.map do |item|` at 104, 41.", 193405706], - [107, 7, 53, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 1601274288] + [10, 3, 7083, "Metrics/ModuleLength: Module has too many lines. [169/100]", 3787459528], + [68, 121, 22, "Layout/LineLength: Line is too long. [142/120]", 1494061343], + [75, 5, 1405, "Metrics/AbcSize: Assignment Branch Condition size for `merge_rust` is too high. [<13, 32, 11> 36.25/17]", 3235979822], + [75, 5, 1405, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_rust` is too high. [11/7]", 3235979822], + [75, 5, 1405, "Metrics/MethodLength: Method has too many lines. [22/10]", 3235979822], + [75, 5, 1405, "Metrics/PerceivedComplexity: Perceived complexity for `merge_rust` is too high. [11/8]", 3235979822], + [94, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [102, 5, 1442, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_rust_module` is too high. [<8, 19, 5> 21.21/17]", 1212922264], + [102, 5, 1442, "Metrics/MethodLength: Method has too many lines. [41/10]", 1212922264] ], "rust-merge.gemspec:2965445534": [ [128, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], diff --git a/gems/rust-merge/Gemfile b/gems/rust-merge/Gemfile index 7c986b6db..e1d9f1d52 100644 --- a/gems/rust-merge/Gemfile +++ b/gems/rust-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/rust-merge/Gemfile.lock b/gems/rust-merge/Gemfile.lock index dfbcd5178..98ef57049 100644 --- a/gems/rust-merge/Gemfile.lock +++ b/gems/rust-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,10 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -519,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -532,21 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/rust-merge/gemfiles/modular/templating.gemfile b/gems/rust-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/rust-merge/gemfiles/modular/templating.gemfile +++ b/gems/rust-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/rust-merge/gemfiles/modular/templating_local.gemfile b/gems/rust-merge/gemfiles/modular/templating_local.gemfile index eabeae610..86918cade 100644 --- a/gems/rust-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/rust-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[rust-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[rust-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[rust-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/rust-merge/lib/rust/merge.rb b/gems/rust-merge/lib/rust/merge.rb index 35ca75e9b..d99d808f5 100644 --- a/gems/rust-merge/lib/rust/merge.rb +++ b/gems/rust-merge/lib/rust/merge.rb @@ -11,20 +11,34 @@ module Merge PACKAGE_NAME = 'rust-merge' TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND DESTINATION_WINS_ARRAY_POLICY = { surface: 'array', name: 'destination_wins_array' }.freeze + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) module_function + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + + grammar_finder = TreeHaver::GrammarFinder.new(:rust) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end + def rust_feature_profile { family: 'rust', supported_dialects: ['rust'], supported_policies: [DESTINATION_WINS_ARRAY_POLICY] } end def available_rust_backends - [TREE_SITTER_BACKEND] + rust_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end def rust_backend_feature_profile(backend: nil) requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && rust_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported Rust backend #{requested}.") end @@ -50,12 +64,24 @@ def rust_plan_context(backend: nil) end def parse_rust(source, dialect) + unless rust_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) + return unsupported_feature_result("Unsupported Rust backend #{TREE_SITTER_BACKEND.id}.") + end + return analyze_rust_module(source) if dialect == 'rust' { ok: false, diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: "Unsupported Rust dialect #{dialect}." }], policies: [] } end + def rust_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == TREE_SITTER_BACKEND.id + + registrations = TreeHaver.registered_languages(:rust) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end + def match_rust_owners(template, destination) Ast::Merge::OwnerSelection.match_by_path(template, destination) end @@ -88,24 +114,35 @@ def merge_rust(template_source, destination_source, dialect) end def analyze_rust_module(source) - parsed = TreeHaver.parse_with_language_pack(TreeHaver::ParserRequest.new(source: source, language: 'rust', - dialect: 'rust')) - return { ok: false, diagnostics: parsed[:diagnostics], policies: [] } unless parsed[:ok] - - processed = TreeHaver.process_with_language_pack(TreeHaver::ProcessRequest.new(source: source, language: 'rust')) - return { ok: false, diagnostics: processed[:diagnostics], policies: [] } unless processed[:ok] - - imports = processed[:analysis].imports.each_with_index.map do |item, index| - { path: "/imports/#{index}", match_key: normalize_rust_import_path(item.source), - text: import_text(source, item.span) } + parser = TreeHaver.parser_for(:rust) + tree = parser.parse(source) + collect_parse_errors(tree.root_node) + + imports = [] + declarations = [] + tree.root_node.children.each do |node| + case node.type + when 'use_declaration' + import_source = line_anchored_slice(source, node) + imports << { + path: "/imports/#{imports.length}", + owner_kind: 'import', + match_key: normalize_rust_import_path(import_source), + text: import_text(source, node) + } + when 'function_item', 'struct_item', 'enum_item', 'trait_item', 'impl_item', 'const_item', 'static_item', + 'type_item', 'mod_item' + name = first_named_descendant_text(source, node, %w[identifier type_identifier]) + next unless name + + declarations << { + path: "/declarations/#{name}", + owner_kind: 'declaration', + match_key: name, + text: declaration_text(source, node) + } + end end - declarations = processed[:analysis].structure - .select { |item| item.name } - .map do |item| - { path: "/declarations/#{item.name}", match_key: item.name, - text: declaration_text(source, item.span) } - end - .sort_by { |item| item[:path] } { ok: true, @@ -113,22 +150,68 @@ def analyze_rust_module(source) analysis: { kind: 'rust', dialect: 'rust', - source: source, - owners: imports.map { |item| { path: item[:path], owner_kind: 'import', match_key: item[:match_key] } } + - declarations.map { |item| { path: item[:path], owner_kind: 'declaration', match_key: item[:match_key] } }, imports: imports, - declarations: declarations + declarations: declarations, + owners: owner_views(imports + declarations) }, policies: [] } + rescue TreeHaver::Error, StandardError => e + parse_failure_result(e) end private_class_method :analyze_rust_module + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'Rust parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'Rust parse contains syntax errors' + end + private_class_method :collect_parse_errors + + def parse_failure_result(error) + { ok: false, + diagnostics: [{ severity: 'error', category: 'parse_error', message: error.message }], + policies: [] } + end + private_class_method :parse_failure_result + + def unsupported_feature_result(message) + { + ok: false, + diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: message }], + policies: [] + } + end + private_class_method :unsupported_feature_result + def normalize_rust_import_path(import_source) import_source.sub(/\Ause\s+/, '').sub(/;\z/, '').strip end private_class_method :normalize_rust_import_path + def first_named_descendant_text(source, node, types) + return slice_span(source, node) if types.include?(node.type) + + node.children.each do |child| + value = first_named_descendant_text(source, child, types) + return value if value && !value.empty? + end + nil + end + private_class_method :first_named_descendant_text + + def owner_view(item) + item.slice(:path, :owner_kind, :match_key) + end + private_class_method :owner_view + + def owner_views(items) + items.map { |item| owner_view(item) } + end + private_class_method :owner_views + def import_text(source, span) = "#{slice_span(source, span)}\n" def declaration_text(source, span) = "#{line_anchored_slice(source, span)}\n" def slice_span(source, span) = source[span.start_byte...span.end_byte].strip @@ -142,6 +225,8 @@ def line_anchored_slice(source, span) end end +Rust::Merge.register_backend! + Rust::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/rust-merge/spec/fixtures_integration_spec.rb b/gems/rust-merge/spec/fixtures_integration_spec.rb index 22582c102..b0e68dd84 100644 --- a/gems/rust-merge/spec/fixtures_integration_spec.rb +++ b/gems/rust-merge/spec/fixtures_integration_spec.rb @@ -68,4 +68,17 @@ def json_ready(value) = Ast::Merge.json_ready(value) %w[rust slice-108-merge module-merge.json] ) end + + it 'fails closed when the Rust TreeHaver backend is unavailable' do + allow(described_class).to receive(:rust_backend_available_for_analysis?).and_return(false) + + expect(described_class.available_rust_backends).to eq([]) + result = described_class.parse_rust("fn main() {}\n", 'rust') + + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to eq( + [{ severity: 'error', category: 'unsupported_feature', + message: 'Unsupported Rust backend kreuzberg-language-pack.' }] + ) + end end diff --git a/gems/smorg-rb/.gitattributes b/gems/smorg-rb/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/smorg-rb/.gitattributes +++ b/gems/smorg-rb/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/smorg-rb/.kettle-drift.lock b/gems/smorg-rb/.kettle-drift.lock index 1e71cffac..9f7fedda8 100644 --- a/gems/smorg-rb/.kettle-drift.lock +++ b/gems/smorg-rb/.kettle-drift.lock @@ -4,7 +4,15 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365, + 405, + 445 ] } ], @@ -13,7 +21,15 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376, + 416, + 456 ] } ], @@ -22,7 +38,15 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366, + 406, + 446 ] } ], @@ -31,7 +55,15 @@ "file": "Gemfile", "lines": [ 98, - 138 + 138, + 178, + 218, + 258, + 298, + 338, + 378, + 418, + 458 ] } ], @@ -40,7 +72,15 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381, + 421, + 461 ] } ], @@ -49,7 +89,15 @@ "file": "Gemfile", "lines": [ 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367, + 407, + 447 ] } ], @@ -59,7 +107,15 @@ "lines": [ 65, 105, - 145 + 145, + 185, + 225, + 265, + 305, + 345, + 385, + 425, + 465 ] } ], @@ -68,7 +124,15 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386, + 426, + 466 ] } ], @@ -78,7 +142,15 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372, + 412, + 452 ] } ], @@ -87,7 +159,15 @@ "file": "Gemfile", "lines": [ 115, - 155 + 155, + 195, + 235, + 275, + 315, + 355, + 395, + 435, + 475 ] } ], @@ -97,7 +177,15 @@ "lines": [ 40, 84, - 124 + 124, + 164, + 204, + 244, + 284, + 324, + 364, + 404, + 444 ] } ], @@ -107,7 +195,15 @@ "lines": [ 74, 114, - 154 + 154, + 194, + 234, + 274, + 314, + 354, + 394, + 434, + 474 ] } ], @@ -116,7 +212,15 @@ "file": "Gemfile", "lines": [ 90, - 130 + 130, + 170, + 210, + 250, + 290, + 330, + 370, + 410, + 450 ] } ], @@ -126,7 +230,15 @@ "lines": [ 53, 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377, + 417, + 457 ] } ], @@ -136,7 +248,15 @@ "lines": [ 49, 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373, + 413, + 453 ] } ], @@ -145,7 +265,15 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371, + 411, + 451 ] } ], @@ -154,7 +282,15 @@ "file": "Gemfile", "lines": [ 108, - 148 + 148, + 188, + 228, + 268, + 308, + 348, + 388, + 428, + 468 ] } ], @@ -163,7 +299,15 @@ "file": "Gemfile", "lines": [ 107, - 147 + 147, + 187, + 227, + 267, + 307, + 347, + 387, + 427, + 467 ] } ], @@ -172,7 +316,15 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382, + 422, + 462 ] } ], @@ -181,7 +333,15 @@ "file": "Gemfile", "lines": [ 111, - 151 + 151, + 191, + 231, + 271, + 311, + 351, + 391, + 431, + 471 ] } ], diff --git a/gems/smorg-rb/Gemfile b/gems/smorg-rb/Gemfile index cd9f0f6ce..17e439642 100644 --- a/gems/smorg-rb/Gemfile +++ b/gems/smorg-rb/Gemfile @@ -157,7 +157,327 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -166,7 +486,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -174,7 +494,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/smorg-rb/Gemfile.lock b/gems/smorg-rb/Gemfile.lock index 7c39665b1..624ce3a54 100644 --- a/gems/smorg-rb/Gemfile.lock +++ b/gems/smorg-rb/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -21,52 +11,285 @@ PATH plain-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) -GEM - remote: https://gem.coop/ +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly specs: - addressable (2.9.0) - public_suffix (>= 2.0.2, < 8.0) - ansi (1.6.0) - appraisal2 (3.1.4) - bundler (>= 1.17.3) - rake (>= 10) - thor (>= 0.14) - ast (2.4.3) - ast-crispr (7.1.0) - ast-merge (= 7.1.0) - service_actor (~> 3.9) - version_gem (~> 1.1, >= 1.1.9) ast-crispr-markdown-markly (7.1.0) ast-crispr (= 7.1.0) markly-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: ast-crispr-ruby-prism (7.1.0) ast-crispr (= 7.1.0) - prism (>= 1.0) + prism-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: ast-merge (7.1.0) benchmark token-resolver (~> 2.0, >= 2.0.4) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) - ast-merge-git (7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) ast-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) - backports (3.25.3) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: bash-merge (7.1.0) ast-merge (= 7.1.0) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + +GEM + remote: https://gem.coop/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + ansi (1.6.0) + appraisal2 (3.2.0) + bundler (>= 1.17.3) + rake (>= 10) + thor (>= 0.14) + ast (2.4.3) + backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) bundler-audit (0.9.3) bundler (>= 1.2.0) thor (~> 1.0) citrus (3.0.2) - citrus-toml-merge (7.1.0) - toml-merge (= 7.1.0) - toml-rb (~> 4.1) - version_gem (~> 1.1, >= 1.1.9) cmdparse (3.0.7) commonmarker (2.9.0-aarch64-linux) commonmarker (2.9.0-aarch64-linux-musl) @@ -74,10 +297,6 @@ GEM commonmarker (2.9.0-x86_64-darwin) commonmarker (2.9.0-x86_64-linux) commonmarker (2.9.0-x86_64-linux-musl) - commonmarker-merge (7.1.0) - commonmarker (~> 2.2) - markdown-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -87,10 +306,6 @@ GEM diff-lcs (1.6.2) diffy (3.4.4) docile (1.4.1) - dotenv-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.14) dry-configurable (1.4.0) dry-core (~> 1.0) zeitwerk (~> 2.6) @@ -128,10 +343,6 @@ GEM geom2d (0.4.1) gitmoji-regex (2.0.4) version_gem (~> 1.1, >= 1.1.13) - go-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) hexapdf (1.9.1) cmdparse (~> 3.0, >= 3.0.3) geom2d (~> 0.4, >= 0.4.1) @@ -144,40 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - json-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) - kettle-jem (7.1.0) - addressable (>= 2.8, < 3) - ast-crispr-markdown-markly (= 7.1.0) - ast-crispr-ruby-prism (= 7.1.0) - ast-merge (= 7.1.0) - bash-merge (= 7.1.0) - citrus-toml-merge (= 7.1.0) - commonmarker-merge (= 7.1.0) - dotenv-merge (= 7.1.0) - json-merge (= 7.1.0) - kettle-dev (~> 2.3, >= 2.3.5) - kettle-rb (~> 0.1, >= 0.1.4) - kramdown-merge (= 7.1.0) - markdown-merge (= 7.1.0) - markly-merge (= 7.1.0) - prism-merge (= 7.1.0) - psych-merge (= 7.1.0) - rbs (>= 3.10) - rbs-merge (= 7.1.0) - ruby-merge (= 7.1.0) - token-resolver (~> 2.0, >= 2.0.4) - toml-merge (= 7.1.0) - toml-rb (~> 4.2) - tree_haver (= 7.1.0) - yaml-merge (= 7.1.0) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -201,24 +385,12 @@ GEM turbo_tests2 (~> 3.1, >= 3.1.12) kramdown (2.5.2) rexml (>= 3.4.4) - kramdown-merge (7.1.0) - kramdown (~> 2.5) - markdown-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) markly (0.16.0) - markly-merge (7.1.0) - markdown-merge (= 7.1.0) - markly (~> 0.9) - version_gem (~> 1.1, >= 1.1.9) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -242,26 +414,13 @@ GEM ast (~> 2.4.1) racc parslet (2.0.0) - plain-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) pp (0.6.4) prettyprint prettyprint (0.2.0) prism (1.9.0) - prism-merge (7.1.0) - prism (~> 1.6) - ruby-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) psych (5.4.0) date stringio - psych-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) - yaml-merge (= 7.1.0) public_suffix (7.0.5) racc (1.8.1) rainbow (3.1.1) @@ -273,11 +432,6 @@ GEM logger prism (>= 1.6.0) tsort - rbs-merge (7.1.0) - ast-merge (= 7.1.0) - rbs (>= 3.10) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.14) rdoc (6.17.0) erb psych (>= 4.0.0) @@ -373,10 +527,6 @@ GEM lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) rubocop-ast (>= 1.44.0, < 2.0) - ruby-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) @@ -434,20 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - toml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) toml-rb (4.2.0) citrus (~> 3.0, > 3.0) racc (~> 1.7) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -460,10 +603,6 @@ GEM kramdown (>= 2.4, < 3) kramdown-parser-gfm (~> 1.1) version_gem (~> 1.1, >= 1.1.13) - yaml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) yard (0.9.45) yard-fence (0.9.6) rdoc (>= 6.11, < 8) @@ -476,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -496,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -520,34 +682,43 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) ast-crispr-markdown-markly (7.1.0) ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 citrus-toml-merge (7.1.0) @@ -585,7 +756,8 @@ CHECKSUMS irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 json-merge (7.1.0) - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad @@ -613,6 +785,7 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 @@ -659,6 +832,7 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 @@ -682,12 +856,14 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 toml-merge (7.1.0) toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 @@ -697,9 +873,10 @@ CHECKSUMS yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/smorg-rb/gemfiles/modular/templating.gemfile b/gems/smorg-rb/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/smorg-rb/gemfiles/modular/templating.gemfile +++ b/gems/smorg-rb/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/smorg-rb/gemfiles/modular/templating_local.gemfile b/gems/smorg-rb/gemfiles/modular/templating_local.gemfile index e28bb5d97..9b5bc2fd4 100644 --- a/gems/smorg-rb/gemfiles/modular/templating_local.gemfile +++ b/gems/smorg-rb/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[smorg-rb] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[smorg-rb] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[smorg-rb] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/smorg-rb/spec/cli_spec.rb b/gems/smorg-rb/spec/cli_spec.rb index b50269af8..5d01b3fc9 100644 --- a/gems/smorg-rb/spec/cli_spec.rb +++ b/gems/smorg-rb/spec/cli_spec.rb @@ -60,8 +60,7 @@ def run_git(dir, *args) expect(exit_code).to eq(described_class::EXIT_SUCCESS), stderr.string merged = File.read(current) - expect(merged).to include('"current":true') - expect(merged).to include('"other":true') + expect(JSON.parse(merged)).to include('current' => true, 'other' => true) expect(stdout.string).to eq('') end @@ -78,8 +77,7 @@ def run_git(dir, *args) expect(exit_code).to eq(described_class::EXIT_SUCCESS), stderr.string merged = File.read(current) - expect(merged).to include('"current":true') - expect(merged).to include('"other":true') + expect(JSON.parse(merged)).to include('current' => true, 'other' => true) end it 'installs local Git diff driver attributes' do diff --git a/gems/toml-merge/.gitattributes b/gems/toml-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/toml-merge/.gitattributes +++ b/gems/toml-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/toml-merge/.kettle-drift.lock b/gems/toml-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/toml-merge/.kettle-drift.lock +++ b/gems/toml-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/toml-merge/.rubocop_gradual.lock b/gems/toml-merge/.rubocop_gradual.lock index 4b65819de..918c85d88 100644 --- a/gems/toml-merge/.rubocop_gradual.lock +++ b/gems/toml-merge/.rubocop_gradual.lock @@ -77,39 +77,17 @@ [1, 1, 0, "Naming/FileName: The name of this source file (`toml-merge.rb`) should use snake_case.", 5381], [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177542] ], - "lib/toml/merge.rb:114483342": [ - [42, 3, 19743, "Metrics/ModuleLength: Module has too many lines. [449/100]", 3377734762], - [122, 5, 16553, "Metrics/ClassLength: Class has too many lines. [420/100]", 3607675918], - [164, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1773216188], - [173, 7, 594, "Metrics/MethodLength: Method has too many lines. [16/10]", 1049978805], - [197, 7, 1640, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml` is too high. [<7, 24, 9> 26.57/17]", 478063103], - [197, 7, 1640, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_toml` is too high. [8/7]", 478063103], - [197, 7, 1640, "Metrics/MethodLength: Method has too many lines. [32/10]", 478063103], - [201, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1773216188], - [236, 7, 1795, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml_with_parser` is too high. [<7, 24, 8> 26.25/17]", 4111497622], - [236, 7, 1795, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_toml_with_parser` is too high. [8/7]", 4111497622], - [236, 7, 1795, "Metrics/MethodLength: Method has too many lines. [33/10]", 4111497622], - [345, 7, 688, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `strip_toml_comment` is too high. [8/7]", 3909397399], - [345, 7, 688, "Metrics/MethodLength: Method has too many lines. [25/10]", 3909397399], - [345, 7, 688, "Metrics/PerceivedComplexity: Perceived complexity for `strip_toml_comment` is too high. [9/8]", 3909397399], - [379, 7, 1087, "Metrics/AbcSize: Assignment Branch Condition size for `split_outside_quotes` is too high. [<13, 16, 15> 25.5/17]", 609465929], - [379, 7, 1087, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `split_outside_quotes` is too high. [12/7]", 609465929], - [379, 7, 1087, "Metrics/MethodLength: Method has too many lines. [39/10]", 609465929], - [379, 7, 1087, "Metrics/PerceivedComplexity: Perceived complexity for `split_outside_quotes` is too high. [13/8]", 609465929], - [386, 9, 762, "Metrics/BlockLength: Block has too many lines. [29/25]", 4212946145], - [437, 7, 462, "Metrics/MethodLength: Method has too many lines. [16/10]", 2527564697], - [456, 7, 1018, "Metrics/AbcSize: Assignment Branch Condition size for `parse_toml_value` is too high. [<7, 28, 11> 30.89/17]", 820781705], - [456, 7, 1018, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_toml_value` is too high. [10/7]", 820781705], - [456, 7, 1018, "Metrics/MethodLength: Method has too many lines. [20/10]", 820781705], - [456, 7, 1018, "Metrics/PerceivedComplexity: Perceived complexity for `parse_toml_value` is too high. [11/8]", 820781705], - [484, 7, 458, "Metrics/MethodLength: Method has too many lines. [13/10]", 3674341378], - [511, 7, 877, "Metrics/AbcSize: Assignment Branch Condition size for `parse_toml_document` is too high. [<9, 20, 6> 22.74/17]", 2959395577], - [511, 7, 877, "Metrics/MethodLength: Method has too many lines. [19/10]", 2959395577], - [560, 7, 581, "Metrics/AbcSize: Assignment Branch Condition size for `render_toml_table` is too high. [<8, 22, 6> 24.17/17]", 3078876750], - [560, 7, 581, "Metrics/MethodLength: Method has too many lines. [13/10]", 3078876750], - [581, 7, 619, "Metrics/MethodLength: Method has too many lines. [12/10]", 451848846], - [596, 7, 614, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml_tables` is too high. [<3, 20, 6> 21.1/17]", 1810526535], - [596, 7, 614, "Metrics/MethodLength: Method has too many lines. [11/10]", 1810526535] + "lib/toml/merge.rb:3069711497": [ + [39, 3, 12193, "Metrics/ModuleLength: Module has too many lines. [231/100]", 1479901406], + [114, 5, 9241, "Metrics/ClassLength: Class has too many lines. [205/100]", 349141169], + [156, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1773216188], + [165, 7, 709, "Metrics/MethodLength: Method has too many lines. [17/10]", 2355964538], + [191, 7, 1280, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml` is too high. [<6, 16, 6> 18.11/17]", 2322240506], + [191, 7, 1280, "Metrics/MethodLength: Method has too many lines. [25/10]", 2322240506], + [195, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 1773216188], + [222, 7, 1401, "Metrics/AbcSize: Assignment Branch Condition size for `merge_toml_with_parser` is too high. [<6, 18, 6> 19.9/17]", 3118052892], + [222, 7, 1401, "Metrics/MethodLength: Method has too many lines. [24/10]", 3118052892], + [321, 9, 11, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 848344986] ], "lib/toml/merge/comment_tracker.rb:743656609": [ [16, 5, 5242, "Metrics/ClassLength: Class has too many lines. [112/100]", 3014190138], @@ -177,8 +155,8 @@ [998, 7, 526, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `emit_preceding_blank_lines` is too high. [8/7]", 3889743093], [998, 7, 526, "Metrics/MethodLength: Method has too many lines. [11/10]", 3889743093] ], - "lib/toml/merge/file_analysis.rb:2689095431": [ - [12, 5, 19523, "Metrics/ClassLength: Class has too many lines. [368/100]", 929433986], + "lib/toml/merge/file_analysis.rb:2630402533": [ + [12, 5, 19537, "Metrics/ClassLength: Class has too many lines. [368/100]", 929433986], [15, 7, 22, "Style/Documentation: Missing top-level documentation comment for `class Toml::Merge::FileAnalysis::CommentAugmenter`.", 2864244718], [20, 9, 849, "Metrics/AbcSize: Assignment Branch Condition size for `initialize` is too high. [<11, 13, 1> 17.06/17]", 1333266342], [20, 9, 849, "Metrics/MethodLength: Method has too many lines. [16/10]", 1333266342], @@ -188,9 +166,9 @@ [228, 7, 959, "Metrics/MethodLength: Method has too many lines. [21/10]", 1481059821], [228, 7, 959, "Metrics/PerceivedComplexity: Perceived complexity for `root_pairs` is too high. [15/8]", 1481059821], [246, 9, 384, "Style/CombinableLoops: Combine this loop with the previous loop.", 2434692315], - [263, 7, 1729, "Metrics/AbcSize: Assignment Branch Condition size for `parse_toml` is too high. [<10, 12, 8> 17.55/17]", 2015178317], - [263, 7, 1729, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_toml` is too high. [9/7]", 2015178317], - [263, 7, 1729, "Metrics/MethodLength: Method has too many lines. [19/10]", 2015178317], + [263, 7, 1743, "Metrics/AbcSize: Assignment Branch Condition size for `parse_toml` is too high. [<10, 12, 8> 17.55/17]", 1966830746], + [263, 7, 1743, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parse_toml` is too high. [9/7]", 1966830746], + [263, 7, 1743, "Metrics/MethodLength: Method has too many lines. [19/10]", 1966830746], [331, 7, 596, "Metrics/MethodLength: Method has too many lines. [13/10]", 995924372], [389, 7, 588, "Metrics/AbcSize: Assignment Branch Condition size for `comment_owner_end_line_for_augmenter` is too high. [<1, 20, 13> 23.87/17]", 1972553155], [389, 7, 588, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `comment_owner_end_line_for_augmenter` is too high. [14/7]", 1972553155], @@ -217,8 +195,8 @@ [215, 11, 4, "Lint/BooleanSymbol: Symbol with a boolean name - you probably meant to use `true`.", 2087932467], [216, 11, 5, "Lint/BooleanSymbol: Symbol with a boolean name - you probably meant to use `false`.", 170962968] ], - "lib/toml/merge/node_wrapper.rb:2123561241": [ - [26, 5, 23635, "Metrics/ClassLength: Class has too many lines. [417/100]", 111672250], + "lib/toml/merge/node_wrapper.rb:975742583": [ + [26, 5, 24084, "Metrics/ClassLength: Class has too many lines. [424/100]", 111672250], [37, 9, 517, "Metrics/MethodLength: Method has too many lines. [11/10]", 3513234297], [37, 17, 154, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [8/5]", 2431837951], [54, 7, 503, "Metrics/MethodLength: Method has too many lines. [12/10]", 2647031658], @@ -231,22 +209,23 @@ [286, 7, 496, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `pairs` is too high. [9/7]", 2741436417], [286, 7, 496, "Metrics/PerceivedComplexity: Perceived complexity for `pairs` is too high. [9/8]", 2741436417], [319, 7, 706, "Metrics/MethodLength: Method has too many lines. [22/10]", 2032215880], - [390, 7, 553, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `effective_end_line` is too high. [8/7]", 2426868004], - [412, 7, 2225, "Metrics/AbcSize: Assignment Branch Condition size for `compute_signature` is too high. [<9, 32, 24> 41/17]", 1299303855], - [412, 7, 2225, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_signature` is too high. [25/7]", 1299303855], - [412, 7, 2225, "Metrics/MethodLength: Method has too many lines. [39/10]", 1299303855], - [412, 7, 2225, "Metrics/PerceivedComplexity: Perceived complexity for `compute_signature` is too high. [16/8]", 1299303855], - [511, 7, 487, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `raw_pair_value_text` is too high. [8/7]", 3177077098], - [535, 7, 1503, "Metrics/AbcSize: Assignment Branch Condition size for `collect_inline_table_keys_recursive` is too high. [<7, 25, 18> 31.59/17]", 3778857543], - [535, 7, 1503, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_inline_table_keys_recursive` is too high. [17/7]", 3778857543], - [535, 7, 1503, "Metrics/MethodLength: Method has too many lines. [24/10]", 3778857543], - [535, 7, 1503, "Metrics/PerceivedComplexity: Perceived complexity for `collect_inline_table_keys_recursive` is too high. [18/8]", 3778857543], - [593, 7, 855, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_sibling_pairs_for_table` is too high. [8/7]", 3160731503], - [593, 7, 855, "Metrics/MethodLength: Method has too many lines. [14/10]", 3160731503], - [624, 7, 655, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `find_next_table_start_line` is too high. [9/7]", 1465728116], - [624, 7, 655, "Metrics/MethodLength: Method has too many lines. [12/10]", 1465728116], - [624, 7, 655, "Metrics/PerceivedComplexity: Perceived complexity for `find_next_table_start_line` is too high. [9/8]", 1465728116], - [653, 7, 861, "Metrics/MethodLength: Method has too many lines. [12/10]", 4202205110] + [390, 7, 753, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `effective_end_line` is too high. [10/7]", 29395992], + [390, 7, 753, "Metrics/PerceivedComplexity: Perceived complexity for `effective_end_line` is too high. [10/8]", 29395992], + [414, 7, 2225, "Metrics/AbcSize: Assignment Branch Condition size for `compute_signature` is too high. [<9, 32, 24> 41/17]", 1299303855], + [414, 7, 2225, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `compute_signature` is too high. [25/7]", 1299303855], + [414, 7, 2225, "Metrics/MethodLength: Method has too many lines. [39/10]", 1299303855], + [414, 7, 2225, "Metrics/PerceivedComplexity: Perceived complexity for `compute_signature` is too high. [16/8]", 1299303855], + [523, 7, 487, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `raw_pair_value_text` is too high. [8/7]", 3177077098], + [547, 7, 1503, "Metrics/AbcSize: Assignment Branch Condition size for `collect_inline_table_keys_recursive` is too high. [<7, 25, 18> 31.59/17]", 3778857543], + [547, 7, 1503, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_inline_table_keys_recursive` is too high. [17/7]", 3778857543], + [547, 7, 1503, "Metrics/MethodLength: Method has too many lines. [24/10]", 3778857543], + [547, 7, 1503, "Metrics/PerceivedComplexity: Perceived complexity for `collect_inline_table_keys_recursive` is too high. [18/8]", 3778857543], + [605, 7, 855, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `collect_sibling_pairs_for_table` is too high. [8/7]", 3160731503], + [605, 7, 855, "Metrics/MethodLength: Method has too many lines. [14/10]", 3160731503], + [636, 7, 655, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `find_next_table_start_line` is too high. [9/7]", 1465728116], + [636, 7, 655, "Metrics/MethodLength: Method has too many lines. [12/10]", 1465728116], + [636, 7, 655, "Metrics/PerceivedComplexity: Perceived complexity for `find_next_table_start_line` is too high. [9/8]", 1465728116], + [665, 7, 861, "Metrics/MethodLength: Method has too many lines. [12/10]", 4202205110] ], "lib/toml/merge/smart_merger.rb:3624815957": [ [39, 5, 9573, "Metrics/ClassLength: Class has too many lines. [190/100]", 1615610584], @@ -265,9 +244,10 @@ [217, 7, 659, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `levenshtein_distance` is too high. [8/7]", 2658150371], [217, 7, 659, "Metrics/MethodLength: Method has too many lines. [18/10]", 2658150371] ], - "spec/fixtures_integration_spec.rb:168123572": [ - [6, 1, 11947, "Metrics/BlockLength: Block has too many lines. [266/25]", 2102318823], - [228, 3, 1368, "Metrics/BlockLength: Block has too many lines. [34/25]", 3324165298] + "spec/fixtures_integration_spec.rb:3985149016": [ + [3, 1, 12320, "Metrics/BlockLength: Block has too many lines. [273/25]", 2102318823], + [34, 3, 2099, "Metrics/BlockLength: Block has too many lines. [27/25]", 677669008], + [233, 3, 1127, "Metrics/BlockLength: Block has too many lines. [27/25]", 3231986094] ], "toml-merge.gemspec:2519299257": [ [128, 121, 20, "Layout/LineLength: Line is too long. [140/120]", 2821357214], diff --git a/gems/toml-merge/Gemfile b/gems/toml-merge/Gemfile index c28cf331d..0be31f1e5 100644 --- a/gems/toml-merge/Gemfile +++ b/gems/toml-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/toml-merge/Gemfile.lock b/gems/toml-merge/Gemfile.lock index 9082e113e..a15d42c66 100644 --- a/gems/toml-merge/Gemfile.lock +++ b/gems/toml-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -518,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -531,22 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/toml-merge/gemfiles/modular/templating.gemfile b/gems/toml-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/toml-merge/gemfiles/modular/templating.gemfile +++ b/gems/toml-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/toml-merge/gemfiles/modular/templating_local.gemfile b/gems/toml-merge/gemfiles/modular/templating_local.gemfile index 884c13d66..c89d7b51c 100644 --- a/gems/toml-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/toml-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[toml-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[toml-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[toml-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/toml-merge/lib/toml/merge.rb b/gems/toml-merge/lib/toml/merge.rb index 8c71baad4..3c07dd473 100644 --- a/gems/toml-merge/lib/toml/merge.rb +++ b/gems/toml-merge/lib/toml/merge.rb @@ -1,8 +1,5 @@ # frozen_string_literal: true -# std libs -require 'json' - # External gems # TreeHaver provides a unified cross-Ruby interface to tree-sitter. # Toml::Merge registers TOML-specific backends with TreeHaver when loaded so @@ -47,13 +44,8 @@ module Merge }.freeze TREE_SITTER_BACKEND_REFERENCE = TreeHaver::BackendReference.new(id: 'kreuzberg-language-pack', family: 'tree-sitter').freeze - CITRUS_BACKEND_REFERENCE = TreeHaver::BackendReference.new(id: 'citrus', family: 'peg').freeze - PARSLET_BACKEND_REFERENCE = TreeHaver::BackendReference.new(id: 'parslet', family: 'peg').freeze BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) - class InlineTable < Hash - end - # Base error class for Toml::Merge # Inherits from Ast::Merge::Error for consistency across merge gems. class Error < Ast::Merge::Error; end @@ -129,11 +121,11 @@ def toml_feature_profile end def available_toml_backends - [TREE_SITTER_BACKEND_REFERENCE, CITRUS_BACKEND_REFERENCE, PARSLET_BACKEND_REFERENCE] + toml_backend_available_for_analysis?(TREE_SITTER_BACKEND_REFERENCE.id) ? [TREE_SITTER_BACKEND_REFERENCE] : [] end def toml_backend_feature_profile(backend: nil) - requested = backend.to_s.empty? ? TREE_SITTER_BACKEND_REFERENCE.id : backend.to_s + requested = requested_toml_backend_id(backend) backend_ref = available_toml_backends.find { |candidate| candidate.id == requested } return unsupported_feature_result("Unsupported TOML backend #{requested}.") unless backend_ref @@ -160,12 +152,12 @@ def toml_plan_context(backend: nil) def parse_toml(source, dialect, backend: nil) return unsupported_feature_parse_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' - requested = backend.to_s.empty? ? TREE_SITTER_BACKEND_REFERENCE.id : backend.to_s + requested = requested_toml_backend_id(backend) return unsupported_feature_parse_result("Unsupported TOML backend #{requested}.") unless available_toml_backends.any? do |candidate| candidate.id == requested end - analyze_toml_source(source, dialect) + TreeHaver.with_backend(requested) { analyze_toml_source(source, dialect) } rescue StandardError => e parse_error_result(e.message) end @@ -173,16 +165,18 @@ def parse_toml(source, dialect, backend: nil) def analyze_toml_source(source, dialect) return unsupported_feature_parse_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' - parsed = parse_toml_document(source) + analysis = FileAnalysis.new(source) + return parse_error_result(analysis.errors.map(&:to_s).join('; ')) unless analysis.valid? + { ok: true, diagnostics: [], analysis: { kind: 'toml', dialect: 'toml', - normalized_source: canonical_toml(parsed), + normalized_source: normalize_toml_source(source), root_kind: 'table', - owners: collect_toml_owners(parsed) + owners: collect_file_analysis_owners(analysis) }, policies: [] } @@ -197,28 +191,20 @@ def match_toml_owners(template, destination) def merge_toml(template_source, destination_source, dialect, backend: nil) return unsupported_feature_merge_result("Unsupported TOML dialect #{dialect}.") unless dialect == 'toml' - requested = backend.to_s.empty? ? TREE_SITTER_BACKEND_REFERENCE.id : backend.to_s + requested = requested_toml_backend_id(backend) return unsupported_feature_merge_result("Unsupported TOML backend #{requested}.") unless available_toml_backends.any? do |candidate| candidate.id == requested end - unless template_source.match?(/^\s*#/) || destination_source.match?(/^\s*#/) - merged = merge_toml_tables(parse_toml_document(template_source), parse_toml_document(destination_source)) - return { - ok: true, - diagnostics: [], - output: canonical_toml(merged), - policies: [DESTINATION_WINS_ARRAY_POLICY] - } + output = TreeHaver.with_backend(requested) do + SmartMerger.new( + template_source, + destination_source, + preference: :destination, + add_template_only_nodes: true + ).merge_result.to_toml end - output = SmartMerger.new( - template_source, - destination_source, - preference: :destination, - add_template_only_nodes: true - ).merge_result.to_toml - { ok: true, diagnostics: [], @@ -243,16 +229,6 @@ def merge_toml_with_parser(template_source, destination_source, dialect) destination_parse = yield(destination_source, dialect) return provider_parse_failure(:destination_parse_error, destination_parse) unless destination_parse[:ok] - unless template_source.match?(/^\s*#/) || destination_source.match?(/^\s*#/) - merged = merge_toml_tables(parse_toml_document(template_source), parse_toml_document(destination_source)) - return { - ok: true, - diagnostics: [], - output: canonical_toml(merged), - policies: [DESTINATION_WINS_ARRAY_POLICY] - } - end - output = SmartMerger.new( template_source, destination_source, @@ -279,12 +255,8 @@ def register_backend! return if BACKEND_REGISTRY.registered TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND_REFERENCE) - TreeHaver::BackendRegistry.register(CITRUS_BACKEND_REFERENCE) - TreeHaver::BackendRegistry.register(PARSLET_BACKEND_REFERENCE) register_tree_sitter_backend! - register_citrus_backend! - register_parslet_backend! BACKEND_REGISTRY.registered = true end @@ -297,30 +269,15 @@ def register_tree_sitter_backend! grammar_finder.register! if grammar_finder.available? end - def register_citrus_backend! - require 'toml-rb' - return unless defined?(TomlRB::Document) + def requested_toml_backend_id(backend) + return backend.to_s unless backend.to_s.empty? - TreeHaver.register_language( - :toml, - grammar_module: TomlRB::Document, - gem_name: 'toml-rb' - ) - rescue LoadError, NameError - nil - end + current = TreeHaver.current_backend_id + return current if toml_backend_available_for_analysis?(current) - def register_parslet_backend! - require 'toml' - return unless defined?(TOML::Parslet) - - TreeHaver.register_language( - :toml, - grammar_class: TOML::Parslet, - gem_name: 'toml' - ) - rescue LoadError, NameError - nil + available_toml_backends.find do |backend_ref| + toml_backend_available_for_analysis?(backend_ref.id) + end&.id || TREE_SITTER_BACKEND_REFERENCE.id end def diagnostic(severity, category, message) @@ -342,273 +299,55 @@ def normalize_toml_source(source) source.gsub(/\r\n?/, "\n") end - def strip_toml_comment(line) - result = +'' - in_string = false - escaped = false - - line.each_char do |char| - if in_string - result << char - if escaped - escaped = false - elsif char == '\\' - escaped = true - elsif char == '"' - in_string = false - end - next - end - - if char == '"' - in_string = true - result << char - next - end - - break if char == '#' - - result << char - end - - raise ParseError, 'Unterminated TOML string.' if in_string - - result.strip - end - - def split_outside_quotes(value, separator) - parts = [] - current = +'' - in_string = false - escaped = false - depth = 0 - - value.each_char do |char| - if in_string - current << char - if escaped - escaped = false - elsif char == '\\' - escaped = true - elsif char == '"' - in_string = false - end - next - end - - case char - when '"' - in_string = true - current << char - when '[', '{' - depth += 1 - current << char - when ']', '}' - depth -= 1 - current << char - else - if char == separator && depth.zero? - parts << current.strip - current = +'' - else - current << char - end - end - end - - raise ParseError, 'Unterminated TOML string, array, or inline table.' if in_string || !depth.zero? - - parts << current.strip - parts - end - - def parse_toml_key_path(value) - trimmed = value.strip - raise ParseError, 'Missing TOML key path.' if trimmed.empty? - - parts = trimmed.split('.').map(&:strip) - raise ParseError, "Unsupported TOML key path #{trimmed}." unless parts.all? do |part| - part.match?(/\A[A-Za-z0-9_-]+\z/) - end - - parts - end - - def parse_toml_scalar_value(value) - case value - when /\A".*"\z/m - JSON.parse(value) - when 'true' - true - when 'false' - false - when /\A-?\d+\z/ - value.to_i - when /\A-?\d+\.\d+\z/ - value.to_f + def toml_backend_available_for_analysis?(backend_id) + register_backend! + registrations = TreeHaver.registered_languages(:toml) + case backend_id.to_s + when TREE_SITTER_BACKEND_REFERENCE.id + registrations.key?(:tree_sitter) || registrations.key?(:tslp) else - raise ParseError, "Unsupported TOML value #{value}." - end - rescue JSON::ParserError - raise ParseError, "Invalid TOML string #{value}." - end - - def parse_toml_value(value) - stripped = value.strip - if stripped.start_with?('[') - raise ParseError, "Invalid TOML array #{value}." unless stripped.end_with?(']') - - inner = stripped[1..-2].strip - return [] if inner.empty? - - split_outside_quotes(inner, ',').map { |entry| parse_toml_scalar_value(entry) } - elsif stripped.start_with?('{') - raise ParseError, "Invalid TOML inline table #{value}." unless stripped.end_with?('}') - - inner = stripped[1..-2].strip - table = InlineTable.new - return table if inner.empty? - - split_outside_quotes(inner, ',').each do |entry| - pair = split_outside_quotes(entry, '=') - raise ParseError, "Invalid TOML inline table entry #{entry}." unless pair.length == 2 - - assign_toml_value(table, parse_toml_key_path(pair[0]), parse_toml_value(pair[1])) - end - table - else - parse_toml_scalar_value(stripped) + false end end - def ensure_toml_table(root, path) - current = root - path.each do |segment| - existing = current[segment] - if existing.nil? - current[segment] = {} - current = current[segment] - elsif toml_table_value?(existing) - current = existing + def collect_file_analysis_owners(analysis) + analysis.statements.flat_map do |statement| + if statement.table? || statement.array_of_tables? + collect_table_statement_owners(statement) + elsif statement.pair? + collect_pair_statement_owners(statement, []) else - raise ParseError, "TOML table path /#{path.join('/')} conflicts with a value." + [] end - end - current + end.sort_by { |owner| owner.fetch(:path) } end - def assign_toml_value(root, path, value) - raise ParseError, 'Missing TOML assignment path.' if path.empty? - - table = ensure_toml_table(root, path[0..-2]) - key = path[-1] - existing = table[key] - raise ParseError, "TOML key /#{path.join('/')} conflicts with a table." if toml_table_value?(existing) - - table[key] = value + def collect_table_statement_owners(statement) + table_path = toml_owner_path_parts(statement.table_name) + owner_kind = statement.array_of_tables? ? 'table_array' : 'table' + [ + { path: toml_owner_path(table_path), owner_kind: owner_kind, match_key: table_path.last } + ] + statement.pairs.flat_map { |pair| collect_pair_statement_owners(pair, table_path) } end - def parse_toml_document(source) - lines = normalize_toml_source(source).split("\n") - root = {} - current_table_path = [] - - lines.each do |raw_line| - line = strip_toml_comment(raw_line) - next if line.empty? - - if line.start_with?('[') - raise ParseError, "Invalid TOML table header #{line}." unless line.end_with?(']') - - current_table_path = parse_toml_key_path(line[1..-2]) - ensure_toml_table(root, current_table_path) - next - end - - parts = split_outside_quotes(line, '=') - raise ParseError, "Invalid TOML assignment #{line}." unless parts.length == 2 - - key_path = parse_toml_key_path(parts[0]) - value = parse_toml_value(parts[1]) - assign_toml_value(root, current_table_path + key_path, value) + def collect_pair_statement_owners(pair, parent_path) + key_path = parent_path + toml_owner_path_parts(pair.key_name) + owners = [{ path: toml_owner_path(key_path), owner_kind: 'key_value', match_key: key_path.last }] + value = pair.value_node + if value&.array? + owners.concat(value.elements.each_with_index.map do |_element, index| + { path: toml_owner_path(key_path + [index.to_s]), owner_kind: 'array_item' } + end) end - - root + owners end - def render_toml_scalar(value) - if value.is_a?(String) - JSON.generate(value) - elsif [true, false].include?(value) - value ? 'true' : 'false' - else - value.to_s - end - end - - def render_toml_value(value) - return "[#{value.map { |item| render_toml_scalar(item) }.join(', ')}]" if value.is_a?(Array) - - if value.is_a?(InlineTable) - pairs = value.keys.sort.map { |key| "#{key} = #{render_toml_value(value[key])}" } - return "{ #{pairs.join(', ')} }" - end - - render_toml_scalar(value) - end - - def render_toml_table(table, path = []) - lines = [] - keys = table.keys.sort - value_keys = keys.reject { |key| toml_table_value?(table[key]) } - table_keys = keys.select { |key| toml_table_value?(table[key]) } - - lines << "[#{path.join('.')}]" unless path.empty? - value_keys.each do |key| - lines << "#{key} = #{render_toml_value(table[key])}" - end - table_keys.each do |key| - lines << '' unless lines.empty? - lines.concat(render_toml_table(table[key], path + [key])) - end - lines - end - - def canonical_toml(table) - "#{render_toml_table(table).join("\n")}\n" - end - - def collect_toml_owners(table, prefix = '') - table.keys.sort.flat_map do |key| - path = "#{prefix}/#{key}" - value = table[key] - if value.is_a?(Array) - [{ path: path, owner_kind: 'key_value', match_key: key }] + - value.each_index.map { |index| { path: "#{path}/#{index}", owner_kind: 'array_item' } } - elsif toml_table_value?(value) - [{ path: path, owner_kind: 'table', match_key: key }] + collect_toml_owners(value, path) - else - [{ path: path, owner_kind: 'key_value', match_key: key }] - end - end - end - - def merge_toml_tables(template, destination) - (template.keys | destination.keys).sort.each_with_object({}) do |key, merged| - merged[key] = if !template.key?(key) - destination[key] - elsif !destination.key?(key) - template[key] - elsif toml_table_value?(template[key]) && toml_table_value?(destination[key]) - merge_toml_tables(template[key], destination[key]) - else - destination[key] - end - end + def toml_owner_path_parts(value) + value.to_s.split('.').map(&:strip).reject(&:empty?) end - def toml_table_value?(value) - value.is_a?(Hash) && !value.is_a?(InlineTable) + def toml_owner_path(parts) + "/#{parts.join('/')}" end def unsupported_feature_parse_result(message) diff --git a/gems/toml-merge/lib/toml/merge/conflict_resolver.rb b/gems/toml-merge/lib/toml/merge/conflict_resolver.rb index 080636b63..fbc8581ec 100644 --- a/gems/toml-merge/lib/toml/merge/conflict_resolver.rb +++ b/gems/toml-merge/lib/toml/merge/conflict_resolver.rb @@ -107,6 +107,10 @@ def merge_node_lists_to_emitter(template_nodes, dest_nodes, template_analysis, d refined_matches = build_refined_matches(template_nodes, dest_nodes, template_by_sig, dest_by_sig) refined_dest_to_template = refined_matches.invert + if canonical_unmatched_pair_list?(template_nodes, dest_nodes, template_by_sig, dest_by_sig, refined_matches) + return merge_unmatched_pair_lists_to_emitter(template_nodes, dest_nodes, template_analysis, dest_analysis) + end + # Track consumed individual node indices (not just signatures) so that # multiple nodes sharing the same signature are matched 1:1 in order # rather than collapsed into a single match. @@ -171,9 +175,13 @@ def merge_node_lists_to_emitter(template_nodes, dest_nodes, template_analysis, d dest_analysis ) - emit_gap_before_node( + emit_gap_before_matched_node( selected_node, selected_analysis, + template_node, + template_analysis, + dest_node, + dest_analysis, prev_emitted_end_line, prev_emitted_analysis, skip_for_borrowed_leading_region: @preference == :template && leading_region_present?(dest_node, @@ -225,9 +233,13 @@ def merge_node_lists_to_emitter(template_nodes, dest_nodes, template_analysis, d end # Merge matched nodes - emit_gap_before_node( + emit_gap_before_matched_node( selected_node, selected_analysis, + template_node, + template_analysis, + dest_node, + dest_analysis, prev_emitted_end_line, prev_emitted_analysis, skip_for_borrowed_leading_region: @preference == :template && leading_region_present?(dest_node, @@ -347,6 +359,29 @@ def redundant_destination_pair_duplicate?(node, signature, emitted_signatures) signature && node.respond_to?(:pair?) && node.pair? && emitted_signatures.include?(signature) end + def canonical_unmatched_pair_list?(template_nodes, dest_nodes, template_by_sig, dest_by_sig, refined_matches) + return false unless @add_template_only_nodes + return false unless refined_matches.empty? + return false unless (template_by_sig.keys & dest_by_sig.keys).empty? + return false if template_nodes.empty? || dest_nodes.empty? + + (template_nodes + dest_nodes).all? { |node| node.respond_to?(:pair?) && node.pair? } + end + + def merge_unmatched_pair_lists_to_emitter(template_nodes, dest_nodes, template_analysis, dest_analysis) + entries = template_nodes.map { |node| [node, template_analysis] } + + dest_nodes.map { |node| [node, dest_analysis] } + prev_emitted_end_line = nil + prev_emitted_analysis = nil + + entries.sort_by { |node, _analysis| node.respond_to?(:key_name) ? node.key_name.to_s : node.type.to_s }.each do |node, analysis| + emit_gap_before_node(node, analysis, prev_emitted_end_line, prev_emitted_analysis) + emit_node(node, analysis) + prev_emitted_end_line = emitted_end_line_for(node) + prev_emitted_analysis = analysis + end + end + # Emit a single node to the emitter # @param node [NodeWrapper] Node to emit # @param analysis [FileAnalysis] Analysis for accessing source @@ -990,6 +1025,27 @@ def emit_gap_before_node(node, analysis, prev_end_line, prev_analysis, skip_for_ emit_interstitial_blank_lines(prev_end_line + 1, node.start_line - 1, analysis) end + def emit_gap_before_matched_node(selected_node, selected_analysis, template_node, template_analysis, dest_node, + dest_analysis, prev_end_line, prev_analysis, + skip_for_borrowed_leading_region: false) + before_count = @emitter.lines.length + emit_gap_before_node( + selected_node, + selected_analysis, + prev_end_line, + prev_analysis, + skip_for_borrowed_leading_region: skip_for_borrowed_leading_region + ) + return if @emitter.lines.length > before_count + + alternate_node, alternate_analysis = if selected_node.equal?(dest_node) + [template_node, template_analysis] + else + [dest_node, dest_analysis] + end + emit_gap_before_node(alternate_node, alternate_analysis, prev_end_line, prev_analysis) + end + def leading_region_present?(node, analysis) region = attachment_region(node, analysis, :leading_region) region && (!region.respond_to?(:empty?) || !region.empty?) diff --git a/gems/toml-merge/lib/toml/merge/file_analysis.rb b/gems/toml-merge/lib/toml/merge/file_analysis.rb index 2627af709..6e7aca1fa 100644 --- a/gems/toml-merge/lib/toml/merge/file_analysis.rb +++ b/gems/toml-merge/lib/toml/merge/file_analysis.rb @@ -263,8 +263,8 @@ def root_pairs def parse_toml # TreeHaver handles everything: # - Backend selection (via TREE_HAVER_BACKEND env or TreeHaver.backend) - # - Registered tree-sitter grammar lookup / provisioning - # - Registered Citrus or Parslet TOML backends from Toml::Merge + # - Registered tree-sitter grammar lookup or TSLP backend provisioning + # - Registered provider backends from parser-specific TOML gems parser_options = {} parser_options[:library_path] = @parser_path if @parser_path diff --git a/gems/toml-merge/lib/toml/merge/node_wrapper.rb b/gems/toml-merge/lib/toml/merge/node_wrapper.rb index 6dbeb058a..9d4326346 100644 --- a/gems/toml-merge/lib/toml/merge/node_wrapper.rb +++ b/gems/toml-merge/lib/toml/merge/node_wrapper.rb @@ -203,7 +203,7 @@ def table_name return node_text(child)&.strip end end - nil + parslet_element_table_name end # Get the key name if this is a pair node @@ -390,9 +390,11 @@ def content def effective_end_line return @end_line if !(table? || array_of_tables?) || @document_root.nil? - # Check if we have pairs as children (tree-sitter structure) + # Check if we have pairs as children (tree-sitter structure). Some + # backends expose table node spans that run through the next table + # boundary, so use the semantic child range when it is available. child_pairs = collect_child_pairs - return @end_line if child_pairs.any? + return child_pairs.map(&:end_line).compact.max || @start_line if child_pairs.any? # Citrus structure: find the last pair that belongs to us sibling_pairs = collect_sibling_pairs_for_table @@ -496,6 +498,16 @@ def parslet_element_canonical_type :element end + def parslet_element_table_name + return unless parslet_element_node? + + name = node_text(@node)&.strip + return if name.nil? || name.empty? + return if name.include?('=') + + name + end + def each_child(node) children = [] node.each { |child| children << child } diff --git a/gems/toml-merge/results/test_results.html b/gems/toml-merge/results/test_results.html new file mode 100644 index 000000000..4ebc70067 --- /dev/null +++ b/gems/toml-merge/results/test_results.html @@ -0,0 +1,341 @@ + + + + RSpec results + + + + + + + + +
    + +
    +
    +

    RSpec Code Examples

    +
    + +
    + + + +
    + +
    +

     

    +

     

    +
    +
    + + +
    +
    +
    +
    TOML reproducible +
    conforms to the TOML parse, structure, matching, and merge fixtures with the tree-sitter substrate0.04824s
    + +
    conforms to +
    produces the expected result0.05502s
    + +
    is idempotent (merging again produces same result)0.00579s
    +
    +
    +
    +
    +
    when template preference keeps destination docs on a matched array of tables
    +
    +
    +
    +
    +
    behaves like a reproducible merge
    + +
    is idempotent (merging again produces same result)0.00287s
    + +
    produces the expected result0.00146s
    +
    +
    +
    +
    +
    when template preference keeps destination docs on an adjacent matched table
    +
    +
    +
    +
    +
    behaves like a reproducible merge
    + +
    is idempotent (merging again produces same result)0.00471s
    + +
    produces the expected result0.00250s
    +
    +
    + + +
    +
    + + +
    conforms to the slice-139 family named-suite plan fixture0.00059s
    + +
    conforms to the slice-137 TOML family manifest fixture0.00034s
    + +
    parses mise-style dotted env keys and inline tables0.00068s
    + +
    projects arrays of tables through the TOML substrate0.00891s
    + + + + + + + + diff --git a/gems/toml-merge/results/test_results.xml b/gems/toml-merge/results/test_results.xml new file mode 100644 index 000000000..a04e3662c --- /dev/null +++ b/gems/toml-merge/results/test_results.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + +ture profile fixtures" file="./spec/fixtures_integration_spec.rb" time="0.000453"> + + + + + + + diff --git a/gems/toml-merge/spec/fixtures_integration_spec.rb b/gems/toml-merge/spec/fixtures_integration_spec.rb index 3a2273c4a..d9956c039 100644 --- a/gems/toml-merge/spec/fixtures_integration_spec.rb +++ b/gems/toml-merge/spec/fixtures_integration_spec.rb @@ -1,8 +1,5 @@ # frozen_string_literal: true -require 'citrus/toml/merge' -require 'parslet/toml/merge' - RSpec.describe Toml::Merge do def fixtures_root Pathname(__dir__).join('..', '..', '..', '..', 'fixtures').expand_path @@ -56,6 +53,15 @@ def json_ready(value) merge_fixture = toml_fixture('merge') merge_result = described_class.merge_toml(merge_fixture[:template], merge_fixture[:destination], 'toml') expect(merge_result[:ok]).to eq(merge_fixture.dig(:expected, :ok)) + expect(merge_result[:output]).to include('title = "Structured Merge"') + expect(merge_result[:output]).to include('name = "structuredmerge"') + expect(merge_result[:output]).to include('tags = ["destination"]') + expect(merge_result[:output]).to include('version = "0.2.0"') + expect(merge_result[:output]).to include('authors = ["pb"]') + expect(merge_result[:output]).to include('enabled = false') + expect(merge_result[:output]).to include('release = true') + expect(merge_result[:output]).not_to include('tags = ["template"]') + expect(merge_result[:output]).not_to include('version = "0.1.0"') expect(merge_result[:output]).to eq(merge_fixture.dig(:expected, :output)) end @@ -63,9 +69,7 @@ def json_ready(value) expect(json_ready(described_class.toml_feature_profile)).to eq(json_ready(family_profile_fixture[:feature_profile])) expect(json_ready(described_class.available_toml_backends.map(&:to_h))).to eq( json_ready([ - { id: 'kreuzberg-language-pack', family: 'tree-sitter' }, - { id: 'citrus', family: 'peg' }, - { id: 'parslet', family: 'peg' } + { id: 'kreuzberg-language-pack', family: 'tree-sitter' } ]) ) expect(json_ready(TreeHaver::BackendRegistry.fetch('kreuzberg-language-pack')&.to_h)).to eq( @@ -82,7 +86,7 @@ def json_ready(value) ) ) - expect(json_ready(described_class.toml_backend_feature_profile)).to include( + expect(json_ready(described_class.toml_backend_feature_profile(backend: 'kreuzberg-language-pack'))).to include( json_ready(fixture[:tree_sitter]) ) end @@ -96,7 +100,9 @@ def json_ready(value) ) ) - expect(json_ready(described_class.toml_plan_context)).to eq(json_ready(fixture[:tree_sitter])) + expect(json_ready(described_class.toml_plan_context(backend: 'kreuzberg-language-pack'))).to eq( + json_ready(fixture[:tree_sitter]) + ) end it 'conforms to the slice-137 TOML family manifest fixture' do @@ -141,26 +147,25 @@ def json_ready(value) end it 'preserves destination TOML comments and blank lines while adding template-only keys' do - template = <<~TOML - # project configuration - name = "kettle-jem" - generated = true - TOML - destination = <<~TOML - # project configuration - name = "kettle-jem" - - # local operator notes - local = true - TOML + fixture = read_json( + fixtures_root.join( + 'toml', + 'slice-721-formatting-preservation', + 'dotted-inline-comments-arrays.json' + ) + ) - result = described_class.merge_toml(template, destination, 'toml') + result = described_class.merge_toml(fixture[:template], fixture[:destination], fixture[:dialect]) - expect(result[:ok]).to be(true) + expect(result[:ok]).to eq(fixture.dig(:expected, :ok)) expect(result[:output]).to include('# project configuration') expect(result[:output]).to include("\n\n# local operator notes\n") expect(result[:output]).to include('local = true') - expect(result[:output]).to include('generated = true') + expect(result[:output]).to include('_.file = { path = ".env.local", redact = true }') + expect(result[:output]).to include('_.path = ["exe", "bin"]') + expect(result[:output]).to include('[[profiles.semantic-diff.attributes]]') + expect(result[:output]).to include('diff = "smorg-rb"') + expect(result[:output]).to eq(fixture.dig(:expected, :output)) end it 'records emitter source provenance line metadata for raw source rendering' do @@ -197,35 +202,73 @@ def json_ready(value) ) end - it 'projects equivalent normalized output across active TOML provider surfaces' do + it 'projects arrays of tables through the TOML substrate' do source = <<~TOML - # Shared provider projection fixture. - title = "example" + version = 1 - [env] - KJ_PROJECT_EMOJI = "gem" - path = ["exe", "bin"] - source = ".config/mise/env.sh" + [profiles.semantic-diff] + description = "Semantic diff" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-rb" + + [[profiles.semantic-diff.git_config]] + scope = "global" + key = "diff.smorg-rb.command" + value = "smorg-rb diff-driver" TOML - results = { - core: described_class.parse_toml(source, 'toml'), - citrus: Citrus::Toml::Merge.parse_toml(source, 'toml'), - parslet: Parslet::Toml::Merge.parse_toml(source, 'toml') - } + result = described_class.parse_toml(source, 'toml') - expect(results.transform_values { |result| result.fetch(:ok) }).to eq( - core: true, - citrus: true, - parslet: true + expect(result.fetch(:ok)).to be(true) + expect(result.dig(:analysis, :normalized_source)).to include('[[profiles.semantic-diff.attributes]]') + expect(result.dig(:analysis, :normalized_source)).to include('[[profiles.semantic-diff.git_config]]') + expect(result.dig(:analysis, :owners)).to include( + include(path: '/profiles/semantic-diff/attributes', owner_kind: 'table_array', match_key: 'attributes'), + include(path: '/profiles/semantic-diff/git_config', owner_kind: 'table_array', match_key: 'git_config') ) - normalized = results.transform_values { |result| result.dig(:analysis, :normalized_source) } - owners = results.transform_values { |result| json_ready(result.dig(:analysis, :owners)) } - expect(normalized.values.uniq).to eq([normalized.fetch(:core)]) - expect(owners.values.uniq).to eq([owners.fetch(:core)]) end - it 'exposes non-overlapping effective table ranges and source fragments across TOML providers' do + it 'merges comment-free TOML arrays of tables with destination preference' do + template = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Template driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-ruby" + + [profiles.textconv-normalized] + description = "Template-only profile" + + [[profiles.textconv-normalized.attributes]] + pattern = "*.json" + diff = "smorg-json-textconv" + TOML + destination = <<~TOML + version = 1 + + [profiles.semantic-diff] + description = "Destination driver" + + [[profiles.semantic-diff.attributes]] + pattern = "*.rb" + diff = "smorg-rb" + TOML + + result = described_class.merge_toml(template, destination, 'toml') + + expect(result.fetch(:ok)).to be(true) + expect(result.fetch(:output)).to include('diff = "smorg-rb"') + expect(result.fetch(:output)).to include('description = "Destination driver"') + expect(result.fetch(:output)).to include('[[profiles.textconv-normalized.attributes]]') + expect(result.fetch(:output)).not_to include('smorg-ruby') + end + + it 'exposes non-overlapping effective table ranges and source fragments through the TOML substrate' do source = <<~TOML title = "example" @@ -237,59 +280,26 @@ def json_ready(value) ruby = "4.0.2" TOML - analyses = { - core: described_class::FileAnalysis.new(source), - citrus: TreeHaver.with_backend('citrus') { described_class::FileAnalysis.new(source) }, - parslet: TreeHaver.with_backend('parslet') { described_class::FileAnalysis.new(source) } - } + analysis = described_class::FileAnalysis.new(source) + expect(analysis).to be_valid - analyses.each_value { |analysis| expect(analysis).to be_valid } - - table_ranges = analyses.transform_values do |analysis| - analysis.tables.to_h do |table| - [table.table_name, table.start_line..table.effective_end_line] - end + table_ranges = analysis.tables.to_h do |table| + [table.table_name, table.start_line..table.effective_end_line] end - table_fragments = analyses.transform_values do |analysis| - analysis.tables.to_h do |table| - [table.table_name, table.content] - end + table_fragments = analysis.tables.to_h do |table| + [table.table_name, table.content] end - expect(table_ranges.values.uniq).to eq([table_ranges.fetch(:core)]) - expect(table_ranges.fetch(:core)).to eq( + expect(table_ranges).to eq( 'env' => 3..5, 'tools' => 7..8 ) - expect(table_fragments.values.uniq).to eq([table_fragments.fetch(:core)]) - expect(table_fragments.fetch(:core)).to eq( + expect(table_fragments).to eq( 'env' => "[env]\nproject = \"kettle-jem\"\npath = [\"exe\", \"bin\"]", 'tools' => "[tools]\nruby = \"4.0.2\"" ) end - it 'reports the Parslet provider gap for mise-style dotted keys and inline tables' do - source = <<~TOML - [env] - KJ_PROJECT_EMOJI = "gem" - _.file = { path = ".env.local", redact = true } - _.path = ["exe", "bin"] - _.source = ".config/mise/env.sh" - TOML - - core = described_class.parse_toml(source, 'toml') - citrus = Citrus::Toml::Merge.parse_toml(source, 'toml') - parslet = Parslet::Toml::Merge.parse_toml(source, 'toml') - - expect(core.fetch(:ok)).to be(true) - expect(citrus.fetch(:ok)).to be(true) - expect(json_ready(citrus.dig(:analysis, :owners))).to eq(json_ready(core.dig(:analysis, :owners))) - expect(parslet.fetch(:ok)).to be(false) - expect(parslet.fetch(:diagnostics)).to include( - include(category: 'parse_error') - ) - end - it 'conforms to the slice-139 family named-suite plan fixture' do fixture = read_json( fixtures_root.join( diff --git a/gems/tree_haver/.gitattributes b/gems/tree_haver/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/tree_haver/.gitattributes +++ b/gems/tree_haver/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/tree_haver/.kettle-drift.lock b/gems/tree_haver/.kettle-drift.lock index 993369d13..a24d67c14 100644 --- a/gems/tree_haver/.kettle-drift.lock +++ b/gems/tree_haver/.kettle-drift.lock @@ -3,8 +3,8 @@ { "file": "README.md", "lines": [ - 1446, - 1472 + 1451, + 1477 ] } ], @@ -12,8 +12,8 @@ { "file": "README.md", "lines": [ - 1447, - 1473 + 1452, + 1478 ] } ], @@ -21,8 +21,8 @@ { "file": "README.md", "lines": [ - 1448, - 1474 + 1453, + 1479 ] } ], diff --git a/gems/tree_haver/.rubocop_gradual.lock b/gems/tree_haver/.rubocop_gradual.lock index 66df63bfc..2a04c6a43 100644 --- a/gems/tree_haver/.rubocop_gradual.lock +++ b/gems/tree_haver/.rubocop_gradual.lock @@ -2,7 +2,7 @@ ".simplecov:3575099246": [ [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177542] ], - "Gemfile:1933889768": [ + "Gemfile:31081928": [ [28, 1, 59, "Lint/EmptyConditionalBody: Avoid `if` branches without a body.", 4279378582] ], "Rakefile:1868927885": [ @@ -76,30 +76,32 @@ [1, 1, 0, "Naming/FileName: The name of this source file (`vHEAD.gemfile`) should use snake_case.", 5381], [1, 1, 1, "Style/FrozenStringLiteralComment: Missing frozen string literal comment.", 177600] ], - "lib/tree_haver.rb:1043643469": [ - [48, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465], - [48, 1, 14703, "Metrics/ModuleLength: Module has too many lines. [395/100]", 2758907023], - [66, 3, 566, "Metrics/MethodLength: Method has too many lines. [12/10]", 1536513137], - [123, 3, 272, "Metrics/MethodLength: Method has too many lines. [11/10]", 505877912], - [155, 3, 543, "Metrics/MethodLength: Method has too many lines. [14/10]", 3733215372], - [220, 3, 458, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `backend_module` is too high. [9/7]", 73937708], - [220, 3, 458, "Metrics/MethodLength: Method has too many lines. [12/10]", 73937708], - [220, 3, 458, "Metrics/PerceivedComplexity: Perceived complexity for `backend_module` is too high. [9/8]", 73937708], - [256, 3, 1024, "Metrics/AbcSize: Assignment Branch Condition size for `register_language` is too high. [<0, 20, 10> 22.36/17]", 53014028], - [256, 3, 1024, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `register_language` is too high. [11/7]", 53014028], - [256, 3, 1024, "Metrics/MethodLength: Method has too many lines. [12/10]", 53014028], - [256, 3, 1024, "Metrics/PerceivedComplexity: Perceived complexity for `register_language` is too high. [11/8]", 53014028], - [256, 24, 150, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [8/5]", 893242366], - [281, 3, 1355, "Metrics/AbcSize: Assignment Branch Condition size for `parser_for` is too high. [<11, 25, 13> 30.25/17]", 4004028797], - [281, 3, 1355, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parser_for` is too high. [14/7]", 4004028797], - [281, 3, 1355, "Metrics/MethodLength: Method has too many lines. [27/10]", 4004028797], - [281, 3, 1355, "Metrics/PerceivedComplexity: Perceived complexity for `parser_for` is too high. [14/8]", 4004028797], - [320, 3, 2089, "Metrics/MethodLength: Method has too many lines. [51/10]", 2791676388], - [374, 3, 565, "Metrics/AbcSize: Assignment Branch Condition size for `requested_backend_type` is too high. [<3, 16, 8> 18.14/17]", 2317624457], - [374, 3, 565, "Metrics/MethodLength: Method has too many lines. [12/10]", 2317624457], - [392, 3, 696, "Metrics/MethodLength: Method has too many lines. [14/10]", 307274721], - [470, 3, 425, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `backend_module_for` is too high. [9/7]", 3448932255], - [470, 3, 425, "Metrics/MethodLength: Method has too many lines. [20/10]", 3448932255] + "lib/tree_haver.rb:2762889207": [ + [49, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465], + [49, 1, 15892, "Metrics/ModuleLength: Module has too many lines. [421/100]", 2307494458], + [67, 3, 566, "Metrics/MethodLength: Method has too many lines. [12/10]", 1536513137], + [124, 3, 272, "Metrics/MethodLength: Method has too many lines. [11/10]", 505877912], + [156, 3, 543, "Metrics/MethodLength: Method has too many lines. [14/10]", 3733215372], + [221, 3, 458, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `backend_module` is too high. [9/7]", 73937708], + [221, 3, 458, "Metrics/MethodLength: Method has too many lines. [12/10]", 73937708], + [221, 3, 458, "Metrics/PerceivedComplexity: Perceived complexity for `backend_module` is too high. [9/8]", 73937708], + [257, 3, 1024, "Metrics/AbcSize: Assignment Branch Condition size for `register_language` is too high. [<0, 20, 10> 22.36/17]", 53014028], + [257, 3, 1024, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `register_language` is too high. [11/7]", 53014028], + [257, 3, 1024, "Metrics/MethodLength: Method has too many lines. [12/10]", 53014028], + [257, 3, 1024, "Metrics/PerceivedComplexity: Perceived complexity for `register_language` is too high. [11/8]", 53014028], + [257, 24, 150, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [8/5]", 893242366], + [282, 3, 1521, "Metrics/AbcSize: Assignment Branch Condition size for `parser_for` is too high. [<12, 27, 14> 32.7/17]", 498764853], + [282, 3, 1521, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `parser_for` is too high. [15/7]", 498764853], + [282, 3, 1521, "Metrics/MethodLength: Method has too many lines. [30/10]", 498764853], + [282, 3, 1521, "Metrics/PerceivedComplexity: Perceived complexity for `parser_for` is too high. [15/8]", 498764853], + [325, 3, 2089, "Metrics/MethodLength: Method has too many lines. [51/10]", 2791676388], + [379, 3, 704, "Metrics/AbcSize: Assignment Branch Condition size for `requested_backend_type` is too high. [<4, 17, 9> 19.65/17]", 3087691662], + [379, 3, 704, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `requested_backend_type` is too high. [8/7]", 3087691662], + [379, 3, 704, "Metrics/MethodLength: Method has too many lines. [14/10]", 3087691662], + [379, 3, 704, "Metrics/PerceivedComplexity: Perceived complexity for `requested_backend_type` is too high. [9/8]", 3087691662], + [409, 3, 696, "Metrics/MethodLength: Method has too many lines. [14/10]", 307274721], + [502, 3, 489, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `backend_module_for` is too high. [10/7]", 3448932255], + [502, 3, 489, "Metrics/MethodLength: Method has too many lines. [22/10]", 3448932255] ], "lib/tree_haver/backend_api.rb:3354059061": [ [30, 3, 12181, "Metrics/ModuleLength: Module has too many lines. [243/100]", 205645546], @@ -246,6 +248,15 @@ [52, 9, 548, "Metrics/MethodLength: Method has too many lines. [15/10]", 3791803966], [156, 121, 1, "Layout/LineLength: Line is too long. [121/120]", 177548] ], + "lib/tree_haver/backends/tslp.rb:1702759733": [ + [18, 9, 559, "Metrics/MethodLength: Method has too many lines. [14/10]", 1306507697], + [68, 7, 14, "Style/Documentation: Missing top-level documentation comment for `class TreeHaver::Backends::Tslp::Language`.", 3674592793], + [80, 7, 12, "Style/Documentation: Missing top-level documentation comment for `class TreeHaver::Backends::Tslp::Parser`.", 2485220908], + [81, 9, 582, "Metrics/AbcSize: Assignment Branch Condition size for `parse` is too high. [<2, 17, 4> 17.58/17]", 103430155], + [103, 7, 10, "Style/Documentation: Missing top-level documentation comment for `class TreeHaver::Backends::Tslp::Tree`.", 3516465773], + [109, 7, 10, "Style/Documentation: Missing top-level documentation comment for `class TreeHaver::Backends::Tslp::Node`.", 3515419275], + [143, 13, 10, "Naming/PredicatePrefix: Rename `has_error?` to `error?`.", 946854183] + ], "lib/tree_haver/base/comment.rb:699160654": [ [10, 5, 8183, "Metrics/ClassLength: Class has too many lines. [152/100]", 4001235397] ], @@ -271,45 +282,44 @@ [66, 5, 3770, "Metrics/PerceivedComplexity: Perceived complexity for `available?` is too high. [22/8]", 3886463212], [94, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5858894] ], - "lib/tree_haver/contracts.rb:1759652181": [ + "lib/tree_haver/contracts.rb:1571706604": [ [3, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465], - [3, 1, 30217, "Metrics/ModuleLength: Module has too many lines. [1005/100]", 1179515902], + [3, 1, 28139, "Metrics/ModuleLength: Module has too many lines. [924/100]", 3701899480], [91, 5, 732, "Metrics/AbcSize: Assignment Branch Condition size for `to_h` is too high. [<0, 18, 2> 18.11/17]", 3031678572], [91, 5, 732, "Metrics/MethodLength: Method has too many lines. [17/10]", 3031678572], [170, 5, 697, "Metrics/MethodLength: Method has too many lines. [18/10]", 389212725], [231, 5, 507, "Metrics/MethodLength: Method has too many lines. [13/10]", 2631332781], - [351, 5, 580, "Metrics/MethodLength: Method has too many lines. [13/10]", 2166080747], - [580, 5, 558, "Metrics/AbcSize: Assignment Branch Condition size for `to_h` is too high. [<0, 17, 4> 17.46/17]", 2109105399], - [580, 5, 558, "Metrics/MethodLength: Method has too many lines. [18/10]", 2109105399], - [632, 3, 780, "Metrics/AbcSize: Assignment Branch Condition size for `library_path_errors` is too high. [<3, 20, 10> 22.56/17]", 1003454820], - [632, 3, 780, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `library_path_errors` is too high. [10/7]", 1003454820], - [632, 3, 780, "Metrics/MethodLength: Method has too many lines. [14/10]", 1003454820], - [632, 3, 780, "Metrics/PerceivedComplexity: Perceived complexity for `library_path_errors` is too high. [10/8]", 1003454820], - [674, 3, 686, "Metrics/MethodLength: Method has too many lines. [16/10]", 2530945134], - [696, 3, 483, "Metrics/MethodLength: Method has too many lines. [15/10]", 3654427448], - [715, 3, 511, "Metrics/MethodLength: Method has too many lines. [16/10]", 145071639], - [792, 5, 384, "Metrics/AbcSize: Assignment Branch Condition size for `to_h` is too high. [<0, 19, 6> 19.92/17]", 1287649270], - [863, 5, 449, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `to_h` is too high. [10/7]", 1722332092], - [863, 5, 449, "Metrics/PerceivedComplexity: Perceived complexity for `to_h` is too high. [10/8]", 1722332092], - [895, 121, 1, "Layout/LineLength: Line is too long. [121/120]", 177610], - [896, 5, 420, "Metrics/MethodLength: Method has too many lines. [12/10]", 722580369], - [936, 42, 8, "Lint/StructNewOverride: `:entries` member overrides `Struct#entries` and it may be unexpected.", 999966509], - [959, 3, 473, "Metrics/MethodLength: Method has too many lines. [18/10]", 1284459726], - [980, 3, 655, "Metrics/AbcSize: Assignment Branch Condition size for `byte_offset_for_point` is too high. [<7, 25, 14> 29.5/17]", 1278853347], - [980, 3, 655, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `byte_offset_for_point` is too high. [9/7]", 1278853347], - [980, 3, 655, "Metrics/MethodLength: Method has too many lines. [17/10]", 1278853347], - [980, 3, 655, "Metrics/PerceivedComplexity: Perceived complexity for `byte_offset_for_point` is too high. [10/8]", 1278853347] - ], - "lib/tree_haver/grammar_finder.rb:3769422606": [ - [55, 3, 13963, "Metrics/ClassLength: Class has too many lines. [213/100]", 842233610], - [120, 5, 516, "Metrics/AbcSize: Assignment Branch Condition size for `search_paths` is too high. [<6, 15, 6> 17.23/17]", 2953596940], - [120, 5, 516, "Metrics/MethodLength: Method has too many lines. [15/10]", 2953596940], - [160, 5, 1737, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `find_library_path` is too high. [8/7]", 4164717952], - [160, 5, 1737, "Metrics/MethodLength: Method has too many lines. [25/10]", 4164717952], - [272, 7, 845, "Metrics/MethodLength: Method has too many lines. [12/10]", 916567473], - [333, 5, 479, "Metrics/MethodLength: Method has too many lines. [13/10]", 309140318], - [352, 5, 805, "Metrics/MethodLength: Method has too many lines. [11/10]", 667615068], - [389, 5, 1028, "Metrics/MethodLength: Method has too many lines. [22/10]", 3088457603] + [329, 5, 580, "Metrics/MethodLength: Method has too many lines. [13/10]", 2166080747], + [558, 5, 558, "Metrics/AbcSize: Assignment Branch Condition size for `to_h` is too high. [<0, 17, 4> 17.46/17]", 2109105399], + [558, 5, 558, "Metrics/MethodLength: Method has too many lines. [18/10]", 2109105399], + [610, 3, 780, "Metrics/AbcSize: Assignment Branch Condition size for `library_path_errors` is too high. [<3, 20, 10> 22.56/17]", 1003454820], + [610, 3, 780, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `library_path_errors` is too high. [10/7]", 1003454820], + [610, 3, 780, "Metrics/MethodLength: Method has too many lines. [14/10]", 1003454820], + [610, 3, 780, "Metrics/PerceivedComplexity: Perceived complexity for `library_path_errors` is too high. [10/8]", 1003454820], + [652, 3, 686, "Metrics/MethodLength: Method has too many lines. [16/10]", 2530945134], + [674, 3, 483, "Metrics/MethodLength: Method has too many lines. [15/10]", 3654427448], + [693, 3, 511, "Metrics/MethodLength: Method has too many lines. [16/10]", 145071639], + [770, 5, 384, "Metrics/AbcSize: Assignment Branch Condition size for `to_h` is too high. [<0, 19, 6> 19.92/17]", 1287649270], + [841, 5, 449, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `to_h` is too high. [10/7]", 1722332092], + [841, 5, 449, "Metrics/PerceivedComplexity: Perceived complexity for `to_h` is too high. [10/8]", 1722332092], + [873, 121, 1, "Layout/LineLength: Line is too long. [121/120]", 177610], + [874, 5, 420, "Metrics/MethodLength: Method has too many lines. [12/10]", 722580369], + [914, 42, 8, "Lint/StructNewOverride: `:entries` member overrides `Struct#entries` and it may be unexpected.", 999966509], + [937, 3, 473, "Metrics/MethodLength: Method has too many lines. [18/10]", 1284459726], + [958, 3, 655, "Metrics/AbcSize: Assignment Branch Condition size for `byte_offset_for_point` is too high. [<7, 25, 14> 29.5/17]", 1278853347], + [958, 3, 655, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `byte_offset_for_point` is too high. [9/7]", 1278853347], + [958, 3, 655, "Metrics/MethodLength: Method has too many lines. [17/10]", 1278853347], + [958, 3, 655, "Metrics/PerceivedComplexity: Perceived complexity for `byte_offset_for_point` is too high. [10/8]", 1278853347] + ], + "lib/tree_haver/grammar_finder.rb:3107533528": [ + [55, 3, 13660, "Metrics/ClassLength: Class has too many lines. [200/100]", 1847629568], + [155, 5, 1710, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `find_library_path` is too high. [8/7]", 4164717952], + [155, 5, 1710, "Metrics/MethodLength: Method has too many lines. [25/10]", 4164717952], + [269, 7, 845, "Metrics/MethodLength: Method has too many lines. [12/10]", 916567473], + [315, 5, 577, "Metrics/MethodLength: Method has too many lines. [16/10]", 651056353], + [340, 5, 623, "Metrics/MethodLength: Method has too many lines. [14/10]", 1438381615], + [360, 5, 846, "Metrics/MethodLength: Method has too many lines. [12/10]", 667615068], + [398, 5, 653, "Metrics/MethodLength: Method has too many lines. [12/10]", 1765172995] ], "lib/tree_haver/kaitai_backend.rb:335397596": [ [3, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465] @@ -328,25 +338,8 @@ [156, 7, 4289, "Metrics/PerceivedComplexity: Perceived complexity for `method_missing` is too high. [26/8]", 1314689525], [274, 7, 786, "Metrics/MethodLength: Method has too many lines. [12/10]", 3697766033] ], - "lib/tree_haver/language_pack.rb:3634605947": [ - [6, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465], - [6, 1, 10559, "Metrics/ModuleLength: Module has too many lines. [285/100]", 1485243593], - [47, 3, 1095, "Metrics/AbcSize: Assignment Branch Condition size for `parse_with_language_pack` is too high. [<5, 25, 3> 25.67/17]", 2100474993], - [47, 3, 1095, "Metrics/MethodLength: Method has too many lines. [20/10]", 2100474993], - [72, 3, 1420, "Metrics/AbcSize: Assignment Branch Condition size for `process_with_language_pack` is too high. [<5, 31, 3> 31.54/17]", 3796531166], - [72, 3, 1420, "Metrics/MethodLength: Method has too many lines. [27/10]", 3796531166], - [110, 3, 708, "Metrics/AbcSize: Assignment Branch Condition size for `language_pack_result_hash` is too high. [<4, 22, 8> 23.75/17]", 3436019149], - [110, 3, 708, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `language_pack_result_hash` is too high. [9/7]", 3436019149], - [110, 3, 708, "Metrics/MethodLength: Method has too many lines. [14/10]", 3436019149], - [110, 3, 708, "Metrics/PerceivedComplexity: Perceived complexity for `language_pack_result_hash` is too high. [9/8]", 3436019149], - [165, 3, 403, "Metrics/MethodLength: Method has too many lines. [11/10]", 1836909640], - [180, 3, 398, "Metrics/MethodLength: Method has too many lines. [11/10]", 2881064520], - [247, 3, 436, "Metrics/MethodLength: Method has too many lines. [13/10]", 4289517332], - [265, 3, 508, "Metrics/AbcSize: Assignment Branch Condition size for `normalize_typescript_import` is too high. [<6, 14, 10> 18.22/17]", 4201027767], - [265, 3, 508, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `normalize_typescript_import` is too high. [9/7]", 4201027767], - [265, 3, 508, "Metrics/MethodLength: Method has too many lines. [11/10]", 4201027767], - [265, 3, 508, "Metrics/PerceivedComplexity: Perceived complexity for `normalize_typescript_import` is too high. [10/8]", 4201027767], - [312, 20, 2, "Naming/MethodParameterName: Method parameter must be at least 3 characters long.", 5861217] + "lib/tree_haver/language_pack.rb:3024861237": [ + [3, 1, 16, "Style/Documentation: Missing top-level documentation comment for `module TreeHaver`.", 3627168465] ], "lib/tree_haver/language_registry.rb:3950096220": [ [83, 121, 2, "Layout/LineLength: Line is too long. [122/120]", 5861089] @@ -428,11 +421,16 @@ [129, 5, 1443, "Metrics/MethodLength: Method has too many lines. [24/10]", 4208399016], [129, 13, 89, "Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]", 3152137646] ], - "spec/backend_registry_spec.rb:2685433903": [ - [5, 1, 2560, "Metrics/BlockLength: Block has too many lines. [49/25]", 3697376763] + "spec/backend_registry_spec.rb:229950927": [ + [5, 1, 3102, "Metrics/BlockLength: Block has too many lines. [62/25]", 3416335650] + ], + "spec/backends/tslp_spec.rb:1444201405": [ + [5, 1, 5497, "Metrics/BlockLength: Block has too many lines. [121/25]", 4279461260], + [30, 3, 1477, "Metrics/BlockLength: Block has too many lines. [32/25]", 2492475187], + [112, 3, 1352, "Metrics/BlockLength: Block has too many lines. [29/25]", 2972556266] ], - "spec/fixtures_integration_spec.rb:433811098": [ - [3, 1, 49194, "Metrics/BlockLength: Block has too many lines. [1024/25]", 2138474637], + "spec/fixtures_integration_spec.rb:3457821347": [ + [3, 1, 48556, "Metrics/BlockLength: Block has too many lines. [1006/25]", 2138474637], [108, 3, 1282, "Metrics/BlockLength: Block has too many lines. [29/25]", 505243730], [141, 3, 1840, "Metrics/BlockLength: Block has too many lines. [35/25]", 1365684528], [180, 3, 1365, "Metrics/BlockLength: Block has too many lines. [33/25]", 1597100003], @@ -451,9 +449,13 @@ [714, 3, 566, "Metrics/AbcSize: Assignment Branch Condition size for `parse_error_tolerance` is too high. [<1, 17, 1> 17.06/17]", 933590597], [714, 3, 566, "Metrics/MethodLength: Method has too many lines. [14/10]", 933590597], [739, 3, 2652, "Metrics/BlockLength: Block has too many lines. [47/25]", 214520278], - [997, 3, 1160, "Metrics/BlockLength: Block has too many lines. [36/25]", 728731748], - [1106, 7, 87, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 3860036845], - [1112, 7, 60, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1411318317] + [1039, 7, 87, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 3860036845], + [1045, 7, 60, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1411318317], + [1063, 3, 1334, "Metrics/BlockLength: Block has too many lines. [41/25]", 1427111445], + [1069, 7, 134, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1166944291], + [1075, 7, 60, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1411318317], + [1085, 7, 134, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1166944291], + [1091, 7, 60, "Lint/ConstantDefinitionInBlock: Do not define constants this way within a block.", 1411318317] ], "tree_haver.gemspec:665267582": [ [16, 121, 19, "Layout/LineLength: Line is too long. [139/120]", 1512975621], diff --git a/gems/tree_haver/Gemfile b/gems/tree_haver/Gemfile index ffa800806..5209ba280 100644 --- a/gems/tree_haver/Gemfile +++ b/gems/tree_haver/Gemfile @@ -21,7 +21,7 @@ gemspec # Local workspace dependency wiring for *_local.gemfile overrides nomono_requirements = ['~> 1.0', '>= 1.0.8'] gem 'nomono', *nomono_requirements, require: false # ruby >= 2.2 -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? diff --git a/gems/tree_haver/Gemfile.lock b/gems/tree_haver/Gemfile.lock index bc820a4ea..9b3b994de 100644 --- a/gems/tree_haver/Gemfile.lock +++ b/gems/tree_haver/Gemfile.lock @@ -7,59 +7,292 @@ PATH tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) version_gem (~> 1.1, >= 1.1.9) -GEM - remote: https://gem.coop/ +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly specs: - addressable (2.9.0) - public_suffix (>= 2.0.2, < 8.0) - ansi (1.6.0) - appraisal2 (3.1.4) - bundler (>= 1.17.3) - rake (>= 10) - thor (>= 0.14) - ast (2.4.3) - ast-crispr (7.1.0) - ast-merge (= 7.1.0) - service_actor (~> 3.9) - version_gem (~> 1.1, >= 1.1.9) ast-crispr-markdown-markly (7.1.0) ast-crispr (= 7.1.0) markly-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: ast-crispr-ruby-prism (7.1.0) ast-crispr (= 7.1.0) - prism (>= 1.0) + prism-merge (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: ast-merge (7.1.0) benchmark token-resolver (~> 2.0, >= 2.0.4) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) - backports (3.25.3) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: bash-merge (7.1.0) ast-merge (= 7.1.0) tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + +GEM + remote: https://gem.coop/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + ansi (1.6.0) + appraisal2 (3.2.0) + bundler (>= 1.17.3) + rake (>= 10) + thor (>= 0.14) + ast (2.4.3) + backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) bundler-audit (0.9.3) bundler (>= 1.2.0) thor (~> 1.0) citrus (3.0.2) - citrus-toml-merge (7.1.0) - toml-merge (= 7.1.0) - toml-rb (~> 4.1) - version_gem (~> 1.1, >= 1.1.9) cmdparse (3.0.7) - commonmarker (2.9.0-aarch64-linux) - commonmarker (2.9.0-aarch64-linux-musl) - commonmarker (2.9.0-arm64-darwin) commonmarker (2.9.0-x86_64-linux) commonmarker (2.9.0-x86_64-linux-musl) - commonmarker-merge (7.1.0) - commonmarker (~> 2.2) - markdown-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -69,10 +302,6 @@ GEM diff-lcs (1.6.2) diffy (3.4.4) docile (1.4.1) - dotenv-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.14) dry-configurable (1.4.0) dry-core (~> 1.0) zeitwerk (~> 2.6) @@ -122,42 +351,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - json-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) kettle-drift (1.0.5) version_gem (~> 1.1, >= 1.1.13) - kettle-jem (7.1.0) - addressable (>= 2.8, < 3) - ast-crispr-markdown-markly (= 7.1.0) - ast-crispr-ruby-prism (= 7.1.0) - ast-merge (= 7.1.0) - bash-merge (= 7.1.0) - citrus-toml-merge (= 7.1.0) - commonmarker-merge (= 7.1.0) - dotenv-merge (= 7.1.0) - json-merge (= 7.1.0) - kettle-dev (~> 2.3, >= 2.3.5) - kettle-rb (~> 0.1, >= 0.1.4) - kramdown-merge (= 7.1.0) - markdown-merge (= 7.1.0) - markly-merge (= 7.1.0) - prism-merge (= 7.1.0) - psych-merge (= 7.1.0) - rbs (>= 3.10) - rbs-merge (= 7.1.0) - ruby-merge (= 7.1.0) - token-resolver (~> 2.0, >= 2.0.4) - toml-merge (= 7.1.0) - toml-rb (~> 4.2) - tree_haver (= 7.1.0) - yaml-merge (= 7.1.0) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -181,31 +381,13 @@ GEM turbo_tests2 (~> 3.1, >= 3.1.12) kramdown (2.5.2) rexml (>= 3.4.4) - kramdown-merge (7.1.0) - kramdown (~> 2.5) - markdown-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) - markdown-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) markly (0.16.0) - markly-merge (7.1.0) - markdown-merge (= 7.1.0) - markly (~> 0.9) - version_gem (~> 1.1, >= 1.1.9) mutex_m (0.3.0) - nokogiri (1.19.4-aarch64-linux-gnu) - racc (~> 1.4) - nokogiri (1.19.4-aarch64-linux-musl) - racc (~> 1.4) - nokogiri (1.19.4-arm64-darwin) - racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-musl) @@ -224,31 +406,20 @@ GEM prettyprint prettyprint (0.2.0) prism (1.9.0) - prism-merge (7.1.0) - prism (~> 1.6) - ruby-merge (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) psych (5.4.0) date stringio - psych-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) - yaml-merge (= 7.1.0) public_suffix (7.0.5) racc (1.8.1) rainbow (3.1.1) rake (13.4.2) + rake-compiler-dock (1.12.0) + rb_sys (0.9.127) + rake-compiler-dock (= 1.12.0) rbs (4.0.3) logger prism (>= 1.6.0) tsort - rbs-merge (7.1.0) - ast-merge (= 7.1.0) - rbs (>= 3.10) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.14) rdoc (6.17.0) erb psych (>= 4.0.0) @@ -344,10 +515,6 @@ GEM lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) rubocop-ast (>= 1.44.0, < 2.0) - ruby-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) @@ -407,21 +574,11 @@ GEM version_gem (~> 1.1, >= 1.1.13) toml (0.3.0) parslet (>= 1.8.0, < 3.0.0) - toml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) toml-rb (4.2.0) citrus (~> 3.0, > 3.0) racc (~> 1.7) - tree_sitter_language_pack (1.9.0.pre.rc.40-aarch64-linux) - sorbet-runtime (~> 0.5) - tree_sitter_language_pack (1.9.0.pre.rc.40-arm64-darwin) - sorbet-runtime (~> 0.5) - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) - sorbet-runtime (~> 0.5) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -434,10 +591,6 @@ GEM kramdown (>= 2.4, < 3) kramdown-parser-gfm (~> 1.1) version_gem (~> 1.1, >= 1.1.13) - yaml-merge (7.1.0) - ast-merge (= 7.1.0) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) yard (0.9.45) yard-fence (0.9.6) rdoc (>= 6.11, < 8) @@ -450,7 +603,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -459,10 +612,6 @@ GEM zlib (3.2.3) PLATFORMS - aarch64-linux - aarch64-linux-gnu - aarch64-linux-musl - arm64-darwin x86_64-linux x86_64-linux-gnu x86_64-linux-musl @@ -470,24 +619,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) kettle-drift (~> 1.0, >= 1.0.5) - kettle-jem (>= 7.0) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -496,41 +666,49 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) toml (~> 0.3) + toml-merge! toml-rb (~> 4.1) tree_haver! + tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 ast-crispr (7.1.0) ast-crispr-markdown-markly (7.1.0) ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 - commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c - commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca - commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e commonmarker-merge (7.1.0) @@ -554,12 +732,13 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 json-merge (7.1.0) - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 @@ -575,9 +754,6 @@ CHECKSUMS markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 - nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f - nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af - nokogiri (1.19.4-arm64-darwin) sha256=a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b nomono (1.0.8) sha256=bf4b9b426cbf216ab17b70db474f691b8ae1f1e29de8db4b0ecd405e6e7e1c80 @@ -587,6 +763,8 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 @@ -597,6 +775,8 @@ CHECKSUMS racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rake-compiler-dock (1.12.0) + rb_sys (0.9.127) rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 @@ -630,6 +810,7 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 @@ -639,6 +820,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -656,11 +838,10 @@ CHECKSUMS toml-merge (7.1.0) toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) - tree_sitter_language_pack (1.9.0.pre.rc.40-aarch64-linux) sha256=c882f4039a1a84a8ed782ef5381a8556acdb53538055d0b9b30d0cd85a0f1b0a - tree_sitter_language_pack (1.9.0.pre.rc.40-arm64-darwin) sha256=b3dc68837a1a626afcbe1abb779cd987e9828a43c78e98cc70aa7e58957f3ef8 - tree_sitter_language_pack (1.9.0.pre.rc.40-x86_64-linux) sha256=ad6743a373eeac954c1b659b17af3aff1c82918b3ce9c9dc572a7c70ff843cdd + tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 @@ -670,9 +851,10 @@ CHECKSUMS yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/tree_haver/README.md b/gems/tree_haver/README.md index 0d5b7152a..66dee99f8 100644 --- a/gems/tree_haver/README.md +++ b/gems/tree_haver/README.md @@ -70,7 +70,7 @@ tree = parser.parse(source_code) - **Commonmarker Backend**: Fast Markdown parser ([Commonmarker][commonmarker], comrak Rust) - **Markly Backend**: GitHub Flavored Markdown ([Markly][markly], cmark-gfm C) - **RBS Backend**: Official RBS parser integration registered by `rbs-merge` - - **Pure Ruby Fallback**: + - **Pure Ruby Provider Backends**: - **Citrus Backend**: Pure Ruby PEG parsing via [`citrus`][citrus] (no native dependencies) - **Parslet Backend**: Pure Ruby PEG parsing via [`parslet`][parslet] (no native dependencies) - **Binary Schema Support**: @@ -446,7 +446,14 @@ TreeHaver exposes a backend registry for parser facades, language-family provide |---------|-------------|-------------|-------------| | **Kaitai Struct** | Backend reference and feature profile for binary schema analysis | Varies | Universal once a schema adapter is supplied | -**`TreeHaver::Parser` Auto-selection priority:** MRI/Rust/FFI on MRI; Java/FFI on JRuby; then Prism → Psych → Citrus → Parslet. +**`TreeHaver::Parser` Auto-selection contract:** `:auto` never means +unregistered parser discovery. It selects the first registered TreeHaver backend +module whose availability check passes. Built-in tree-sitter facade priority is +MRI/Rust/FFI on MRI and Java/FFI on JRuby, followed by registered provider +modules such as Prism, Psych, Citrus, and Parslet when those providers have been +registered for the requested language. Explicit backend requests fail closed if +that backend is unavailable or has no parser registered for the requested +language. **Known Issues:** @@ -534,7 +541,7 @@ This is particularly useful for: - **Testing**: Test the same code with different backends - **Performance comparison**: Benchmark different backends -- **Fallback scenarios**: Try one backend, fall back to another +- **Backend-selection scenarios**: Exercise each registered backend explicitly - **Thread isolation**: Each thread can use a different backend safely ```ruby @@ -641,7 +648,8 @@ export TREE_SITTER_TOML_PATH=~/.local/share/mise/installs/lua/5.4.8/luarocks/lib ### Backend Selection -TreeHaver automatically selects the best backend for your Ruby implementation, but you can override this behavior: +TreeHaver can select an available registered backend for you, but you can +override this behavior: ```ruby # Automatic backend selection (default) @@ -661,7 +669,13 @@ TreeHaver.backend = :parslet # Use Parslet pure Ruby parser # CAVEAT: few major language grammars, but many esoteric grammars ``` -**Auto-selection priority on MRI:** MRI → Rust → FFI → Citrus → Parslet +**Auto-selection rule:** `:auto` uses the registered backend list and chooses +the first backend module that is allowed by environment configuration and reports +itself available. It does not call parser libraries directly, search for +language-specific fallback parsers outside the registry, or hide an explicit +backend failure by silently switching to a different backend. + +**Built-in facade priority on MRI:** MRI → Rust → FFI → Citrus → Parslet You can also set the backend via environment variable: @@ -880,8 +894,8 @@ require "tree_haver" require "toml-merge" require "markdown-merge" -TomlMerge.register_tree_haver_grammars! -MarkdownMerge.register_tree_haver_grammars! +Toml::Merge.register_backend! +Markdown::Merge.register_backend! parser = TreeHaver.parser_for(:toml) ``` @@ -909,7 +923,31 @@ Given just the language name, `GrammarFinder` automatically derives: 1. **Environment variable**: `TREE_SITTER__PATH` (highest priority) 2. **Existing TreeHaver registration**: previously-registered tree-sitter grammar path 3. **Extra paths**: explicit paths provided at initialization -4. **`tree_sitter_language_pack`**: cache lookup plus on-demand download when the gem is available +4. **`tree_sitter_language_pack`**: parser API availability through its on-demand grammar loader + +#### TSLP Cold-Cache Troubleshooting + +`tree_sitter_language_pack` loads bundled grammars on demand. A cold install may +not have a populated shared-library cache before the first parse, so +`GrammarFinder` must not treat cache contents as the source of truth for TSLP +availability. + +For TSLP-backed languages, check availability through the TSLP parser API and +then register the language with the TreeHaver TSLP backend: + +```ruby +finder = TreeHaver::GrammarFinder.new(:toml) +finder.register! if finder.available? + +TreeHaver.with_backend("kreuzberg-language-pack") do + TreeHaver.parser_for(:toml).parse("title = \"example\"\n") +end +``` + +If this fails from a cold start, inspect `finder.search_info` and confirm that +the `tree-sitter-language-pack` gem is in the bundle being used. Do not add a +merge-gem parser fallback to hide the failure; fix the TreeHaver registration +or the TSLP grammar binding instead. #### Usage in \*-merge Gems @@ -917,14 +955,19 @@ The `GrammarFinder` pattern enables clean integration in language-specific merge gems: ```ruby -# In toml-merge +# In a substrate merge gem finder = TreeHaver::GrammarFinder.new(:toml) finder.register! if finder.available? +``` + +Parser-specific gems should register their own TreeHaver backend wrappers: -# Register non-tree-sitter backends in the merge gem as well +```ruby +# In a TOML parser provider gem TreeHaver.register_language( :toml, - grammar_module: TomlRB::Document, + backend_module: Citrus::Toml::Merge::Backend, + backend_type: :citrus, gem_name: "toml-rb", ) ``` @@ -1000,7 +1043,7 @@ TreeHaver does not ship a `TreeSitter::*` compatibility namespace. Use the `Tree language = TreeHaver::Language.toml rescue TreeHaver::NotAvailable => e warn("TOML grammar not available: #{e.message}") - # Fallback to another backend or fail gracefully + # Select another registered TreeHaver backend explicitly, or fail gracefully end ``` @@ -1032,7 +1075,7 @@ tree = parser.parse("#!/bin/bash\necho hello") # With explicit library path parser = TreeHaver.parser_for(:toml, library_path: "/custom/path/libtree-sitter-toml.so") -# With explicit Citrus fallback configuration +# With explicit Citrus provider configuration parser = TreeHaver.parser_for( :toml, citrus_config: {gem_name: "toml-rb", grammar_const: "TomlRB::Document"}, @@ -1575,23 +1618,15 @@ TreeHaver.with_backend(:rust) do end ``` -#### Fallback Pattern +#### Explicit Backend Selection Pattern -Try one backend, fall back to another on failure: +Try registered TreeHaver backends explicitly when you want controlled provider +selection. Structured merge gems should fail closed when no registered TreeHaver +backend can parse the requested language. ```ruby -def parse_with_fallback(source) - TreeHaver.with_backend(:mri) do - TreeHaver::Parser.new.tap { |p| p.language = load_language }.parse(source) - end -rescue TreeHaver::NotAvailable - # Fall back to Citrus if MRI backend unavailable - TreeHaver.with_backend(:citrus) do - TreeHaver::Parser.new.tap { |p| p.language = load_language }.parse(source) - end -rescue TreeHaver::NotAvailable - # Fall back to Parslet if Citrus backend unavailable - TreeHaver.with_backend(:parslet) do +def parse_with_backend(source, backend_name) + TreeHaver.with_backend(backend_name) do TreeHaver::Parser.new.tap { |p| p.language = load_language }.parse(source) end end diff --git a/gems/tree_haver/gemfiles/modular/templating.gemfile b/gems/tree_haver/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/tree_haver/gemfiles/modular/templating.gemfile +++ b/gems/tree_haver/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/tree_haver/gemfiles/modular/templating_local.gemfile b/gems/tree_haver/gemfiles/modular/templating_local.gemfile index 3369e7beb..e5463da30 100644 --- a/gems/tree_haver/gemfiles/modular/templating_local.gemfile +++ b/gems/tree_haver/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[tree_haver] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[tree_haver] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[tree_haver] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/tree_haver/lib/tree_haver.rb b/gems/tree_haver/lib/tree_haver.rb index 8844e09ea..030da294a 100644 --- a/gems/tree_haver/lib/tree_haver.rb +++ b/gems/tree_haver/lib/tree_haver.rb @@ -32,6 +32,7 @@ class BackendConflict < Error; end require_relative 'tree_haver/backends/ffi' require_relative 'tree_haver/backends/rust' require_relative 'tree_haver/backends/java' +require_relative 'tree_haver/backends/tslp' require_relative 'tree_haver/grammar_finder' require_relative 'tree_haver/citrus_grammar_finder' require_relative 'tree_haver/parslet_grammar_finder' @@ -314,6 +315,10 @@ def parser_for(language_name, library_path: nil, symbol: nil, citrus_config: nil return parser_for_tree_sitter(name, config[:path], config[:symbol]) end + if (backend_type = first_available_registered_backend_type(registrations)) + return parser_for_registered_backend(name, backend_type, registrations) + end + raise NotAvailable, "No parser registered for #{name}" end @@ -378,6 +383,8 @@ def requested_backend_type(registrations) backend_ref = BackendRegistry.fetch(backend_id.to_s) type = if registrations.key?(backend_id.to_s.to_sym) backend_id.to_s.to_sym + elsif (registered_type = registered_backend_type_for_requested_backend(backend_id, registrations)) + registered_type elsif backend_ref&.family == 'tree-sitter' :tree_sitter else @@ -389,6 +396,16 @@ def requested_backend_type(registrations) end private_class_method :requested_backend_type + def registered_backend_type_for_requested_backend(backend_id, registrations) + requested_module = backend_module_for(backend_id) + return unless requested_module + + registrations.find do |_backend_type, config| + config[:backend_module].equal?(requested_module) + end&.first + end + private_class_method :registered_backend_type_for_requested_backend + def parser_for_registered_backend(name, backend_type, registrations) config = registrations.fetch(backend_type) case backend_type @@ -409,6 +426,21 @@ def parser_for_registered_backend(name, backend_type, registrations) end private_class_method :parser_for_registered_backend + def first_available_registered_backend_type(registrations) + registrations.each do |backend_type, config| + next unless config[:backend_module] + next unless backend_allowed?(backend_type) + + backend_module = config.fetch(:backend_module) + next if backend_module.respond_to?(:available?) && !backend_module.available? + + return backend_type + end + + nil + end + private_class_method :first_available_registered_backend_type + def parser_for_backend_module(backend_module, name) parser = backend_module::Parser.new language_factory = backend_module::Language @@ -477,6 +509,8 @@ def backend_module_for(backend_name) Backends::FFI when :java Backends::Java + when :tslp, :"kreuzberg-language-pack" + Backends::Tslp when :citrus Backends::Citrus when :parslet diff --git a/gems/tree_haver/lib/tree_haver/backends/tslp.rb b/gems/tree_haver/lib/tree_haver/backends/tslp.rb new file mode 100644 index 000000000..c8e5aeda0 --- /dev/null +++ b/gems/tree_haver/lib/tree_haver/backends/tslp.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +module TreeHaver + module Backends + # TSLP backend using tree_sitter_language_pack's on-demand parser API. + # + # This backend intentionally requires the real parser API. The language-pack + # process API is not a TreeHaver parser backend and must not be used as a + # merge-gem integration surface. + module Tslp + @load_attempted = false + @loaded = false + @unavailable_reason = nil + + class << self + attr_reader :unavailable_reason + + def available? + return @loaded if @load_attempted + + @load_attempted = true + begin + require 'tree_sitter_language_pack' + @loaded = parser_api_available? + @unavailable_reason = 'tree_sitter_language_pack parser API is not exposed' unless @loaded + rescue LoadError => e + @loaded = false + @unavailable_reason = e.message + rescue StandardError => e + @loaded = false + @unavailable_reason = e.message + end + @loaded + end + + def reset! + @load_attempted = false + @loaded = false + @unavailable_reason = nil + end + + def capabilities + return {} unless available? + + { + backend: :tslp, + query: false, + bytes_field: true, + incremental: false, + comment_support: :nodes_only, + language_pack: true + } + end + + private + + def parser_api_available? + return false unless ::TreeSitterLanguagePack.respond_to?(:get_parser) + return false unless defined?(::TreeSitterLanguagePack::Parser) + + ::TreeSitterLanguagePack::Parser.instance_methods.include?(:parse) + rescue StandardError => e + @unavailable_reason = e.message + false + end + end + + class Language < TreeHaver::Base::Language + def initialize(name) + super(name.to_sym, backend: :tslp, options: {}) + end + + class << self + def from_library(_path = nil, symbol: nil, name: nil) # rubocop:disable Lint/UnusedMethodArgument + new(name || :unknown) + end + end + end + + class Parser < TreeHaver::Base::Parser + def parse(source) + raise TreeHaver::NotAvailable, unavailable_message unless Tslp.available? + raise TreeHaver::NotAvailable, 'TSLP language is not set' unless language + + parser = ::TreeSitterLanguagePack.get_parser(language.name.to_s) + raise TreeHaver::NotAvailable, "TSLP did not return a parser for #{language.name}" unless parser + + raw_tree = parser.parse(source) + raise TreeHaver::NotAvailable, "TSLP did not return a parse tree for #{language.name}" unless raw_tree + + Tree.new(raw_tree, source: source) + end + + private + + def unavailable_message + reason = Tslp.unavailable_reason + detail = reason.to_s.empty? ? 'unknown reason' : reason + "tree_sitter_language_pack parser API is unavailable: #{detail}" + end + end + + class Tree < TreeHaver::Base::Tree + def root_node + Node.new(inner_tree.root_node, source: source, lines: lines) + end + end + + class Node < TreeHaver::Base::Node + def type + inner_node.kind + end + + def start_byte + inner_node.start_byte + end + + def end_byte + inner_node.end_byte + end + + def start_point + point = inner_node.start_position + { row: point.row, column: point.column } + end + + def end_point + point = inner_node.end_position + { row: point.row, column: point.column } + end + + def children + Array.new(inner_node.child_count) do |index| + child = inner_node.child(index) + child && self.class.new(child, source: source, lines: lines) + end.compact + end + + def named? + inner_node.is_named + end + + def has_error? + inner_node.has_error + end + + def error? + inner_node.is_error + end + + def missing? + inner_node.is_missing + end + + def extra? + inner_node.is_extra + end + end + end + end +end diff --git a/gems/tree_haver/lib/tree_haver/contracts.rb b/gems/tree_haver/lib/tree_haver/contracts.rb index 7f2f451a3..9ffb1d078 100644 --- a/gems/tree_haver/lib/tree_haver/contracts.rb +++ b/gems/tree_haver/lib/tree_haver/contracts.rb @@ -283,28 +283,6 @@ def deep_dup(value) end end - ProcessRequest = Struct.new(:source, :language, keyword_init: true) do - def to_h - { - source: source, - language: language - } - end - end - - ProcessSpan = Struct.new(:start_byte, :end_byte, :start_row, :start_col, :end_row, :end_col, keyword_init: true) do - def to_h - { - start_byte: start_byte, - end_byte: end_byte, - start_row: start_row, - start_col: start_col, - end_row: end_row, - end_col: end_col - } - end - end - ByteRange = Struct.new(:start_byte, :end_byte, keyword_init: true) do def valid? start_byte.to_i >= 0 && end_byte.to_i >= start_byte.to_i @@ -1000,76 +978,6 @@ def self.byte_offset_for_point(source, point) raise RangeError, "source point (#{point.row}, #{point.column}) is outside source" end - ProcessStructureItem = Struct.new(:kind, :name, :span, keyword_init: true) do - def to_h - { - kind: kind, - **(name ? { name: name } : {}), - span: span.to_h - } - end - end - - ProcessImportInfo = Struct.new(:source, :items, :span, keyword_init: true) do - def to_h - { - source: source, - items: deep_dup(items || []), - span: span.to_h - } - end - - private - - def deep_dup(value) - Marshal.load(Marshal.dump(value)) - end - end - - ProcessDiagnostic = Struct.new(:message, :severity, keyword_init: true) do - def to_h - { - message: message, - severity: severity - } - end - end - - LanguagePackAnalysis = Struct.new(:language, :dialect, :root_type, :has_error, :backend_ref, keyword_init: true) do - def kind - 'tree-sitter' - end - - def to_h - { - kind: kind, - language: language, - **(dialect ? { dialect: dialect } : {}), - root_type: root_type, - has_error: has_error, - backend_ref: backend_ref.to_h - } - end - end - - LanguagePackProcessAnalysis = Struct.new(:language, :structure, :imports, :diagnostics, :backend_ref, - keyword_init: true) do - def kind - 'tree-sitter-process' - end - - def to_h - { - kind: kind, - language: language, - structure: (structure || []).map(&:to_h), - imports: (imports || []).map(&:to_h), - diagnostics: (diagnostics || []).map(&:to_h), - backend_ref: backend_ref.to_h - } - end - end - KaitaiByteSpan = Struct.new(:start_byte, :end_byte, keyword_init: true) do def to_h { diff --git a/gems/tree_haver/lib/tree_haver/grammar_finder.rb b/gems/tree_haver/lib/tree_haver/grammar_finder.rb index 7c716e154..510be84f7 100644 --- a/gems/tree_haver/lib/tree_haver/grammar_finder.rb +++ b/gems/tree_haver/lib/tree_haver/grammar_finder.rb @@ -10,7 +10,7 @@ module TreeHaver # 1. explicit environment override # 2. existing TreeHaver registration # 3. explicit extra paths - # 4. tree_sitter_language_pack cache/provisioning + # 4. tree_sitter_language_pack parser backend registration # # This class is designed to be used by language-specific merge gems # without requiring TreeHaver to own parser- or grammar-specific policy. @@ -31,7 +31,7 @@ module TreeHaver # @example Basic usage # finder = TreeHaver::GrammarFinder.new(:toml) # path = finder.find_library_path - # # => "/home/user/.cache/tree-sitter-language-pack/vX/libs/libtree_sitter_toml.so" + # # => "/usr/local/lib/libtree_sitter_toml.so" # # @example Check availability # finder = TreeHaver::GrammarFinder.new(:json) @@ -114,7 +114,7 @@ def library_filenames # Generate the full list of search paths for this language # - # Order: registered path, explicit extra paths, then tree_sitter_language_pack cache + # Order: registered path, then explicit extra paths. # # @return [Array] all paths to search def search_paths @@ -129,13 +129,6 @@ def search_paths end end - cache_dir = tree_sitter_language_pack_cache_dir - if cache_dir - library_filenames.each do |filename| - paths << File.join(cache_dir, filename) - end - end - paths.uniq end @@ -145,7 +138,9 @@ def search_paths # 1. Environment variable override (validated for safety) # 2. Existing TreeHaver tree-sitter registration # 3. Extra paths provided at initialization - # 4. tree_sitter_language_pack cache / on-demand download + # tree_sitter_language_pack is intentionally not exposed as a shared-library + # path fallback here. It is registered as a TreeHaver backend module when + # its parser API is available. # # @note Paths from ENV are validated using {PathValidator.safe_library_path?} # to prevent path traversal and other attacks. Invalid ENV paths cause @@ -200,7 +195,7 @@ def find_library_path explicit_path = explicit_search_path return explicit_path if explicit_path - tree_sitter_language_pack_path + nil end # Validate an environment variable path and return reason if invalid @@ -245,6 +240,8 @@ def find_library_path_safe # # @return [Boolean] true if the library can be found AND tree-sitter runtime works def available? + return true if tree_sitter_language_pack_parser_available? + path = find_library_path return false if path.nil? @@ -316,6 +313,16 @@ def available_safe? # @return [Boolean] true if registration succeeded # @raise [NotAvailable] if library not found and raise_on_missing is true def register!(raise_on_missing: false) + if tree_sitter_language_pack_parser_available? + TreeHaver.register_language( + @language_name, + backend_module: TreeHaver::Backends::Tslp, + backend_type: :tslp, + gem_name: 'tree_sitter_language_pack' + ) + return true + end + path = find_library_path unless path raise NotAvailable, not_found_message if raise_on_missing @@ -337,12 +344,13 @@ def search_info env_var: env_var_name, env_value: ENV[env_var_name], env_rejection_reason: @env_rejection_reason, + tree_sitter_language_pack_parser_available: tree_sitter_language_pack_parser_available?, symbol: symbol_name, library_filename: library_filename, library_filenames: library_filenames, search_paths: search_paths, found_path: found, - available: !found.nil? + available: tree_sitter_language_pack_parser_available? || !found.nil? } end @@ -363,7 +371,8 @@ def not_found_message " Searched: #{search_paths.join(', ')}." end - msg + " Register the grammar, install tree_sitter_language_pack, or set #{env_var_name} to a valid path." + msg + ' Register the grammar, install tree_sitter_language_pack with parser API support, ' \ + "or set #{env_var_name} to a valid path." end private @@ -386,41 +395,19 @@ def explicit_search_path search_paths.find { |path| File.exist?(path) } end - def tree_sitter_language_pack_path - return @tree_sitter_language_pack_path if defined?(@tree_sitter_language_pack_path) - - @tree_sitter_language_pack_path = begin - require 'tree_sitter_language_pack' - language = @language_name.to_s - if TreeSitterLanguagePack.has_language(language) - TreeSitterLanguagePack.download([language]) - cache_dir = TreeSitterLanguagePack.cache_dir - @tree_sitter_language_pack_cache_dir = cache_dir - - library_filenames - .map { |filename| File.join(cache_dir, filename) } - .find { |path| File.exist?(path) } - else - @tree_sitter_language_pack_rejection_reason = 'language not published by tree_sitter_language_pack' - nil - end + def tree_sitter_language_pack_parser_available? + return @tree_sitter_language_pack_parser_available if defined?(@tree_sitter_language_pack_parser_available) + + @tree_sitter_language_pack_parser_available = begin + require 'tree_sitter_language_pack' unless defined?(::TreeSitterLanguagePack) + TreeHaver::Backends::Tslp.available? && + ::TreeSitterLanguagePack.respond_to?(:has_language) && + ::TreeSitterLanguagePack.has_language(@language_name.to_s) rescue LoadError - @tree_sitter_language_pack_rejection_reason = 'tree_sitter_language_pack gem not available' - nil + false rescue StandardError => e @tree_sitter_language_pack_rejection_reason = e.message - nil - end - end - - def tree_sitter_language_pack_cache_dir - return @tree_sitter_language_pack_cache_dir if defined?(@tree_sitter_language_pack_cache_dir) - - @tree_sitter_language_pack_cache_dir = begin - require 'tree_sitter_language_pack' - TreeSitterLanguagePack.cache_dir - rescue LoadError, StandardError - nil + false end end diff --git a/gems/tree_haver/lib/tree_haver/language_pack.rb b/gems/tree_haver/lib/tree_haver/language_pack.rb index 45b4657e2..29bc963f0 100644 --- a/gems/tree_haver/lib/tree_haver/language_pack.rb +++ b/gems/tree_haver/lib/tree_haver/language_pack.rb @@ -1,11 +1,6 @@ # frozen_string_literal: true -require 'json' -require 'tree_sitter_language_pack' - module TreeHaver - LanguagePackResultError = Class.new(StandardError) unless const_defined?(:LanguagePackResultError) - TSLP_BACKEND = BackendReference.new( id: 'tslp', family: 'tree-sitter' @@ -18,7 +13,7 @@ module TreeHaver BackendRegistry.register(TSLP_BACKEND) BackendRegistry.register(KREUZBERG_LANGUAGE_PACK_BACKEND) BackendRegistry.register_availability_checker(:tslp) do - defined?(TreeSitterLanguagePack) && TreeSitterLanguagePack.respond_to?(:process) + Backends::Tslp.available? end BackendRegistry.register_availability_checker(:"kreuzberg-language-pack") do BackendRegistry.available?(:tslp) @@ -43,288 +38,4 @@ def language_pack_feature_profile supported_policies: [] ) end - - def parse_with_language_pack(request) - ensure_language_pack_language(request.language) - raw = language_pack_result_hash(TreeSitterLanguagePack.process( - request.source, - JSON.generate(language: request.language, diagnostics: true) - )) - return language_pack_unsupported_result(request.language, 'diagnostics', 'process result was empty') unless raw - - diagnostics = Array(raw['diagnostics']) - return parse_error_result(request.language) unless diagnostics.empty? - - analysis = LanguagePackAnalysis.new( - language: request.language, - dialect: request.dialect, - root_type: inferred_root_type(request), - has_error: false, - backend_ref: TSLP_BACKEND - ) - parse_result(ok: true, analysis: analysis, diagnostics: []) - rescue LanguagePackResultError => e - language_pack_unsupported_result(request.language, 'diagnostics', e.message) - rescue StandardError => e - language_pack_runtime_failure(request.language, 'diagnostics', e.message) - end - - def process_with_language_pack(request) - ensure_language_pack_language(request.language) - raw = language_pack_result_hash(TreeSitterLanguagePack.process( - request.source, - JSON.generate(language: request.language, structure: true, imports: true, - diagnostics: true) - )) - unless raw - return language_pack_unsupported_result(request.language, 'structure/imports/diagnostics', - 'process result was empty') - end - - analysis = LanguagePackProcessAnalysis.new( - language: raw.fetch('language'), - structure: normalize_structure(Array(raw['structure'])), - imports: normalize_imports(request.language, Array(raw['imports'])), - diagnostics: Array(raw['diagnostics']).map do |item| - ProcessDiagnostic.new( - message: item.fetch('message'), - severity: item.fetch('severity') - ) - end, - backend_ref: TSLP_BACKEND - ) - parse_result(ok: true, analysis: analysis, diagnostics: []) - rescue LanguagePackResultError => e - language_pack_unsupported_result(request.language, 'structure/imports/diagnostics', e.message) - rescue StandardError => e - language_pack_runtime_failure(request.language, 'structure/imports/diagnostics', e.message) - end - - def ensure_language_pack_language(language) - return if TreeSitterLanguagePack.has_language(language) - - TreeSitterLanguagePack.init(JSON.generate(languages: [language])) - end - private_class_method :ensure_language_pack_language - - def language_pack_result_hash(raw) - return raw if raw.is_a?(Hash) - return raw.to_h if raw.respond_to?(:to_h) - if raw.respond_to?(:language) - return { - 'language' => raw.language, - 'structure' => Array(raw.structure).map { |item| language_pack_object_hash(item) }, - 'imports' => Array(raw.imports).map { |item| language_pack_object_hash(item) }, - 'diagnostics' => Array(raw.diagnostics).map { |item| language_pack_object_hash(item) } - } - end - - parsed = JSON.parse(raw.to_json) - parsed.is_a?(Hash) ? parsed : nil - rescue StandardError - raise LanguagePackResultError, "Ruby binding could not expose a structured process result from #{raw.class}" - end - private_class_method :language_pack_result_hash - - def language_pack_object_hash(object) - return object if object.is_a?(Hash) - - language_pack_object_methods.each_with_object({}) do |method_name, method_result| - next unless object.respond_to?(method_name) - - method_result[method_name.to_s] = language_pack_object_value(object.public_send(method_name)) - rescue StandardError - next - end - end - private_class_method :language_pack_object_hash - - def language_pack_object_value(value) - case value - when nil, true, false, Numeric, String, Symbol - value - when Array - value.map { |item| language_pack_object_value(item) } - when Hash - value.transform_values { |item| language_pack_object_value(item) } - else - language_pack_object_hash(value) - end - end - private_class_method :language_pack_object_value - - def language_pack_object_methods - %i[ - kind name visibility span children decorators doc_comment signature body_span - source module names items message severity start_byte end_byte start_line - start_column end_line end_column start_row start_col end_row end_col - ] - end - private_class_method :language_pack_object_methods - - def language_pack_unsupported_result(language, feature, detail) - parse_result( - ok: false, - diagnostics: [ - diagnostic( - 'error', - 'unsupported_feature', - "tree-sitter-language-pack did not provide readable #{feature} for #{language}. " \ - "Please report this to tree-sitter-language-pack with this detail: #{detail}" - ) - ] - ) - end - private_class_method :language_pack_unsupported_result - - def language_pack_runtime_failure(language, feature, detail) - parse_result( - ok: false, - diagnostics: [ - diagnostic( - 'error', - 'unsupported_feature', - "tree-sitter-language-pack failed while providing #{feature} for #{language}. " \ - "Please report this to tree-sitter-language-pack with this detail: #{detail}" - ) - ] - ) - end - private_class_method :language_pack_runtime_failure - - def normalize_structure(items) - items.flat_map do |item| - normalized_item = ProcessStructureItem.new( - kind: item.fetch('kind').downcase, - name: item['name'], - span: process_span(item.fetch('span')) - ) - [normalized_item, *normalize_structure(Array(item['children']))] - end - end - private_class_method :normalize_structure - - def parse_error_result(language) - parse_result( - ok: false, - diagnostics: [ - diagnostic( - 'error', - 'parse_error', - "tree-sitter-language-pack reported syntax errors for #{language}." - ) - ] - ) - end - private_class_method :parse_error_result - - def process_span(raw) - ProcessSpan.new( - start_byte: raw.fetch('start_byte'), - end_byte: raw.fetch('end_byte'), - start_row: raw['start_row'] || raw.fetch('start_line'), - start_col: raw['start_col'] || raw.fetch('start_column'), - end_row: raw['end_row'] || raw.fetch('end_line'), - end_col: raw['end_col'] || raw.fetch('end_column') - ) - end - private_class_method :process_span - - def inferred_root_type(request) - stripped = request.source.lstrip - case request.language - when 'json' - return 'object' if stripped.start_with?('{') - return 'array' if stripped.start_with?('[') - - 'scalar' - else - request.language - end - end - private_class_method :inferred_root_type - - def normalize_imports(language, raw_imports) - raw_imports.map do |item| - source, items = - if language == 'typescript' - normalize_typescript_import(item) - else - [item['module'] || item['source'] || '', Array(item['names'] || item['items'])] - end - - ProcessImportInfo.new( - source: source, - items: items, - span: process_span(item.fetch('span')) - ) - end - end - private_class_method :normalize_imports - - def normalize_typescript_import(item) - raw_source = item['module'] || item['source'] || '' - source = quoted_import_source(raw_source) || raw_source.strip - names = if (named_items = braced_import_items(raw_source)) - named_items - .split(',') - .map { |part| part.split.reject { |word| word == 'type' }.join(' ') } - .reject(&:empty?) - else - Array(item['names'] || item['items']) - end - - [source, names] - end - private_class_method :normalize_typescript_import - - def quoted_import_source(source) - %w[from import].each do |marker| - marker_index = source.index(marker) - next unless marker_index - - quoted = quoted_segment(source, marker_index + marker.length) - return quoted if quoted - end - nil - end - private_class_method :quoted_import_source - - def quoted_segment(source, start_index) - quote_index = [source.index("'", start_index), source.index('"', start_index)].compact.min - return nil unless quote_index - - quote = source[quote_index] - close_index = source.index(quote, quote_index + 1) - close_index ? source[(quote_index + 1)...close_index] : nil - end - private_class_method :quoted_segment - - def braced_import_items(source) - open_index = source.index('{') - return nil unless open_index - - close_index = source.index('}', open_index + 1) - close_index ? source[(open_index + 1)...close_index] : nil - end - private_class_method :braced_import_items - - def parse_result(ok:, diagnostics:, analysis: nil, policies: []) - { - ok: ok, - diagnostics: diagnostics, - **(analysis ? { analysis: analysis } : {}), - policies: policies - } - end - private_class_method :parse_result - - def diagnostic(severity, category, message) - { - severity: severity, - category: category, - message: message - } - end - private_class_method :diagnostic end diff --git a/gems/tree_haver/spec/backend_registry_spec.rb b/gems/tree_haver/spec/backend_registry_spec.rb index b9dc81408..d63af2028 100644 --- a/gems/tree_haver/spec/backend_registry_spec.rb +++ b/gems/tree_haver/spec/backend_registry_spec.rb @@ -19,6 +19,22 @@ end end + it 'resolves registered backend-module aliases before falling back to tree-sitter paths' do + TreeHaver.register_language( + :alias_resolution_json, + backend_module: TreeHaver::Backends::Tslp, + backend_type: :tslp, + gem_name: 'tree_sitter_language_pack' + ) + + parser = TreeHaver.with_backend('kreuzberg-language-pack') do + TreeHaver.parser_for(:alias_resolution_json) + end + + expect(parser).to be_a(TreeHaver::Backends::Tslp::Parser) + expect(parser.language.name).to eq(:alias_resolution_json) + end + it 'loads MRI tree-sitter languages with a string language name' do stub_const('TreeSitter', Module.new) language_class = class_double('TreeSitter::Language') diff --git a/gems/tree_haver/spec/backends/tslp_spec.rb b/gems/tree_haver/spec/backends/tslp_spec.rb new file mode 100644 index 000000000..8c55d2c71 --- /dev/null +++ b/gems/tree_haver/spec/backends/tslp_spec.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require_relative '../spec_helper' + +RSpec.describe TreeHaver::Backends::Tslp do + before do + described_class.reset! + end + + it 'reports availability only when tree_sitter_language_pack exposes a parser API' do + stub_const('TreeSitterLanguagePack', Module.new) + parser_class = Class.new do + def parse(_source) + :tree + end + end + TreeSitterLanguagePack.const_set(:Parser, parser_class) + allow(TreeSitterLanguagePack).to receive(:get_parser) + + expect(described_class.available?).to be(true) + end + + it 'fails closed when the installed language pack does not expose parser methods' do + allow(described_class).to receive(:parser_api_available?).and_return(false) + + expect(described_class.available?).to be(false) + expect(described_class.unavailable_reason).to eq('tree_sitter_language_pack parser API is not exposed') + end + + it 'parses through the language-pack parser API when available' do + raw_node = instance_double( + 'TreeSitterLanguagePack::Node', + kind: 'document', + start_byte: 0, + end_byte: 9, + start_position: instance_double('TreeSitterLanguagePack::Point', row: 0, column: 0), + end_position: instance_double('TreeSitterLanguagePack::Point', row: 0, column: 9), + child_count: 0, + is_named: true, + has_error: false, + is_error: false, + is_missing: false, + is_extra: false + ) + raw_tree = instance_double('TreeSitterLanguagePack::Tree', root_node: raw_node) + parser = double('TreeSitterLanguagePack::Parser', parse: raw_tree) + parser_class = Class.new do + def parse(_source) + :tree + end + end + stub_const('TreeSitterLanguagePack', Module.new) + TreeSitterLanguagePack.const_set(:Parser, parser_class) + allow(TreeSitterLanguagePack).to receive(:get_parser).with('toml').and_return(parser) + + tree_haver_parser = described_class::Parser.new + tree_haver_parser.language = described_class::Language.new(:toml) + tree = tree_haver_parser.parse("title = 1\n") + + expect(TreeSitterLanguagePack).to have_received(:get_parser).with('toml') + expect(parser).to have_received(:parse).with("title = 1\n") + expect(tree.root_node.type).to eq('document') + expect(tree.root_node.start_point).to eq({ row: 0, column: 0 }) + expect(tree.root_node.end_point).to eq({ row: 0, column: 9 }) + end + + it 'can parse through a real TSLP language when the installed binding exposes parser methods' do + begin + require 'tree_sitter_language_pack' + rescue LoadError + skip 'tree_sitter_language_pack is not installed' + end + + described_class.reset! + unless described_class.available? + skip described_class.unavailable_reason || 'tree_sitter_language_pack parser API is unavailable' + end + skip 'tree_sitter_language_pack does not publish json' unless TreeSitterLanguagePack.has_language('json') + + tree_haver_parser = described_class::Parser.new + tree_haver_parser.language = described_class::Language.new(:json) + tree = tree_haver_parser.parse('{"a":1}') + + expect(tree.root_node.type).to eq('document') + expect(tree.root_node.children.map(&:type)).to include('object') + end + + it 'exposes real TSLP point locations through TreeHaver nodes when available' do + begin + require 'tree_sitter_language_pack' + rescue LoadError + skip 'tree_sitter_language_pack is not installed' + end + + described_class.reset! + unless described_class.available? + skip described_class.unavailable_reason || 'tree_sitter_language_pack parser API is unavailable' + end + skip 'tree_sitter_language_pack does not publish json' unless TreeSitterLanguagePack.has_language('json') + + tree_haver_parser = described_class::Parser.new + tree_haver_parser.language = described_class::Language.new(:json) + object = tree_haver_parser.parse("{\n \"a\": 1\n}\n").root_node.children.find { |child| child.type == 'object' } + pair = object.children.find { |child| child.type == 'pair' } + + expect(pair.start_point).to eq({ row: 1, column: 2 }) + expect(pair.end_point).to eq({ row: 1, column: 8 }) + expect(pair.start_line).to eq(2) + expect(pair.end_line).to eq(2) + end + + it 'parses the source-family languages expected to use TSLP when available' do + begin + require 'tree_sitter_language_pack' + rescue LoadError + skip 'tree_sitter_language_pack is not installed' + end + + described_class.reset! + unless described_class.available? + skip described_class.unavailable_reason || 'tree_sitter_language_pack parser API is unavailable' + end + + fixtures = { + json: ['{"a":1}', 'document'], + toml: ["title = \"demo\"\n[tool]\nname = \"x\"\n", 'document'], + bash: ["echo hi\n", 'program'], + go: ["package main\nfunc main() {}\n", 'source_file'], + rust: ["fn main() {}\n", 'source_file'], + typescript: ["export const x = 1;\n", 'program'], + ruby: ["class X\nend\n", 'program'], + yaml: ["name: demo\n", 'stream'], + markdown: ["# Heading\n\nBody\n", 'document'] + } + + fixtures.each do |language, (source, expected_root)| + unless TreeSitterLanguagePack.has_language(language.to_s) + skip "tree_sitter_language_pack does not publish #{language}" + end + + TreeHaver::GrammarFinder.new(language).register!(raise_on_missing: true) + tree = TreeHaver.with_backend('tslp') { TreeHaver.parser_for(language).parse(source) } + + expect(tree.root_node.type).to eq(expected_root) + expect(tree.root_node).not_to have_error + end + end +end diff --git a/gems/tree_haver/spec/fixtures_integration_spec.rb b/gems/tree_haver/spec/fixtures_integration_spec.rb index ed2371bd0..1904006c6 100644 --- a/gems/tree_haver/spec/fixtures_integration_spec.rb +++ b/gems/tree_haver/spec/fixtures_integration_spec.rb @@ -994,73 +994,6 @@ def source_span(fixture) expect(json_ready(result.to_h)).to eq(json_ready(expected.to_h)) end - it 'conforms to the slice-100 process baseline fixture' do - fixture = diagnostics_fixture('process_baseline') - result = described_class.process_with_language_pack( - described_class::ProcessRequest.new(**fixture[:request]) - ) - - if result[:ok] - analysis = result[:analysis] - expect(analysis.language).to eq(fixture.dig(:expected, :language)) - expect( - json_ready( - analysis.structure.map do |item| - { - kind: item.kind, - **(item.name ? { name: item.name } : {}) - } - end - ) - ).to eq(json_ready(fixture.dig(:expected, :structure))) - expect( - json_ready( - analysis.imports.map do |item| - { - source: item.source, - items: item.items - } - end - ) - ).to eq(json_ready(fixture.dig(:expected, :imports))) - else - expect(result[:diagnostics]).to contain_exactly( - include( - severity: 'error', - category: 'unsupported_feature', - message: include('Please report this to tree-sitter-language-pack') - ) - ) - end - end - - it 'fails closed when the language-pack result object is unreadable' do - unreadable_result = Class.new do - def language - raise TypeError, 'binding accessor failed' - end - end.new - - allow(TreeSitterLanguagePack).to receive(:has_language).and_return(true) - allow(TreeSitterLanguagePack).to receive(:process).and_return(unreadable_result) - - result = described_class.process_with_language_pack( - described_class::ProcessRequest.new( - language: 'ruby', - source: "module A\nend\n" - ) - ) - - expect(result[:ok]).to be(false) - expect(result[:diagnostics]).to contain_exactly( - include( - severity: 'error', - category: 'unsupported_feature', - message: include('Please report this to tree-sitter-language-pack') - ) - ) - end - it 'supports temporary backend context selection' do expect(described_class.current_backend_id).to be_nil @@ -1127,6 +1060,58 @@ class self::Parser expect(parser.language).to eq(:rbs_language) end + it 'auto-selects an available registered backend module without explicit backend selection' do + unavailable_backend = Module.new do + def self.available? + false + end + + class self::Language + def self.from_library(_path = nil, symbol: nil, name: nil) + [name, symbol] + end + end + + class self::Parser + attr_accessor :language + end + end + + available_backend = Module.new do + def self.available? + true + end + + class self::Language + def self.from_library(_path = nil, symbol: nil, name: nil) + [name, symbol] + end + end + + class self::Parser + attr_accessor :language + end + end + + described_class.register_language( + :auto_provider_markdown, + backend_module: unavailable_backend, + backend_type: :unavailable_markdown_provider, + gem_name: 'unavailable-markdown-provider' + ) + described_class.register_language( + :auto_provider_markdown, + backend_module: available_backend, + backend_type: :available_markdown_provider, + gem_name: 'available-markdown-provider' + ) + + parser = described_class.parser_for(:auto_provider_markdown) + + expect(parser).to be_a(available_backend::Parser) + expect(parser.language).to eq([:auto_provider_markdown, nil]) + end + it 'provides PEG framework parsing helpers' do require 'toml' require 'toml-rb' diff --git a/gems/tree_haver/spec/grammar_finder_spec.rb b/gems/tree_haver/spec/grammar_finder_spec.rb new file mode 100644 index 000000000..e661e0f60 --- /dev/null +++ b/gems/tree_haver/spec/grammar_finder_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require_relative 'spec_helper' + +RSpec.describe TreeHaver::GrammarFinder do + describe '#available?' do + it 'uses the TSLP parser backend without requiring a cached shared library' do + stub_const('TreeSitterLanguagePack', Module.new) + allow(TreeSitterLanguagePack).to receive(:has_language).with('cold_cache_toml').and_return(true) + allow(TreeHaver::Backends::Tslp).to receive(:available?).and_return(true) + + finder = described_class.new(:cold_cache_toml) + + expect(finder).to be_available + end + end + + describe '#register!' do + it 'registers a TSLP backend module when the language pack parser is available' do + stub_const('TreeSitterLanguagePack', Module.new) + allow(TreeSitterLanguagePack).to receive(:has_language).with('cold_cache_json').and_return(true) + allow(TreeHaver::Backends::Tslp).to receive(:available?).and_return(true) + + finder = described_class.new(:cold_cache_json) + + expect(finder.register!).to be(true) + expect(TreeHaver.registered_languages(:cold_cache_json)).to include( + tslp: include( + backend_module: TreeHaver::Backends::Tslp, + gem_name: 'tree_sitter_language_pack' + ) + ) + end + + it 'does not require shared-library cache discovery for TSLP registration' do + stub_const('TreeSitterLanguagePack', Module.new) + allow(TreeSitterLanguagePack).to receive(:has_language).with('cold_cache_markdown').and_return(true) + allow(TreeHaver::Backends::Tslp).to receive(:available?).and_return(true) + + finder = described_class.new(:cold_cache_markdown) + allow(finder).to receive(:find_library_path).and_raise( + TreeHaver::NotAvailable, + 'shared-library cache is intentionally empty' + ) + + expect(finder.register!(raise_on_missing: true)).to be(true) + parser = TreeHaver.with_backend('tslp') { TreeHaver.parser_for(:cold_cache_markdown) } + + expect(parser).to be_a(TreeHaver::Backends::Tslp::Parser) + expect(finder).not_to have_received(:find_library_path) + end + end +end diff --git a/gems/typescript-merge/.gitattributes b/gems/typescript-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/typescript-merge/.gitattributes +++ b/gems/typescript-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/typescript-merge/.kettle-drift.lock b/gems/typescript-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/typescript-merge/.kettle-drift.lock +++ b/gems/typescript-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/typescript-merge/.rubocop_gradual.lock b/gems/typescript-merge/.rubocop_gradual.lock index 7aa08206d..d318188a5 100644 --- a/gems/typescript-merge/.rubocop_gradual.lock +++ b/gems/typescript-merge/.rubocop_gradual.lock @@ -76,23 +76,18 @@ "lib/typescript-merge.rb:4058528402": [ [1, 1, 0, "Naming/FileName: The name of this source file (`typescript-merge.rb`) should use snake_case.", 5381] ], - "lib/typescript/merge.rb:4009690741": [ + "lib/typescript/merge.rb:3369400219": [ [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module TypeScript::Merge`.", 2866359175], - [10, 3, 6018, "Metrics/ModuleLength: Module has too many lines. [124/100]", 3011109954], + [10, 3, 7859, "Metrics/ModuleLength: Module has too many lines. [184/100]", 3930211313], [11, 5, 11, "Style/ModuleFunction: Use `module_function` instead of `extend self`.", 1210897631], - [60, 121, 28, "Layout/LineLength: Line is too long. [148/120]", 3724408137], - [67, 5, 1427, "Metrics/AbcSize: Assignment Branch Condition size for `merge_type_script` is too high. [<13, 32, 11> 36.25/17]", 626793766], - [67, 5, 1427, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_type_script` is too high. [11/7]", 626793766], - [67, 5, 1427, "Metrics/MethodLength: Method has too many lines. [22/10]", 626793766], - [67, 5, 1427, "Metrics/PerceivedComplexity: Perceived complexity for `merge_type_script` is too high. [11/8]", 626793766], - [86, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], - [95, 5, 1753, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_type_script_module` is too high. [<11, 33, 8> 35.69/17]", 4006594753], - [95, 5, 1753, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `analyze_type_script_module` is too high. [9/7]", 4006594753], - [95, 5, 1753, "Metrics/MethodLength: Method has too many lines. [30/10]", 4006594753], - [95, 5, 1753, "Metrics/PerceivedComplexity: Perceived complexity for `analyze_type_script_module` is too high. [9/8]", 4006594753], - [108, 50, 20, "Style/SymbolProc: Pass `&:name` as an argument to `select` instead of a block.", 2833012298], - [112, 7, 3, "Layout/BlockAlignment: `end` at 112, 6 is not aligned with `processed[:analysis].structure` at 107, 21 or `.map do |item|` at 109, 41.", 193405706], - [112, 7, 53, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 1601274288] + [72, 121, 28, "Layout/LineLength: Line is too long. [148/120]", 3724408137], + [79, 5, 1427, "Metrics/AbcSize: Assignment Branch Condition size for `merge_type_script` is too high. [<13, 32, 11> 36.25/17]", 626793766], + [79, 5, 1427, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_type_script` is too high. [11/7]", 626793766], + [79, 5, 1427, "Metrics/MethodLength: Method has too many lines. [22/10]", 626793766], + [79, 5, 1427, "Metrics/PerceivedComplexity: Perceived complexity for `merge_type_script` is too high. [11/8]", 626793766], + [98, 34, 7, "Style/MultilineBlockChain: Avoid multi-line chains of blocks.", 4045560504], + [107, 5, 1486, "Metrics/AbcSize: Assignment Branch Condition size for `analyze_type_script_module` is too high. [<8, 19, 5> 21.21/17]", 961716773], + [107, 5, 1486, "Metrics/MethodLength: Method has too many lines. [41/10]", 961716773] ], "spec/fixtures_integration_spec.rb:2894274721": [ [3, 1, 5091, "Metrics/BlockLength: Block has too many lines. [67/25]", 332568190], diff --git a/gems/typescript-merge/Gemfile b/gems/typescript-merge/Gemfile index 98fb6890e..8ea5e52eb 100644 --- a/gems/typescript-merge/Gemfile +++ b/gems/typescript-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/typescript-merge/Gemfile.lock b/gems/typescript-merge/Gemfile.lock index f5a0a58a0..b0f1dce9d 100644 --- a/gems/typescript-merge/Gemfile.lock +++ b/gems/typescript-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,32 +682,54 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -518,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -531,22 +856,27 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/typescript-merge/gemfiles/modular/templating.gemfile b/gems/typescript-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/typescript-merge/gemfiles/modular/templating.gemfile +++ b/gems/typescript-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/typescript-merge/gemfiles/modular/templating_local.gemfile b/gems/typescript-merge/gemfiles/modular/templating_local.gemfile index 2b5c576e3..3708e23e1 100644 --- a/gems/typescript-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/typescript-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[typescript-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[typescript-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[typescript-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/typescript-merge/lib/typescript/merge.rb b/gems/typescript-merge/lib/typescript/merge.rb index afc2711ef..d1854360e 100644 --- a/gems/typescript-merge/lib/typescript/merge.rb +++ b/gems/typescript-merge/lib/typescript/merge.rb @@ -13,18 +13,32 @@ module Merge PACKAGE_NAME = 'typescript-merge' TREE_SITTER_BACKEND = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND DESTINATION_WINS_ARRAY_POLICY = { surface: 'array', name: 'destination_wins_array' }.freeze + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) + + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(TREE_SITTER_BACKEND) + + grammar_finder = TreeHaver::GrammarFinder.new(:typescript) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end def type_script_feature_profile { family: 'typescript', supported_dialects: ['typescript'], supported_policies: [DESTINATION_WINS_ARRAY_POLICY] } end def available_type_script_backends - [TREE_SITTER_BACKEND] + type_script_backend_available_for_analysis?(TREE_SITTER_BACKEND.id) ? [TREE_SITTER_BACKEND] : [] end def type_script_backend_feature_profile(backend: nil) requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && type_script_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported TypeScript backend #{requested}.") end @@ -51,7 +65,7 @@ def type_script_plan_context(backend: nil) def parse_type_script(source, dialect) requested = TREE_SITTER_BACKEND.id - unless requested == TREE_SITTER_BACKEND.id + unless requested == TREE_SITTER_BACKEND.id && type_script_backend_available_for_analysis?(requested) return unsupported_feature_result("Unsupported TypeScript backend #{requested}.") end return analyze_type_script_module(source) if dialect == 'typescript' @@ -60,6 +74,14 @@ def parse_type_script(source, dialect) diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: "Unsupported TypeScript dialect #{dialect}." }], policies: [] } end + def type_script_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == TREE_SITTER_BACKEND.id + + registrations = TreeHaver.registered_languages(:typescript) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end + def match_type_script_owners(template, destination) Ast::Merge::OwnerSelection.match_by_path(template, destination) end @@ -93,24 +115,35 @@ def merge_type_script(template_source, destination_source, dialect) end def analyze_type_script_module(source) - parsed = TreeHaver.parse_with_language_pack(TreeHaver::ParserRequest.new(source: source, language: 'typescript', - dialect: 'typescript')) - return { ok: false, diagnostics: parsed[:diagnostics], policies: [] } unless parsed[:ok] - - processed = TreeHaver.process_with_language_pack(TreeHaver::ProcessRequest.new(source: source, - language: 'typescript')) - return { ok: false, diagnostics: processed[:diagnostics], policies: [] } unless processed[:ok] - - imports = processed[:analysis].imports.each_with_index.map do |item, index| - { path: "/imports/#{index}", match_key: item.source, text: import_text(source, item.span) } - end - declarations = processed[:analysis].structure - .select { |item| item.name } - .map do |item| - { path: "/declarations/#{item.name}", match_key: item.name, - text: declaration_text(source, item.span) } + parser = TreeHaver.parser_for(:typescript) + tree = parser.parse(source) + collect_parse_errors(tree.root_node) + + imports = [] + declarations = [] + tree.root_node.children.each do |node| + case node.type + when 'import_statement' + import_source = line_anchored_slice(source, node) + imports << { + path: "/imports/#{imports.length}", + owner_kind: 'import', + match_key: normalize_type_script_import_path(import_source), + text: import_text(source, node) + } + when 'export_statement', 'function_declaration', 'class_declaration', 'interface_declaration', + 'lexical_declaration', 'variable_declaration' + name = first_named_descendant_text(source, node, %w[identifier type_identifier]) + next unless name + + declarations << { + path: "/declarations/#{name}", + owner_kind: 'declaration', + match_key: name, + text: declaration_text(source, node) + } + end end - .sort_by { |item| item[:path] } { ok: true, @@ -118,17 +151,61 @@ def analyze_type_script_module(source) analysis: { kind: 'typescript', dialect: 'typescript', - source: source, - owners: imports.map { |item| { path: item[:path], owner_kind: 'import', match_key: item[:match_key] } } + - declarations.map { |item| { path: item[:path], owner_kind: 'declaration', match_key: item[:match_key] } }, imports: imports, - declarations: declarations + declarations: declarations, + owners: owner_views(imports + declarations) }, policies: [] } + rescue TreeHaver::Error, StandardError => e + parse_failure_result(e) end private_class_method :analyze_type_script_module + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'TypeScript parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'TypeScript parse contains syntax errors' + end + private_class_method :collect_parse_errors + + def parse_failure_result(error) + { ok: false, + diagnostics: [{ severity: 'error', category: 'parse_error', message: error.message }], + policies: [] } + end + private_class_method :parse_failure_result + + def normalize_type_script_import_path(import_source) + match = import_source.match(/from\s+['"]([^'"]+)['"]/) || import_source.match(/import\s+['"]([^'"]+)['"]/) + match ? match[1] : import_source.sub(/\Aimport\s+/, '').strip + end + private_class_method :normalize_type_script_import_path + + def first_named_descendant_text(source, node, types) + return slice_span(source, node) if types.include?(node.type) + + node.children.each do |child| + value = first_named_descendant_text(source, child, types) + return value if value && !value.empty? + end + nil + end + private_class_method :first_named_descendant_text + + def owner_view(item) + item.slice(:path, :owner_kind, :match_key) + end + private_class_method :owner_view + + def owner_views(items) + imports, declarations = items.partition { |item| item.fetch(:owner_kind) == 'import' } + (imports + declarations.sort_by { |item| item.fetch(:path) }).map { |item| owner_view(item) } + end + private_class_method :owner_views + def import_text(source, span) "#{slice_span(source, span)}\n" end @@ -152,12 +229,18 @@ def line_anchored_slice(source, span) private_class_method :line_anchored_slice def unsupported_feature_result(message) - Ast::Merge.unsupported_feature_result(message) + { + ok: false, + diagnostics: [{ severity: 'error', category: 'unsupported_feature', message: message }], + policies: [] + } end private_class_method :unsupported_feature_result end end +TypeScript::Merge.register_backend! + TypeScript::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/typescript-merge/spec/fixtures_integration_spec.rb b/gems/typescript-merge/spec/fixtures_integration_spec.rb index 752b8564d..0d1dc742f 100644 --- a/gems/typescript-merge/spec/fixtures_integration_spec.rb +++ b/gems/typescript-merge/spec/fixtures_integration_spec.rb @@ -77,4 +77,17 @@ def json_ready(value) = Ast::Merge.json_ready(value) %w[typescript slice-104-merge module-merge.json] ) end + + it 'fails closed when the TypeScript TreeHaver backend is unavailable' do + allow(described_class).to receive(:type_script_backend_available_for_analysis?).and_return(false) + + expect(described_class.available_type_script_backends).to eq([]) + result = described_class.parse_type_script("export function main() {}\n", 'typescript') + + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to eq( + [{ severity: 'error', category: 'unsupported_feature', + message: 'Unsupported TypeScript backend kreuzberg-language-pack.' }] + ) + end end diff --git a/gems/yaml-merge/.gitattributes b/gems/yaml-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/yaml-merge/.gitattributes +++ b/gems/yaml-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/yaml-merge/.kettle-drift.lock b/gems/yaml-merge/.kettle-drift.lock index 9295a3562..09df60df7 100644 --- a/gems/yaml-merge/.kettle-drift.lock +++ b/gems/yaml-merge/.kettle-drift.lock @@ -4,7 +4,13 @@ "file": "Gemfile", "lines": [ 80, - 120 + 120, + 160, + 200, + 240, + 280, + 320, + 360 ] } ], @@ -13,7 +19,13 @@ "file": "Gemfile", "lines": [ 91, - 131 + 131, + 171, + 211, + 251, + 291, + 331, + 371 ] } ], @@ -22,7 +34,13 @@ "file": "Gemfile", "lines": [ 81, - 121 + 121, + 161, + 201, + 241, + 281, + 321, + 361 ] } ], @@ -31,7 +49,13 @@ "file": "Gemfile", "lines": [ 93, - 133 + 133, + 173, + 213, + 253, + 293, + 333, + 373 ] } ], @@ -40,7 +64,13 @@ "file": "Gemfile", "lines": [ 96, - 136 + 136, + 176, + 216, + 256, + 296, + 336, + 376 ] } ], @@ -49,7 +79,13 @@ "file": "Gemfile", "lines": [ 82, - 122 + 122, + 162, + 202, + 242, + 282, + 322, + 362 ] } ], @@ -59,7 +95,13 @@ "lines": [ 60, 100, - 140 + 140, + 180, + 220, + 260, + 300, + 340, + 380 ] } ], @@ -68,7 +110,13 @@ "file": "Gemfile", "lines": [ 101, - 141 + 141, + 181, + 221, + 261, + 301, + 341, + 381 ] } ], @@ -78,7 +126,13 @@ "lines": [ 43, 87, - 127 + 127, + 167, + 207, + 247, + 287, + 327, + 367 ] } ], @@ -87,7 +141,13 @@ "file": "Gemfile", "lines": [ 110, - 150 + 150, + 190, + 230, + 270, + 310, + 350, + 390 ] } ], @@ -97,7 +157,13 @@ "lines": [ 35, 79, - 119 + 119, + 159, + 199, + 239, + 279, + 319, + 359 ] } ], @@ -107,7 +173,13 @@ "lines": [ 69, 109, - 149 + 149, + 189, + 229, + 269, + 309, + 349, + 389 ] } ], @@ -116,7 +188,13 @@ "file": "Gemfile", "lines": [ 85, - 125 + 125, + 165, + 205, + 245, + 285, + 325, + 365 ] } ], @@ -126,7 +204,13 @@ "lines": [ 48, 92, - 132 + 132, + 172, + 212, + 252, + 292, + 332, + 372 ] } ], @@ -136,7 +220,13 @@ "lines": [ 44, 88, - 128 + 128, + 168, + 208, + 248, + 288, + 328, + 368 ] } ], @@ -145,7 +235,13 @@ "file": "Gemfile", "lines": [ 86, - 126 + 126, + 166, + 206, + 246, + 286, + 326, + 366 ] } ], @@ -154,7 +250,13 @@ "file": "Gemfile", "lines": [ 103, - 143 + 143, + 183, + 223, + 263, + 303, + 343, + 383 ] } ], @@ -163,7 +265,13 @@ "file": "Gemfile", "lines": [ 102, - 142 + 142, + 182, + 222, + 262, + 302, + 342, + 382 ] } ], @@ -172,7 +280,13 @@ "file": "Gemfile", "lines": [ 97, - 137 + 137, + 177, + 217, + 257, + 297, + 337, + 377 ] } ], @@ -181,7 +295,13 @@ "file": "Gemfile", "lines": [ 106, - 146 + 146, + 186, + 226, + 266, + 306, + 346, + 386 ] } ], diff --git a/gems/yaml-merge/.rubocop_gradual.lock b/gems/yaml-merge/.rubocop_gradual.lock index afe31b140..c264c3689 100644 --- a/gems/yaml-merge/.rubocop_gradual.lock +++ b/gems/yaml-merge/.rubocop_gradual.lock @@ -76,26 +76,33 @@ "lib/yaml-merge.rb:2387720316": [ [1, 1, 0, "Naming/FileName: The name of this source file (`yaml-merge.rb`) should use snake_case.", 5381] ], - "lib/yaml/merge.rb:4205598808": [ - [11, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Yaml::Merge`.", 2866359175], - [11, 3, 11361, "Metrics/ModuleLength: Module has too many lines. [266/100]", 2351644433], - [59, 5, 812, "Metrics/MethodLength: Method has too many lines. [13/10]", 3270754177], - [78, 5, 735, "Metrics/MethodLength: Method has too many lines. [16/10]", 1550073549], - [99, 5, 674, "Metrics/AbcSize: Assignment Branch Condition size for `match_yaml_owners` is too high. [<10, 23, 8> 26.32/17]", 2258573674], - [99, 5, 674, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `match_yaml_owners` is too high. [9/7]", 2258573674], - [99, 5, 674, "Metrics/PerceivedComplexity: Perceived complexity for `match_yaml_owners` is too high. [9/8]", 2258573674], - [123, 5, 1604, "Metrics/AbcSize: Assignment Branch Condition size for `merge_yaml_with_parser` is too high. [<6, 19, 8> 21.47/17]", 1557726711], - [123, 5, 1604, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_yaml_with_parser` is too high. [8/7]", 1557726711], - [123, 5, 1604, "Metrics/MethodLength: Method has too many lines. [31/10]", 1557726711], - [165, 5, 857, "Metrics/AbcSize: Assignment Branch Condition size for `validate_yaml_node` is too high. [<8, 20, 8> 22.98/17]", 1513454330], - [165, 5, 857, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `validate_yaml_node` is too high. [8/7]", 1513454330], - [165, 5, 857, "Metrics/MethodLength: Method has too many lines. [17/10]", 1513454330], - [165, 5, 857, "Metrics/PerceivedComplexity: Perceived complexity for `validate_yaml_node` is too high. [9/8]", 1513454330], - [183, 121, 25, "Layout/LineLength: Line is too long. [145/120]", 223655047], - [232, 5, 472, "Metrics/MethodLength: Method has too many lines. [12/10]", 3240975354], - [253, 5, 773, "Metrics/MethodLength: Method has too many lines. [16/10]", 3727949237], - [273, 5, 582, "Metrics/AbcSize: Assignment Branch Condition size for `merge_yaml_mappings` is too high. [<3, 17, 6> 18.28/17]", 3352000353], - [273, 5, 582, "Metrics/MethodLength: Method has too many lines. [11/10]", 3352000353] + "lib/yaml/merge.rb:1796884563": [ + [10, 3, 12, "Style/Documentation: Missing top-level documentation comment for `module Yaml::Merge`.", 2866359175], + [10, 3, 14840, "Metrics/ModuleLength: Module has too many lines. [356/100]", 2006289345], + [86, 5, 774, "Metrics/MethodLength: Method has too many lines. [17/10]", 3937655844], + [108, 5, 674, "Metrics/AbcSize: Assignment Branch Condition size for `match_yaml_owners` is too high. [<10, 23, 8> 26.32/17]", 2258573674], + [108, 5, 674, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `match_yaml_owners` is too high. [9/7]", 2258573674], + [108, 5, 674, "Metrics/PerceivedComplexity: Perceived complexity for `match_yaml_owners` is too high. [9/8]", 2258573674], + [132, 5, 1298, "Metrics/AbcSize: Assignment Branch Condition size for `merge_yaml_with_parser` is too high. [<6, 17, 8> 19.72/17]", 3115490450], + [132, 5, 1298, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `merge_yaml_with_parser` is too high. [8/7]", 3115490450], + [132, 5, 1298, "Metrics/MethodLength: Method has too many lines. [29/10]", 3115490450], + [181, 5, 925, "Metrics/AbcSize: Assignment Branch Condition size for `yaml_value_from_tree` is too high. [<2, 20, 10> 22.45/17]", 787182706], + [181, 5, 925, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `yaml_value_from_tree` is too high. [9/7]", 787182706], + [181, 5, 925, "Metrics/MethodLength: Method has too many lines. [21/10]", 787182706], + [238, 5, 685, "Metrics/AbcSize: Assignment Branch Condition size for `yaml_scalar_from_text` is too high. [<1, 21, 12> 24.21/17]", 3123350773], + [238, 5, 685, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `yaml_scalar_from_text` is too high. [12/7]", 3123350773], + [238, 5, 685, "Metrics/MethodLength: Method has too many lines. [11/10]", 3123350773], + [238, 5, 685, "Metrics/PerceivedComplexity: Perceived complexity for `yaml_scalar_from_text` is too high. [12/8]", 3123350773], + [255, 5, 334, "Metrics/MethodLength: Method has too many lines. [12/10]", 732082977], + [271, 5, 857, "Metrics/AbcSize: Assignment Branch Condition size for `validate_yaml_node` is too high. [<8, 20, 8> 22.98/17]", 1513454330], + [271, 5, 857, "Metrics/CyclomaticComplexity: Cyclomatic complexity for `validate_yaml_node` is too high. [8/7]", 1513454330], + [271, 5, 857, "Metrics/MethodLength: Method has too many lines. [17/10]", 1513454330], + [271, 5, 857, "Metrics/PerceivedComplexity: Perceived complexity for `validate_yaml_node` is too high. [9/8]", 1513454330], + [289, 121, 25, "Layout/LineLength: Line is too long. [145/120]", 223655047], + [338, 5, 472, "Metrics/MethodLength: Method has too many lines. [12/10]", 3240975354], + [359, 5, 773, "Metrics/MethodLength: Method has too many lines. [16/10]", 3727949237], + [379, 5, 582, "Metrics/AbcSize: Assignment Branch Condition size for `merge_yaml_mappings` is too high. [<3, 17, 6> 18.28/17]", 3352000353], + [379, 5, 582, "Metrics/MethodLength: Method has too many lines. [11/10]", 3352000353] ], "spec/fixtures_integration_spec.rb:679605696": [ [3, 1, 9328, "Metrics/BlockLength: Block has too many lines. [217/25]", 4279594244], diff --git a/gems/yaml-merge/Gemfile b/gems/yaml-merge/Gemfile index 28cd3d1a0..4f76f3a3d 100644 --- a/gems/yaml-merge/Gemfile +++ b/gems/yaml-merge/Gemfile @@ -152,7 +152,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -161,7 +401,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -169,7 +409,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/yaml-merge/Gemfile.lock b/gems/yaml-merge/Gemfile.lock index 8377ba74b..5568bc028 100644 --- a/gems/yaml-merge/Gemfile.lock +++ b/gems/yaml-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -16,22 +6,283 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/zip-merge + specs: + zip-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) ast (2.4.3) - ast-merge (7.1.0) - benchmark - token-resolver (~> 2.0, >= 2.0.4) - tree_haver (= 7.1.0) - version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) benchmark (0.5.0) bigdecimal (4.1.2) @@ -40,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -98,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -131,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -270,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -322,13 +584,13 @@ GEM token-resolver (2.0.4) parslet (~> 2.0) version_gem (~> 1.1, >= 1.1.13) - tree_haver (7.1.0) - citrus (~> 3.0) - parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -353,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -373,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -397,11 +682,17 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) yaml-merge! yard (~> 0.9, >= 0.9.44) @@ -410,19 +701,35 @@ DEPENDENCIES yard-relative_markdown_links (~> 0.6) yard-timekeeper (~> 0.1) yard-yaml (~> 0.1, >= 0.1.2) + zip-merge! CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -430,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -442,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -469,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -480,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -507,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -518,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -531,10 +856,14 @@ CHECKSUMS timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 @@ -544,9 +873,10 @@ CHECKSUMS yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 + zip-merge (7.1.0) zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/gems/yaml-merge/gemfiles/modular/templating.gemfile b/gems/yaml-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/yaml-merge/gemfiles/modular/templating.gemfile +++ b/gems/yaml-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/yaml-merge/gemfiles/modular/templating_local.gemfile b/gems/yaml-merge/gemfiles/modular/templating_local.gemfile index 6097b8fa9..2e5d4ae44 100644 --- a/gems/yaml-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/yaml-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[yaml-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[yaml-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[yaml-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/gems/yaml-merge/lib/yaml/merge.rb b/gems/yaml-merge/lib/yaml/merge.rb index 600624752..1a65fb0c2 100644 --- a/gems/yaml-merge/lib/yaml/merge.rb +++ b/gems/yaml-merge/lib/yaml/merge.rb @@ -4,7 +4,6 @@ require_relative 'merge/version' require 'json' -require 'yaml' require 'tree_haver' module Yaml @@ -15,9 +14,23 @@ module Merge name: 'destination_wins_array' }.freeze BACKEND_REFERENCE = TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND + BACKEND_REGISTRY = Struct.new(:registered, :mutex).new(false, Mutex.new) module_function + def register_backend! + BACKEND_REGISTRY.mutex.synchronize do + return if BACKEND_REGISTRY.registered + + TreeHaver::BackendRegistry.register(BACKEND_REFERENCE) + + grammar_finder = TreeHaver::GrammarFinder.new(:yaml) + grammar_finder.register! if grammar_finder.available? + + BACKEND_REGISTRY.registered = true + end + end + def yaml_feature_profile { family: 'yaml', @@ -27,12 +40,12 @@ def yaml_feature_profile end def available_yaml_backends - [BACKEND_REFERENCE] + yaml_backend_available_for_analysis?(BACKEND_REFERENCE.id) ? [BACKEND_REFERENCE] : [] end def yaml_backend_feature_profile(backend: nil) resolved_backend = resolve_backend(backend) - unless resolved_backend == BACKEND_REFERENCE.id + unless resolved_backend == BACKEND_REFERENCE.id && yaml_backend_available_for_analysis?(resolved_backend) return unsupported_feature_result("Unsupported YAML backend #{resolved_backend}.") end @@ -60,18 +73,15 @@ def parse_yaml(source, dialect, backend: nil) return unsupported_feature_parse_result("Unsupported YAML dialect #{dialect}.") unless dialect == 'yaml' resolved_backend = resolve_backend(backend) - unless resolved_backend == BACKEND_REFERENCE.id + unless resolved_backend == BACKEND_REFERENCE.id && yaml_backend_available_for_analysis?(resolved_backend) return unsupported_feature_parse_result("Unsupported YAML backend #{resolved_backend}.") end - syntax_result = TreeHaver.parse_with_language_pack( - TreeHaver::ParserRequest.new(source: source, language: 'yaml') - ) - return { ok: false, diagnostics: syntax_result[:diagnostics], policies: [] } unless syntax_result[:ok] + tree = TreeHaver.with_backend(resolved_backend) { TreeHaver.parser_for(:yaml).parse(source) } + collect_parse_errors(tree.root_node) - parsed = YAML.safe_load(source, permitted_classes: [], aliases: false) - analyze_yaml_document(parsed, dialect) - rescue StandardError => e + analyze_yaml_document(yaml_value_from_tree(tree.root_node, source), dialect) + rescue TreeHaver::Error, StandardError => e parse_error_result(e.message) end @@ -89,6 +99,7 @@ def analyze_yaml_document(parsed, dialect) kind: 'yaml', dialect: 'yaml', normalized_source: canonical_yaml(validated[:value]), + document: validated[:value], root_kind: 'mapping', owners: collect_yaml_owners(validated[:value]) }, @@ -111,7 +122,7 @@ def match_yaml_owners(template, destination) def merge_yaml(template_source, destination_source, dialect, backend: nil) resolved_backend = resolve_backend(backend) - unless resolved_backend == BACKEND_REFERENCE.id + unless resolved_backend == BACKEND_REFERENCE.id && yaml_backend_available_for_analysis?(resolved_backend) return unsupported_feature_merge_result("Unsupported YAML backend #{resolved_backend}.") end @@ -135,10 +146,8 @@ def merge_yaml_with_parser(template_source, destination_source, dialect) } end - template_document = YAML.safe_load(template.dig(:analysis, :normalized_source), permitted_classes: [], - aliases: false) - destination_document = YAML.safe_load(destination.dig(:analysis, :normalized_source), permitted_classes: [], - aliases: false) + template_document = template.dig(:analysis, :document) + destination_document = destination.dig(:analysis, :document) unless template_document.is_a?(Hash) && destination_document.is_a?(Hash) return parse_error_merge_result('YAML documents must parse to a mapping root.') end @@ -162,6 +171,114 @@ def resolve_backend(backend) end private_class_method :resolve_backend + def yaml_backend_available_for_analysis?(backend_id) + register_backend! + return false unless backend_id.to_s == BACKEND_REFERENCE.id + + registrations = TreeHaver.registered_languages(:yaml) + registrations.key?(:tree_sitter) || registrations.key?(:tslp) + end + private_class_method :yaml_backend_available_for_analysis? + + def collect_parse_errors(node) + raise TreeHaver::NotAvailable, 'YAML parse returned no root node' unless node + return unless node.respond_to?(:has_error?) && node.has_error? + + raise TreeHaver::NotAvailable, + 'YAML parse contains syntax errors' + end + private_class_method :collect_parse_errors + + def yaml_value_from_tree(node, source) + named = yaml_named_children(node) + case node.type + when 'stream', 'document', 'block_node', 'flow_node' + return nil if named.empty? + + yaml_value_from_tree(named.first, source) + when 'block_mapping', 'flow_mapping' + yaml_mapping_from_node(node, source) + when 'block_sequence', 'flow_sequence' + yaml_sequence_from_node(node, source) + when 'block_sequence_item' + value_node = named.first + value_node ? yaml_value_from_tree(value_node, source) : nil + when 'plain_scalar', 'string_scalar', 'double_quote_scalar', 'single_quote_scalar' + yaml_scalar_from_text(source[node.start_byte...node.end_byte]) + else + if named.length == 1 + yaml_value_from_tree(named.first, source) + else + yaml_scalar_from_text(source[node.start_byte...node.end_byte]) + end + end + end + private_class_method :yaml_value_from_tree + + def yaml_mapping_from_node(node, source) + yaml_named_children(node).each_with_object({}) do |child, mapping| + next unless child.type.end_with?('mapping_pair') + + pair_children = yaml_named_children(child) + key_node = pair_children.first + next unless key_node + + value_node = pair_children[1] + mapping[yaml_value_from_tree(key_node, source).to_s] = + value_node ? yaml_value_from_tree(value_node, source) : nil + end + end + private_class_method :yaml_mapping_from_node + + def yaml_sequence_from_node(node, source) + yaml_named_children(node).filter_map do |child| + next unless %w[block_sequence_item flow_node].include?(child.type) + + yaml_value_from_tree(child, source) + end + end + private_class_method :yaml_sequence_from_node + + def yaml_named_children(node) + node.children.select do |child| + (!child.respond_to?(:named?) || child.named?) && child.type != 'comment' + end + end + private_class_method :yaml_named_children + + def yaml_scalar_from_text(text) + stripped = text.to_s.strip + return nil if stripped.empty? || stripped == '~' || stripped.casecmp('null').zero? + return true if stripped.casecmp('true').zero? + return false if stripped.casecmp('false').zero? + return stripped.to_i if stripped.match?(/\A[-+]?\d+\z/) + return stripped.to_f if stripped.match?(/\A[-+]?(?:\d+\.\d*|\d*\.\d+)(?:[eE][-+]?\d+)?\z/) + + if stripped.start_with?('"') && stripped.end_with?('"') + return unescape_yaml_double_quoted_scalar(stripped[1...-1]) + end + return stripped[1...-1].gsub("''", "'") if stripped.start_with?("'") && stripped.end_with?("'") + + stripped + end + private_class_method :yaml_scalar_from_text + + def unescape_yaml_double_quoted_scalar(value) + value.gsub(%r{\\(["\\/bfnrt])}) do + { + '"' => '"', + '\\' => '\\', + '/' => '/', + 'b' => "\b", + 'f' => "\f", + 'n' => "\n", + 'r' => "\r", + 't' => "\t" + }.fetch(Regexp.last_match(1)) + end + end + private_class_method :unescape_yaml_double_quoted_scalar + def validate_yaml_node(value, path) if scalar?(value) { ok: true, value: value } @@ -319,6 +436,8 @@ def unsupported_feature_result(message) end end +Yaml::Merge.register_backend! + Yaml::Merge::Version.class_eval do extend VersionGem::Basic end diff --git a/gems/yaml-merge/spec/fixtures_integration_spec.rb b/gems/yaml-merge/spec/fixtures_integration_spec.rb index 948c88510..1fa557ce1 100644 --- a/gems/yaml-merge/spec/fixtures_integration_spec.rb +++ b/gems/yaml-merge/spec/fixtures_integration_spec.rb @@ -151,6 +151,27 @@ def json_ready(value) ) end + it 'documents YAML formatting preservation fixture support for comments, anchors, aliases, documents, and sequences' do + fixture = read_json( + fixtures_root.join( + 'yaml', + 'slice-721-formatting-preservation', + 'comments-anchors-documents-sequences.json' + ) + ) + apply_conformance_fixture_support!(fixture.dig(:implementation_support, :ruby_tslp)) + + result = described_class.merge_yaml( + fixture[:template], + fixture[:destination], + fixture[:dialect], + backend: 'kreuzberg-language-pack' + ) + + expect(result[:ok]).to eq(fixture.dig(:expected, :ok)) + expect(result[:output]).to eq(fixture.dig(:expected, :output)) + end + it 'conforms to the slice-183 YAML polyglot backend feature profile fixtures' do fixture = read_json( fixtures_root.join( diff --git a/gems/zip-merge/.gitattributes b/gems/zip-merge/.gitattributes index 0ac65aaa7..35a3c7359 100644 --- a/gems/zip-merge/.gitattributes +++ b/gems/zip-merge/.gitattributes @@ -1,5 +1,5 @@ # <> do not edit below this line -*.rb diff=smorg-ruby +*.rb diff=smorg-rb *.go diff=smorg-go *.rs diff=smorg-rs # <> diff --git a/gems/zip-merge/.kettle-drift.lock b/gems/zip-merge/.kettle-drift.lock index 9878fb8f5..f1287e677 100644 --- a/gems/zip-merge/.kettle-drift.lock +++ b/gems/zip-merge/.kettle-drift.lock @@ -5,7 +5,13 @@ "lines": [ 79, 119, - 159 + 159, + 199, + 239, + 279, + 319, + 359, + 399 ] } ], @@ -15,7 +21,13 @@ "lines": [ 90, 130, - 170 + 170, + 210, + 250, + 290, + 330, + 370, + 410 ] } ], @@ -25,7 +37,13 @@ "lines": [ 80, 120, - 160 + 160, + 200, + 240, + 280, + 320, + 360, + 400 ] } ], @@ -35,7 +53,13 @@ "lines": [ 92, 132, - 172 + 172, + 212, + 252, + 292, + 332, + 372, + 412 ] } ], @@ -45,7 +69,13 @@ "lines": [ 95, 135, - 175 + 175, + 215, + 255, + 295, + 335, + 375, + 415 ] } ], @@ -55,7 +85,13 @@ "lines": [ 81, 121, - 161 + 161, + 201, + 241, + 281, + 321, + 361, + 401 ] } ], @@ -66,7 +102,13 @@ 59, 99, 139, - 179 + 179, + 219, + 259, + 299, + 339, + 379, + 419 ] } ], @@ -76,7 +118,13 @@ "lines": [ 100, 140, - 180 + 180, + 220, + 260, + 300, + 340, + 380, + 420 ] } ], @@ -87,7 +135,13 @@ 42, 86, 126, - 166 + 166, + 206, + 246, + 286, + 326, + 366, + 406 ] } ], @@ -97,7 +151,13 @@ "lines": [ 109, 149, - 189 + 189, + 229, + 269, + 309, + 349, + 389, + 429 ] } ], @@ -108,7 +168,13 @@ 34, 78, 118, - 158 + 158, + 198, + 238, + 278, + 318, + 358, + 398 ] } ], @@ -119,7 +185,13 @@ 68, 108, 148, - 188 + 188, + 228, + 268, + 308, + 348, + 388, + 428 ] } ], @@ -129,7 +201,13 @@ "lines": [ 84, 124, - 164 + 164, + 204, + 244, + 284, + 324, + 364, + 404 ] } ], @@ -140,7 +218,13 @@ 47, 91, 131, - 171 + 171, + 211, + 251, + 291, + 331, + 371, + 411 ] } ], @@ -151,7 +235,13 @@ 43, 87, 127, - 167 + 167, + 207, + 247, + 287, + 327, + 367, + 407 ] } ], @@ -161,7 +251,13 @@ "lines": [ 85, 125, - 165 + 165, + 205, + 245, + 285, + 325, + 365, + 405 ] } ], @@ -171,7 +267,13 @@ "lines": [ 102, 142, - 182 + 182, + 222, + 262, + 302, + 342, + 382, + 422 ] } ], @@ -181,7 +283,13 @@ "lines": [ 101, 141, - 181 + 181, + 221, + 261, + 301, + 341, + 381, + 421 ] } ], @@ -191,7 +299,13 @@ "lines": [ 96, 136, - 176 + 176, + 216, + 256, + 296, + 336, + 376, + 416 ] } ], @@ -201,7 +315,13 @@ "lines": [ 105, 145, - 185 + 185, + 225, + 265, + 305, + 345, + 385, + 425 ] } ], diff --git a/gems/zip-merge/Gemfile b/gems/zip-merge/Gemfile index f735ba663..bc1ea8998 100644 --- a/gems/zip-merge/Gemfile +++ b/gems/zip-merge/Gemfile @@ -191,7 +191,247 @@ if direct_sibling_gems.any? && end end -# Use the StructuredMerge TLSP branch until upstream ships Ruby 4-compatible gem metadata. +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +if direct_sibling_gems.any? && + (direct_sibling_local || + ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero?) + direct_sibling_dev_was_set = ENV.key?('STRUCTUREDMERGE_DEV') + direct_sibling_dev_original = ENV.fetch('STRUCTUREDMERGE_DEV', nil) + begin + nomono_activation_requirements = nomono_requirements + nomono_lockfile = File.expand_path('Gemfile.lock', __dir__) + if File.file?(nomono_lockfile) + nomono_locked_spec = Bundler::LockfileParser + .new(Bundler.read_file(nomono_lockfile)) + .specs + .find { |spec| spec.name == 'nomono' } + nomono_locked = nomono_locked_spec && + Gem::Requirement.new(nomono_requirements).satisfied_by?(nomono_locked_spec.version) + nomono_activation_requirements = ["= #{nomono_locked_spec.version}"] if nomono_locked + end + Kernel.send(:gem, 'nomono', *nomono_activation_requirements) + require 'nomono/bundler' + ENV['STRUCTUREDMERGE_DEV'] = File.expand_path('..', __dir__) if direct_sibling_templating && !direct_sibling_local + + eval_nomono_gems( + gems: direct_sibling_gems, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', + root: %w[src my structuredmerge] + ) + rescue LoadError + warn 'Install nomono to enable STRUCTUREDMERGE_DEV local sibling-gem dependencies.' + ensure + if direct_sibling_templating && !direct_sibling_local + if direct_sibling_dev_was_set + ENV['STRUCTUREDMERGE_DEV'] = direct_sibling_dev_original + else + ENV.delete('STRUCTUREDMERGE_DEV') + end + end + end +end + +# Use the StructuredMerge TSLP branch until upstream ships Ruby 4-compatible gem metadata. tslp_dev = ENV.fetch('TSLP_DEV', nil) tslp_declared_by_templating = ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? && !tslp_dev.to_s.empty? @@ -200,7 +440,7 @@ unless tslp_declared_by_templating gem( 'tree_sitter_language_pack', git: 'https://github.com/structuredmerge/tree-sitter-language-pack.git', - branch: 'fix/ruby-4-installs', + branch: 'fix/ruby-parser-api-methods', glob: 'packages/ruby/*.gemspec' ) else @@ -208,7 +448,7 @@ unless tslp_declared_by_templating end end -# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths) +# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths) eval_gemfile 'gemfiles/modular/templating.gemfile' if ENV.fetch('K_JEM_TEMPLATING', 'false').casecmp('true').zero? # Debugging diff --git a/gems/zip-merge/Gemfile.lock b/gems/zip-merge/Gemfile.lock index b8658f0b2..49c74eb86 100644 --- a/gems/zip-merge/Gemfile.lock +++ b/gems/zip-merge/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: https://github.com/structuredmerge/tree-sitter-language-pack.git - revision: dcc959b12d02d6e379abf1c8ac536a852d1b8416 - branch: fix/ruby-4-installs - glob: packages/ruby/*.gemspec - specs: - tree_sitter_language_pack (1.12.5) - rb_sys (>= 0.9, < 0.9.128) - sorbet-runtime (~> 0.5) - PATH remote: . specs: @@ -15,13 +5,280 @@ PATH tree_haver (= 7.1.0) version_gem (~> 1.1, >= 1.1.9) +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-markdown-markly + specs: + ast-crispr-markdown-markly (7.1.0) + ast-crispr (= 7.1.0) + markly-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr-ruby-prism + specs: + ast-crispr-ruby-prism (7.1.0) + ast-crispr (= 7.1.0) + prism-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-crispr + specs: + ast-crispr (7.1.0) + ast-merge (= 7.1.0) + service_actor (~> 3.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge-git + specs: + ast-merge-git (7.1.0) + ast-merge (= 7.1.0) + json-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-merge + specs: + ast-merge (7.1.0) + benchmark + token-resolver (~> 2.0, >= 2.0.4) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ast-template + specs: + ast-template (7.1.0) + ast-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/bash-merge + specs: + bash-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/binary-merge + specs: + binary-merge (7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/citrus-toml-merge + specs: + citrus-toml-merge (7.1.0) + toml-merge (= 7.1.0) + toml-rb (~> 4.1) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/commonmarker-merge + specs: + commonmarker-merge (7.1.0) + commonmarker (~> 2.2) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/dotenv-merge + specs: + dotenv-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/go-merge + specs: + go-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/json-merge + specs: + json-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kettle-jem + specs: + kettle-jem (7.1.0) + addressable (>= 2.8, < 3) + ast-crispr-markdown-markly (= 7.1.0) + ast-crispr-ruby-prism (= 7.1.0) + ast-merge (= 7.1.0) + bash-merge (= 7.1.0) + citrus-toml-merge (= 7.1.0) + commonmarker-merge (= 7.1.0) + dotenv-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-dev (~> 2.3, >= 2.3.5) + kettle-rb (~> 0.1, >= 0.1.4) + kramdown-merge (= 7.1.0) + markdown-merge (= 7.1.0) + markly-merge (= 7.1.0) + prism-merge (= 7.1.0) + psych-merge (= 7.1.0) + rbs (>= 3.10) + rbs-merge (= 7.1.0) + ruby-merge (= 7.1.0) + token-resolver (~> 2.0, >= 2.0.4) + toml-merge (= 7.1.0) + toml-rb (~> 4.2) + tree_haver (= 7.1.0) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/kramdown-merge + specs: + kramdown-merge (7.1.0) + kramdown (~> 2.5) + markdown-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markdown-merge + specs: + markdown-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/markly-merge + specs: + markly-merge (7.1.0) + markdown-merge (= 7.1.0) + markly (~> 0.9) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/parslet-toml-merge + specs: + parslet-toml-merge (7.1.0) + toml (~> 0.3) + toml-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/plain-merge + specs: + plain-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/prism-merge + specs: + prism-merge (7.1.0) + prism (~> 1.6) + ruby-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/psych-merge + specs: + psych-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + yaml-merge (= 7.1.0) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rbs-merge + specs: + rbs-merge (7.1.0) + ast-merge (= 7.1.0) + rbs (>= 3.10) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.14) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/ruby-merge + specs: + ruby-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/rust-merge + specs: + rust-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/smorg-rb + specs: + smorg-rb (7.1.0) + ast-merge (= 7.1.0) + ast-merge-git (= 7.1.0) + go-merge (= 7.1.0) + json-merge (= 7.1.0) + kettle-jem (= 7.1.0) + markly-merge (= 7.1.0) + plain-merge (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/toml-merge + specs: + toml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/tree_haver + specs: + tree_haver (7.1.0) + citrus (~> 3.0) + parslet (~> 2.0) + tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/typescript-merge + specs: + typescript-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /home/pboling/src/my/structuredmerge/ruby/gems/yaml-merge + specs: + yaml-merge (7.1.0) + ast-merge (= 7.1.0) + tree_haver (= 7.1.0) + version_gem (~> 1.1, >= 1.1.9) + +PATH + remote: /var/home/pboling/src/my/structuredmerge/vendor/tree-sitter-language-pack/packages/ruby + specs: + tree_sitter_language_pack (1.12.5) + rb_sys (>= 0.9, < 0.9.128) + sorbet-runtime (~> 0.5) + GEM remote: https://gem.coop/ specs: addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) - appraisal2 (3.1.4) + appraisal2 (3.2.0) bundler (>= 1.17.3) rake (>= 10) thor (>= 0.14) @@ -34,6 +291,12 @@ GEM thor (~> 1.0) citrus (3.0.2) cmdparse (3.0.7) + commonmarker (2.9.0-aarch64-linux) + commonmarker (2.9.0-aarch64-linux-musl) + commonmarker (2.9.0-arm64-darwin) + commonmarker (2.9.0-x86_64-darwin) + commonmarker (2.9.0-x86_64-linux) + commonmarker (2.9.0-x86_64-linux-musl) concurrent-ruby (1.3.7) date (3.5.1) debug (1.11.1) @@ -92,11 +355,13 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.1) - kettle-dev (2.3.6) + kettle-dev (2.3.7) emoji_regex (>= 15.0) kettle-rb (~> 0.1, >= 0.1.2) kettle-test (~> 2.0, >= 2.0.4) ruby-progressbar (~> 1.13) + kettle-drift (1.0.5) + version_gem (~> 1.1, >= 1.1.13) kettle-rb (0.1.4) kettle-soup-cover (1.1.3) simplecov (~> 0.22) @@ -125,6 +390,7 @@ GEM language_server-protocol (3.17.0.6) lint_roller (1.1.0) logger (1.7.0) + markly (0.16.0) mutex_m (0.3.0) nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) @@ -264,6 +530,8 @@ GEM ruby-progressbar (1.13.0) ruby_engine (2.0.3) ruby_version (1.0.3) + service_actor (3.9.4) + zeitwerk (>= 1.0) silent_stream (1.0.12) logger (~> 1.2) version_gem (>= 1.1.8, < 3) @@ -313,13 +581,16 @@ GEM delegate (~> 0.1) rspec (~> 3.0) timecop (>= 0.7, < 1) - tree_haver (7.1.0) - citrus (~> 3.0) + token-resolver (2.0.4) parslet (~> 2.0) - tree_sitter_language_pack (>= 1.9.0.pre.rc.40, < 2.0) - version_gem (~> 1.1, >= 1.1.9) + version_gem (~> 1.1, >= 1.1.13) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + toml-rb (4.2.0) + citrus (~> 3.0, > 3.0) + racc (~> 1.7) tsort (0.2.0) - turbo_tests2 (3.1.14) + turbo_tests2 (3.2.0) parallel_tests (>= 3.3.0, < 6) rspec (>= 3.10) version_gem (~> 1.1, >= 1.1.14) @@ -344,7 +615,7 @@ GEM yard yard-relative_markdown_links (0.6.0) nokogiri (>= 1.14.3, < 2) - yard-timekeeper (0.2.3) + yard-timekeeper (0.2.4) version_gem (~> 1.1, >= 1.1.13) yard-yaml (0.2.3) version_gem (~> 1.1, >= 1.1.13) @@ -364,22 +635,45 @@ PLATFORMS DEPENDENCIES addressable (>= 2.8, < 3) appraisal2 (~> 3.0, >= 3.0.6) + ast-crispr! + ast-crispr-markdown-markly! + ast-crispr-ruby-prism! + ast-merge! + ast-merge-git! + ast-template! + bash-merge! benchmark (~> 0.5, >= 0.5.0) + binary-merge! bundler-audit (~> 0.9.3) + citrus-toml-merge! + commonmarker-merge! debug (>= 1.1) + dotenv-merge! erb (~> 6.0, >= 6.0.4) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 2.0, >= 2.0.0) + go-merge! irb (~> 1.17) + json-merge! kettle-dev (~> 2.0, >= 2.2.25) + kettle-drift (~> 1.0, >= 1.0.5) + kettle-jem! kettle-soup-cover (~> 1.0, >= 1.1.3) kettle-test (~> 2.0, >= 2.0.9) kramdown (~> 2.5, >= 2.5.1) + kramdown-merge! kramdown-parser-gfm (~> 1.1) + markdown-merge! + markly-merge! mutex_m (~> 0.2) nomono (~> 1.0, >= 1.0.8) + parslet-toml-merge! + plain-merge! + prism-merge! + psych-merge! rake (~> 13.0) rbs (>= 3.0) + rbs-merge! rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) @@ -388,12 +682,19 @@ DEPENDENCIES rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) rubocop-ruby3_2 (~> 3.0.0) + ruby-merge! ruby-progressbar (~> 1.13) + rust-merge! + smorg-rb! standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) + toml-merge! + tree_haver! tree_sitter_language_pack! + typescript-merge! yaml-converter (~> 0.1) + yaml-merge! yard (~> 0.9, >= 0.9.44) yard-fence (~> 0.9, >= 0.9.1) yard-junk (~> 0.1, >= 0.1.0) @@ -405,14 +706,30 @@ DEPENDENCIES CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 - appraisal2 (3.1.4) sha256=f88c27e600adf4bd5bf06c0ab0afd1de6ce4361497760ce35e86e782036286f4 + appraisal2 (3.2.0) sha256=ccd0b767ac4060cd7af6d16747459b6990f49c39c7b4fb1f7d1146b1e97c492f ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + ast-crispr (7.1.0) + ast-crispr-markdown-markly (7.1.0) + ast-crispr-ruby-prism (7.1.0) + ast-merge (7.1.0) + ast-merge-git (7.1.0) + ast-template (7.1.0) backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 + bash-merge (7.1.0) benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + binary-merge (7.1.0) bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9 citrus (3.0.2) sha256=4ec2412fc389ad186735f4baee1460f7900a8e130ffe3f216b30d4f9c684f650 + citrus-toml-merge (7.1.0) cmdparse (3.0.7) sha256=f7c5cace10bec6abf853370ae095e4b97a84ed9d847b3fb38f41cc4fbc950739 + commonmarker (2.9.0-aarch64-linux) sha256=e2b4aadb9a2cfa4e206582641ce3a49465549ac1ed4c289fdd63b78d8f24579c + commonmarker (2.9.0-aarch64-linux-musl) sha256=1cf4d2821f2a7e64945f1ed7c4eeced586fdb27ea7fe7337788802cf8f57cfca + commonmarker (2.9.0-arm64-darwin) sha256=1748dbfa4f5813b0d2a14bb4bbfa65a4ec293aa1c825016d60029ee0e132b046 + commonmarker (2.9.0-x86_64-darwin) sha256=0a9914ccfd2f5d2a59c7bd0dda4fe90eb084cf513b477e499008e09ec9d6edd6 + commonmarker (2.9.0-x86_64-linux) sha256=8cfe92970eef585a19ddf6613224b91cab64d6029834661bda801f877c9c7f43 + commonmarker (2.9.0-x86_64-linux-musl) sha256=293921398b839f79ceaf55010e061357e34f053822c3b003cd0be6686176335e + commonmarker-merge (7.1.0) concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 @@ -420,6 +737,7 @@ CHECKSUMS diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 diffy (3.4.4) sha256=79384ab5ca82d0e115b2771f0961e27c164c456074bd2ec46b637ebf7b6e47e3 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + dotenv-merge (7.1.0) dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc @@ -432,19 +750,27 @@ CHECKSUMS gem_bench (2.0.5) sha256=0dc0fb44a5a5eb7b2f5c1c68a5b0164d72007132822c012bac3abe976b199ead geom2d (0.4.1) sha256=ea0998ea90c4f2752e24fe13d85a4f89bee689d151316140ebcc6369bf634ed9 gitmoji-regex (2.0.4) sha256=01410d3217940bd0e7b2299ec805245afe8d0f06a5d6d38f623d63a63c0ac34f + go-merge (7.1.0) hexapdf (1.9.1) sha256=2d1f6a3622e6bc2a70a707d4c3f3fa44f5552ecd9d899f6283abb07398a84884 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 - kettle-dev (2.3.6) sha256=955b01e8aca46438365332d1b4413f22cb58dabfeab5cba04d71237c53cc70ae + json-merge (7.1.0) + kettle-dev (2.3.7) sha256=eb370113cd030d03cbe2d33b31c99858951017e5ad21a17e9ed89dc3770028ee + kettle-drift (1.0.5) sha256=07094e80140a049164142820bdd327c30fcd855bb00697a0a430600a2b5144a2 + kettle-jem (7.1.0) kettle-rb (0.1.4) sha256=9cef7ce4f7021666b7222292f29051e51eaf042e8a5db11f3f4dd72f74243fc1 kettle-soup-cover (1.1.3) sha256=a373827da22a7131d093afd32945e5b7d7a10a01ebfdded8fd2cb8230d69c8ad kettle-test (2.0.11) sha256=c710c90f7ab79d51f9452f0c09f5f90657e7a893f63583855c164d0b1b107ab2 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-merge (7.1.0) kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + markdown-merge (7.1.0) + markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511 + markly-merge (7.1.0) mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri (1.19.4-aarch64-linux-musl) sha256=35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af @@ -459,10 +785,14 @@ CHECKSUMS parallel_tests (5.7.0) sha256=3f1762c46ca2c223b8af8ef877217f9d76974e191bfa934f2580b58bcf1d005c parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 parslet (2.0.0) sha256=d45130695d39b43d7e6a91f4d2ec66b388a8d822bae38de9b4de9a5fbde1f606 + parslet-toml-merge (7.1.0) + plain-merge (7.1.0) pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + prism-merge (7.1.0) psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 + psych-merge (7.1.0) public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a @@ -470,6 +800,7 @@ CHECKSUMS rake-compiler-dock (1.12.0) sha256=f13205c2738f3d2053afcd03491a9e4541b22a59a0bfc53fc8bc883bd8188023 rb_sys (0.9.127) sha256=e9f90df3bb0577472d26d96127d5b5774b98f44de881e7d36aeefd28d6337847 rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14 + rbs-merge (7.1.0) rdoc (6.17.0) sha256=0f50d4e568fc98195f9bb155a9e8dff6c7feabfb515fb22ef6df1d12ad5a02b7 reek (6.5.0) sha256=d26d3a492773b2bbc228888067a21afe33ac07954a17dbd64cdeae42c4c69be1 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -497,9 +828,12 @@ CHECKSUMS rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2 rubocop-ruby3_2 (3.0.7) sha256=f53dd6d286fb05186214fc6ec116783e7f837030918e8931c05de773e98f8466 rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431 + ruby-merge (7.1.0) ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby_engine (2.0.3) sha256=ca2ae7def8cfcdc2bfb6a186d36d5d59c8b403245dc0256c3802b767fa278aaa ruby_version (1.0.3) sha256=5930f9950746b7e6c973184398ee364ee7440b170fef7922b9f5cdf317f1ccb5 + rust-merge (7.1.0) + service_actor (3.9.4) sha256=e63b523630b9a7e62959b2a90113b08d2565b5de9c148557b281ef847c9539ce silent_stream (1.0.12) sha256=377c43aa10033fe90c33b39ea8cd97d79f2d1c4856df598efc56f3091f3ae782 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.2.0) sha256=70d702658677fcb20e5aceb6915ccf8bc62ff2ccd38b62b3ad5c9db5c0888740 @@ -508,6 +842,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + smorg-rb (7.1.0) sorbet-runtime (0.6.13342) sha256=dbeb9892597f593ed2b29e38018912787f6c4e0c4b736d8af0d6bd3c63bde3c3 standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b @@ -520,19 +855,25 @@ CHECKSUMS thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73 timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542 timecop-rspec (1.0.3) sha256=005f14841bb606dcaefb060e321b5388e2e59537742bee8b3a9a9a40e598fab9 + token-resolver (2.0.4) sha256=33b926958f504525bba3ed511ab66fbcbf8ef30390815e931436b30f27ffcad0 + toml (0.3.0) sha256=0a91d0f76a9036e84e44f95693b12f58d358c1df3ac8e3b5271f2056ecc6e4b9 + toml-merge (7.1.0) + toml-rb (4.2.0) sha256=10a48c91613e20cf63483a7a776767dfb3cd7d70e9327c0237443da601e13776 tree_haver (7.1.0) tree_sitter_language_pack (1.12.5) tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f - turbo_tests2 (3.1.14) sha256=cc29d5b36bdbba67a83eee09a9546880d0926edfbbe50d99633fc0b5763ee94c + turbo_tests2 (3.2.0) sha256=8b35421548399d1923567b177970f42671c65695b93cdd134d78fbcbab85dff0 + typescript-merge (7.1.0) unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f version_gem (1.1.14) sha256=6b7306c7e9416d06067561981ab3444e2cecb844f26cc325ae3c27b44cf85613 yaml-converter (0.2.3) sha256=d35e69e547610d9e347672cc277fcb7d71dff3c53a942e66f82b1c64022ada72 + yaml-merge (7.1.0) yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51 yard-fence (0.9.6) sha256=3d1dbf4e3df462ac78b8bd2e01cf740a2de20168387c929aca31a0bcee490659 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.6.0) sha256=3e5ffa85cbad9bac70bee5421774b190fb25d3bdf489323a5b3534f647d1a70e - yard-timekeeper (0.2.3) sha256=849a3e74a0484b1e0b5209cf86823e418b3091e21f4f143c141d38e1cc262034 + yard-timekeeper (0.2.4) sha256=62f8d001d737c6e2ac688e7b37386f958dceb0f6aff9c909575e1bec8d20775a yard-yaml (0.2.3) sha256=fe5fef18819e1cbd05bb8f1b9e1baad6bf70c28125eb75b57bbf6397b0831812 zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12 zip-merge (7.1.0) diff --git a/gems/zip-merge/gemfiles/modular/templating.gemfile b/gems/zip-merge/gemfiles/modular/templating.gemfile index 0d1c9bcf4..e3c24e6b7 100644 --- a/gems/zip-merge/gemfiles/modular/templating.gemfile +++ b/gems/zip-merge/gemfiles/modular/templating.gemfile @@ -1,9 +1,9 @@ # frozen_string_literal: true -smorg_remote = ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false').zero? +structuredmerge_remote = ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false').zero? kettle_remote = ENV.fetch('KETTLE_RB_DEV', 'false').casecmp('false').zero? -if smorg_remote +if structuredmerge_remote # Merge recipes and parser dependencies for released installs. gem 'kettle-jem', '>= 7.0' end @@ -13,10 +13,10 @@ if kettle_remote gem 'kettle-drift', '~> 1.0', '>= 1.0.5', require: false end -# Set SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. +# Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies. # When false (default / CI), released kettle-jem brings merge gems and parser dependencies. # Local path overrides bring the same dependencies from sibling gemspecs. # # Set KETTLE_RB_DEV=/path/to/kettle-rb for local development with Kettle plugin gems. # When false (default / CI), released Kettle plugin gems are used. -eval_gemfile 'templating_local.gemfile' unless smorg_remote && kettle_remote +eval_gemfile 'templating_local.gemfile' unless structuredmerge_remote && kettle_remote diff --git a/gems/zip-merge/gemfiles/modular/templating_local.gemfile b/gems/zip-merge/gemfiles/modular/templating_local.gemfile index 1e68ab586..48389338d 100644 --- a/gems/zip-merge/gemfiles/modular/templating_local.gemfile +++ b/gems/zip-merge/gemfiles/modular/templating_local.gemfile @@ -1,12 +1,12 @@ # frozen_string_literal: true # Local path overrides for templating development. -# Loaded by the associated non-local gemfile when SMORG_RB_DEV or KETTLE_RB_DEV +# Loaded by the associated non-local gemfile when STRUCTUREDMERGE_DEV or KETTLE_RB_DEV # is not "false". require 'nomono/bundler' unless defined?(Nomono) -smorg_rb_local_gems = %w[ +structuredmerge_local_gems = %w[ tree_haver ast-merge ast-merge-git @@ -43,7 +43,7 @@ kettle_rb_local_gems = %w[ kettle-dev kettle-test kettle-soup-cover kettle-drift ] declared_gems = instance_variable_get(:@dependencies).to_a.map(&:name) -smorg_rb_local_gems_to_eval = smorg_rb_local_gems - %w[zip-merge] - declared_gems +structuredmerge_local_gems_to_eval = structuredmerge_local_gems - %w[zip-merge] - declared_gems kettle_rb_local_gems_to_eval = kettle_rb_local_gems - %w[zip-merge] - declared_gems tslp_dev = ENV.fetch('TSLP_DEV', nil) @@ -52,14 +52,14 @@ tslp_dev = ENV.fetch('TSLP_DEV', nil) platform :mri do gem 'tree_sitter_language_pack', path: tslp_dev unless tslp_dev.to_s.empty? - if ENV.fetch('SMORG_RB_DEV', 'false').casecmp('false') != 0 + if ENV.fetch('STRUCTUREDMERGE_DEV', 'false').casecmp('false') != 0 eval_nomono_gems( - gems: smorg_rb_local_gems_to_eval, - prefix: 'SMORG_RB', - path_env: 'SMORG_RB_DEV', + gems: structuredmerge_local_gems_to_eval, + prefix: 'STRUCTUREDMERGE', + path_env: 'STRUCTUREDMERGE_DEV', vendored_gems_env: 'VENDORED_GEMS', vendor_gem_dir_env: 'VENDOR_GEM_DIR', - debug_env: 'SMORG_RB_DEBUG' + debug_env: 'STRUCTUREDMERGE_DEBUG' ) end diff --git a/spec/architecture/source_family_tree_haver_spec.rb b/spec/architecture/source_family_tree_haver_spec.rb new file mode 100644 index 000000000..fd43d586b --- /dev/null +++ b/spec/architecture/source_family_tree_haver_spec.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require_relative '../../gems/go-merge/lib/go/merge' +require_relative '../../gems/rust-merge/lib/rust/merge' +require_relative '../../gems/typescript-merge/lib/typescript/merge' +require_relative '../../gems/ruby-merge/lib/ruby/merge' +require_relative '../../gems/markdown-merge/lib/markdown/merge' +require_relative '../../gems/yaml-merge/lib/yaml/merge' +require_relative '../../gems/json-merge/lib/json/merge' +require_relative '../../gems/psych-merge/lib/psych/merge' +require_relative '../../gems/toml-merge/lib/toml/merge' + +RSpec.describe 'source-family TreeHaver parsing' do + before do + allow(TreeHaver).to receive(:parser_for) do |language_name| + raise TreeHaver::NotAvailable, "No parser registered for #{language_name}" + end + end + + it 'fails closed through TreeHaver when Go has no registered parser' do + result = Go::Merge.parse_go("package main\n", 'go') + + expect(TreeHaver).to have_received(:parser_for).with(:go) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for go')) + ) + end + + it 'fails closed through TreeHaver when Rust has no registered parser' do + result = Rust::Merge.parse_rust("fn main() {}\n", 'rust') + + expect(TreeHaver).to have_received(:parser_for).with(:rust) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for rust')) + ) + end + + it 'fails closed through TreeHaver when TypeScript has no registered parser' do + result = TypeScript::Merge.parse_type_script("export const x = 1;\n", 'typescript') + + expect(TreeHaver).to have_received(:parser_for).with(:typescript) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for typescript')) + ) + end + + it 'fails closed through TreeHaver when Ruby has no registered parser' do + result = Ruby::Merge.parse_ruby("class Example\nend\n", 'ruby') + + expect(TreeHaver).to have_received(:parser_for).with(:ruby) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for ruby')) + ) + end + + it 'fails closed through TreeHaver when Markdown has no registered parser' do + result = Markdown::Merge.parse_markdown("# Example\n", 'markdown') + + expect(TreeHaver).to have_received(:parser_for).with(:markdown) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for markdown')) + ) + end + + it 'fails closed through TreeHaver when YAML has no registered parser' do + result = Yaml::Merge.parse_yaml("key: value\n", 'yaml') + + expect(TreeHaver).to have_received(:parser_for).with(:yaml) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for yaml')) + ) + end + + it 'fails closed through TreeHaver when JSON has no registered parser' do + result = Json::Merge.parse_json("{\"key\":\"value\"}\n", 'json') + + expect(TreeHaver).to have_received(:parser_for).with(:json) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for json')) + ) + end + + it 'fails closed through TreeHaver when the Psych YAML provider has no registered parser' do + result = Psych::Merge.parse_yaml("key: value\n", 'yaml') + + expect(TreeHaver).to have_received(:parser_for).with(:yaml) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for yaml')) + ) + end + + it 'fails closed through TreeHaver when TOML has no registered parser' do + result = Toml::Merge.parse_toml("key = \"value\"\n", 'toml') + + expect(TreeHaver).to have_received(:parser_for).with(:toml) + expect(result[:ok]).to be(false) + expect(result[:diagnostics]).to include( + include(severity: 'error', category: 'parse_error', message: include('No parser registered for toml')) + ) + end +end diff --git a/spec/architecture/tree_haver_only_spec.rb b/spec/architecture/tree_haver_only_spec.rb new file mode 100644 index 000000000..489583083 --- /dev/null +++ b/spec/architecture/tree_haver_only_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'pathname' +require 'set' + +RSpec.describe 'TreeHaver-only merge architecture' do + ROOT = Pathname.new(__dir__).join('..', '..').expand_path + + PARSER_BYPASS_PATTERN = / + TreeHaver\.(?:parse_with_language_pack|process_with_language_pack|parse_with_citrus|parse_with_parslet) | + Json::Merge::SyntheticParser | + (?