ra10ke 0.5.0 → 0.6.0
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 +4 -4
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +16 -0
- data/README.md +59 -1
- data/Rakefile +7 -1
- data/lib/ra10ke/dependencies.rb +71 -0
- data/lib/ra10ke/install.rb +32 -0
- data/lib/ra10ke/monkey_patches.rb +28 -0
- data/lib/ra10ke/puppetfile_parser.rb +83 -0
- data/lib/ra10ke/solve.rb +185 -189
- data/lib/ra10ke/syntax.rb +18 -0
- data/lib/ra10ke/validate.rb +126 -0
- data/lib/ra10ke/version.rb +1 -1
- data/lib/ra10ke.rb +29 -122
- data/ra10ke.gemspec +2 -0
- data/spec/fixtures/Puppetfile +43 -0
- data/spec/fixtures/Puppetfile_test +12 -0
- data/spec/fixtures/Puppetfile_with_bad_refs +10 -0
- data/spec/fixtures/reflist.txt +290 -0
- data/spec/ra10ke/puppetfile_parser_spec.rb +103 -0
- data/spec/ra10ke/validate_spec.rb +81 -0
- data/spec/ra10ke_spec.rb +73 -0
- data/spec/spec_helper.rb +3 -0
- metadata +45 -2
data/lib/ra10ke/solve.rb
CHANGED
@@ -11,218 +11,214 @@ require 'semverse/version'
|
|
11
11
|
FETCH_LIMIT = 3
|
12
12
|
|
13
13
|
module Ra10ke::Solve
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
require 'r10k/module/metadata_file'
|
22
|
-
require 'puppet_forge'
|
14
|
+
def define_task_solve_dependencies(*_args)
|
15
|
+
desc 'Find missing or outdated module dependencies'
|
16
|
+
task :solve_dependencies, [:allow_major_bump] do |_t, args|
|
17
|
+
require 'r10k/puppetfile'
|
18
|
+
require 'r10k/module/git'
|
19
|
+
require 'r10k/module/metadata_file'
|
20
|
+
require 'puppet_forge'
|
23
21
|
|
24
|
-
|
25
|
-
|
22
|
+
allow_major_bump = false
|
23
|
+
allow_major_bump = true if args[:allow_major_bump]
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
# Same as in the dependencies task, but oh well.
|
26
|
+
PuppetForge.user_agent = "ra10ke/#{Ra10ke::VERSION}"
|
27
|
+
puppetfile = get_puppetfile
|
28
|
+
puppetfile.load!
|
29
|
+
PuppetForge.host = puppetfile.forge if puppetfile.forge =~ /^http/
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
puppetfile.modules.each do |puppet_module|
|
54
|
-
next if ignore_modules.include? puppet_module.title
|
55
|
-
if puppet_module.class == R10K::Module::Forge
|
56
|
-
module_name = puppet_module.title.tr('/', '-')
|
57
|
-
installed_version = puppet_module.expected_version
|
58
|
-
puts "Processing Forge module #{module_name}-#{installed_version}"
|
59
|
-
@current_modules << [module_name, installed_version]
|
60
|
-
@graph.artifact(module_name, installed_version)
|
61
|
-
constraint = '>=0.0.0'
|
62
|
-
unless allow_major_bump
|
63
|
-
ver = Semverse::Version.new installed_version
|
64
|
-
if ver.major.zero?
|
65
|
-
constraint = "~>#{installed_version}"
|
66
|
-
else
|
67
|
-
nver = Semverse::Version.new([ver.major + 1, 0, 0])
|
68
|
-
constraint = "<#{nver}"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
puts "...Adding a demand: #{module_name} #{constraint}"
|
31
|
+
# ignore file allows for "don't tell me about this"
|
32
|
+
ignore_modules = []
|
33
|
+
if File.exist?('.r10kignore')
|
34
|
+
ignore_modules = File.readlines('.r10kignore').each(&:chomp!)
|
35
|
+
end
|
36
|
+
# Actual new logic begins here:
|
37
|
+
cache = (ENV['XDG_CACHE_DIR'] || File.expand_path('~/.cache'))
|
38
|
+
# Metadata cache, since the Forge is slow:
|
39
|
+
@metadata_cache = YAML::Store.new File.join(cache, 'ra10ke.metadata_cache')
|
40
|
+
# The graph of available module versions
|
41
|
+
@graph = Solve::Graph.new
|
42
|
+
# Set of modules that we have already added to the graph
|
43
|
+
@processed_modules = Set.new
|
44
|
+
# The set of "demands" we make of the solver. Will be a list of module names
|
45
|
+
# Could also demand certain version constraints to hold, but the code does not do it
|
46
|
+
# Can be either "module-name" or ["module-name", "version-constraint"]
|
47
|
+
@demands = Set.new
|
48
|
+
# List of modules we have in the Puppetfile, as [name, version] pairs
|
49
|
+
@current_modules = []
|
72
50
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
51
|
+
puppetfile.modules.each do |puppet_module|
|
52
|
+
next if ignore_modules.include? puppet_module.title
|
53
|
+
if puppet_module.class == R10K::Module::Forge
|
54
|
+
module_name = puppet_module.title.tr('/', '-')
|
55
|
+
installed_version = puppet_module.expected_version
|
56
|
+
puts "Processing Forge module #{module_name}-#{installed_version}"
|
57
|
+
@current_modules << [module_name, installed_version]
|
58
|
+
@graph.artifact(module_name, installed_version)
|
59
|
+
constraint = '>=0.0.0'
|
60
|
+
unless allow_major_bump
|
61
|
+
ver = Semverse::Version.new installed_version
|
62
|
+
if ver.major.zero?
|
63
|
+
constraint = "~>#{installed_version}"
|
64
|
+
else
|
65
|
+
nver = Semverse::Version.new([ver.major + 1, 0, 0])
|
66
|
+
constraint = "<#{nver}"
|
80
67
|
end
|
81
|
-
|
82
|
-
next unless puppet_module.class == R10K::Module::Git
|
83
|
-
# This downloads the git module to modules/modulename
|
84
|
-
meta = fetch_git_metadata(puppet_module)
|
85
|
-
version = get_key_or_sym(meta, :version)
|
86
|
-
module_name = puppet_module.title.tr('/', '-')
|
87
|
-
@current_modules << [module_name, version]
|
88
|
-
# We should add git modules with exact versions, or the system might recommend updating to a
|
89
|
-
# Forge version.
|
90
|
-
puts "Adding git module #{module_name} to the list of required modules with exact version: #{version}"
|
91
|
-
@demands.add([module_name, version])
|
92
|
-
mod = @graph.artifact(module_name, version)
|
93
|
-
puts "...Adding requirements for git module #{module_name}-#{version}"
|
94
|
-
add_reqs_to_graph(mod, meta)
|
95
68
|
end
|
96
|
-
puts
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
puts
|
103
|
-
|
69
|
+
puts "...Adding a demand: #{module_name} #{constraint}"
|
70
|
+
|
71
|
+
@demands.add([module_name, constraint])
|
72
|
+
puts '...Fetching latest release version information'
|
73
|
+
forge_rel = PuppetForge::Module.find(module_name).current_release
|
74
|
+
mod = @graph.artifact(module_name, forge_rel.version)
|
75
|
+
puts '...Adding its requirements to the graph'
|
76
|
+
meta = get_release_metadata(module_name, forge_rel)
|
77
|
+
add_reqs_to_graph(mod, meta)
|
104
78
|
end
|
79
|
+
|
80
|
+
next unless puppet_module.class == R10K::Module::Git
|
81
|
+
# This downloads the git module to modules/modulename
|
82
|
+
meta = fetch_git_metadata(puppet_module)
|
83
|
+
version = get_key_or_sym(meta, :version)
|
84
|
+
module_name = puppet_module.title.tr('/', '-')
|
85
|
+
@current_modules << [module_name, version]
|
86
|
+
# We should add git modules with exact versions, or the system might recommend updating to a
|
87
|
+
# Forge version.
|
88
|
+
puts "Adding git module #{module_name} to the list of required modules with exact version: #{version}"
|
89
|
+
@demands.add([module_name, version])
|
90
|
+
mod = @graph.artifact(module_name, version)
|
91
|
+
puts "...Adding requirements for git module #{module_name}-#{version}"
|
92
|
+
add_reqs_to_graph(mod, meta)
|
93
|
+
end
|
94
|
+
puts
|
95
|
+
puts 'Resolving dependencies...'
|
96
|
+
if allow_major_bump
|
97
|
+
puts 'WARNING: Potentially breaking updates are allowed for this resolution'
|
105
98
|
end
|
99
|
+
result = Solve.it!(@graph, @demands, sorted: true)
|
100
|
+
puts
|
101
|
+
print_module_diff(@current_modules, result)
|
106
102
|
end
|
103
|
+
end
|
107
104
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
105
|
+
private
|
106
|
+
|
107
|
+
def get_release_metadata(name, release)
|
108
|
+
meta = nil
|
109
|
+
@metadata_cache.transaction do
|
110
|
+
meta = @metadata_cache["#{name}-#{release.version}"]
|
111
|
+
unless meta
|
112
|
+
meta = release.metadata
|
113
|
+
@metadata_cache["#{name}-#{release.version}"] = meta
|
116
114
|
end
|
117
|
-
meta
|
118
115
|
end
|
116
|
+
meta
|
117
|
+
end
|
119
118
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
}
|
132
|
-
end
|
133
|
-
metadata = R10K::Module::MetadataFile.new(metadata_path)
|
134
|
-
metadata = metadata.read
|
135
|
-
{
|
136
|
-
version: metadata.version,
|
137
|
-
name: metadata.name,
|
138
|
-
dependencies: metadata.dependencies
|
119
|
+
def fetch_git_metadata(puppet_module)
|
120
|
+
# No caching here. I don't think it's really possible to do in a sane way.
|
121
|
+
puts "Fetching git module #{puppet_module.title}, saving to modules/"
|
122
|
+
puppet_module.sync
|
123
|
+
metadata_path = Pathname.new(puppet_module.full_path) + 'metadata.json'
|
124
|
+
unless metadata_path.exist?
|
125
|
+
puts 'WARNING: metadata.json does not exist, assuming version 0.0.0 and no dependencies'
|
126
|
+
return {
|
127
|
+
version: '0.0.0',
|
128
|
+
name: puppet_module.title,
|
129
|
+
dependencies: []
|
139
130
|
}
|
140
131
|
end
|
132
|
+
metadata = R10K::Module::MetadataFile.new(metadata_path)
|
133
|
+
metadata = metadata.read
|
134
|
+
{
|
135
|
+
version: metadata.version,
|
136
|
+
name: metadata.name,
|
137
|
+
dependencies: metadata.dependencies
|
138
|
+
}
|
139
|
+
end
|
141
140
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
141
|
+
# Is there a better way? :(
|
142
|
+
def get_key_or_sym(hash, k)
|
143
|
+
hash.fetch(k.to_sym, hash.fetch(k.to_s, nil))
|
144
|
+
end
|
146
145
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
146
|
+
# At least puppet-extlib has malformed metadata
|
147
|
+
def get_version_req(dep)
|
148
|
+
req = get_key_or_sym(dep, :version_requirement)
|
149
|
+
req = get_key_or_sym(dep, :version_range) unless req
|
150
|
+
req
|
151
|
+
end
|
153
152
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end
|
168
|
-
end
|
169
|
-
missing.each do |m|
|
170
|
-
puts format('MISSING: %-25s %s', *m)
|
171
|
-
end
|
172
|
-
outdated.each do |o|
|
173
|
-
puts format('OUTDATED: %-25s %s -> %s', *o)
|
153
|
+
def print_module_diff(current, resolution)
|
154
|
+
current.sort!
|
155
|
+
resolution.sort!
|
156
|
+
outdated = []
|
157
|
+
missing = []
|
158
|
+
resolution.each do |mod|
|
159
|
+
cur_mod, cur_version = current.shift
|
160
|
+
mod, version = mod
|
161
|
+
if (cur_mod == mod) && cur_version && (cur_version != version)
|
162
|
+
outdated << [mod, cur_version, version]
|
163
|
+
elsif cur_mod != mod
|
164
|
+
missing << [mod, version]
|
165
|
+
current.unshift [cur_mod, cur_version]
|
174
166
|
end
|
175
167
|
end
|
168
|
+
missing.each do |m|
|
169
|
+
puts format('MISSING: %-25s %s', *m)
|
170
|
+
end
|
171
|
+
outdated.each do |o|
|
172
|
+
puts format('OUTDATED: %-25s %s -> %s', *o)
|
173
|
+
end
|
174
|
+
end
|
176
175
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
202
|
-
end
|
203
|
-
# Find the dependency in the forge, unless it's already been processed
|
204
|
-
# and add its releases to the global graph
|
205
|
-
next unless @processed_modules.add?(name)
|
206
|
-
puts "Fetching module info for #{name}"
|
207
|
-
mod = begin
|
208
|
-
PuppetForge::Module.find(name)
|
209
|
-
rescue
|
210
|
-
# It's probably a git module
|
211
|
-
nil
|
212
|
-
end
|
213
|
-
next unless mod # Git module, or non-forge dependency. Skip to next for now.
|
214
|
-
# Fetching metadata for all releases takes ages (which is weird, since it's mostly static info)
|
215
|
-
mod.releases.take(FETCH_LIMIT).each do |rel|
|
216
|
-
meta = get_release_metadata(name, rel)
|
217
|
-
rel_artifact = @graph.artifact(name, rel.version)
|
218
|
-
puts "...Recursively adding requirements for dependency #{name} version #{rel.version}"
|
219
|
-
# We don't want to add the requirements to the list of demands for all versions,
|
220
|
-
# but we need them in the graph to be able to solve dependencies
|
221
|
-
add_reqs_to_graph(rel_artifact, meta, :no_demands)
|
176
|
+
def add_reqs_to_graph(artifact, metadata, no_demands = nil)
|
177
|
+
deps = get_key_or_sym(metadata, :dependencies)
|
178
|
+
my_name = get_key_or_sym(metadata, :name)
|
179
|
+
deps.each do |dep|
|
180
|
+
name = get_key_or_sym(dep, :name).tr('/', '-')
|
181
|
+
# Add dependency to the global set of modules we want, so that we can
|
182
|
+
# actually ask the solver for the versioned thing
|
183
|
+
@demands.add(name) unless no_demands
|
184
|
+
ver = get_version_req(dep)
|
185
|
+
unless ver
|
186
|
+
# no version specified, so anything will do
|
187
|
+
ver = '>=0.0.0'
|
188
|
+
end
|
189
|
+
ver.split(/(?=[<])/).each do |bound|
|
190
|
+
bound.strip!
|
191
|
+
v = begin
|
192
|
+
Semverse::Constraint.new(bound)
|
193
|
+
rescue
|
194
|
+
nil
|
195
|
+
end
|
196
|
+
if v
|
197
|
+
artifact.depends(name, v.to_s)
|
198
|
+
else
|
199
|
+
puts "WARNING: Invalid version constraint: #{bound}"
|
222
200
|
end
|
223
201
|
end
|
202
|
+
# Find the dependency in the forge, unless it's already been processed
|
203
|
+
# and add its releases to the global graph
|
204
|
+
next unless @processed_modules.add?(name)
|
205
|
+
puts "Fetching module info for #{name}"
|
206
|
+
mod = begin
|
207
|
+
PuppetForge::Module.find(name)
|
208
|
+
rescue
|
209
|
+
# It's probably a git module
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
next unless mod # Git module, or non-forge dependency. Skip to next for now.
|
213
|
+
# Fetching metadata for all releases takes ages (which is weird, since it's mostly static info)
|
214
|
+
mod.releases.take(FETCH_LIMIT).each do |rel|
|
215
|
+
meta = get_release_metadata(name, rel)
|
216
|
+
rel_artifact = @graph.artifact(name, rel.version)
|
217
|
+
puts "...Recursively adding requirements for dependency #{name} version #{rel.version}"
|
218
|
+
# We don't want to add the requirements to the list of demands for all versions,
|
219
|
+
# but we need them in the graph to be able to solve dependencies
|
220
|
+
add_reqs_to_graph(rel_artifact, meta, :no_demands)
|
221
|
+
end
|
224
222
|
end
|
225
223
|
end
|
226
224
|
end
|
227
|
-
|
228
|
-
Ra10ke::Solve::RakeTask.new
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Ra10ke::Syntax
|
2
|
+
def define_task_syntax(*_args)
|
3
|
+
desc "Syntax check Puppetfile"
|
4
|
+
task :syntax do
|
5
|
+
require 'r10k/action/puppetfile/check'
|
6
|
+
|
7
|
+
puppetfile = R10K::Action::Puppetfile::Check.new({
|
8
|
+
:root => @basedir,
|
9
|
+
:moduledir => @moduledir,
|
10
|
+
:puppetfile => @puppetfile_path
|
11
|
+
}, '')
|
12
|
+
|
13
|
+
unless puppetfile.call
|
14
|
+
abort("Puppetfile syntax check failed")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ra10ke/monkey_patches'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'table_print'
|
6
|
+
require 'ra10ke/puppetfile_parser'
|
7
|
+
require 'English'
|
8
|
+
|
9
|
+
module Ra10ke
|
10
|
+
module Validate
|
11
|
+
|
12
|
+
GOOD_EMOJI = ENV['GOOD_EMOJI'] || '👍'
|
13
|
+
BAD_EMOJI = ENV['BAD_EMOJI'] || '😨'
|
14
|
+
|
15
|
+
# Validate the git urls and refs
|
16
|
+
def define_task_validate(*args)
|
17
|
+
desc 'Validate the git urls and branches, refs, or tags'
|
18
|
+
task :validate do
|
19
|
+
gitvalididation = Ra10ke::Validate::Validation.new(get_puppetfile.puppetfile_path)
|
20
|
+
exit_code = 0
|
21
|
+
if gitvalididation.bad_mods?
|
22
|
+
exit_code = 1
|
23
|
+
message = BAD_EMOJI + ' Not all modules in the Puppetfile are valid. '.red + BAD_EMOJI
|
24
|
+
else
|
25
|
+
message = GOOD_EMOJI + ' Puppetfile looks good. '.green + GOOD_EMOJI
|
26
|
+
end
|
27
|
+
tp gitvalididation.sorted_mods, :name, { url: { width: 50 } }, :ref, :status
|
28
|
+
abort(message) if exit_code.positive?
|
29
|
+
puts message
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Validation
|
34
|
+
include Ra10ke::PuppetfileParser
|
35
|
+
|
36
|
+
attr_reader :puppetfile
|
37
|
+
|
38
|
+
def initialize(file)
|
39
|
+
file ||= './Puppetfile'
|
40
|
+
@puppetfile = File.expand_path(file)
|
41
|
+
abort("Puppetfile does not exist at #{puppetfile}") unless File.readable?(puppetfile)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Boolean] - return true if the ref is valid
|
45
|
+
# @param url [String] - the git string either https or ssh url
|
46
|
+
# @param ref [String] - the ref object, branch name, tag name, or commit sha, defaults to HEAD
|
47
|
+
def valid_ref?(url, ref = 'HEAD')
|
48
|
+
raise ArgumentError unless ref
|
49
|
+
found = all_refs(url).find do |sha, data |
|
50
|
+
# we don't need to bother with these types
|
51
|
+
next if data[:type] == :pull || data[:type] == :merge_request
|
52
|
+
# is the name equal to the tag or branch? Is the commit sha equal?
|
53
|
+
data[:name].eql?(ref) || sha.slice(0,8).eql?(ref.slice(0,8))
|
54
|
+
end
|
55
|
+
!found.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Hash] - a hash of all the refs associated with the remote repository
|
59
|
+
# @param url [String] - the git string either https or ssh url
|
60
|
+
# @example
|
61
|
+
# {"0ec707e431367bbe2752966be8ab915b6f0da754"=>{:ref=>"refs/heads/74110ac", :type=>:branch, :subtype=>nil, :name=>"74110ac"},
|
62
|
+
# "07bb5d2d94db222dca5860eb29c184e8970f36f4"=>{:ref=>"refs/pull/74/head", :type=>:pull, :subtype=>:head, :name=>"74"},
|
63
|
+
# "156ca9a8ea69e056e86355b27d944e59d1b3a1e1"=>{:ref=>"refs/heads/master", :type=>:branch, :subtype=>nil, :name=>"master"},
|
64
|
+
# "fcc0532bbc5a5b65f3941738339e9cc7e3d767ce"=>{:ref=>"refs/pull/249/head", :type=>:pull, :subtype=>:head, :name=>"249"},
|
65
|
+
# "8d54891fa5df75890ee15d53080c2a81b4960f92"=>{:ref=>"refs/pull/267/head", :type=>:pull, :subtype=>:head, :name=>"267"} }
|
66
|
+
def all_refs(url)
|
67
|
+
data = `git ls-remote --symref #{url}`
|
68
|
+
raise "Error downloading #{url}" unless $CHILD_STATUS.success?
|
69
|
+
data.lines.reduce({}) do |refs, line|
|
70
|
+
sha, ref = line.split("\t")
|
71
|
+
next refs if sha.eql?('ref: refs/heads/master')
|
72
|
+
_, type, name, subtype = ref.chomp.split('/')
|
73
|
+
next refs unless name
|
74
|
+
type = :tag if type.eql?('tags')
|
75
|
+
type = type.to_sym
|
76
|
+
subtype = subtype.to_sym if subtype
|
77
|
+
type = :branch if type.eql?(:heads)
|
78
|
+
refs[sha] = {ref: ref.chomp, type: type, subtype: subtype, name: name }
|
79
|
+
refs
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Boolean] - return true if the commit sha is valid
|
84
|
+
# @param url [String] - the git string either https or ssh url
|
85
|
+
# @param ref [String] - the sha id
|
86
|
+
def valid_commit?(url, sha)
|
87
|
+
return false if sha.nil? || sha.empty?
|
88
|
+
return true if valid_ref?(url, sha)
|
89
|
+
Dir.mktmpdir do |dir|
|
90
|
+
`git clone --no-tags #{url} #{dir} 2>&1 > /dev/null`
|
91
|
+
Dir.chdir(dir) do
|
92
|
+
`git show #{sha} 2>&1 > /dev/null`
|
93
|
+
$CHILD_STATUS.success?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [Array[Hash]] array of module information and git status
|
99
|
+
def all_modules
|
100
|
+
begin
|
101
|
+
git_modules(puppetfile).map do |mod|
|
102
|
+
ref = mod[:args][:ref] || mod[:args][:tag] || mod[:args][:branch]
|
103
|
+
valid_ref = valid_ref?(mod[:args][:git], ref) || valid_commit?(mod[:args][:git], mod[:args][:ref])
|
104
|
+
{
|
105
|
+
name: mod[:name],
|
106
|
+
url: mod[:args][:git],
|
107
|
+
ref: ref,
|
108
|
+
valid_ref?: valid_ref,
|
109
|
+
status: valid_ref ? Ra10ke::Validate::GOOD_EMOJI : Ra10ke::Validate::BAD_EMOJI
|
110
|
+
}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @return [Boolean] - true if there are any bad mods
|
116
|
+
def bad_mods?
|
117
|
+
all_modules.find_all { |mod| !mod[:valid_ref?] }.count > 0
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [Hash] - sorts the mods based on good/bad
|
121
|
+
def sorted_mods
|
122
|
+
all_modules.sort_by { |a| a[:valid_ref?] ? 1 : 0 }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/ra10ke/version.rb
CHANGED