ratatui_ruby-devtools 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e42c1eb334a8258f81be914b98c98d561eb88cbbd994bafdf1c795dc6eea976
4
- data.tar.gz: 89c0cc556e030abc3c218842afd01c1320f9ee43adec14b5c8eddb62ac4f9cad
3
+ metadata.gz: 57fc1bc3e22f7db96b7434687a5ba68ebd2e791af094ca8c7b0fa93046c0c8e0
4
+ data.tar.gz: ce0771ddec4a189df1e9ec5de19a9bc2fad461b6265575380d1c15a8120e6939
5
5
  SHA512:
6
- metadata.gz: e6d0b98c938b05cec67b959334be558e3b134c3ebc18297bd286168c35ddf6d5a2482891855dae53da7809e923ba996bc416dfe444f088c6cc9d7e83d59dbb76
7
- data.tar.gz: b09df8f84796a39206e541540d793a635bbec3c6553cb0efeb9032f59caa96179ebe36d3962c073a007de6c66c8543c7cdc2f0fd013d86da0bd068c5136ef0d4
6
+ metadata.gz: ee73b0da8bbe0f1ae17c266f7320a6795036e7c8e9a2b9c2c0ecb2f4c125a788a319ed475a76e759e7531805fdafda9372ec6dd20baed006dc95fe95b00fc8a4
7
+ data.tar.gz: 14d72b6a59018d202eba6e175d4cf8716a4c42791ac759402a6367b23168fe6d6678e2199384cf34269b6d67899d7610ee19c0c8c73f6b5238b8506b28cebc72
data/CHANGELOG.md CHANGED
@@ -21,6 +21,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
21
 
22
22
  ### Removed
23
23
 
24
+ ## [0.4.0] - 2026-10-23
25
+
26
+ ### Added
27
+
28
+ - **Changes too small for copyright**: The license tasks wrote a copyright notice for every commit author whose lines remained in a file, even when all they changed was a path or a typo, which no one can hold copyright in. List such commits in `.git-blame-ignore-revs`, and the license tasks blame their lines on the commits before them. Git reads that file only when each contributor configures it, so the license tasks pass it to `git blame` themselves.
29
+
30
+ ### Changed
31
+
32
+ ### Fixed
33
+
34
+ - **Scaffolded gem builds on Node.js 24**: The scaffolded `build-gems` workflow used versions of `actions/checkout`, `jdx/mise-action`, and the artifact actions that run on Node.js 20, which GitHub removed on September 16, 2026, so it could no longer build your precompiled gems. It now uses their Node.js 24 versions. Run `scaffold --update` to pick it up.
35
+ - **License headers deleted lines above them**: When the license tasks rewrote a header, they deleted every line above it except `# frozen_string_literal: true`, such as a `# rubocop:disable` directive or a Rust `//!` comment. A Ruby script that opened with a shebang lost it, and one without a header got its new header above the shebang, so the script no longer ran. A file that opened with an encoding comment got `# frozen_string_literal: true` above it, and Ruby ignores an encoding comment below that line. Those lines now stay above the header, with the shebang first and the encoding comment right after it.
36
+
37
+ ### Removed
38
+
24
39
  ## [0.3.0] - 2026-10-22
25
40
 
26
41
  ### Added
@@ -141,6 +156,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
141
156
  ### Removed
142
157
 
143
158
  [Unreleased]: https://github.com/setdef/ratatui_ruby-devtools/tree/HEAD
159
+ [0.4.0]: https://github.com/setdef/ratatui_ruby-devtools/releases/tag/v0.4.0
144
160
  [0.3.0]: https://github.com/setdef/ratatui_ruby-devtools/releases/tag/v0.3.0
145
161
  [0.2.1]: https://github.com/setdef/ratatui_ruby-devtools/releases/tag/v0.2.1
146
162
  [0.2.0]: https://github.com/setdef/ratatui_ruby-devtools/releases/tag/v0.2.0
