ra10ke 4.4.0 → 4.5.1

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: 4a3ef455bedc72f4a8efb127b1f3160deee1dfe81c2c38de72ada47bfc4ca8c3
4
- data.tar.gz: b94450b0e414f8dbba9239138cc0f979d636b8261dd0032f3fef86039a4133db
3
+ metadata.gz: e89462c238286812deefe1c66b23bd3458f10f68545f19394cda6e5cae239fa3
4
+ data.tar.gz: be70614d1b793aaae4e3e9151186709b70d68506687b3a3590f6e79ed6fe4298
5
5
  SHA512:
6
- metadata.gz: 890afd26cc69393d81da69a4498e239eaa05dbbac969822884ebf5f63f200581f3303e09a4f91815c3ec8af3deb1ce42b2e37544cb1b9e4a1b10a583f3176e39
7
- data.tar.gz: 6e18e3e79fa83491b68370e90953730a1d7106eff069024b9a84b33e0d2b5990197c3c9580fd895adb03b3012a45aad1a4709d7890af4873b5d15358c434f592
6
+ metadata.gz: 95bbe0ab0fea1b2598c75f4e0f7cfee5c1b77acc457574bd55627bd584d9a9ae2b0360f6bb70fcafb8b4df03559b05d63db2ee5abc1f8364276e126ddfaae047
7
+ data.tar.gz: 0c1d340000c757922d5929b27f61d814c4d7a1b8c1c7220d2a4bd50ba30f42c66bec026eb959bb03b74169ff567a6ec409a0c0c2ac357aa5744e86fbe2dce287
data/.github/release.yml CHANGED
@@ -25,6 +25,7 @@ changelog:
25
25
  - title: Bug Fixes 🐛
26
26
  labels:
27
27
  - bug
28
+ - bugfix
28
29
 
29
30
  - title: Documentation Updates 📚
30
31
  labels:
@@ -1,50 +1,106 @@
1
1
  ---
2
- name: Release
2
+ name: Gem Release
3
3
 
4
4
  on:
5
5
  push:
6
6
  tags:
7
7
  - '*'
8
8
 
9
+ permissions: {}
10
+
9
11
  jobs:
10
- release:
11
- runs-on: ubuntu-latest
12
+ build-release:
13
+ # Prevent releases from forked repositories
12
14
  if: github.repository_owner == 'voxpupuli'
15
+ name: Build the gem
16
+ runs-on: ubuntu-24.04
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ - name: Install Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: 'ruby'
23
+ - name: Build gem
24
+ shell: bash
25
+ run: gem build --verbose *.gemspec
26
+ - name: Upload gem to GitHub cache
27
+ uses: actions/upload-artifact@v7
28
+ with:
29
+ name: gem-artifact
30
+ path: '*.gem'
31
+ retention-days: 1
32
+ compression-level: 0
13
33
 
34
+ create-github-release:
35
+ needs: build-release
36
+ name: Create GitHub release
37
+ runs-on: ubuntu-24.04
14
38
  permissions:
15
- contents: write
16
- packages: write
17
-
39
+ contents: write # clone repo and create release
18
40
  steps:
19
- - uses: actions/checkout@v4
41
+ - name: Download gem from GitHub cache
42
+ uses: actions/download-artifact@v8
20
43
  with:
21
- fetch-depth: 0
22
- - name: Install Ruby 3.3
23
- uses: ruby/setup-ruby@v1
44
+ name: gem-artifact
45
+ - name: Create Release
46
+ shell: bash
47
+ env:
48
+ GH_TOKEN: ${{ github.token }}
49
+ run: gh release create --repo ${{ github.repository }} ${{ github.ref_name }} --generate-notes *.gem
50
+
51
+ release-to-github:
52
+ needs: build-release
53
+ name: Release to GitHub
54
+ runs-on: ubuntu-24.04
55
+ permissions:
56
+ packages: write # publish to rubygems.pkg.github.com
57
+ steps:
58
+ - name: Download gem from GitHub cache
59
+ uses: actions/download-artifact@v8
24
60
  with:
25
- ruby-version: '3.3'
61
+ name: gem-artifact
62
+ - name: Publish gem to GitHub packages
63
+ run: gem push --host https://rubygems.pkg.github.com/${{ github.repository_owner }} *.gem
26
64
  env:
