Module: Simp::Rake::Build::RpmDeps

Defined in:
lib/simp/rake/build/rpmdeps.rb

Class Method Summary collapse

Class Method Details

.generate_custom_rpm_obsoletes(obsoletes_hash, module_metadata) ⇒ Object

Generate ‘Obsoletes’ lines from obsoletes_hash.

returns array of strings, each of which is an ‘Obsoletes’ line for use in an RPM spec file

obsoletes_hash

Hash containing package names and their versions

this module obsoletes from the `dependencies.yaml` file
module_metadata

Hash containing the contents of the module’s

'metadata.json' file


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/simp/rake/build/rpmdeps.rb', line 53

def self.generate_custom_rpm_obsoletes(obsoletes_hash, )
   = []

  obsoletes_hash.each_pair do |pkg, version|
    module_version = ['version']

    # We don't want to add this if we're building an older
    # version or the RPM will be malformed
    main_version, release = version.split('-')
    release = '0' unless release

    if Gem::Version.new(module_version) > Gem::Version.new(main_version)
       << "Obsoletes: #{pkg} < #{main_version}-#{release}.obsolete"
       << "Provides: #{pkg} = #{main_version}-#{release}.obsolete"
    else
      puts "Ignoring 'obsoletes' for #{pkg}: module version" +
       " #{module_version} from metadata.json is not >" +
       " obsolete version #{version}"
    end
  end
  
end

.generate_custom_rpm_requires(requires_list, module_metadata, ignores = []) ⇒ Object

Generate ‘Requires’ lines, from a combination of the module_rpm_meta and module_metadata. Only dependencies listed in the module_rpm_meta hash will be included in the output. The version requirements for each dependency will be pulled from module_metadata.

returns array of strings, each of which is a ‘Requires’ line for use in an RPM spec file

raises SIMPRpmDepException if any ‘metadata.json’ dependency

version string from module_metadata cannot be parsed or a
dependency specified in module_rpm_meta is not found in
module_metadata
requires_list

list of package this module should require

from the 'dependencies.yaml'

* If the entry is an Array, the second value will be treated as the
  minimum version and the third as the maximum version
* If you specify your own limiters, it will put them in place verbatim
* Examples:
  * ['rpm-name', '1.2.3']
    * Requires rpm-name >= 1.2.3
  * ['rpm-name', '1.2.3', '2.0.0']
    * Requires rpm-name >= 1.2.3
    * Requires rpm-name < 2.0.0
  * ['rpm-name', '> 1.2.3', '<= 2.0.0']
    * Requires rpm-name > 1.2.3
    * Requires rpm-name <= 2.0.0
module_metadata

Hash containing the contents of the

module's 'metadata.json' file
ignores

Array of package names to ignore during processing



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/simp/rake/build/rpmdeps.rb', line 108

def self.generate_custom_rpm_requires(requires_list, , ignores=[])
   = []

  requires_list.each do |pkg_to_modify|
    pkg = pkg_to_modify
    min_version = nil
    max_version = nil

    pkg, min_version, max_version = pkg if pkg.is_a?(Array)

    next if ignores.include?(pkg)

    rpm_version_chars = ['<','>','=']

    if min_version && rpm_version_chars.none? { |x| min_version.include?(x) }
      min_version = ">= #{min_version}"
    end
    if max_version && rpm_version_chars.none? { |x| max_version.include?(x) }
      max_version = "< #{max_version}"
    end

    pkg_parts = pkg.split(%r(-|/))[-2..-1]

    # Need to cover all base cases
    short_names = [pkg_parts.join('/'), pkg_parts.join('-')]

    dep_info = ['dependencies'].select{ |dep|
      short_names.include?(dep['name'])
    }

    if dep_info.empty? && ['simp'] &&
      ['simp']['optional_dependencies']
      dep_info = ['simp']['optional_dependencies'].select{ |dep|
        short_names.include?(dep['name'])
      }
    end

    if dep_info.empty?
      err_msg = "Could not find '#{short_names.first}' dependency"
      raise SIMPRpmDepException.new(err_msg)
    else
      dep_version = dep_info.first['version_requirement']
    end

    # Use the version specified in the config file if it exists
    if min_version || max_version
       << "Requires: #{pkg} #{min_version}" if min_version
       << "Requires: #{pkg} #{max_version}" if max_version
    else
      begin
         << get_version_requires(pkg, dep_version)
      rescue SIMPRpmDepVersionException
        err_msg = "Unable to parse '#{short_names.first}' dependency" +
          " version '#{dep_version}'"
        raise SIMPRpmDepException.new(err_msg)
      end
    end
  end
  .flatten
end

.generate_external_rpm_requires(ext_deps_list, ignores = []) ⇒ Object

Generate ‘Requires’ lines from each dependency specified in the ext_deps_list array

returns array of strings, each of which is a ‘Requires’ line for use in an RPM spec file

ext_deps_list

