kettle-dev 1.1.55 → 1.1.56

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: e4782eb3b39e080e427e189f57e3aed63e153847e42a1941ab5878bbd105c2fc
4
- data.tar.gz: 4b2403df88b14c7bdab14a016eba9566412bf82df7e941d95802c6eb06148376
3
+ metadata.gz: 62e325c872a074389b37b26430debd850401b38e86d9e21beecde17565beb561
4
+ data.tar.gz: 9f2698e5f4fd28e0c97cef4c9ca6b41b313cca732bb7b1338ef333e87c2b7240
5
5
  SHA512:
6
- metadata.gz: 85ea8797ad85aa8fdc7e81c87c5690ea51de9d11f72c2bc3d3a27d98592677ef7b3d4586d25d57faa08d2e75d578dd474962ca3f7393f4ba84546f307e08c33c
7
- data.tar.gz: 6d1480c222f28119e4207b8b98083148c6633f94fe160f501622eff7628e06ba813cd0aa4cb756a494ec3e1751259841b0e09dd482153fae12786f767de43185
6
+ metadata.gz: 5799a7e73b2d365f1adedae8a00b66197547727937be9b88cabc16dc17755e8aa96e53ce34c379f88fb917fe7be9b22db7090095500140f592e1372f77006835
7
+ data.tar.gz: b7dcc7f75644618b7f5294bd94c4ba3157cc64306509ef66ff173a16f25ad7a123b66c0304df0633bbbc8fdfdd69d0db1ab01d0e9bec03e016eb9f830bdf6cac
checksums.yaml.gz.sig CHANGED
Binary file
data/.envrc.example ADDED
@@ -0,0 +1,50 @@
1
+ # Run any command in this library's bin/ without the bin/ prefix!
2
+ # Prefer exe version over binstub
3
+ PATH_add exe
4
+ PATH_add bin
5
+
6
+ # Only add things to this file that should be shared with the team.
7
+
8
+ # **dotenv** (See end of file for .env.local integration)
9
+ # .env would override anything in this file, if enabled.
10
+ # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments.
11
+ # Override and customize anything below in your own .env.local
12
+ # If you are using dotenv and not direnv,
13
+ # copy the following `export` statements to your own .env file.
14
+
15
+ ### General Ruby ###
16
+ # Turn off Ruby Warnings about deprecated code
17
+ # export RUBYOPT="-W0"
18
+
19
+ ### External Testing Controls
20
+ export K_SOUP_COV_DO=true # Means you want code coverage
21
+ export K_SOUP_COV_COMMAND_NAME="Test Coverage"
22
+ # Available formats are html, xml, rcov, lcov, json, tty
23
+ export K_SOUP_COV_FORMATTERS="html,xml,rcov,lcov,json,tty"
24
+ export K_SOUP_COV_MIN_BRANCH=76 # Means you want to enforce X% branch coverage
25
+ export K_SOUP_COV_MIN_LINE=92 # Means you want to enforce X% line coverage
26
+ export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met
27
+ export K_SOUP_COV_MULTI_FORMATTERS=true
28
+ export K_SOUP_COV_OPEN_BIN= # Means don't try to open coverage results in browser
29
+ export MAX_ROWS=1 # Setting for simplecov-console gem for tty output, limits to the worst N rows of bad coverage
30
+ export KETTLE_TEST_SILENT=true
31
+
32
+ # Internal Debugging Controls
33
+ export DEBUG=false # do not allow byebug statements (override in .env.local)
34
+ export FLOSS_CFG_FUND_DEBUG=false # extra logging to help diagnose issues (override in .env.local)
35
+ export FLOSS_CFG_FUND_LOGFILE=tmp/log/debug.log
36
+
37
+ # Concurrently developing the rubocop-lts suite?
38
+ export RUBOCOP_LTS_LOCAL=false
39
+
40
+ # If {TARGET|GEM|NAME} does not have an open source collective set these to false.
41
+ export OPENCOLLECTIVE_HANDLE={OPENCOLLECTIVE|ORG_NAME}
42
+ export FUNDING_ORG={OPENCOLLECTIVE|ORG_NAME}
43
+
44
+ # .env would override anything in this file, if `dotenv` is uncommented below.
45
+ # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments,
46
+ # and that is why we generally want to leave it commented out.
47
+ # dotenv
48
+
49
+ # .env.local will override anything in this file.
50
+ dotenv_if_exists .env.local
@@ -0,0 +1,50 @@
1
+ # Run any command in this library's bin/ without the bin/ prefix!
2
+ # Prefer exe version over binstub
3
+ PATH_add exe
4
+ PATH_add bin
5
+
6
+ # Only add things to this file that should be shared with the team.
7
+
8
+ # **dotenv** (See end of file for .env.local integration)
9
+ # .env would override anything in this file, if enabled.
10
+ # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments.
11
+ # Override and customize anything below in your own .env.local
12
+ # If you are using dotenv and not direnv,
13
+ # copy the following `export` statements to your own .env file.
14
+
15
+ ### General Ruby ###
16
+ # Turn off Ruby Warnings about deprecated code
17
+ # export RUBYOPT="-W0"
18
+
19
+ ### External Testing Controls
20
+ export K_SOUP_COV_DO=true # Means you want code coverage
21
+ export K_SOUP_COV_COMMAND_NAME="Test Coverage"
22
+ # Available formats are html, xml, rcov, lcov, json, tty
23
+ export K_SOUP_COV_FORMATTERS="html,xml,rcov,lcov,json,tty"
24
+ export K_SOUP_COV_MIN_BRANCH=76 # Means you want to enforce X% branch coverage
25
+ export K_SOUP_COV_MIN_LINE=92 # Means you want to enforce X% line coverage
26
+ export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met
27
+ export K_SOUP_COV_MULTI_FORMATTERS=true
28
+ export K_SOUP_COV_OPEN_BIN= # Means don't try to open coverage results in browser
29
+ export MAX_ROWS=1 # Setting for simplecov-console gem for tty output, limits to the worst N rows of bad coverage
30
+ export KETTLE_TEST_SILENT=true
31
+
32
+ # Internal Debugging Controls
33
+ export DEBUG=false # do not allow byebug statements (override in .env.local)
34
+ export FLOSS_CFG_FUND_DEBUG=false # extra logging to help diagnose issues (override in .env.local)
35
+ export FLOSS_CFG_FUND_LOGFILE=tmp/log/debug.log
36
+
37
+ # Concurrently developing the rubocop-lts suite?
38
+ export RUBOCOP_LTS_LOCAL=false
39
+
40
+ # {TARGET|GEM|NAME} has no open source collective.
41
+ export OPENCOLLECTIVE_HANDLE=false
42
+ export FUNDING_ORG=false
43
+
44
+ # .env would override anything in this file, if `dotenv` is uncommented below.
45
+ # .env is a DOCKER standard, and if we use it, it would be in deployed, or DOCKER, environments,
46
+ # and that is why we generally want to leave it commented out.
47
+ # dotenv
48
+
49
+ # .env.local will override anything in this file.
50
+ dotenv_if_exists .env.local
@@ -55,7 +55,7 @@ jobs:
55
55
  include:
