Skip to content

Commit b488296

Browse files
committed
Converts puppet forge module entries into puppetfile git entries
* This feature is useful when you want to bring all the forge modules in house on the local git server. This will auto lookup the module's homepage url and use that as the git source. Sometimes the author doesn't provide the homepage url so this will fail and the code isn't always tagged to the version so some manual intervention will be required before final approval of conversion output.
1 parent af46a43 commit b488296

File tree

7 files changed

+113
-2
lines changed

7 files changed

+113
-2
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ Ignoring specific modules:
6868
Under specific conditions you may not wish to report on specific modules being out of date,
6969
to ignore a module create `.r10kignore` file in the same directory as your Puppetfile.
7070

71+
### r10k::print_git_conversion
72+
This rake task will go through the puppetfile and convert forge based modules into git based modules using
73+
the modules't source repository and version tag.
74+
75+
This feature is useful when you want to bring all the forge modules into git source control. This assumes every module
76+
tags the release or provides a valid repo url. We recommend to manually review
77+
the output provided by this task before replacing the forge based content in your puppetfile as not every module author
78+
tagged a release or provided a working url.
79+
7180
### r10k:solve_dependencies
7281

7382
Reads the Puppetfile in the current directory and uses the ruby 'solve' library to find

lib/ra10ke.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def initialize(*args)
4141
define_task_duplicates(*args)
4242
define_task_install(*args)
4343
define_task_validate(*args)
44+
define_task_print_git_conversion(*args)
4445
end
4546
end
4647

lib/ra10ke/dependencies.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,49 @@ def print_table(mods)
138138
end
139139
end
140140

141+
def define_task_print_git_conversion(*_args)
142+
desc "Convert and print forge modules to git format"
143+
task :print_git_conversion do
144+
require 'ra10ke/git_repo'
145+
require 'r10k/puppetfile'
146+
require 'puppet_forge'
147+
148+
PuppetForge.user_agent = "ra10ke/#{Ra10ke::VERSION}"
149+
puppetfile = get_puppetfile
150+
puppetfile.load!
151+
PuppetForge.host = puppetfile.forge if puppetfile.forge =~ /^http/
152+
153+
# ignore file allows for "don't tell me about this"
154+
ignore_modules = []
155+
if File.exist?('.r10kignore')
156+
ignore_modules = File.readlines('.r10kignore').each {|l| l.chomp!}
157+
end
158+
forge_mods = puppetfile.modules.find_all { |mod| mod.instance_of?(R10K::Module::Forge) && mod.v3_module.homepage_url? }
159+
160+
threads = forge_mods.map do |mod|
161+
Thread.new do
162+
source_url = mod.v3_module.attributes.dig(:current_release, :metadata, :source) || mod.v3_module.homepage_url
163+
# git:// does not work with ls-remote command, convert to https
164+
source_url = source_url.gsub('git://', 'https://')
165+
source_url = source_url.gsub(/\Agit\@(.*)\:(.*)/) do
166+
"https://#{$1}/#{$2}"
167+
end
168+
repo = ::Ra10ke::GitRepo.new(source_url)
169+
ref = repo.get_ref_like(mod.expected_version)
170+
ref_name = ref ? ref[:name] : "bad url or tag #{mod.expected_version} is missing"
171+
<<~EOF
172+
mod '#{mod.name}',
173+
:git => '#{source_url}',
174+
:ref => '#{ref_name}'
175+
176+
EOF
177+
end
178+
end
179+
output = threads.map { |th| th.join.value }
180+
puts output
181+
end
182+
end
183+
141184
def define_task_dependencies(*_args)
142185
desc "Print outdated forge modules"
143186
task :dependencies do

lib/ra10ke/git_repo.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ def all_refs
8585
@all_refs ||= begin
8686
remote_refs.each_with_object([]) do |line, refs|
8787
sha, ref = line.split("\t")
88+
next refs if line.include?('redirecting')
8889
next refs if sha.eql?('ref: refs/heads/master')
89-
9090
_, type, name, subtype = ref.chomp.split('/')
9191
next refs unless name
9292

@@ -99,6 +99,18 @@ def all_refs
9999
end
100100
end
101101

102+
# @summary searches all the refs for a ref similar to the name provided
103+
# This is useful when looking for tags if a v or not a v
104+
# @param ref_name [String]
105+
# @return [String] the matching ref_name or nil
106+
def get_ref_like(ref_name)
107+
return nil unless valid_url?
108+
ref = all_refs.find do |ref|
109+
ref[:name].include?(ref_name)
110+
end
111+
ref
112+
end
113+
102114
# useful for mocking easily
103115
# @param cmd [String]
104116
# @param silent [Boolean] set to true if you wish to send output to /dev/null, false by default
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mod 'choria',
2+
:git => 'https://github.com/choria-io/puppet-choria',
3+
:ref => '0.26.2'
4+
5+
mod 'inifile',
6+
:git => 'https://github.com/puppetlabs/puppetlabs-inifile',
7+
:ref => '2.2.0'
8+
9+
mod 'ruby',
10+
:git => 'https://github.com/puppetlabs/puppetlabs-ruby.git',
11+
:ref => 'v1.0.1'
12+
13+
mod 'stdlib',
14+
:git => 'https://github.com/puppetlabs/puppetlabs-stdlib',
15+
:ref => '4.24.0'
16+
17+
mod 'concat',
18+
:git => 'https://github.com/puppetlabs/puppetlabs-concat',
19+
:ref => '4.0.0'
20+
21+
mod 'ntp',
22+
:git => 'https://github.com/puppetlabs/puppetlabs-ntp',
23+
:ref => '6.4.1'
24+
25+
mod 'archive',
26+
:git => 'https://github.com/voxpupuli/puppet-archive',
27+
:ref => 'v3.1.1'
28+

spec/ra10ke/dependencies_spec.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
require 'r10k/puppetfile'
33
require 'spec_helper'
44
require 'ra10ke/dependencies'
5+
require 'ra10ke'
6+
57
RSpec::Mocks.configuration.allow_message_expectations_on_nil = true
68

79
RSpec.describe 'Ra10ke::Dependencies::Verification' do
@@ -89,6 +91,18 @@
8991
'tags' => test_tags,
9092
})).to eq(latest_tag)
9193
end
92-
end
94+
end
95+
96+
context 'convert to ref' do
97+
98+
it 'run rake task' do
99+
output_conversion = File.read(File.join(fixtures_dir, 'Puppetfile_git_conversion'))
100+
require 'ra10ke'
101+
Ra10ke::RakeTask.new do |t|
102+
t.basedir = fixtures_dir
103+
end
104+
expect{Rake::Task['r10k:print_git_conversion'].invoke}.to output(output_conversion).to_stdout
105+
end
106+
end
93107
end
94108
end

spec/ra10ke/git_repo_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
expect(instance.remote_refs.first).to eq("1b3322d525e96bf7d0565b08703e2a44c90e7b4a\tHEAD\n")
3939
end
4040

41+
it '#get_ref_like' do
42+
expect(instance.get_ref_like('8.0.0'))
43+
end
44+
4145
it '#valid_ref?' do
4246
expect(instance.valid_ref?('master')).to be true
4347
end

0 commit comments

Comments
 (0)