Array of dependency Hashes. The key of each

 dependency Hash the name of the dependency package and its value
 is a Hash containing the version info.  For example,
[ 'package1' => { :min => '1.0.0' },
  'package2' => { :min => '3.1-1', :max => '4.0' } ]
ignores

Array of package names to ignore during processing



181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/simp/rake/build/rpmdeps.rb', line 181

def self.generate_external_rpm_requires(ext_deps_list, ignores=[])
  requires = []

  ext_deps_list.each do |pkg_name, options|
    next if ignores.include?(pkg_name)

    requires << "Requires: #{pkg_name} >= #{options[:min]}"
    if options[:max]
      requires << "Requires: #{pkg_name} < #{options[:max]}"
    end
  end

  requires
end

.generate_module_rpm_requires(module_metadata, ignores = []) ⇒ Object

Generate ‘Requires’ lines from each dependency specified in the module_metadata hash, including SIMP optional dependencies

returns array of strings, each of which is a ‘Requires’ line for use in an RPM spec file

raises SIMPRpmDepException if any ‘metadata.json’ dependency

version string from  cannot be parsed
module_metadata

Hash containing the contents of the

module's 'metadata.json' file
ignores

Array of package names to ignore during processing



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/simp/rake/build/rpmdeps.rb', line 208

def self.generate_module_rpm_requires(, ignores=[])
   = []

  deps = []
  if ['dependencies']
    deps += ['dependencies']
  end

  if ['simp'] &&
    ['simp']['optional_dependencies']

    deps += ['simp']['optional_dependencies']
  end

  deps.sort! { |x,y| x['name'] <=> y['name'] }
  deps.each do |dep|
    pkg = "pupmod-#{dep['name'].gsub('/', '-')}"

    next if ignores.include?(pkg)

    dep_version = dep['version_requirement']

    begin
       << get_version_requires(pkg, dep_version)
    rescue SIMPRpmDepVersionException
      err_msg = "Unable to parse '#{dep['name']}' dependency" +
        " version '#{dep_version}'"
      raise SIMPRpmDepException.new(err_msg)
    end
  end

  .flatten
end

.generate_rpm_meta_files(dir, rpm_metadata) ⇒ Object

Generate RPM metadata files

  • ‘build/rpm_metadata/requires’ file containing RPM dependency/obsoletes information from the ‘dependencies.yaml’ and the module’s ‘metadata.json’; always created

  • ‘build/rpm_metadata/release’ file containing RPM release qualifier from the ‘dependencies.yaml’; only created if release qualifier if specified in the ‘dependencies.yaml’

raises SIMPRpmDepException if any ‘metadata.json’ dependency

version string from module_metadata cannot be parsed or a
dependency specified in module_rpm_meta is not found in
module_metadata
dir

module root directory

rpm_metadata

contents of top-level ‘dependencies.yaml’ file



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/simp/rake/build/rpmdeps.rb', line 377

def self.generate_rpm_meta_files(dir, )
  require 'json'

   = File.join(dir, 'metadata.json')
   = JSON.parse(File.read())
  module_name = ['name'].split(%r(-|/)).last
  module_rpm_meta = [module_name]

  begin
    generate_rpm_requires_file(dir, , module_rpm_meta)
  rescue SIMPRpmDepException => e
    fail "#{e.message} in #{}"
  end

  generate_rpm_release_file(dir, module_rpm_meta)
end

.generate_rpm_release_file(dir, module_rpm_meta) ⇒ Object

Generate ‘build/rpm_metadata/release’ file containing release qualifier specified in the module_rpm_meta

dir

module root directory

module_rpm_meta

module entry from the top-level

'dependencies.yaml' file or nil, if no entry exists


347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/simp/rake/build/rpmdeps.rb', line 347

def self.generate_rpm_release_file(dir, module_rpm_meta)
 return unless (module_rpm_meta and module_rpm_meta[:release])

  rpm_release_file = File.join(dir, 'build', 'rpm_metadata', 'release')

  unless release_file_up_to_date?(module_rpm_meta[:release], rpm_release_file)
    FileUtils.mkdir_p(File.dirname(rpm_release_file))
    File.open(rpm_release_file, 'w') do |fh|
      fh.puts('# release set by simp-core dependencies.yaml')
      fh.puts(module_rpm_meta[:release])
      fh.flush
    end
  end
end

.generate_rpm_requires_file(dir, module_metadata, module_rpm_meta) ⇒ Object

Generate ‘build/rpm_metadata/requires’ file containing ‘Obsoletes’ and/or ‘Requires’ lines for use in an RPM spec file.

If the module_rpm_meta is not nil, the generated ‘requires’ file will contain

  • ‘Obsoletes’ lines for any obsoletes specified in the module_rpm_meta hash

  • ‘Requires’ lines for any requires specified in the module_rpm_meta hash, where the versions for those dependencies are pulled from module_metadata.

  • ‘Requires’ line(s) for any external dependencies specified in the module_rpm_meta hash.

  • Any items matching the name in an ‘ignores’ array will be removed from the dependency list.

    • This will be an exact match, globbing and regexes are not supported

    • Does not affect Obsoletes statements