27
- BUNDLE_WITHOUT: release
28
- - name: Build gem
29
- run: gem build --strict --verbose *.gemspec
65
+ GEM_HOST_API_KEY: ${{ secrets.GITHUB_TOKEN }}
66
+
67
+ release-to-rubygems:
68
+ needs: build-release
69
+ name: Release gem to rubygems.org
70
+ runs-on: ubuntu-24.04
71
+ environment: release # recommended by rubygems.org
72
+ permissions:
73
+ id-token: write # rubygems.org authentication
74
+ steps:
75
+ - name: Download gem from GitHub cache
76
+ uses: actions/download-artifact@v8
77
+ with:
78
+ name: gem-artifact
79
+ - uses: rubygems/configure-rubygems-credentials@v2.0.0
30
80
  - name: Publish gem to rubygems.org
31
- run: gem push *.gem
32
- env:
33
- GEM_HOST_API_KEY: '${{ secrets.RUBYGEMS_AUTH_TOKEN }}'
34
- - name: Setup GitHub packages access
35
- run: |
36
- mkdir -p ~/.gem
37
- echo ":github: Bearer ${{ secrets.GITHUB_TOKEN }}" >> ~/.gem/credentials
38
- chmod 0600 ~/.gem/credentials
39
- - name: Publish gem to GitHub packages
40
- run: gem push --key github --host https://rubygems.pkg.github.com/voxpupuli *.gem
41
- - name: Create Release Page
42
81
  shell: bash
43
- env:
44
- GH_TOKEN: ${{ github.token }}
45
- run: gh release create ${{ github.ref_name }} --generate-notes
46
- - name: Attach gem to GitHub Release
82
+ run: gem push *.gem
83
+
84
+ release-verification:
85
+ name: Check that all releases are done
86
+ runs-on: ubuntu-24.04
87
+ permissions:
88
+ contents: read # minimal permissions that we have to grant
89
+ needs:
90
+ - create-github-release
91
+ - release-to-github
92
+ - release-to-rubygems
93
+ steps:
94
+ - name: Download gem from GitHub cache
95
+ uses: actions/download-artifact@v8
96
+ with:
97
+ name: gem-artifact
98
+ - name: Install Ruby
99
+ uses: ruby/setup-ruby@v1
100
+ with:
101
+ ruby-version: 'ruby'
102
+ - name: Wait for release to propagate
47
103
  shell: bash
48
- env:
49
- GH_TOKEN: ${{ github.token }}
50
- run: gh release upload ${{ github.ref_name }} *.gem
104
+ run: |
105
+ gem install rubygems-await
106
+ gem await *.gem
@@ -1,3 +1,4 @@
1
+ ---
1
2
  name: Test
2
3
 
3
4
  on:
@@ -6,8 +7,8 @@ on:
6
7
  branches:
7
8
  - master
8
9
 
9
- env:
10
- BUNDLE_WITHOUT: release
10
+ permissions:
11
+ contents: read
11
12
 
12
13
  jobs:
13
14
  rubocop_and_matrix:
@@ -15,7 +16,7 @@ jobs:
15
16
  outputs:
16
17
  ruby: ${{ steps.ruby.outputs.versions }}
17
18
  steps:
18
- - uses: actions/checkout@v4
19
+ - uses: actions/checkout@v6
19
20
  - name: Install Ruby ${{ matrix.ruby }}
20
21
  uses: ruby/setup-ruby@v1
21
22
  with:
@@ -24,7 +25,7 @@ jobs:
24
25
  - name: Run Rubocop
25
26
  run: bundle exec rake rubocop
26
27
  - id: ruby
27
- uses: voxpupuli/ruby-version@v1
28
+ uses: voxpupuli/ruby-version@v2
28
29
  test:
29
30
  runs-on: ubuntu-latest
30
31
  needs: rubocop_and_matrix
@@ -34,7 +35,7 @@ jobs:
34
35
  ruby: ${{ fromJSON(needs.rubocop_and_matrix.outputs.ruby) }}
35
36
  name: Ruby ${{ matrix.ruby }}
36
37
  steps:
37
- - uses: actions/checkout@v4
38
+ - uses: actions/checkout@v6
38
39
  - name: Install Ruby ${{ matrix.ruby }}
39
40
  uses: ruby/setup-ruby@v1