56
56
  # Ruby <whichever version is current, e.g., 3.4 as of 2025-07-12>
57
57
  - ruby: "ruby"
58
- appraisal_name: "unlocked_deps"
58
+ appraisal: "unlocked_deps"
59
59
  exec_cmd: "rake"
60
60
  gemfile: "Appraisal.root"
61
61
  rubygems: latest
@@ -78,7 +78,7 @@ jobs:
78
78
  # NOTE: This does not use the primary Gemfile at all.
79
79
  - name: Install Root Appraisal
80
80
  run: bundle
81
- - name: Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal_name }}
82
- run: bundle exec appraisal ${{ matrix.appraisal_name }} bundle
83
- - name: Run ${{ matrix.exec_cmd }} on ${{ matrix.ruby }}@${{ matrix.appraisal_name }}
84
- run: bundle exec appraisal ${{ matrix.appraisal_name }} bundle exec ${{ matrix.exec_cmd }}
81
+ - name: Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }}
82
+ run: bundle exec appraisal ${{ matrix.appraisal }} bundle
83
+ - name: Run ${{ matrix.exec_cmd }} on ${{ matrix.ruby }}@${{ matrix.appraisal }}
84
+ run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
@@ -22,7 +22,6 @@ variables:
22
22
  K_SOUP_COV_DEBUG: true
