Skip to content

Releases: kettle-rb/kettle-dev

v2.0.0

26 Feb 19:04
v2.0.0
fef9731

Choose a tag to compare

2.0.0 - 2026-02-25

  • TAG: v2.0.0
  • COVERAGE: 96.06% -- 2683/2793 lines in 20 files
  • BRANCH COVERAGE: 79.16% -- 1113/1406 branches in 20 files
  • 80.25% documented

Added

  • New kettle-gh-release executable for standalone GitHub release creation
    • Extracted from kettle-release step 18
    • Useful when RubyGems release succeeded but GitHub release failed
    • Supports explicit version via version=<VERSION> argument
    • Auto-detects version from lib/**/version.rb if not specified
    • Requires GITHUB_TOKEN with repo:public_repo (classic) or contents:write scope
  • Added .kettle-dev.yml configuration file for per-file merge options
    • Hybrid format: defaults for shared merge options, patterns for glob fallbacks, files for per-file config
    • Nested directory structure under files allows individual file configuration
    • Supports all Prism::Merge::SmartMerger options: preference, add_template_only_nodes, freeze_token, max_recursion_depth
    • Added TemplateHelpers.kettle_config, .config_for, .find_file_config methods
    • Added spec coverage in template_helpers_config_spec.rb

Changed

  • Updated documentation on hostile takeover of RubyGems
  • BREAKING: Replaced template_manifest.yml with .kettle-dev.yml
    • New hybrid format supports both glob patterns and per-file configuration
    • TemplateHelpers.load_manifest now reads from .kettle-dev.yml patterns section
    • TemplateHelpers.strategy_for checks explicit file configs before falling back to patterns
  • BREAKING: Simplified SourceMerger to fully rely on prism-merge for AST merging
    • Reduced from ~610 lines to ~175 lines (71% reduction)
    • Removed custom newline normalization - prism-merge preserves original formatting
    • Removed custom comment deduplication logic - prism-merge handles this natively
    • All strategies (:skip, :replace, :append, :merge) now use prism-merge consistently
    • Freeze blocks (kettle-dev:freeze / kettle-dev:unfreeze) handled by prism-merge's freeze_token option

Removed

  • Removed all .example template files from the kettle-dev root and subdirectories
    (27 files). Template files now live exclusively in kettle-jem's template/ directory.
    Only .env.local.example is retained as a dev resource for all destination gems.
  • Removed unused methods from SourceMerger:
    • normalize_source - replaced by prism-merge
    • normalize_newlines - prism-merge preserves original formatting
    • shebang?, magic_comment?, ruby_magic_comment_key? - no longer needed
    • Comment extraction/deduplication: extract_magic_comments, extract_file_leading_comments,
      create_comment_tuples, deduplicate_comment_sequences, deduplicate_sequences_pass1,
      deduplicate_singles_pass2, extract_nodes_with_comments, count_blank_lines_before,
      build_source_from_nodes
    • Unused comment restoration: restore_custom_leading_comments, deduplicate_leading_comment_block,
      extract_comment_lines, normalize_comment, leading_comment_block
  • Removed unused constants: RUBY_MAGIC_COMMENT_KEYS, MAGIC_COMMENT_REGEXES

