nomono 1.1.7 → 1.1.12

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: dc52d97362be7f9850217971a0157dc86a0fad2a1fec6aad1e07b56e75eeb841
4
- data.tar.gz: 394eac4e7a449d2e6f94e3ac81556b59abd2a686f72c67c203cbba66afa4d7ae
3
+ metadata.gz: 352da75d9b7ee4cce8138807cd9adf2cc6b80e5e3ae3d95cfe9c1dfedf0f4b50
4
+ data.tar.gz: 07543cdd4db51a080d4d0c35fd83357d70bc9f9bbe8381cb340701dbfe4f3ee2
5
5
  SHA512:
6
- metadata.gz: 0e66565a3cfa1d4b61203462e1af2b794be9e445081c76a43aaaf8e160ff50f796e7bb1560b05f8e76ac07503a41b0ffd0ad244f988f4511113020014142d4a9
7
- data.tar.gz: 677ad8cfdb82d9c12521508f82b73251eba992fc32790d168248c3af6b640746a0d7465f755fa3606ae354a5e1402cdc470726c259dd17ff3ad5ca7dfc8f7d00
6
+ metadata.gz: fe21911800405624ca4a9f43fb294d22c44d1f38d8af2273a2e292f3405c66bff3bc5e4fa039408a37db5d2fd75b40cf8d4dbe03f769cb10de3b7b03ec1a7551
7
+ data.tar.gz: f05fe0979f7a03575129a9bc0186dcd53ac5dbed095b1ce421a76a3a3632f285b167f24a853cdfb70b8069b55987ee4d9b4b500f436b75a346541facb1e616b1
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,47 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.1.12] - 2026-10-19
34
+
35
+ - TAG: [v1.1.12][1.1.12t]
36
+ - COVERAGE: 97.37% -- 185/190 lines in 7 files
37
+ - BRANCH COVERAGE: 83.10% -- 59/71 branches in 7 files
38
+ - 27.78% documented
39
+
40
+ ## [1.1.11] - 2026-10-19
41
+
42
+ - TAG: [v1.1.11][1.1.11t]
43
+ - COVERAGE: 97.37% -- 185/190 lines in 7 files
44
+ - BRANCH COVERAGE: 83.10% -- 59/71 branches in 7 files
45
+ - 27.78% documented
46
+
47
+ ### Fixed
48
+
49
+ - [kc] nomono-fact-requirements: Forward explicit dependency requirements through eval_nomono_gems instead of discarding them before declaring local path dependencies.
50
+
51
+ - Make eval_nomono_gems intentionally override existing direct dependencies with registered local path sources while intersecting caller and gemspec constraints, preserving dependency conditions and metadata, and supporting either declaration order and repeated calls.
52
+
53
+ - [kc] shared-local-template-overrides: Regenerate coverage and templating local Gemfiles with the shared Nomono override API instead of obsolete custom merge and inline dependency replacement.
54
+
55
+ ## [1.1.8] - 2026-10-15
56
+
57
+ - TAG: [v1.1.8][1.1.8t]
58
+ - COVERAGE: 97.56% -- 120/123 lines in 7 files
59
+ - BRANCH COVERAGE: 86.67% -- 39/45 branches in 7 files
60
+ - 25.00% documented
61
+
62
+ ### Changed
63
+
64
+ - [kc] kettle-jem/prepare: updated 8 project files:
65
+ - configuration (1)
66
+ - dependencies (7)
67
+
68
+ - [kc] kettle-jem/template: updated 20 project files:
69
+ - code and tests (1)
70
+ - documentation (1)
71
+ - other (1)
72
+ - workflows (17)
73
+
33
74
  ## [1.1.7] - 2026-10-10
34
75
 
35
76
  - TAG: [v1.1.7][1.1.7t]
@@ -385,7 +426,13 @@ Please file a bug if you notice a violation of semantic versioning.
385
426
  - TAG: [v1.0.0][1.0.0t]
386
427
  - 12.50% documented
387
428
 