40
41
  with:
@@ -46,10 +47,14 @@ jobs:
46
47
  run: gem build --strict --verbose *.gemspec
47
48
 
48
49
  tests:
50
+ if: always()
49
51
  needs:
50
52
  - rubocop_and_matrix
51
53
  - test
52
- runs-on: ubuntu-latest
54
+ runs-on: ubuntu-24.04
53
55
  name: Test suite
54
56
  steps:
55
- - run: echo Test suite completed
57
+ - name: Decide whether the needed jobs succeeded or failed
58
+ uses: re-actors/alls-green@release/v1
59
+ with:
60
+ jobs: ${{ toJSON(needs) }}
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2025-05-09 13:01:13 UTC using RuboCop version 1.75.5.
2
+ # `rubocop --auto-gen-config --no-auto-gen-timestamp`
3
+ # using RuboCop version 1.79.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -23,14 +23,6 @@ Lint/SuppressedException:
23
23
  Exclude:
24
24
  - 'Rakefile'
25
25
 
26
- # Offense count: 4
27
- # This cop supports safe autocorrection (--autocorrect).
28
- # Configuration parameters: AutoCorrect.
29
- Lint/UselessAssignment:
30
- Exclude:
31
- - 'lib/ra10ke/dependencies.rb'
32
- - 'lib/ra10ke/solve.rb'
33
-
34
26
  # Offense count: 2
35
27
  Naming/AccessorMethodName:
36
28
  Exclude:
@@ -51,6 +43,12 @@ Naming/MethodParameterName:
51
43
  Exclude:
52
44
  - 'lib/ra10ke/solve.rb'
53
45
 
46
+ # Offense count: 1
47
+ # Configuration parameters: MinSize.
48
+ Performance/CollectionLiteralInLoop:
49
+ Exclude:
50
+ - 'lib/ra10ke/git_repo.rb'
51
+
54
52
  # Offense count: 2
55
53
  # This cop supports unsafe autocorrection (--autocorrect-all).
56
54
  Performance/Count:
@@ -100,10 +98,6 @@ RSpec/ExpectInHook:
100
98
  RSpec/MessageSpies:
101
99
  EnforcedStyle: receive
102
100
 
103
- # Offense count: 7
104
- RSpec/MultipleExpectations:
105
- Max: 3
106
-
107
101
  # Offense count: 1
108
102
  # Configuration parameters: AllowedPatterns.
109
103
  # AllowedPatterns: ^expect_, ^assert_
@@ -142,8 +136,8 @@ RSpec/VoidExpect:
142
136
  # This cop supports unsafe autocorrection (--autocorrect-all).
143
137
  # Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
144
138
  # SupportedStyles: nested, compact
145
- # SupportedStylesForClasses: , nested, compact
146
- # SupportedStylesForModules: , nested, compact
139
+ # SupportedStylesForClasses: ~, nested, compact
140
+ # SupportedStylesForModules: ~, nested, compact
147
141
  Style/ClassAndModuleChildren:
148
142
  Exclude:
149
143
  - 'lib/ra10ke/dependencies.rb'
@@ -160,6 +154,12 @@ Style/CollectionCompact:
160
154
  Exclude:
161
155
  - 'lib/ra10ke/dependencies.rb'
162
156
 
157
+ # Offense count: 1
158
+ # This cop supports unsafe autocorrection (--autocorrect-all).
159
+ Style/CollectionQuerying:
160
+ Exclude:
161
+ - 'lib/ra10ke/validate.rb'
162
+
163
163
  # Offense count: 17
164
164
  # Configuration parameters: AllowedConstants.
165
165
  Style/Documentation:
@@ -217,13 +217,6 @@ Style/MultilineBlockChain:
217
217
  Exclude:
218
218
  - 'lib/ra10ke/dependencies.rb'
219
219
 
220
- # Offense count: 1
221
- # This cop supports safe autocorrection (--autocorrect).
222
- # Configuration parameters: AllowMethodComparison, ComparisonsThreshold.
223
- Style/MultipleComparison:
224
- Exclude:
225
- - 'lib/ra10ke/git_repo.rb'
226
-
227
220
  # Offense count: 1
228
221
  # This cop supports unsafe autocorrection (--autocorrect-all).
229
222
  # Configuration parameters: EnforcedStyle.