Fixed

  • Fixed PrismAppraisals various comment chunk spacing
    • extract_block_header:
      • skips the blank spacer immediately above an appraise block
      • treats any following blank line as the stop boundary once comment lines have been collected
      • prevents preamble comments from being pulled into the first block’s header
    • restores expected ordering:
      • magic comments and their blank line stay at the top
      • block headers remain adjacent to their blocks
      • preserves blank lines between comment chunks
  • Fixed SourceMerger freeze block location preservation
    • Freeze blocks now stay in their original location in the file structure
    • Skip normalization for files with existing freeze blocks to prevent movement
    • Only include contiguous comments immediately before freeze markers (no arbitrary 3-line lookback)
    • Don't add freeze reminder to files that already have freeze/unfreeze blocks
    • Prevents unrelated comments from being incorrectly captured in freeze block ranges
    • Added comprehensive test coverage for multiple freeze blocks at different nesting levels
  • Fixed TemplateTask to not override template summary/description with empty strings from destination gemspec
    • Only carries over summary/description when they contain actual content (non-empty)
    • Allows token replacements to work correctly (e.g., kettle-dev summarymy-gem summary)
    • Prevents empty destination fields from erasing meaningful template values
  • Fixed SourceMerger magic comment ordering and freeze block protection
    • Magic comments now preserve original order
    • No blank lines inserted between consecutive magic comments
    • Freeze reminder block properly separated from magic comments (not merged)
    • Leverages Prism's built-in parse_result.magic_comments API for accurate detection
    • Detects kettle-dev:freeze/unfreeze pairs using Prism, then reclassifies as file-level comments to keep blocks intact
    • Removed obsolete is_magic_comment? method in favor of Prism's native detection
  • Fixed PrismGemspec and PrismGemfile to use pure Prism AST traversal instead of regex fallbacks
    • Removed regex-based extract_gemspec_emoji that parsed spec.summary = and spec.description = with regex
    • Now traverses Prism AST to find Gem::Specification block, extracts summary/description nodes, and gets literal values
    • Removed regex-based source line detection in PrismGemfile.merge_gem_calls
    • Now uses PrismUtils.statement_key to find source statements via AST instead of ln =~ /^\s*source\s+/
    • Aligns with project goal: move away from regex parsing toward proper AST manipulation with Prism
    • All functionality preserved, tested, and working correctly
  • Fixed PrismGemspec.replace_gemspec_fields block parameter extraction to use Prism AST
    • CRITICAL: Was using regex fallback that incorrectly captured entire block body as parameter name
    • Removed buggy regex fallback in favor of pure Prism AST traversal
    • Now properly extracts block parameter from Prism::BlockParametersNode → Prism::ParametersNode → Prism::RequiredParameterNode
  • Fixed PrismGemspec.replace_gemspec_fields insert offset calculation for emoji-containing gemspecs
    • CRITICAL: Was using character length (String#length) instead of byte length (String#bytesize) to calculate insert offset
    • When gemspecs contain multi-byte UTF-8 characters (emojis like 🍲), character length != byte length
    • This caused fields to be inserted at wrong byte positions, resulting in truncated strings and massive corruption
    • Changed body_src.rstrip.length to body_src.rstrip.bytesize for correct byte-offset calculations
    • Prevents gemspec templating from producing corrupted output with truncated dependency lines
    • Added comprehensive debug logging to trace byte offset calculations and edit operations
  • Fixed SourceMerger variable assignment duplication during merge operations
    • node_signature now identifies variable/constant assignments by name only, not full source
    • Previously used full source text as signature, causing duplicates when assignment bodies differed
    • Added specific handlers for: LocalVariableWriteNode, InstanceVariableWriteNode, ClassVariableWriteNode, ConstantWriteNode, GlobalVariableWriteNode
    • Also added handlers for ClassNode and ModuleNode to match by name
    • Example: gem_version = ... assignments with different bodies now correctly merge instead of duplicating
    • Prevents bin/kettle-dev-setup from creating duplicate variable assignments in gemspecs and other files
    • Added comprehensive specs for variable assignment deduplication and idempotency
  • Fixed SourceMerger conditional block duplication during merge operations
    • node_signature now identifies conditional nodes (if/unless/case) by their predicate only
    • Previously used full source text, causing duplicate blocks when template updates conditional bodies
    • Example: if ENV["FOO"] blocks with different bodies now correctly merge instead of duplicating
    • Prevents bin/kettle-dev-setup from creating duplicate if/else blocks in gemfiles
    • Added comprehensive specs for conditional merging behavior and idempotency
  • Fixed PrismGemspec.replace_gemspec_fields to use byte-aware string operations
    • CRITICAL: Was using character-based String#[]= with Prism's byte offsets
    • This caused catastrophic corruption when emojis or multi-byte UTF-8 characters were present
    • Symptoms: gemspec blocks duplicated/fragmented, statements escaped outside blocks
    • Now uses byteslice and byte-aware concatenation for all edit operations
    • Prevents gemspec templating from producing mangled output with duplicated Gem::Specification blocks
  • Fixed PrismGemspec.replace_gemspec_fields to correctly handle multi-byte UTF-8 characters (e.g., emojis)
    • Prism uses byte offsets, not character offsets, when parsing Ruby code
    • Changed string slicing from String#[] to String#byteslice for all offset-based operations
    • Added validation to use String#bytesize instead of String#length for offset bounds checking
    • Prevents TypeError: no implicit conversion of nil into String when gemspecs contain emojis
    • Ensures gemspec field carryover works correctly with emoji in summary/description fields
    • Enhanced error reporting to show backtraces when debug mode is enabled

Official Discord 👉️ [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite]

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![Open...

Read more

v1.2.4

29 Nov 04:43
v1.2.4
9b6ed9c

Choose a tag to compare

1.2.4 - 2025-11-28

  • TAG: v1.2.4
  • COVERAGE: 93.53% -- 4701/5026 lines in 31 files
  • BRANCH COVERAGE: 76.61% -- 1913/2497 branches in 31 files
  • 69.78% documented

Fixed

  • Fixed comment deduplication in restore_custom_leading_comments to prevent accumulation across multiple template runs
    • Comments from destination are now deduplicated before being merged back into result
    • Fixes issue where :replace strategy (used by kettle-dev-setup --force) would accumulate duplicate comments
    • Ensures truly idempotent behavior when running templating multiple times on the same file
    • Example: frozen_string_literal comments no longer multiply from 1→4→5→6 on repeated runs

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.2.3

29 Nov 03:00
v1.2.3
d0309b7

Choose a tag to compare

1.2.3 - 2025-11-28

  • TAG: v1.2.3
  • COVERAGE: 93.43% -- 4681/5010 lines in 31 files
  • BRANCH COVERAGE: 76.63% -- 1912/2495 branches in 31 files
  • 70.55% documented

Fixed

  • Fixed Gemfile parsing to properly deduplicate comments across multiple template runs
    • Implemented two-pass comment deduplication: sequences first, then individual lines
    • Magic comments (frozen_string_literal, encoding, etc.) are now properly deduplicated by content, not line position
    • File-level comments are deduplicated while preserving leading comments attached to statements
    • Ensures idempotent behavior when running templating multiple times on the same file
    • Prevents accumulation of duplicate frozen_string_literal comments and comment blocks

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.2.2

27 Nov 10:59
v1.2.2
7ada462

Choose a tag to compare

1.2.2 - 2025-11-27

  • TAG: v1.2.2
  • COVERAGE: 93.28% -- 4596/4927 lines in 31 files
  • BRANCH COVERAGE: 76.45% -- 1883/2463 branches in 31 files
  • 70.00% documented

Added

  • Prism AST-based manipulation of ruby during templating
    • Gemfiles
    • gemspecs
    • .simplecov
  • Stop rescuing Exception in certain scenarios (just StandardError)
  • Refactored logging logic and documentation
  • Prevent self-referential gemfile injection
    • in Gemfiles, gemspecs, and Appraisals
  • Improve reliability of coverage and documentation stats
    • in the changelog version heading
    • fails hard when unable to generate stats, unless --no-strict provided

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.2.1

26 Nov 22:21
v1.2.1
97bd302

Choose a tag to compare

[1.2.1] - 2025-11-25

  • TAG: [v1.2.0][1.2.0t]
  • COVERAGE: 94.38% -- 4066/4308 lines in 26 files
  • BRANCH COVERAGE: 78.81% -- 1674/2124 branches in 26 files
  • 69.14% documented

Changed

  • Source merging switched from Regex-based string manipulation to Prism AST-based manipulation
    • Comments are preserved in the resulting file

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.2.0

26 Nov 00:42
v1.2.0
f57ad5a

Choose a tag to compare

1.2.0 - 2025-11-25

  • TAG: v1.2.0
  • COVERAGE: 94.38% -- 4066/4308 lines in 26 files
  • BRANCH COVERAGE: 78.81% -- 1674/2124 branches in 26 files
  • 69.14% documented

Changed

  • Source merging switched from Regex-based string manipulation to Prism AST-based manipulation
    • Comments are preserved in the resulting file

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.1.60

24 Nov 03:26
v1.1.60
6830321

Choose a tag to compare

1.1.60 - 2025-11-23

  • TAG: v1.1.60
  • COVERAGE: 94.38% -- 4066/4308 lines in 26 files
  • BRANCH COVERAGE: 78.86% -- 1675/2124 branches in 26 files
  • 79.89% documented

Added

Fixed

  • Prevent double test runs by ensuring only one of test/coverage/spec are in default task
    • Add debugging when more than one registered

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.1.59

14 Nov 00:10
v1.1.59
020618d

Choose a tag to compare

1.1.59 - 2025-11-13

  • TAG: v1.1.59
  • COVERAGE: 94.38% -- 4066/4308 lines in 26 files
  • BRANCH COVERAGE: 78.77% -- 1673/2124 branches in 26 files
  • 79.89% documented

Changed

  • Improved default devcontainer with common dependencies of most Ruby projects

Fixed

  • token replacement of {TARGET|GEM|NAME}

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.1.58

13 Nov 21:40
v1.1.58
118bc3b

Choose a tag to compare

1.1.58 - 2025-11-13

  • TAG: v1.1.58
  • COVERAGE: 94.41% -- 4067/4308 lines in 26 files
  • BRANCH COVERAGE: 78.77% -- 1673/2124 branches in 26 files
  • 79.89% documented

Added

  • Ignore more .idea plugin artifacts

Fixed

  • bin/rake yard no longer overrides the .yardignore for checksums

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon

v1.1.57

13 Nov 10:11
v1.1.57
c88092b

Choose a tag to compare

1.1.57 - 2025-11-13

  • TAG: v1.1.57
  • COVERAGE: 94.36% -- 4065/4308 lines in 26 files
  • BRANCH COVERAGE: 78.81% -- 1674/2124 branches in 26 files
  • 79.89% documented

Added

  • New Rake task: appraisal:reset — deletes all Appraisal lockfiles (gemfiles/*.gemfile.lock).
  • Improved .env.local.example template

Fixed

  • .yardignore more comprehensively ignores directories that are not relevant to documentation

Official Discord 👉️ Live Chat on Discord

Many paths lead to being a sponsor or a backer of this project. Are you on such a path?

OpenCollective Backers OpenCollective Sponsors Sponsor Me on Github Liberapay Goal Progress Donate on PayPal

Buy me a coffee Donate on Polar Donate to my FLOSS efforts at ko-fi.com Donate to my FLOSS efforts using Patreon