388
- [Unreleased]: https://github.com/kettle-dev/nomono/compare/v1.1.7...HEAD
429
+ [Unreleased]: https://github.com/kettle-dev/nomono/compare/v1.1.12...HEAD
430
+ [1.1.12]: https://github.com/kettle-dev/nomono/compare/v1.1.11...v1.1.12
431
+ [1.1.12t]: https://github.com/kettle-dev/nomono/releases/tag/v1.1.12
432
+ [1.1.11]: https://github.com/kettle-dev/nomono/compare/v1.1.8...v1.1.11
433
+ [1.1.11t]: https://github.com/kettle-dev/nomono/releases/tag/v1.1.11
434
+ [1.1.8]: https://github.com/kettle-dev/nomono/compare/v1.1.7...v1.1.8
435
+ [1.1.8t]: https://github.com/kettle-dev/nomono/releases/tag/v1.1.8
389
436
  [1.1.7]: https://github.com/kettle-dev/nomono/compare/v1.1.6...v1.1.7
390
437
  [1.1.7t]: https://github.com/kettle-dev/nomono/releases/tag/v1.1.7
391
438
  [1.1.6]: https://github.com/kettle-dev/nomono/compare/v1.1.5...v1.1.6
data/README.md CHANGED
@@ -29,6 +29,31 @@ It provides two Gemfile macros:
29
29
  - `eval_nomono_gems(**opts)` directly emits `gem "name", path: "..."`
30
30
 
31
31
  The API mirrors existing `*_local.gemfile` patterns used in kettle-dev projects, but centralizes path/env logic in one reusable library.
32
+
33
+ Pass dependency requirements from the caller's project facts to the same macro:
34
+
35
+ ```ruby
36
+ eval_nomono_gems(
37
+ gems: %w[shared-core shared-leaf],
38
+ requirements: {
39
+ "shared-core" => ["= 7.1.14"],
40
+ "shared-leaf" => ["~> 2.0", ">= 2.0.3"]
41
+ },
42
+ path_env: "FAMILY_DEV"
43
+ )
44
+ ```
45
+
46
+ `requirements` is a map of gem names to requirement strings or arrays. Omitted
47
+ entries keep the unversioned (`>= 0`) behavior. Requirements go directly to
48
+ Bundler; Nomono does not infer them from checkout versions, filter incompatible
49
+ checkouts, or silently select a registry source instead. Repository shape and
50
+ CI/local-development policy remain the caller's responsibility.
51
+
52
+ Declare each direct dependency's source once. A runtime gemspec requirement can
53
+ coexist with a matching path dependency, but repeated direct Gemfile declarations
54
+ with different requirements or different sources are Bundler DSL errors; merely
55
+ repeating a version requirement does not reconcile different direct sources.
56
+
32
57
  Use `require "nomono"` for the runtime resolver API.
33
58
  Use `require "nomono/bundler"` from Gemfiles or modular Gemfiles; this is the explicit hook that installs the Gemfile macros into `Bundler::Dsl`.
34
59
 
@@ -37,7 +62,7 @@ Use `require "nomono/bundler"` from Gemfiles or modular Gemfiles; this is the ex
37
62
  | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
38
63
  |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
39
64
  | Works with JRuby | [![JRuby 10.0 Compat][💎jruby-10.0i]][🚎jruby-10.0-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]|
40
- | Works with Truffle Ruby | [![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby 33.0 Compat][💎truby-33.0i]][🚎truby-33.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf]|
65
+ | Works with Truffle Ruby | [![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby 33.0 Compat][💎truby-33.0i]][🚎truby-33.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf]|
41
66
  | Works with MRI Ruby 4 | [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]|
42
67
  | Works with MRI Ruby 3 | [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf]|
43
68
  | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Get help from RubyForum][✉️ruby-forum-img]][✉️ruby-forum] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
@@ -76,6 +101,23 @@ The _amazing_ test matrix is powered by the kettle-dev stack.
76
101
 
77
102
  </details>
78
103
 
