nomono 1.1.8 → 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: f835e50fda7577145ec9df9586ac34f86fe123ca026e204503962b662e50983b
4
- data.tar.gz: 1dcfd241420c33f51361d8ec875a3b02a4b729a85574e732378dd69e9d65ff25
3
+ metadata.gz: 352da75d9b7ee4cce8138807cd9adf2cc6b80e5e3ae3d95cfe9c1dfedf0f4b50
4
+ data.tar.gz: 07543cdd4db51a080d4d0c35fd83357d70bc9f9bbe8381cb340701dbfe4f3ee2
5
5
  SHA512:
6
- metadata.gz: 771ca4c88a0ba2f722f37aa3ca3a825cc0b0c690c0324275ee3c3fbd9d828d7adf3fc2c0e2ce4ca360cc64dbdbfb294fffcb889d6ba3bf6b0357726da6b7dd05
7
- data.tar.gz: 997d15fe1266f6429e69623a4667b7acb3d5d21f120c5638e366f38c4aba1b9e53a78274bebecb637903d4de9cfeff50adbb1da08d1aae7d986f5e9f34127f91
6
+ metadata.gz: fe21911800405624ca4a9f43fb294d22c44d1f38d8af2273a2e292f3405c66bff3bc5e4fa039408a37db5d2fd75b40cf8d4dbe03f769cb10de3b7b03ec1a7551
7
+ data.tar.gz: f05fe0979f7a03575129a9bc0186dcd53ac5dbed095b1ce421a76a3a3632f285b167f24a853cdfb70b8069b55987ee4d9b4b500f436b75a346541facb1e616b1
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -22,6 +22,45 @@ Please file a bug if you notice a violation of semantic versioning.
22
22
 
23
23
  ### Changed
24
24
 
25
+ ### Deprecated
26
+
27
+ ### Removed
28
+
29
+ ### Fixed
30
+
31
+ ### Security
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
+
25
64
  - [kc] kettle-jem/prepare: updated 8 project files:
26
65
  - configuration (1)
27
66
  - dependencies (7)
@@ -32,14 +71,6 @@ Please file a bug if you notice a violation of semantic versioning.
32
71
  - other (1)
33
72
  - workflows (17)
34
73
 
35
- ### Deprecated
36
-
37
- ### Removed
38
-
39
- ### Fixed
40
-
41
- ### Security
42
-
43
74
  ## [1.1.7] - 2026-10-10
44
75
 
45
76
  - TAG: [v1.1.7][1.1.7t]
@@ -395,7 +426,13 @@ Please file a bug if you notice a violation of semantic versioning.
395
426
  - TAG: [v1.0.0][1.0.0t]
396
427
  - 12.50% documented
397
428
 
398
- [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
399
436
  [1.1.7]: https://github.com/kettle-dev/nomono/compare/v1.1.6...v1.1.7
400
437
  [1.1.7t]: https://github.com/kettle-dev/nomono/releases/tag/v1.1.7
401
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
 
@@ -508,7 +533,7 @@ Thanks for RTFM. ☺️
508
533
  [📌gitmoji]: https://gitmoji.dev
509
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
510
535
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
511
- [🧮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
512
537
  [🔐security]: https://github.com/kettle-dev/nomono/blob/main/SECURITY.md
513
538
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
514
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.8"
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.8
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.13
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.13
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.25
177
+ version: 2.0.27
178
178
  type: :development
179
179
  prerelease: false
180
180
  version_requirements: !ruby/object:Gem::Requirement
@@ -184,7 +184,7 @@ dependencies:
184
184
  version: '2.0'
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
- version: 2.0.25
187
+ version: 2.0.27
188
188
  - !ruby/object:Gem::Dependency
189
189
  name: turbo_tests2
190
190
  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.8
287
- changelog_uri: https://github.com/kettle-dev/nomono/blob/v1.1.8/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.8
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