Otherwise, the generated ‘requires’ file will contain “Requires” lines for each dependency and each SIMP optional dependency specified in module_metadata.

raises SIMPRpmDepException if any ‘metadata.json’ dependency

version string from module_metadata cannot be parsed or a
dependency specified in module_rpm_meta is not found in
module_metadata
dir

module root directory

module_metadata

Hash containing the contents of the

module's 'metadata.json' file
module_rpm_meta

module entry from the top-level

'dependencies.yaml' file or nil, if no entry exists


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/simp/rake/build/rpmdeps.rb', line 285

def self.generate_rpm_requires_file(dir, , module_rpm_meta)
   = []

  ignores = module_rpm_meta ? Array(module_rpm_meta[:ignores]) : []

  if module_rpm_meta and module_rpm_meta[:obsoletes]
     = generate_custom_rpm_obsoletes(
      module_rpm_meta[:obsoletes],
      
    )
  end

  if module_rpm_meta and module_rpm_meta[:requires]
     += generate_custom_rpm_requires(
      module_rpm_meta[:requires],
      ,
      ignores
    )
  else
     += generate_module_rpm_requires(, ignores)
  end

  if module_rpm_meta and module_rpm_meta[:external_dependencies]
     += generate_external_rpm_requires(
      module_rpm_meta[:external_dependencies],
      ignores
    )
  end

   = File.join(dir, 'build', 'rpm_metadata', 'requires')

  unless rpm_requires_up_to_date?(, )
    FileUtils.mkdir_p(File.dirname())
    File.open(, 'w') do |fh|
      fh.puts(.flatten.join("\n"))
      fh.flush
    end
  end
end

.get_version_requires(pkg, dep_version) ⇒ Object

returns array of RPM spec file ‘Requires’ lines derived from a ‘metadata.json’ dependency version specification.

pkg

dependency package name

dep_version

dependency version string from a ‘metadata.json’

raises SIMPRpmDepVersionException if the dependency version

string cannot be parsed


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/simp/rake/build/rpmdeps.rb', line 17

def self.get_version_requires(pkg, dep_version)
  return ["Requires: #{pkg}"] if dep_version.nil?
  return ["Requires: #{pkg} = #{$1}"] if dep_version =~ /^\s*(\d+\.\d+\.\d+)\s*$/

  requires = []

  if dep_version.include?('x')
    dep_parts = dep_version.split('.')

    if dep_parts.count == 3
      dep_version = ">= #{dep_parts[0]}.#{dep_parts[1]}.0 < #{dep_parts[0].to_i + 1}.0.0"
    else
      dep_version = ">= #{dep_parts[0]}.0.0 < #{dep_parts[0].to_i + 1}.0.0"
    end
  end

  # metadata.json is a LOT more forgiving than the RPM spec file
  if dep_version =~ /^\s*(?:(?:([<>]=?)\s*(\d+\.\d+\.\d+))\s*(?:(<)\s*(\d+\.\d+\.\d+))?)\s*$/
    requires << "Requires: #{pkg} #{$1} #{$2}"
    requires << "Requires: #{pkg} #{$3} #{$4}" if $3
  else
    raise SIMPRpmDepVersionException.new
  end

  requires
end

.release_file_up_to_date?(new_release_info, rpm_release_file) ⇒ Boolean

Check to see if the contents of the release file match the new release info

new_release_info

The new release metadata string

rpm_release_file

The path to the module release file

Returns:

  • (Boolean)


329
330
331
332
333
334
335
336
337
338
339
# File 'lib/simp/rake/build/rpmdeps.rb', line 329

def self.release_file_up_to_date?(new_release_info, rpm_release_file)
  return false unless File.exist?(rpm_release_file)

  # remove comments like "# release set by simp-core dependencies.yaml"
  release_file_content = File.readlines(rpm_release_file).reject{|x| x =~ /^ *#/}.join("\n").strip

  # sanitize numerics, etc.
  new_release_content = "#{new_release_info}".strip

  return release_file_content == new_release_content
end

.rpm_requires_up_to_date?(new_requires, rpm_requires_file) ⇒ Boolean

Check to see if the contents of the requires file match the new requires info

new_requires_info

The new requires metadata Array

rpm_requires_file

The path to the module requires file

Returns:

  • (Boolean)


246
247
248
249
250
251
252
# File 'lib/simp/rake/build/rpmdeps.rb', line 246

def self.rpm_requires_up_to_date?(new_requires, rpm_requires_file)
  return false unless File.exist?(rpm_requires_file)

  rpm_requires_content = File.read(rpm_requires_file).lines.map(&:strip) - ['']

  return (new_requires.flatten - rpm_requires_content).empty?
end