104
+ ### Runtime and Platform Support
105
+
106
+ Support tiers describe what this project's CI actually exercises, not what may
107
+ work in an untested environment:
108
+
109
+ - **Parallel support**: CI runs the test suite with multiple workers available.
110
+ - **Unsupported**: the engine/platform combination is not covered by CI and is
111
+ not a project compatibility claim.
112
+
113
+ | Ruby engine/version | Linux | macOS | Windows | Notes |
114
+ |---------------------|-------|-------|---------|-------|
115
+ | MRI 3.2-3.4 | Parallel support | Unsupported | Unsupported | Versioned Ruby workflows run on Linux. |
116
+ | MRI current | Parallel support | Parallel support | Unsupported | Current Ruby workflow covers the declared OS platforms. |
117
+ | MRI head | Parallel support | Unsupported | Unsupported | CI is allowed to fail while Ruby is in development. |
118
+ | JRuby (all CI lanes) | Parallel support | Unsupported | Unsupported | Engine workflows run on Linux; macOS and Windows are not exercised by CI. |
119
+ | TruffleRuby (all CI lanes) | Parallel support | Unsupported | Unsupported | Never shipped a Windows build (zero Windows assets across 66 releases scanned 2026-10-10); setup-ruby hard-fails ([source](https://github.com/ruby/setup-ruby/blob/master/README.md)) |
120
+
79
121
  ### Federated DVCS
80
122
 
81
123
  <details markdown="1">
@@ -462,7 +504,6 @@ Thanks for RTFM. ☺️
462
504
  [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
463
505
  [💎truby-33.0i]: https://img.shields.io/badge/Truffle_Ruby-33.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
464
506
  [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
465
- [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
466
507
  [💎jruby-10.0i]: https://img.shields.io/badge/JRuby-10.0-FBE742?style=for-the-badge&logo=ruby&logoColor=red
467
508
  [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
468
509
  [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
@@ -492,7 +533,7 @@ Thanks for RTFM. ☺️
492
533
  [📌gitmoji]: https://gitmoji.dev
493
534
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
494
535
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
495
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.123-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
536
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.190-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
496
537
  [🔐security]: https://github.com/kettle-dev/nomono/blob/main/SECURITY.md
497
538
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
498
539
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/lib/nomono/dsl.rb CHANGED
@@ -2,14 +2,132 @@
2
2
 
3
3
  module Nomono
4
4
  module GemfileDsl
5
+ # Only source-related state is replaced. Dependency#dup retains effective
6
+ # conditions and metadata, including fields unknown to this Bundler adapter.
7
+ SOURCE_OPTIONS = %w[source path git github branch ref tag glob submodules name].freeze
8
+ private_constant :SOURCE_OPTIONS
9
+
10
+ # Activated on this DSL instance only, after an intentional local override.
11
+ # Bundler 4 routes gemspec development dependencies through add_dependency;
12
+ # Bundler 2 routes them through gem instead.
13
+ module LocalDeclarations
14
+ def gem(name, *args)
15
+ return super if method(:add_dependency).super_method
16
+
17
+ options = args.last.is_a?(Hash) ? args.last : {}
18
+ nomono_declaration(name, options[:type] == :development || options["type"] == :development) { super }
19
+ end
20
+
21
+ def to_definition(*args)
22
+ nomono_prune_displaced_sources
23
+ super
24
+ end
25
+
26
+ private
27
+
28
+ def add_dependency(name, version = nil, options = {})
29
+ nomono_declaration(name, options["gemspec_dev_dep"]) { super }
30
+ end
31
+ end
32
+ private_constant :LocalDeclarations
33
+
5
34
  def nomono_gems(gems:, **opts)
6
35
  Nomono.resolver.gems(gems: gems, **opts)
7
36
  end
8
37
 
9
- def eval_nomono_gems(gems:, **opts)
38
+ # Requirements are caller facts, not checkout versions. An existing direct
39
+ # dependency keeps its constraints and metadata; explicit facts only narrow
40
+ # them. A new dependency with no facts retains Bundler's default >= 0.
41
+ def eval_nomono_gems(gems:, requirements: {}, **opts)
10
42
  nomono_gems(gems: gems, **opts).each do |gem_name, gem_path|
11
- gem(gem_name, path: gem_path)
43
+ # Keep lightweight non-Bundler consumers of the macro working too.
44
+ unless respond_to?(:dependencies)
45
+ gem(gem_name, *Array(requirements[gem_name]), path: gem_path)
46
+ next
47
+ end
48
+
49
+ constraints = Array(requirements[gem_name]) + nomono_gemspec_requirements(gem_name)
50
+ current = dependencies.find { |dep| dep.name == gem_name }
51
+ if current
52
+ local_source = path(gem_path) {}
53
+ replacement = nomono_local_dependency(current, local_source, gem_path, constraints)
54
+ dependencies[dependencies.index(current)] = replacement
55
+ else
56
+ gem(gem_name, *Array(requirements[gem_name]), path: gem_path)
57
+ replacement = dependencies.last
58
+ end
59
+ @nomono_overrides ||= {}
60
+ previous = @nomono_overrides[gem_name]
61
+ @nomono_overrides[gem_name] = {
62
+ source: replacement.source,
63
+ path: gem_path,
64
+ declaration: previous ? previous[:declaration] : !current.nil?
65
+ }
66
+ singleton_class.prepend(LocalDeclarations) unless singleton_class < LocalDeclarations
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ # Bundler may already have preferred a direct Gemfile declaration and
73
+ # discarded the intersected gemspec development constraint from its list.
74
+ def nomono_gemspec_requirements(name)
75
+ gemspecs.flat_map(&:development_dependencies).select { |dep| dep.name == name }.flat_map { |dep| dep.requirement.as_list }
76
+ end
77
+
78
+ # Let Bundler construct the later declaration normally, but in isolation so
79
+ # its duplicate guard cannot discard a gemspec constraint or reject the
80
+ # deliberate source override. Always restore the real list on failure.
81
+ def nomono_declaration(name, gemspec_development)
82
+ override = @nomono_overrides && @nomono_overrides[name]
83
+ current = dependencies.find { |dep| dep.name == name }
84
+ return yield unless override && current
85
+ development = current.respond_to?(:gemspec_dev_dep?) ? current.gemspec_dev_dep? : current.type == :development
86
+ return yield if override[:declaration] && !development && !gemspec_development
87
+
88
+ original = @dependencies
89
+ begin
90
+ @dependencies = []
91
+ yield
92
+ incoming = @dependencies.fetch(0)
93
+ ensure
94
+ @dependencies = original
95
+ end
96
+ metadata = (gemspec_development && override[:declaration]) ? current : incoming
97
+ constraints = current.requirement.as_list + incoming.requirement.as_list
98
+ replacement = nomono_local_dependency(metadata, override[:source], override[:path], constraints)
99
+ dependencies[dependencies.index(current)] = replacement
100
+ override[:declaration] = true
101
+ end
102
+
103
+ # Defer cleanup until declarations are complete: an enclosing source block
104
+ # can still declare other gems after the override. Unreferenced old git/path
105
+ # sources otherwise participate in resolution and may require a checkout.
106
+ def nomono_prune_displaced_sources
107
+ Array(@nomono_displaced_sources).each do |source|
108
+ next if source == @sources.default_source || dependencies.any? { |dep| dep.source == source }
109
+
110
+ @sources.git_sources.delete(source)
111
+ @sources.path_sources.delete(source)
112
+ @sources.non_global_rubygems_sources.delete(source)
113
+ @sources.plugin_sources.delete(source)
114
+ end
115
+ end
116
+
117
+ def nomono_local_dependency(dependency, source, gem_path, requirements)
118
+ replacement = dependency.dup
119
+ replacement.instance_variable_set(:@requirement, Gem::Requirement.new(dependency.requirement.as_list + requirements))
120
+ @nomono_displaced_sources ||= []
121
+ @nomono_displaced_sources |= [dependency.source] if dependency.source && dependency.source != source
122
+ (SOURCE_OPTIONS - ["name"]).each { |key| replacement.instance_variable_set(:"@#{key}", nil) }
123
+ replacement.instance_variable_set(:@source, source)
124
+ replacement.instance_variable_set(:@path, gem_path)
125
+ # Bundler 4 lazily reads @options; older Bundlers store eager ivars.
126
+ if (options = dependency.instance_variable_get(:@options))
127
+ options = options.except(*SOURCE_OPTIONS)
128
+ replacement.instance_variable_set(:@options, options.merge("source" => source, "path" => gem_path))
12
129
  end
130
+ replacement
13
131
  end
14
132
  end
15
133
  end
@@ -4,7 +4,7 @@ module Nomono
4
4
  # Version namespace for this gem.
5
5
  module Version
6
6
  # Current gem version.
7
- VERSION = "1.1.7"
7
+ VERSION = "1.1.12"
8
8
  end
9
9
  # Current gem version exposed at the traditional constant location.
10
10
  VERSION = Version::VERSION # Traditional Constant Location
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nomono
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -66,7 +66,7 @@ dependencies:
66
66
  version: '3.1'
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 3.1.9
69
+ version: 3.1.18
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '3.1'
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: 3.1.9
79
+ version: 3.1.18
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bundler-audit
82
82
  requirement: !ruby/object:Gem::Requirement
@@ -174,7 +174,7 @@ dependencies:
174
174
  version: '2.0'
175
175
  - - ">="
176
176
  - !ruby/object:Gem::Version
177
- version: 2.0.24
177
+ version: 2.0.27
178
178
  type: :development
179
179
  prerelease: false
180
180
  version_requirements: !ruby/object:Gem::Requirement
@@ -184,27 +184,27 @@ dependencies:
184
184
  version: '2.0'
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
- version: 2.0.24
187
+ version: 2.0.27
188
188
  - !ruby/object:Gem::Dependency
189
189
  name: turbo_tests2
190
190
  requirement: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '3.2'
194
+ version: '4.0'
195
195
  - - ">="
196
196
  - !ruby/object:Gem::Version
197
- version: 3.2.14
197
+ version: 4.0.0
198
198
  type: :development
199
199
  prerelease: false
200
200
  version_requirements: !ruby/object:Gem::Requirement
201
201
  requirements:
202
202
  - - "~>"
203
203
  - !ruby/object:Gem::Version
204
- version: '3.2'
204
+ version: '4.0'
205
205
  - - ">="
206
206
  - !ruby/object:Gem::Version
207
- version: 3.2.14
207
+ version: 4.0.0
208
208
  - !ruby/object:Gem::Dependency
209
209
  name: ruby-progressbar
210
210
  requirement: !ruby/object:Gem::Requirement
@@ -283,10 +283,10 @@ licenses:
283
283
  - AGPL-3.0-only
284
284
  metadata:
285
285
  homepage_uri: https://nomono.galtzo.com/
286
- source_code_uri: https://github.com/kettle-dev/nomono/tree/v1.1.7
287
- changelog_uri: https://github.com/kettle-dev/nomono/blob/v1.1.7/CHANGELOG.md
286
+ source_code_uri: https://github.com/kettle-dev/nomono/tree/v1.1.12
287
+ changelog_uri: https://github.com/kettle-dev/nomono/blob/v1.1.12/CHANGELOG.md
288
288
  bug_tracker_uri: https://github.com/kettle-dev/nomono/issues
289
- documentation_uri: https://www.rubydoc.info/gems/nomono/1.1.7
289
+ documentation_uri: https://www.rubydoc.info/gems/nomono/1.1.12
290
290
  funding_uri: https://github.com/sponsors/pboling
291
291
  wiki_uri: https://github.com/kettle-dev/nomono/wiki
292
292
  news_uri: https://www.railsbling.com/tags/nomono
metadata.gz.sig CHANGED
Binary file