data/README.md CHANGED
@@ -219,6 +219,19 @@ RatatuiRuby::Devtools.install_gem_tasks!(
219
219
  ```
220
220
  <!-- SPDX-SnippetEnd -->
221
221
 
222
+ Each header names the commit authors whose lines remain in the file, with the last year each touched them. Copyright protects only original expression, so a change too small to hold it, such as a corrected path, needs no notice. List its commit in `.git-blame-ignore-revs`, and the license tasks blame its lines on the commits before it, as GitHub's blame view does:
223
+
224
+ <!-- SPDX-SnippetBegin -->
225
+ <!--
226
+ SPDX-SnippetCopyrightText: 2026 Kerrick Long
227
+ SPDX-License-Identifier: MIT-0
228
+ -->
229
+ ```text
230
+ # Corrects the relative paths to examples/
231
+ 0123456789abcdef0123456789abcdef01234567
232
+ ```
233
+ <!-- SPDX-SnippetEnd -->
234
+
222
235
  `rake reuse:fix` gives Ruby, RBS, Rust, and Markdown files the same headers the license tasks write. Environment variables set what it writes for other files:
223
236
 
224
237
  | Variable | Default |
@@ -16,8 +16,13 @@ require_relative "contribution"
16
16
  # Only commit authors count. Co-Authored-By trailers credit AI tools, which
17
17
  # can't hold copyright, and people whose idea a commit took up without their
18
18
  # code; git history already credits both.
19
+ #
20
+ # Commits listed in .git-blame-ignore-revs count for no one, so a change too
21
+ # small to hold copyright, such as a corrected path, adds no notice. Git reads
22
+ # that file only when each contributor configures it, so blame names it here.
19
23
  class Blame < Data.define(:path, :contents) # :nodoc:
20
24
  UNCOMMITTED = "0" * 40
25
+ IGNORE_REVS = ".git-blame-ignore-revs"
21
26
 
22
27
  def initialize(path:, contents: nil)
23
28
  super
@@ -54,6 +59,7 @@ class Blame < Data.define(:path, :contents) # :nodoc:
54
59
  command = %w[git blame --porcelain]
55
60
  command += ["-L", range.join(",")] if range
56
61
  command += ["--contents", "-"] if contents
62
+ command += ["--ignore-revs-file", IGNORE_REVS] if File.exist?(IGNORE_REVS)
57
63
  output, status = Open3.capture2(*command, "--", path, stdin_data: contents.to_s, err: File::NULL)
58
64
  return unless status.success?
59
65
 
@@ -25,7 +25,9 @@ class RbsHeaderSyntax # :nodoc:
25
25
  "#{block(header)}\n#{lines.drop_while { |line| line.strip.empty? }.join}"
26
26
  end
27
27
 
28
+ # A magic comment means nothing in RBS.
28
29
  def replaced(header, lines, end_line)
29
- "#{block(header)}\n#{after_header(lines, end_line).join}"
30
+ opening = preamble(lines, end_line).reject { |line| line.include?("frozen_string_literal") }
31
+ "#{opening.join}#{"\n" if opening.any?}#{block(header)}\n#{after_header(lines, end_line).join}"
30
32
  end
31
33
  end
@@ -46,4 +46,12 @@ module RubyCommentHeader # :nodoc:
46
46
  private def block(header)
47
47
  "#--\n#{header.commented('#')}#++\n"
48
48
  end
49
+
50
+ # The file's own lines among the header's, such as a shebang or a linter
51
+ # directive, which stay above the new header.
52
+ private def preamble(lines, end_line)
53
+ lines.take(end_line + 1).reject do |line|
54
+ line.match?(COPYRIGHT) || line.match?(LICENSE) || line.match?(/^#(--|\+\+)?\s*$/) || line.strip.empty?
55
+ end
56
+ end
49
57
  end
@@ -13,6 +13,10 @@ class RubyHeaderSyntax # :nodoc:
13
13
  include RubyCommentHeader
14
14
 
15
15
  FROZEN_STRING_LITERAL = "# frozen_string_literal: true\n"
16
+ # Ruby finds an encoding wherever "coding" meets a colon or equals sign, as
17
+ # in Emacs and Vim modelines.
18
+ ENCODING_COMMENT = /\A#.*coding[:=]/
19
+ MAGIC_COMMENT = /\A#.*(coding[:=]|\b(frozen_string_literal|warn_indent|shareable_constant_value)\s*:)/
16
20
 
17
21
  def extensions
18
22
  %w[rb]
@@ -23,17 +27,21 @@ class RubyHeaderSyntax # :nodoc:
23
27
  end
24
28
 
25
29
  def added(header, lines)
26
- frozen = frozen_string_literal_in(lines)
27
- body = (frozen ? lines.drop(1) : lines).drop_while { |line| line.strip.empty? }
28
- "#{frozen || FROZEN_STRING_LITERAL}\n#{block(header)}\n#{body.join}"
30
+ opening = lines.take_while { |line| line.start_with?("#!") || line.match?(MAGIC_COMMENT) }
31
+ body = lines.drop(opening.length).drop_while { |line| line.strip.empty? }
32
+ "#{frozen(opening).join}\n#{block(header)}\n#{body.join}"
29
33
  end
30
34
 
31
35
  def replaced(header, lines, end_line)
32
- frozen = frozen_string_literal_in(lines)
33
- "#{frozen || FROZEN_STRING_LITERAL}\n#{block(header)}\n#{after_header(lines, end_line).join}"
36
+ "#{frozen(preamble(lines, end_line)).join}\n#{block(header)}\n#{after_header(lines, end_line).join}"
34
37
  end
35
38
 
36
- private def frozen_string_literal_in(lines)
37
- lines.first if lines.first&.include?("frozen_string_literal")
39
+ # Ruby reads a shebang only on the first line, and an encoding comment only
40
+ # on the first line or right after a shebang.
41
+ private def frozen(opening)
42
+ return opening if opening.any? { |line| line.include?("frozen_string_literal") }
43
+
44
+ first_lines = opening.take_while { |line| line.start_with?("#!") || line.match?(ENCODING_COMMENT) }
45
+ opening.dup.insert(first_lines.length, FROZEN_STRING_LITERAL)
38
46
  end
39
47
  end
@@ -54,6 +54,15 @@ class RustHeaderSyntax # :nodoc:
54
54
  end
55
55
 
56
56
  def replaced(header, lines, end_line)
57
- "#{header.commented('//')}\n#{after_header(lines, end_line).join}"
57
+ opening = preamble(lines, end_line)
58
+ "#{opening.join}#{"\n" if opening.any?}#{header.commented('//')}\n#{after_header(lines, end_line).join}"
59
+ end
60
+
61
+ # The file's own comments among the header's, which stay above the new
62
+ # header.
63
+ private def preamble(lines, end_line)
64
+ lines.take(end_line + 1).reject do |line|
65
+ line.match?(COPYRIGHT) || line.match?(LICENSE) || line.match?(%r{^//\s*$}) || line.strip.empty?
66
+ end
58
67
  end
59
68
  end
@@ -23,7 +23,7 @@ jobs:
23
23
  CI: "true"
24
24
  BINDGEN_EXTRA_CLANG_ARGS: "-include stdbool.h"
25
25
  steps:
26
- - uses: actions/checkout@v4
26
+ - uses: actions/checkout@v6
27
27
 
28
28
  - name: Override Ruby version in mise.toml
29
29
  shell: bash
@@ -47,7 +47,7 @@ jobs:
47
47
  rustup target add x86_64-pc-windows-gnu
48
48
 
49
49
  - name: Install toolchain via mise
50
- uses: jdx/mise-action@v2
50
+ uses: jdx/mise-action@v4
51
51
 
52
52
  - name: Setup (Unix)
53
53
  if: runner.os != 'Windows'
@@ -63,7 +63,7 @@ jobs:
63
63
  run: mise x -- bundle exec rake
64
64
 
65
65
  - name: Upload compiled binary
66
- uses: actions/upload-artifact@v4
66
+ uses: actions/upload-artifact@v7
67
67
  with:
68
68
  name: native-${{ matrix.os }}-ruby${{ matrix.ruby }}
69
69
  path: lib/<%= ext_name %>/<%= ext_name %>.*
@@ -78,7 +78,7 @@ jobs:
78
78
  matrix:
79
79
  os: [ubuntu-latest, macos-latest, windows-latest]
80
80
  steps:
81
- - uses: actions/checkout@v4
81
+ - uses: actions/checkout@v6
82
82
 
83
83
  - name: Install Ruby via RubyInstaller (Windows)
84
84
  if: runner.os == 'Windows'
@@ -93,7 +93,7 @@ jobs:
93
93
 
94
94
  - name: Install toolchain via mise (Unix)
95
95
  if: runner.os != 'Windows'
96
- uses: jdx/mise-action@v2
96
+ uses: jdx/mise-action@v4
97
97
 
98
98
  - name: Configure Windows mise (skip Ruby)
99
99
  if: runner.os == 'Windows'
@@ -103,11 +103,11 @@ jobs:
103
103
 
104
104
  - name: Install toolchain via mise (Windows)
105
105
  if: runner.os == 'Windows'
106
- uses: jdx/mise-action@v2
106
+ uses: jdx/mise-action@v4
107
107
 
108
108
  <%- rubies.map { |r| r.split(".")[0..1].join(".") }.uniq.each do |minor| -%>
109
109
  - name: Download Ruby <%= minor %> binary
110
- uses: actions/download-artifact@v4
110
+ uses: actions/download-artifact@v8
111
111
  with:
112
112
  name: native-${{ matrix.os }}-ruby<%= minor %>
113
113
  path: lib/<%= ext_name %>/<%= minor %>
@@ -123,7 +123,7 @@ jobs:
123
123
  run: mise x -- bundle exec rake release:platform_gem
124
124
 
125
125
  - name: Upload gem artifact
126
- uses: actions/upload-artifact@v4
126
+ uses: actions/upload-artifact@v7
127
127
  with:
128
128
  name: gem-${{ matrix.os }}
129
129
  path: pkg/*.gem
@@ -8,6 +8,6 @@
8
8
  module RatatuiRuby
9
9
  module Devtools
10
10
  # Current version of the ratatui_ruby-devtools gem.
11
- VERSION = "0.3.0"
11
+ VERSION = "0.4.0"
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratatui_ruby-devtools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kerrick Long