23
23
  K_SOUP_COV_DO: true
24
24
  K_SOUP_COV_HARD: true
25
- # Lower than local, which is at 100/100, because rubocop-lts isn't installed in the coverage workflow
26
25
  K_SOUP_COV_MIN_BRANCH: 74
27
26
  K_SOUP_COV_MIN_LINE: 90
28
27
  K_SOUP_COV_VERBOSE: true
data/CHANGELOG.md CHANGED
@@ -30,6 +30,20 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.1.56] - 2025-11-11
34
+
35
+ - TAG: [v1.1.56][1.1.56t]
36
+ - COVERAGE: 94.38% -- 4066/4308 lines in 26 files
37
+ - BRANCH COVERAGE: 78.77% -- 1673/2124 branches in 26 files
38
+ - 79.89% documented
39
+
40
+ ### Fixed
41
+
42
+ - Appraisals template merge with existing header
43
+ - Don't set opencollective in FUNDING.yml when osc is disabled
44
+ - handling of open source collective ENV variables in .envrc templates
45
+ - Don't invent an open collective handle when open collective is not enabled
46
+
33
47
  ## [1.1.55] - 2025-11-11
34
48
 
35
49
  - TAG: [v1.1.55][1.1.55t]
@@ -1380,7 +1394,9 @@ Please file a bug if you notice a violation of semantic versioning.
1380
1394
  - Selecting will run the selected workflow via `act`
1381
1395
  - This may move to its own gem in the future.
1382
1396
 