@@ -278,7 +271,7 @@ Style/SymbolProc:
278
271
 
279
272
  # Offense count: 6
280
273
  # This cop supports safe autocorrection (--autocorrect).
281
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
274
+ # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
282
275
  # URISchemes: http, https
283
276
  Layout/LineLength:
284
277
  Max: 137
data/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [v4.5.1](https://github.com/voxpupuli/ra10ke/tree/v4.5.1) (2026-05-11)
6
+
7
+ [Full Changelog](https://github.com/voxpupuli/ra10ke/compare/v4.5.0...v4.5.1)
8
+
9
+ **Fixed bugs:**
10
+
11
+ - fix: process git modules before Forge modules to prevent dependency conflicts [\#145](https://github.com/voxpupuli/ra10ke/pull/145) ([bastelfreak](https://github.com/bastelfreak))
12
+
13
+ **Closed issues:**
14
+
15
+ - r10k:solve\_dependencies pulls in outdated constraints from last forge release as implicit dependency instead of explicit git module [\#128](https://github.com/voxpupuli/ra10ke/issues/128)
16
+
17
+ ## [v4.5.0](https://github.com/voxpupuli/ra10ke/tree/v4.5.0) (2025-10-16)
18
+
19
+ [Full Changelog](https://github.com/voxpupuli/ra10ke/compare/v4.4.0...v4.5.0)
20
+
21
+ **Merged pull requests:**
22
+
23
+ - Update voxpupuli-rubocop requirement from ~\> 4.2.0 to ~\> 4.3.0 [\#133](https://github.com/voxpupuli/ra10ke/pull/133) ([dependabot[bot]](https://github.com/apps/dependabot))
24
+ - Update voxpupuli-rubocop requirement from ~\> 4.1.0 to ~\> 4.2.0 [\#130](https://github.com/voxpupuli/ra10ke/pull/130) ([dependabot[bot]](https://github.com/apps/dependabot))
25
+ - Update git requirement from \>= 1.18, \< 4.0 to \>= 1.18, \< 5.0 [\#129](https://github.com/voxpupuli/ra10ke/pull/129) ([dependabot[bot]](https://github.com/apps/dependabot))
26
+
5
27
  ## [v4.4.0](https://github.com/voxpupuli/ra10ke/tree/v4.4.0) (2025-06-08)
6
28
 
7
29
  [Full Changelog](https://github.com/voxpupuli/ra10ke/compare/v4.3.0...v4.4.0)
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in ra10ke.gemspec
4
4
  gemspec
5
5
 
6
- group :release do
6
+ group :release, optional: true do
7
7
  gem 'faraday-retry', '~> 2.1', require: false
8
- gem 'github_changelog_generator', '~> 1.16.4', require: false
8
+ gem 'github_changelog_generator', '~> 1.18', require: false
9
9
  end
@@ -27,7 +27,7 @@ module Ra10ke::Dependencies
27
27
  # ignore tags that do not comply to semver
28
28
  nil
29
29
  end.select { |tag| !tag.nil? }.sort.last.to_s.downcase
30
- latest_ref = tags.detect { |tag| tag[/\Av?(.*)\Z/, 1] == latest_tag }
30
+ tags.detect { |tag| tag[/\Av?(.*)\Z/, 1] == latest_tag }
31
31
  end
32
32
  attr_reader :puppetfile
33
33
 
@@ -151,8 +151,7 @@ module Ra10ke::Dependencies
151
151
  PuppetForge.host = puppetfile.forge if puppetfile.forge =~ /^http/
152
152
 
153
153
  # ignore file allows for "don't tell me about this"
154
- ignore_modules = []
155
- ignore_modules = File.readlines('.r10kignore').each { |l| l.chomp! } if File.exist?('.r10kignore')
154
+ File.readlines('.r10kignore').each { |l| l.chomp! } if File.exist?('.r10kignore')
156
155
  forge_mods = puppetfile.modules.find_all do |mod|
157
156
  mod.instance_of?(R10K::Module::Forge) && mod.v3_module.homepage_url?
158
157
  end
@@ -32,6 +32,7 @@ module Ra10ke::Duplicates
32
32
 
33
33
  class Verification
34
34
  include Ra10ke::PuppetfileParser
35
+
35
36
  Module = Struct.new(:namespace, :name, :args) do
36
37
  def git?
37
38
  args.key? :git
@@ -65,7 +65,7 @@ module Ra10ke
65
65
 
66
66
  found = all_refs.find do |data|
67
67
  # we don't need to bother with these types
68
- next if data[:type] == :pull || data[:type] == :merge_request
68
+ next if %i[pull merge_request].include?(data[:type])
69
69
 
70
70
  # is the name equal to the tag or branch? Is the commit sha equal?
71
71
  data[:name].eql?(ref) || data[:sha].slice(0, 8).eql?(ref.slice(0, 8))
data/lib/ra10ke/solve.rb CHANGED
@@ -50,38 +50,26 @@ module Ra10ke::Solve
50
50
  # List of modules we have in the Puppetfile, as [name, version] pairs
51
51
  @current_modules = []
52
52
 
53
+ # Single pass: partition modules into git/Forge arrays and simultaneously seed
54
+ # @processed_modules with all git module names. Seeding upfront prevents
55
+ # add_reqs_to_graph from fetching Forge releases for any git module encountered
56
+ # as a transitive dependency, regardless of declaration order in the Puppetfile.
57
+ git_modules = []
58
+ forge_modules = []
53
59
  puppetfile.modules.each do |puppet_module|
54
60
  next if ignore_modules.include? puppet_module.title
55
61
 
56
62
  if puppet_module.instance_of?(R10K::Module::Forge)
57
- module_name = puppet_module.title.tr('/', '-')
58
- installed_version = puppet_module.expected_version
59
- puts "Processing Forge module #{module_name}-#{installed_version}"
60
- @current_modules << [module_name, installed_version]
61
- @graph.artifact(module_name, installed_version)
62
- constraint = '>=0.0.0'
63
- unless allow_major_bump
64
- ver = Semverse::Version.new installed_version
65
- if ver.major.zero?
66
- constraint = "~>#{installed_version}"
67
- else
68
- nver = Semverse::Version.new([ver.major + 1, 0, 0])
69
- constraint = "<#{nver}"
70
- end
71
- end
72
- puts "...Adding a demand: #{module_name} #{constraint}"
73
-
74
- @demands.add([module_name, constraint])
75
- puts '...Fetching latest release version information'
76
- forge_rel = PuppetForge::Module.find(module_name).current_release
77
- mod = @graph.artifact(module_name, forge_rel.version)
78
- puts '...Adding its requirements to the graph'
79
- meta = get_release_metadata(module_name, forge_rel)
80
- add_reqs_to_graph(mod, meta)
63
+ forge_modules << puppet_module
64
+ elsif puppet_module.instance_of?(R10K::Module::Git)
65
+ @processed_modules.add(puppet_module.title.tr('/', '-'))
66
+ git_modules << puppet_module
81
67
  end
68
+ end
82
69
 
83
- next unless puppet_module.instance_of?(R10K::Module::Git)
84
-
70
+ # Process git modules first so their metadata populates the graph before
71
+ # any Forge module's transitive dependencies are resolved.
72
+ git_modules.each do |puppet_module|
85
73
  # This downloads the git module to modules/modulename
86
74
  meta = fetch_git_metadata(puppet_module)
87
75
  version = get_key_or_sym(meta, :version)
@@ -95,6 +83,35 @@ module Ra10ke::Solve
95
83
  puts "...Adding requirements for git module #{module_name}-#{version}"
96
84
  add_reqs_to_graph(mod, meta)
97
85
  end
86
+
87
+ # Process Forge modules. Any git module already in @processed_modules will
88
+ # be skipped by add_reqs_to_graph when encountered as a transitive dependency.
89
+ forge_modules.each do |puppet_module|
90
+ module_name = puppet_module.title.tr('/', '-')
91
+ installed_version = puppet_module.expected_version
92
+ puts "Processing Forge module #{module_name}-#{installed_version}"
93
+ @current_modules << [module_name, installed_version]
94
+ @graph.artifact(module_name, installed_version)
95
+ constraint = '>=0.0.0'
96
+ unless allow_major_bump
97
+ ver = Semverse::Version.new installed_version
98
+ if ver.major.zero?
99
+ constraint = "~>#{installed_version}"
100
+ else
101
+ nver = Semverse::Version.new([ver.major + 1, 0, 0])
102
+ constraint = "<#{nver}"
103
+ end
104
+ end
105
+ puts "...Adding a demand: #{module_name} #{constraint}"
106
+
107
+ @demands.add([module_name, constraint])
108
+ puts '...Fetching latest release version information'
109
+ forge_rel = PuppetForge::Module.find(module_name).current_release
110
+ mod = @graph.artifact(module_name, forge_rel.version)
111
+ puts '...Adding its requirements to the graph'
112
+ meta = get_release_metadata(module_name, forge_rel)
113
+ add_reqs_to_graph(mod, meta)
114
+ end
98
115
  puts
99
116
  puts 'Resolving dependencies...'
100
117
  puts 'WARNING: Potentially breaking updates are allowed for this resolution' if allow_major_bump
@@ -177,7 +194,7 @@ module Ra10ke::Solve
177
194
 
178
195
  def add_reqs_to_graph(artifact, metadata, no_demands = nil)
179
196
  deps = get_key_or_sym(metadata, :dependencies)
180
- my_name = get_key_or_sym(metadata, :name)
197
+ get_key_or_sym(metadata, :name)
181
198
  deps.each do |dep|
182
199
  name = get_key_or_sym(dep, :name).tr('/', '-')
183
200
  # Add dependency to the global set of modules we want, so that we can
@@ -1,3 +1,3 @@
1
1
  module Ra10ke
2
- VERSION = '4.4.0'
2
+ VERSION = '4.5.1'
3
3
  end
data/ra10ke.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.require_paths = ['lib']
17
17
  spec.required_ruby_version = '>= 3.1.0'
18
18
 
19
- spec.add_dependency 'git', '>= 1.18', '< 4.0'
19
+ spec.add_dependency 'git', '>= 1.18', '< 5.0'
20
20
  spec.add_dependency 'puppet_forge', '~> 6.0'
21
21
  spec.add_dependency 'r10k', '~> 5.0'
22
22
  spec.add_dependency 'rake', '~> 13.0', '>= 13.0.6'
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'solve', '~> 4.0', '>= 4.0.4'
25
25
  spec.add_dependency 'table_print', '~> 1.5.6'
26
26
  spec.add_development_dependency 'rspec', '~> 3.6'
27
- spec.add_development_dependency 'voxpupuli-rubocop', '~> 4.1.0'
27
+ spec.add_development_dependency 'voxpupuli-rubocop', '~> 4.3.0'
28
28
  end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec::Mocks.configuration.allow_message_expectations_on_nil = true
6
+
7
+ RSpec.describe Ra10ke::Solve do
8
+ # Minimal helper class that mixes in the module so we can test its private methods.
9
+ let(:instance) do
10
+ klass = Class.new do
11
+ include Ra10ke::Solve
12
+
13
+ # Expose private helpers for direct testing.
14
+ public :get_key_or_sym, :get_version_req, :print_module_diff, :add_reqs_to_graph
15
+
16
+ def initialize
17
+ @graph = Solve::Graph.new
18
+ @processed_modules = Set.new
19
+ @demands = Set.new
20
+ # @metadata_cache is intentionally left nil here; tests that need it
21
+ # set it via instance_variable_set in a before block.
22
+ end
23
+ end
24
+ klass.new
25
+ end
26
+
27
+ let(:processed_modules) { instance.instance_variable_get(:@processed_modules) }
28
+ let(:demands) { instance.instance_variable_get(:@demands) }
29
+ let(:graph) { instance.instance_variable_get(:@graph) }
30
+
31
+ # -------------------------------------------------------------------------
32
+ describe '#get_key_or_sym' do
33
+ it 'fetches a value by symbol key' do
34
+ expect(instance.get_key_or_sym({ version: '1.0.0' }, :version)).to eq('1.0.0')
35
+ end
36
+
37
+ it 'fetches a value by string key when only the string form is present' do
38
+ expect(instance.get_key_or_sym({ 'version' => '2.0.0' }, :version)).to eq('2.0.0')
39
+ end
40
+
41
+ it 'prefers the symbol key over the string key when both are present' do
42
+ expect(instance.get_key_or_sym({ version: 'sym', 'version' => 'str' }, :version)).to eq('sym')
43
+ end
44
+
45
+ it 'returns nil when the key is absent in both forms' do
46
+ expect(instance.get_key_or_sym({}, :version)).to be_nil
47
+ end
48
+ end
49
+
50
+ # -------------------------------------------------------------------------
51
+ describe '#get_version_req' do
52
+ it 'returns version_requirement when present' do
53
+ expect(instance.get_version_req({ version_requirement: '>= 1.0.0' })).to eq('>= 1.0.0')
54
+ end
55
+
56
+ it 'falls back to version_range when version_requirement is absent' do
57
+ expect(instance.get_version_req({ version_range: '>= 2.0.0' })).to eq('>= 2.0.0')
58
+ end
59
+
60
+ it 'returns nil when neither key is present' do
61
+ expect(instance.get_version_req({})).to be_nil
62
+ end
63
+
64
+ it 'works with string keys' do
65
+ expect(instance.get_version_req({ 'version_requirement' => '~> 3.0' })).to eq('~> 3.0')
66
+ end
67
+ end
68
+
69
+ # -------------------------------------------------------------------------
70
+ describe '#print_module_diff' do
71
+ it 'reports OUTDATED for a module whose version has changed' do
72
+ expect do
73
+ instance.print_module_diff([['foo-bar', '1.0.0']], [['foo-bar', '2.0.0']])
74
+ end.to output(/OUTDATED.*foo-bar.*1\.0\.0.*2\.0\.0/).to_stdout
75
+ end
76
+
77
+ it 'reports MISSING for a module present in the resolution but not in current' do
78
+ expect do
79
+ instance.print_module_diff([], [['missing-mod', '1.2.3']])
80
+ end.to output(/MISSING.*missing-mod.*1\.2\.3/).to_stdout
81
+ end
82
+
83
+ it 'produces no output when all modules are up to date' do
84
+ expect do
85
+ instance.print_module_diff([['foo-bar', '1.0.0']], [['foo-bar', '1.0.0']])
86
+ end.not_to output.to_stdout
87
+ end
88
+
89
+ it 'reports all outdated modules in a single pass' do
90
+ current = [['aaa-one', '1.0.0'], ['bbb-two', '2.0.0']]
91
+ resolution = [['aaa-one', '1.1.0'], ['bbb-two', '2.1.0']]
92
+ expect do
93
+ instance.print_module_diff(current, resolution)
94
+ end.to output(/aaa-one.*bbb-two/m).to_stdout
95
+ end
96
+ end
97
+
98
+ # -------------------------------------------------------------------------
99
+ describe '#add_reqs_to_graph' do
100
+ let(:artifact) { graph.artifact('mymod', '1.0.0') }
101
+
102
+ context 'when the dependency is already in @processed_modules' do
103
+ before { processed_modules.add('puppetlabs-stdlib') }
104
+
105
+ it 'does not attempt a Forge lookup' do
106
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/stdlib', version_requirement: '>= 4.0.0' }] }
107
+ expect(PuppetForge::Module).not_to receive(:find)
108
+ instance.add_reqs_to_graph(artifact, meta)
109
+ end
110
+
111
+ it 'adds the dependency name to @demands' do
112
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/stdlib', version_requirement: '>= 4.0.0' }] }
113
+ instance.add_reqs_to_graph(artifact, meta)
114
+ expect(demands).to include('puppetlabs-stdlib')
115
+ end
116
+
117
+ it 'records the version constraint on the artifact' do
118
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/stdlib', version_requirement: '>= 4.0.0' }] }
119
+ instance.add_reqs_to_graph(artifact, meta)
120
+ dep = artifact.dependencies.find { |d| d.name == 'puppetlabs-stdlib' }
121
+ expect(dep).not_to be_nil
122
+ expect(dep.constraint.to_s).to eq('>= 4.0.0')
123
+ end
124
+ end
125
+
126
+ context 'when no_demands flag is set' do
127
+ before { processed_modules.add('puppetlabs-stdlib') }
128
+
129
+ it 'does not add the dependency to @demands' do
130
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/stdlib', version_requirement: '>= 4.0.0' }] }
131
+ instance.add_reqs_to_graph(artifact, meta, :no_demands)
132
+ expect(demands).not_to include('puppetlabs-stdlib')
133
+ end
134
+ end
135
+
136
+ context 'when dependency has an invalid version constraint' do
137
+ before { processed_modules.add('puppetlabs-badmod') }
138
+
139
+ it 'prints a warning and continues without raising' do
140
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/badmod', version_requirement: 'not_valid' }] }
141
+ expect do
142
+ instance.add_reqs_to_graph(artifact, meta)
143
+ end.to output(/WARNING.*Invalid version constraint/).to_stdout
144
+ end
145
+ end
146
+
147
+ context 'when dependency has no version constraint' do
148
+ before { processed_modules.add('puppetlabs-nover') }
149
+
150
+ it 'falls back to >=0.0.0 and does not raise' do
151
+ meta = { name: 'mymod', dependencies: [{ name: 'puppetlabs/nover' }] }
152
+ expect { instance.add_reqs_to_graph(artifact, meta) }.not_to raise_error
153
+ dep = artifact.dependencies.find { |d| d.name == 'puppetlabs-nover' }
154
+ expect(dep.constraint.to_s).to eq('>= 0.0.0')
155
+ end
156
+ end
157
+
158
+ context 'when dependency has a compound constraint (>=x <y)' do
159
+ before { processed_modules.add('puppetlabs-compound') }
160
+
161
+ it 'records both bounds on the artifact' do
162
+ meta = {
163
+ name: 'mymod',
164
+ dependencies: [{ name: 'puppetlabs/compound', version_requirement: '>= 4.0.0 <9.0.0' }],
165
+ }
166
+ instance.add_reqs_to_graph(artifact, meta)
167
+ constraints = artifact.dependencies.select { |d| d.name == 'puppetlabs-compound' }
168
+ .map { |d| d.constraint.to_s }
169
+ expect(constraints).to include('>= 4.0.0')
170
+ expect(constraints).to include('< 9.0.0')
171
+ end
172
+ end
173
+ end
174
+ end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ra10ke
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 4.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo Chatzimichos
8
8
  - Vox Pupuli
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2025-06-08 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: git
@@ -20,7 +19,7 @@ dependencies:
20
19
  version: '1.18'
21
20
  - - "<"
22
21
  - !ruby/object:Gem::Version
23
- version: '4.0'
22
+ version: '5.0'
24
23
  type: :runtime
25
24
  prerelease: false
26
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +29,7 @@ dependencies:
30
29
  version: '1.18'
31
30
  - - "<"
32
31
  - !ruby/object:Gem::Version
33
- version: '4.0'
32
+ version: '5.0'
34
33
  - !ruby/object:Gem::Dependency
35
34
  name: puppet_forge
36
35
  requirement: !ruby/object:Gem::Requirement
@@ -153,14 +152,14 @@ dependencies:
153
152
  requirements:
154
153
  - - "~>"
155
154
  - !ruby/object:Gem::Version
156
- version: 4.1.0
155
+ version: 4.3.0
157
156
  type: :development
158
157
  prerelease: false
159
158
  version_requirements: !ruby/object:Gem::Requirement
160
159
  requirements:
161
160
  - - "~>"
162
161
  - !ruby/object:Gem::Version
163
- version: 4.1.0
162
+ version: 4.3.0
164
163
  description: R10K and Puppetfile rake tasks
165
164
  email:
166
165
  - voxpupuli@groups.io
@@ -214,6 +213,7 @@ files:
214
213
  - spec/ra10ke/duplicates_spec.rb
215
214
  - spec/ra10ke/git_repo_spec.rb
216
215
  - spec/ra10ke/puppetfile_parser_spec.rb
216
+ - spec/ra10ke/solve_spec.rb
217
217
  - spec/ra10ke/validate_spec.rb
218
218
  - spec/ra10ke_spec.rb
219
219
  - spec/spec_helper.rb
@@ -221,7 +221,6 @@ homepage: https://github.com/voxpupuli/ra10ke
221
221
  licenses:
222
222
  - MIT
223
223
  metadata: {}
224
- post_install_message:
225
224
  rdoc_options: []
226
225
  require_paths:
227
226
  - lib
@@ -236,8 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
235
  - !ruby/object:Gem::Version
237
236
  version: '0'
238
237
  requirements: []
239
- rubygems_version: 3.5.22
240
- signing_key:
238
+ rubygems_version: 4.0.6
241
239
  specification_version: 4
242
240
  summary: Syntax check for the Puppetfile, check for outdated installed puppet modules
243
241
  test_files: []