1383
- [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.55...HEAD
1397
+ [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.56...HEAD
1398
+ [1.1.56]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.55...v1.1.56
1399
+ [1.1.56t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.56
1384
1400
  [1.1.55]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.54...v1.1.55
1385
1401
  [1.1.55t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.55
1386
1402
  [1.1.54]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.53...v1.1.54
data/README.md CHANGED
@@ -968,7 +968,7 @@ Thanks for RTFM. ☺️
968
968
  [📌gitmoji]: https://gitmoji.dev
969
969
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
970
970
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
971
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.278-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
971
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.308-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
972
972
  [🔐security]: SECURITY.md
973
973
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
974
974
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/README.md.example CHANGED
@@ -544,7 +544,7 @@ Thanks for RTFM. ☺️
544
544
  [📌gitmoji]: https://gitmoji.dev
545
545
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
546
546
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
547
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.278-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
547
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.308-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
548
548
  [🔐security]: SECURITY.md
549
549
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
550
550
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/Rakefile.example CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # kettle-dev Rakefile v1.1.55 - 2025-11-11
3
+ # kettle-dev Rakefile v1.1.56 - 2025-11-11
4
4
  # Ruby 2.3 (Safe Navigation) or higher required
5
5
  #
6
6
  # MIT License (see License.txt)
@@ -66,7 +66,7 @@ module Kettle
66
66
  gem_name = meta[:gem_name]
67
67
  min_ruby = meta[:min_ruby]
68
68
  forge_org = meta[:forge_org] || meta[:gh_org]
69
- funding_org = meta[:funding_org] || forge_org
69
+ funding_org = helpers.opencollective_disabled? ? nil : meta[:funding_org] || forge_org
70
70
  entrypoint_require = meta[:entrypoint_require]
71
71
  namespace = meta[:namespace]
72
72
  namespace_shield = meta[:namespace_shield]
@@ -143,15 +143,22 @@ module Kettle
143
143
  if File.basename(rel) == "FUNDING.yml"
144
144
  helpers.copy_file_with_prompt(src, dest, allow_create: true, allow_replace: true) do |content|
145
145
  c = content.dup
146
- c = c.gsub(/^open_collective:\s+.*$/i) { |line| funding_org ? "open_collective: #{funding_org}" : line }
146
+ # Effective funding handle should fall back to forge_org when funding_org is nil.
147
+ # This allows tests to stub FUNDING_ORG=false to bypass explicit funding detection
148
+ # while still templating the line with the derived organization (e.g., from homepage URL).
149
+ effective_funding = funding_org || forge_org
150
+ c = if helpers.opencollective_disabled?
151
+ c.gsub(/^open_collective:\s+.*$/i) { |line| "open_collective: # Replace with a single Open Collective username" }
152
+ else
153
+ c.gsub(/^open_collective:\s+.*$/i) { |line| effective_funding ? "open_collective: #{effective_funding}" : line }
154
+ end
147
155
  if gem_name && !gem_name.empty?
148
156
  c = c.gsub(/^tidelift:\s+.*$/i, "tidelift: rubygems/#{gem_name}")
149
157
  end
150
- # Also apply common replacements for org/gem/namespace/shields
151
158
  helpers.apply_common_replacements(
152
159
  c,
153
160
  org: forge_org,
154
- funding_org: funding_org,
161
+ funding_org: effective_funding, # pass effective funding for downstream tokens
155
162
  gem_name: gem_name,
156
163
  namespace: namespace,
157
164
  namespace_shield: namespace_shield,
@@ -469,6 +469,21 @@ module Kettle
469
469
  # - Preamble (content before first appraise) comes from template when present, else destination.
470
470
  def merge_appraisals(template_content, dest_content)
471
471
  begin
472
+ # Helper: extract contiguous leading header lines (comments and blank lines)
473
+ extract_leading_header = lambda do |text|
474
+ lines = text.lines
475
+ header_lines = []
476
+ idx = 0
477
+ while idx < lines.length
478
+ ln = lines[idx]
479
+ break unless ln.strip.empty? || ln.lstrip.start_with?("#")
480
+ header_lines << ln
481
+ idx += 1
482
+ end
483
+ body = (idx < lines.length) ? lines[idx..-1].join : ""
484
+ {header: header_lines.join, body: body}
485
+ end
486
+
472
487
  parse_blocks = lambda do |text|
473
488
  lines = text.lines
474
489
  blocks = []
@@ -526,8 +541,22 @@ module Kettle
526
541
  {blocks: blocks, preamble: preamble}
527
542
  end
528
543
 
529
- tmpl = parse_blocks.call(template_content)
530
- dest = parse_blocks.call(dest_content)
544
+ # Extract leading headers from template and destination and parse their bodies
545
+ tmpl_parts = extract_leading_header.call(template_content)
546
+ dest_parts = extract_leading_header.call(dest_content)
547
+
548
+ # If the template does not provide a leading header, preserve the destination as-is
549
+ # so that per-block adjacent header comments (including those at the top of file)
550
+ # are still parsed and preserved. Only strip the destination leading header when
551
+ # the template has a leading header to replace it.
552
+ dest_parse_source = if tmpl_parts[:header].to_s.strip.empty?
553
+ dest_content
554
+ else
555
+ dest_parts[:body]
556
+ end
557
+
558
+ tmpl = parse_blocks.call(tmpl_parts[:body])
559
+ dest = parse_blocks.call(dest_parse_source)
531
560
  tmpl_blocks = tmpl[:blocks]
532
561
  dest_blocks = dest[:blocks]
533
562
  dest_by_name = dest_blocks.map { |b| [b[:name], b] }.to_h
@@ -553,9 +582,17 @@ module Kettle
553
582
  merged_body += additions
554
583
  end
555
584
  header = tb[:header].any? ? tb[:header] : db[:header]
585
+ # If the template provides no leading header and the destination preamble
586
+ # already ends with this header, skip emitting the header for this block
587
+ # to avoid duplicating it (it will already be present at the top of the file).
588
+ header_to_emit = if tmpl_parts[:header].to_s.strip.empty? && !dest[:preamble].to_s.strip.empty? && !header.empty? && dest[:preamble].to_s.end_with?(header.join)
589
+ []
590
+ else
591
+ header
592
+ end
556
593
  block_text = +""
557
594
  block_text << "\n" unless merged_blocks_strings.empty?
558
- header.each { |hl| block_text << hl } if header.any?
595
+ header_to_emit.each { |hl| block_text << hl } if header_to_emit.any?
559
596
  block_text << "appraise \"#{tb[:name]}\" do\n"
560
597
  merged_body.each { |bl| block_text << bl }
561
598
  block_text << db[:end_line]
@@ -584,7 +621,21 @@ module Kettle
584
621
  merged_blocks_strings << block_text
585
622
  end
586
623
 
587
- preamble = tmpl[:preamble].to_s.strip.empty? ? dest[:preamble] : tmpl[:preamble]
624
+ # Build final preamble:
625
+ # - If template provides a leading header, use that header and then prefer the
626
+ # template's body preamble when present, otherwise fall back to the
627
+ # destination's body preamble.
628
+ # - If template does NOT provide a leading header, leave the destination
629
+ # preamble (including any leading header/comments) intact.
630
+ preamble = +""
631
+ if tmpl_parts[:header].to_s.strip.empty?
632
+ preamble << dest[:preamble].to_s
633
+ else
634
+ body_preamble = tmpl[:preamble].to_s.strip.empty? ? dest[:preamble].to_s : tmpl[:preamble].to_s
635
+ preamble << tmpl_parts[:header].to_s
636
+ preamble << body_preamble.to_s
637
+ end
638
+
588
639
  out = +""
589
640
  out << preamble unless preamble.nil? || preamble.empty?
590
641
  out << "\n" unless out.end_with?("\n")
@@ -792,7 +843,7 @@ module Kettle
792
843
 
793
844
  c = content.dup
794
845
  c = c.gsub("kettle-rb", org.to_s)
795
- c = c.gsub("{OPENCOLLECTIVE|ORG_NAME}", funding_org)
846
+ c = c.gsub("{OPENCOLLECTIVE|ORG_NAME}", funding_org || "opencollective")
796
847
  # Replace min ruby token if present
797
848
  begin
798
849
  if min_ruby && !min_ruby.to_s.empty? && c.include?("{K_D_MIN_RUBY}")
@@ -813,6 +864,15 @@ module Kettle
813
864
  # ignore
814
865
  end
815
866
 
867
+ # Replace target gem name token if present
868
+ begin
869
+ token = "{TARGET|GEM|NAME}"
870
+ c = c.gsub(token, gem_name) if c.include?(token)
871
+ rescue StandardError => e
872
+ Kettle::Dev.debug_error(e, __method__)
873
+ # If replacement fails unexpectedly, proceed with content as-is
874
+ end
875
+
816
876
  # Special-case: yard-head link uses the gem name as a subdomain and must be dashes-only.
817
877
  # Apply this BEFORE other generic replacements so it isn't altered incorrectly.
818
878
  begin
@@ -6,7 +6,7 @@ module Kettle
6
6
  module Version
7
7
  # The gem version.
8
8
  # @return [String]
9
- VERSION = "1.1.55"
9
+ VERSION = "1.1.56"
10
10
 
11
11
  module_function
12
12
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.55
4
+ version: 1.1.56
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -203,6 +203,8 @@ extra_rdoc_files:
203
203
  files:
204
204
  - "./.aiignore.example"
205
205
  - "./.env.local.example"
206
+ - "./.envrc.example"
207
+ - "./.envrc.no-osc.example"
206
208
  - "./.gitlab-ci.yml.example"
207
209
  - "./.opencollective.yml.example"
208
210
  - "./.simplecov.example"
@@ -219,6 +221,8 @@ files:
219
221
  - ".devcontainer/devcontainer.json"
220
222
  - ".env.local.example"
221
223
  - ".envrc"
224
+ - ".envrc.example"
225
+ - ".envrc.no-osc.example"
222
226
  - ".git-hooks/commit-msg"
223
227
  - ".git-hooks/commit-subjects-goalie.txt"
224
228
  - ".git-hooks/footer-template.erb.txt"
@@ -397,10 +401,10 @@ licenses:
397
401
  - MIT
398
402
  metadata:
399
403
  homepage_uri: https://kettle-dev.galtzo.com/
400
- source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.55
401
- changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.55/CHANGELOG.md
404
+ source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.56
405
+ changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.56/CHANGELOG.md
402
406
  bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
403
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.55
407
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.56
404
408
  funding_uri: https://github.com/sponsors/pboling
405
409
  wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
406
410
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file