packaging 0.88.77

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.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +17 -0
  3. data/README-Solaris.md +117 -0
  4. data/README.md +977 -0
  5. data/lib/packaging.rb +32 -0
  6. data/lib/packaging/archive.rb +126 -0
  7. data/lib/packaging/artifactory.rb +651 -0
  8. data/lib/packaging/artifactory/extensions.rb +94 -0
  9. data/lib/packaging/config.rb +492 -0
  10. data/lib/packaging/config/params.rb +387 -0
  11. data/lib/packaging/config/validations.rb +13 -0
  12. data/lib/packaging/deb.rb +28 -0
  13. data/lib/packaging/deb/repo.rb +264 -0
  14. data/lib/packaging/gem.rb +70 -0
  15. data/lib/packaging/metrics.rb +15 -0
  16. data/lib/packaging/nuget.rb +39 -0
  17. data/lib/packaging/paths.rb +376 -0
  18. data/lib/packaging/platforms.rb +507 -0
  19. data/lib/packaging/repo.rb +155 -0
  20. data/lib/packaging/retrieve.rb +75 -0
  21. data/lib/packaging/rpm.rb +5 -0
  22. data/lib/packaging/rpm/repo.rb +254 -0
  23. data/lib/packaging/sign.rb +8 -0
  24. data/lib/packaging/sign/deb.rb +9 -0
  25. data/lib/packaging/sign/dmg.rb +41 -0
  26. data/lib/packaging/sign/ips.rb +57 -0
  27. data/lib/packaging/sign/msi.rb +124 -0
  28. data/lib/packaging/sign/rpm.rb +115 -0
  29. data/lib/packaging/tar.rb +163 -0
  30. data/lib/packaging/util.rb +146 -0
  31. data/lib/packaging/util/date.rb +20 -0
  32. data/lib/packaging/util/execution.rb +85 -0
  33. data/lib/packaging/util/file.rb +125 -0
  34. data/lib/packaging/util/git.rb +174 -0
  35. data/lib/packaging/util/git_tags.rb +73 -0
  36. data/lib/packaging/util/gpg.rb +66 -0
  37. data/lib/packaging/util/jenkins.rb +95 -0
  38. data/lib/packaging/util/misc.rb +69 -0
  39. data/lib/packaging/util/net.rb +410 -0
  40. data/lib/packaging/util/os.rb +17 -0
  41. data/lib/packaging/util/platform.rb +40 -0
  42. data/lib/packaging/util/rake_utils.rb +112 -0
  43. data/lib/packaging/util/serialization.rb +19 -0
  44. data/lib/packaging/util/ship.rb +300 -0
  45. data/lib/packaging/util/tool.rb +41 -0
  46. data/lib/packaging/util/version.rb +334 -0
  47. data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
  48. data/spec/fixtures/config/ext/project_data.yaml +2 -0
  49. data/spec/fixtures/configs/components/test_file.json +1 -0
  50. data/spec/fixtures/configs/components/test_file_2.json +0 -0
  51. data/spec/fixtures/configs/components/test_file_not_tagged.json +1 -0
  52. data/spec/fixtures/configs/components/test_file_wrong_ext.txt +0 -0
  53. data/spec/fixtures/configs/components/test_file_wrong_ext.wrong +0 -0
  54. data/spec/fixtures/util/pre_tasks.yaml +4 -0
  55. data/spec/lib/packaging/artifactory_spec.rb +221 -0
  56. data/spec/lib/packaging/config_spec.rb +576 -0
  57. data/spec/lib/packaging/deb/repo_spec.rb +157 -0
  58. data/spec/lib/packaging/deb_spec.rb +52 -0
  59. data/spec/lib/packaging/gem_spec.rb +86 -0
  60. data/spec/lib/packaging/paths_spec.rb +418 -0
  61. data/spec/lib/packaging/platforms_spec.rb +178 -0
  62. data/spec/lib/packaging/repo_spec.rb +135 -0
  63. data/spec/lib/packaging/retrieve_spec.rb +100 -0
  64. data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
  65. data/spec/lib/packaging/sign_spec.rb +133 -0
  66. data/spec/lib/packaging/tar_spec.rb +116 -0
  67. data/spec/lib/packaging/util/execution_spec.rb +56 -0
  68. data/spec/lib/packaging/util/file_spec.rb +139 -0
  69. data/spec/lib/packaging/util/git_spec.rb +160 -0
  70. data/spec/lib/packaging/util/git_tag_spec.rb +36 -0
  71. data/spec/lib/packaging/util/gpg_spec.rb +64 -0
  72. data/spec/lib/packaging/util/jenkins_spec.rb +112 -0
  73. data/spec/lib/packaging/util/misc_spec.rb +31 -0
  74. data/spec/lib/packaging/util/net_spec.rb +259 -0
  75. data/spec/lib/packaging/util/os_spec.rb +31 -0
  76. data/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
  77. data/spec/lib/packaging/util/ship_spec.rb +199 -0
  78. data/spec/lib/packaging/util/version_spec.rb +123 -0
  79. data/spec/lib/packaging_spec.rb +19 -0
  80. data/spec/spec_helper.rb +22 -0
  81. data/static_artifacts/PackageInfo.plist +3 -0
  82. data/tasks/00_utils.rake +214 -0
  83. data/tasks/30_metrics.rake +33 -0
  84. data/tasks/apple.rake +268 -0
  85. data/tasks/archive.rake +69 -0
  86. data/tasks/build.rake +12 -0
  87. data/tasks/clean.rake +5 -0
  88. data/tasks/config.rake +35 -0
  89. data/tasks/deb.rake +129 -0
  90. data/tasks/deb_repos.rake +28 -0
  91. data/tasks/deprecated.rake +130 -0
  92. data/tasks/doc.rake +20 -0
  93. data/tasks/education.rake +57 -0
  94. data/tasks/fetch.rake +60 -0
  95. data/tasks/gem.rake +159 -0
  96. data/tasks/jenkins.rake +538 -0
  97. data/tasks/jenkins_dynamic.rake +202 -0
  98. data/tasks/load_extras.rake +21 -0
  99. data/tasks/mock.rake +348 -0
  100. data/tasks/nightly_repos.rake +286 -0
  101. data/tasks/pe_deb.rake +12 -0
  102. data/tasks/pe_rpm.rake +13 -0
  103. data/tasks/pe_ship.rake +226 -0
  104. data/tasks/pe_sign.rake +13 -0
  105. data/tasks/pe_tar.rake +5 -0
  106. data/tasks/retrieve.rake +52 -0
  107. data/tasks/rpm.rake +66 -0
  108. data/tasks/rpm_repos.rake +29 -0
  109. data/tasks/ship.rake +692 -0
  110. data/tasks/sign.rake +154 -0
  111. data/tasks/tag.rake +8 -0
  112. data/tasks/tar.rake +28 -0
  113. data/tasks/update.rake +16 -0
  114. data/tasks/vanagon.rake +35 -0
  115. data/tasks/vendor_gems.rake +117 -0
  116. data/tasks/version.rake +33 -0
  117. data/tasks/z_data_dump.rake +65 -0
  118. data/templates/README +1 -0
  119. data/templates/downstream.xml.erb +47 -0
  120. data/templates/msi.xml.erb +197 -0
  121. data/templates/packaging.xml.erb +346 -0
  122. data/templates/repo.xml.erb +117 -0
  123. metadata +287 -0
@@ -0,0 +1,94 @@
1
+ require 'artifactory'
2
+
3
+ module ArtifactoryExtensions
4
+ module ClassMethods
5
+ #
6
+ # Search for an artifact in a repo using an Ant-like pattern.
7
+ # Unlike many Artifactory searches, this one is restricted to a single
8
+ # repository.
9
+ #
10
+ # @example Search in a repository named 'foo_local' for an artifact in a directory containing
11
+ # the word "recent", named "artifact[0-9].txt"
12
+ # Artifact.pattern_search(pattern: '*recent*/artifact[0-9].txt',
13
+ # repo: 'foo_local')
14
+ #
15
+ # @param [Hash] options
16
+ # A hash of options, as follows:
17
+ #
18
+ # @option options [Artifactory::Client] :client
19
+ # the client object to make the request with
20
+ # @option options [String] :pattern
21
+ # the Ant-like pattern to use for finding artifacts within the repos. Note that the
22
+ # Ant pattern '**' is barred in this case by JFrog.
23
+ # @option options [String] :repo
24
+ # the repo to search
25
+ #
26
+ # @return [Array<Resource::Artifact>]
27
+ # a list of artifacts that match the query
28
+ #
29
+ def pattern_search(options = {})
30
+ client = extract_client!(options)
31
+ params = Artifactory::Util.slice(options, :pattern, :repo)
32
+ pattern_search_parameter = { :pattern => "#{params[:repo]}:#{params[:pattern]}" }
33
+ response = client.get('/api/search/pattern', pattern_search_parameter)
34
+ return [] if response['files'].nil? || response['files'].empty?
35
+
36
+ # A typical response:
37
+ # {
38
+ # "repoUri"=>"https:<artifactory endpoint>/<repo>",
39
+ # "sourcePattern"=>"<repo>:<provided search pattern>",
40
+ # "files"=>[<filename that matched pattern>, ...]
41
+ # }
42
+ #
43
+ # Inserting '/api/storage' before the repo makes the 'from_url' call work correctly.
44
+ #
45
+ repo_uri = response['repoUri']
46
+ unless repo_uri.include?('/api/storage/')
47
+ # rubocop:disable Style/PercentLiteralDelimiters
48
+ repo_uri.sub!(%r(/#{params[:repo]}$), "/api/storage/#{params[:repo]}")
49
+ end
50
+ response['files'].map do |file_path|
51
+ from_url("#{repo_uri}/#{file_path}", client: client)
52
+ end
53
+ end
54
+
55
+ # This adds the `exact_match` option to artifactory search, and defaults it
56
+ # to true. With `exact_match` set to `true` the artifact will only be
57
+ # returned if the name in the download uri matches the name we're trying to
58
+ # download
59
+ def search(options = {})
60
+ exact_match = options[:exact_match].nil? ? true : options[:exact_match]
61
+ artifacts = super
62
+
63
+ if exact_match
64
+ artifacts.select! { |artifact| File.basename(artifact.download_uri) == options[:name] }
65
+ end
66
+ artifacts
67
+ end
68
+
69
+ # This adds the `name` option to artifactory checksum search. It defaults to
70
+ # unset. If set, the artifact is only returned if the download uri matches
71
+ # the passed name
72
+ def checksum_search(options = {})
73
+ artifacts = super
74
+ if options[:name]
75
+ artifacts.select! { |artifact| File.basename(artifact.download_uri) == options[:name] }
76
+ end
77
+ artifacts
78
+ end
79
+ end
80
+
81
+ # needed to prepend class methods, see https://stackoverflow.com/questions/18683750/how-to-prepend-classmethods
82
+ def self.prepended(base)
83
+ class << base
84
+ prepend ClassMethods
85
+ end
86
+ end
87
+ end
88
+
89
+ module Artifactory
90
+ class Resource::Artifact
91
+ # use prepend instead of monkeypatching so we can call `super`
92
+ prepend ArtifactoryExtensions
93
+ end
94
+ end
@@ -0,0 +1,492 @@
1
+ module Pkg
2
+ ##
3
+ # This class is meant to encapsulate all of the data we know about a build invoked with
4
+ # `rake package:<build>` or `rake pl:<build>`. It can read in this data via a yaml file,
5
+ # have it set via accessors, and serialize it back to yaml for easy transport.
6
+ #
7
+ class Config
8
+ require 'packaging/config/params.rb'
9
+ require 'packaging/config/validations.rb'
10
+ require 'yaml'
11
+
12
+ class << self
13
+ ##
14
+ # Returns a hash with string keys that maps instance variable
15
+ # names without "@"" to their corresponding values.
16
+ #
17
+ def instance_values
18
+ Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
19
+ end
20
+
21
+ # Every element in Pkg::Params::BUILD_PARAMS is a configurable setting
22
+ # for the build. We use Pkg::Params::BUILD_PARAMS as the source of
23
+ # truth for defining the the class instance variables and their
24
+ # accessors of the Pkg::Config class
25
+ Pkg::Params::BUILD_PARAMS.each do |v|
26
+ attr_accessor v
27
+ end
28
+
29
+ # Return the binding of class context. Used for erb templates.
30
+ #
31
+ def get_binding
32
+ return binding
33
+ end
34
+
35
+ ##
36
+ # Take a hash of Config parameters, and iterate over them, setting the
37
+ # value for each Config param to the corresponding hash key,value.
38
+ #
39
+ def config_from_hash(data = {})
40
+ data.each do |param, value|
41
+ if Pkg::Params::BUILD_PARAMS.include?(param.to_sym)
42
+ self.instance_variable_set("@#{param}", value)
43
+ else
44
+ warn "Warning - No build data parameter found for '#{param}'. Perhaps you have an erroneous entry in your yaml file?"
45
+ end
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Load a yaml file and use its contents to set the values for Pkg::Config
51
+ # class instance variables
52
+ #
53
+ def config_from_yaml(file)
54
+ build_data = Pkg::Util::Serialization.load_yaml(file)
55
+ config_from_hash(build_data)
56
+ end
57
+
58
+ ##
59
+ # By default return a hash of the names, values of current Pkg::Config
60
+ # instance variables. With :format => :yaml, write a yaml file containing
61
+ # the current names,values of Pkg::Config class instance variables
62
+ #
63
+ def config(args = { :target => nil, :format => :hash })
64
+ case args[:format]
65
+ when :hash
66
+ self.config_to_hash
67
+ when :yaml
68
+ self.config_to_yaml(args[:target])
69
+ end
70
+ end
71
+
72
+ ##
73
+ # For each platform we ship for, find paths to its artifact and repo_config (if applicable).
74
+ # This is to be consumed by beaker and later replaced with our metadata service.
75
+ #
76
+ def platform_data
77
+ # Return nil if something is not right..
78
+ return nil unless self.project && self.ref &&
79
+ Pkg::Util::Net.check_host_ssh([self.builds_server]).empty?
80
+
81
+ dir = "/opt/jenkins-builds/#{self.project}/#{self.ref}"
82
+ cmd = "if [ -s \"#{dir}/artifacts\" ]; then cd #{dir};"\
83
+ "find ./artifacts/ -mindepth 2 -type f; fi"
84
+ artifacts, _ = Pkg::Util::Net.remote_execute(
85
+ self.builds_server,
86
+ cmd,
87
+ { capture_output: true }
88
+ )
89
+
90
+ artifacts = artifacts.split("\n")
91
+ data = {}
92
+ artifacts.each do |artifact|
93
+ # We need to preserve the original tag to make sure we look for
94
+ # fedora repo configs in the 1.10.x branch of puppet-agent in
95
+ # the correct place. For 5.x and 6.x release streams the f prefix
96
+ # has been removed and so tag will equal original_tag
97
+ original_tag = Pkg::Paths.tag_from_artifact_path(artifact)
98
+
99
+ # Remove the f-prefix from the fedora platform tag keys so that
100
+ # beaker can rely on consistent keys once we rip out the f for good
101
+ tag = original_tag.sub(/fedora-f/, 'fedora-')
102
+
103
+ data[tag] ||= {}
104
+
105
+ platform, version, arch = Pkg::Platforms.parse_platform_tag(tag)
106
+ package_format = Pkg::Platforms.get_attribute(tag, :package_format)
107
+
108
+ # Skip this if it's an unversioned MSI. We create these to help
109
+ # beaker install the msi without having to know any version
110
+ # information, but we should report the versioned artifact in
111
+ # platform_data
112
+ next if platform =~ /^windows.*$/ &&
113
+ File.basename(artifact) == "#{self.project}-#{arch}.#{package_format}"
114
+
115
+ # Sometimes we have source or debug packages. We don't want to save
116
+ # these paths in favor of the artifact paths.
117
+ if platform == 'solaris'
118
+ next if version == '10' && File.extname(artifact) != '.gz'
119
+ next if version == '11' && File.extname(artifact) != '.p5p'
120
+ else
121
+ next if File.extname(artifact) != ".#{package_format}"
122
+ end
123
+
124
+ # Don't want to include debian debug packages
125
+ next if /-dbgsym/.match(File.basename(artifact))
126
+
127
+ if /#{self.project}-[a-z]+/.match(File.basename(artifact))
128
+ add_additional_artifact(data, tag, artifact.sub('artifacts/', ''))
129
+ next
130
+ end
131
+
132
+ case package_format
133
+ when 'deb'
134
+ repo_config = "../repo_configs/deb/pl-#{self.project}-#{self.ref}-"\
135
+ "#{Pkg::Platforms.get_attribute(tag, :codename)}.list"
136
+ when 'rpm'
137
+ # Using original_tag here to not break legacy fedora repo targets
138
+ unless tag.include? 'aix'
139
+ repo_config = "../repo_configs/rpm/pl-#{self.project}-"\
140
+ "#{self.ref}-#{original_tag}.repo"
141
+ end
142
+ when 'swix', 'svr4', 'ips', 'dmg', 'msi'
143
+ # No repo_configs for these platforms, so do nothing.
144
+ else
145
+ fail "Error: Unknown package format: '#{package_format}'. Maybe update PLATFORM_INFO?"
146
+ end
147
+
148
+ # handle the case where there are multiple artifacts but the artifacts are not
149
+ # named based on project name (e.g. puppet-enterprise-vanagon).
150
+ # In this case, the first one will get set as the artifact, everything else
151
+ # will be in the additional artifacts
152
+ if data[tag][:artifact].nil?
153
+ data[tag][:artifact] = artifact.sub('artifacts/', '')
154
+ data[tag][:repo_config] = repo_config
155
+ else
156
+ add_additional_artifact(data, tag, artifact.sub('artifacts/', ''))
157
+ end
158
+ end
159
+ return data
160
+ end
161
+
162
+ # Add artifact to the `additional_artifacts` array in platform data.
163
+ # This will not add noarch package paths for the same noarch package
164
+ # multiple times.
165
+ #
166
+ # @param platform_data The platform data hash to update
167
+ # @param tag the platform tag
168
+ # @param artifact the path of the additional artifact path to add
169
+ def add_additional_artifact(platform_data, tag, artifact)
170
+ # Don't add noarch packages to additional_artifacts if the same package
171
+ # is already the artifact
172
+ if !platform_data[tag][:artifact].nil? && File.basename(platform_data[tag][:artifact]) == File.basename(artifact)
173
+ return
174
+ end
175
+
176
+ platform_data[tag][:additional_artifacts] ||= []
177
+
178
+ if platform_data[tag][:additional_artifacts].select { |a| File.basename(a) == File.basename(artifact) }.empty?
179
+ platform_data[tag][:additional_artifacts] << artifact
180
+ end
181
+
182
+ # try to avoid empty entries in the yaml for more concise output
183
+ if platform_data[tag][:additional_artifacts].empty?
184
+ platform_data[tag][:additional_artifacts] = nil
185
+ end
186
+ end
187
+
188
+ ##
189
+ # Return a hash of all build parameters and their values, nil if unassigned.
190
+ #
191
+ def config_to_hash
192
+ data = {}
193
+ Pkg::Params::BUILD_PARAMS.each do |param|
194
+ data.store(param, self.instance_variable_get("@#{param}"))
195
+ end
196
+ data.store(:platform_data, platform_data)
197
+ data
198
+ end
199
+
200
+ ##
201
+ # Write all build parameters to a yaml file, either one specified or in a
202
+ # temporary location. Print the path to the file and return it as a
203
+ # string. Accept an argument for the write target file. If not specified,
204
+ # the name of the params file is the current git commit sha or tag.
205
+ #
206
+ def config_to_yaml(target = nil)
207
+ file = "#{self.ref}.yaml"
208
+ target = target.nil? ? File.join(Pkg::Util::File.mktemp, "#{self.ref}.yaml") : File.join(target, file)
209
+ Pkg::Util::File.file_writable?(File.dirname(target), :required => true)
210
+ File.open(target, 'w') do |f|
211
+ f.puts self.config_to_hash.to_yaml
212
+ end
213
+ puts target
214
+ target
215
+ end
216
+
217
+ ##
218
+ # Print the names and values of all the params known to the build object
219
+ #
220
+ def print_config
221
+ self.config_to_hash.each { |k, v| puts "#{k}: #{v}" }
222
+ end
223
+
224
+ ##
225
+ # Return the names of all of the cows for the project, taking off the
226
+ # base prefix, the architecture, and the .cow suffix. This is helpful in
227
+ # the debian changelog.
228
+ #
229
+ def cow_list
230
+ self.cows.split(' ').map do
231
+ |cow| cow.split('-')[1]
232
+ end.uniq.join(' ')
233
+ end
234
+
235
+ def default_project_root
236
+ # Assume that either PROJECT_ROOT has been set, or we're running from the
237
+ # project root
238
+ #
239
+ ENV['PROJECT_ROOT'] || Dir.pwd
240
+ end
241
+
242
+ def default_packaging_root
243
+ # Assume that PACKAGING_ROOT has been set, or set the PACKAGING_ROOT to
244
+ # one directory above the LIBDIR
245
+ #
246
+ defined?(PACKAGING_ROOT) ? File.expand_path(PACKAGING_ROOT) : File.expand_path(File.join(LIBDIR, ".."))
247
+ end
248
+
249
+ def load_default_configs
250
+ got_config = false
251
+ default_project_data = { :path => File.join(@project_root, "ext", "project_data.yaml"), :required => false }
252
+ default_build_defaults = { :path => File.join(@project_root, "ext", "build_defaults.yaml"), :required => true }
253
+
254
+ [default_project_data, default_build_defaults].each do |config|
255
+ if File.readable? config[:path]
256
+ self.config_from_yaml(config[:path])
257
+ got_config = true if config[:required]
258
+ else
259
+ puts "Skipping load of expected default config #{config[:path]}, cannot read file."
260
+ end
261
+ end
262
+
263
+ if got_config
264
+ self.config
265
+ else
266
+ # Since the default configuration files are not readable, most
267
+ # likely not present, at this point we assume the project_root
268
+ # isn't what we hoped it would be, and unset it.
269
+ @project_root = nil
270
+ end
271
+ end
272
+
273
+ # Set all aspects of how the package will be versioned. Versioning
274
+ # relies exclusively on the git describe of the project, which will
275
+ # fail if either Pkg::Config.project_root is nil, isn't in a git repo,
276
+ # or is in a git repo, but there are no tags in the repo, in which case
277
+ # git-describe will fail.
278
+ #
279
+ # It probably seems odd to load packaging-specific version
280
+ # determinations, such as rpmversion here, at the top-level, and it is.
281
+ # The reason for this that the creation of the most basic package
282
+ # composition, the tarball, includes the generation of many different
283
+ # packaging-specific files from templates in the source, and if faced
284
+ # with loading rpmversion in the Tar object vs rpmversion in the
285
+ # Config, I opt for the latter. It's basically a lose-lose, since it
286
+ # really belongs in the Rpm object.
287
+
288
+ def load_versioning
289
+ if @project_root and Pkg::Util::Git.describe
290
+ @ref = Pkg::Util::Git.sha_or_tag
291
+ @short_ref = Pkg::Util::Git.sha_or_tag(7)
292
+ @version = Pkg::Util::Version.dash_version
293
+ @gemversion = Pkg::Util::Version.dot_version
294
+ @debversion = Pkg::Util::Version.debversion
295
+ @origversion = Pkg::Util::Version.origversion
296
+ @rpmversion = Pkg::Util::Version.rpmversion
297
+ @rpmrelease = Pkg::Util::Version.rpmrelease
298
+ else
299
+ puts "Skipping determination of version via git describe, Pkg::Config.project_root is not set to the path of a tagged git repo."
300
+ end
301
+ end
302
+
303
+ ##
304
+ # Since we're dealing with rake, much of the parameter override support
305
+ # is via environment variables passed on the command line to a rake task.
306
+ # These override any existing values of Pkg::Config class instance
307
+ # variables
308
+ #
309
+ def load_envvars
310
+ Pkg::Params::ENV_VARS.each do |v|
311
+ if var = ENV[v[:envvar].to_s]
312
+ case v[:type]
313
+ when :bool
314
+ self.instance_variable_set("@#{v[:var]}", Pkg::Util.boolean_value(var))
315
+ when :array
316
+ self.instance_variable_set("@#{v[:var]}", string_to_array(var))
317
+ else
318
+ self.instance_variable_set("@#{v[:var]}", var)
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ ##
325
+ # We supply several values by default, if they haven't been specified
326
+ # already by config or environment variable. This includes the project
327
+ # root as the default project root, which is relative to the
328
+ # packaging path
329
+ #
330
+ def load_defaults
331
+ @project_root ||= default_project_root
332
+ @packaging_root ||= default_packaging_root
333
+
334
+ Pkg::Params::DEFAULTS.each do |v|
335
+ unless self.instance_variable_get("@#{v[:var]}")
336
+ self.instance_variable_set("@#{v[:var]}", v[:val])
337
+ end
338
+ end
339
+ end
340
+
341
+ ##
342
+ #
343
+ # Several workflows rely on being able to supply an optional yaml
344
+ # parameters file that overrides all set values with its data. This has
345
+ # always been supplied as an environment variable, "PARAMS_FILE." To
346
+ # honor this, we have a method in config to override values as
347
+ # expected. There is, however, a twist - it is absolutely essential
348
+ # that the overrides do not override the project_root or packaging_root
349
+ # settings, because this is environment-specific, and any value in a
350
+ # params file is going to be wrong. Thus, if we have a project root or
351
+ # packaging root before we begin overriding, we save it and restore it
352
+ # after overrides.
353
+ #
354
+ def load_overrides
355
+ if ENV['PARAMS_FILE'] && ENV['PARAMS_FILE'] != ''
356
+ if File.readable?(ENV['PARAMS_FILE'])
357
+ project_root = self.instance_variable_get("@project_root")
358
+ packaging_root = self.instance_variable_get("@packaging_root")
359
+ self.config_from_yaml(ENV['PARAMS_FILE'])
360
+ self.instance_variable_set("@project_root", project_root) if project_root
361
+ self.instance_variable_set("@packaging_root", packaging_root) if packaging_root
362
+ else
363
+ fail "PARAMS_FILE was set, but not to the path to a readable file."
364
+ end
365
+ end
366
+ end
367
+
368
+ ##
369
+ # We also have renamed various variables as part of deprecations, and
370
+ # if any of these are still in use, we want to assign the values to the
371
+ # new variables. However, we skip this if they target variable is already
372
+ # populated, to avoid overwriting in the case that the user has started
373
+ # by populating the new variable name but left the old crufty one behind.
374
+ #
375
+ def issue_reassignments
376
+ Pkg::Params::REASSIGNMENTS.each do |v|
377
+ oldval = self.instance_variable_get("@#{v[:oldvar]}")
378
+ newval = self.instance_variable_get("@#{v[:newvar]}")
379
+ if newval.nil? && oldval
380
+ self.instance_variable_set("@#{v[:newvar]}", oldval)
381
+ end
382
+ end
383
+ end
384
+
385
+ ##
386
+ # Quite a few variables we also want to issue custom warnings about.
387
+ # These are they.
388
+ #
389
+ def issue_deprecations
390
+ Pkg::Params::DEPRECATIONS.each do |v|
391
+ if self.instance_variable_get("@#{v[:var]}")
392
+ warn v[:message]
393
+ end
394
+ end
395
+ end
396
+
397
+ ##
398
+ # Ask for validation of BUILD_PARAMS
399
+ #
400
+ # Issued as warnings initially but the intent is to turn this into
401
+ # a failure.
402
+ #
403
+ def perform_validations
404
+ error_count = 0
405
+ Pkg::Params::VALIDATIONS.each do |v|
406
+ variable_name = v[:var]
407
+ variable_value = self.instance_variable_get("@#{v[:var]}")
408
+ validations = v[:validations]
409
+ validations.each do |validation|
410
+ unless Pkg::ConfigValidations.send(validation, variable_value)
411
+ warn "Warning: variable \"#{variable_name}\" failed validation \"#{validation}\""
412
+ error_count += 1
413
+ end
414
+ end
415
+ end
416
+
417
+ if error_count != 0
418
+ warn "Warning: #{error_count} validation failure(s)."
419
+ end
420
+ end
421
+
422
+ def string_to_array(str)
423
+ delimiters = /[,\s;]/
424
+ return str if str.respond_to?('each')
425
+ str.split(delimiters).reject { |s| s.empty? }.map { |s| s.strip }
426
+ end
427
+
428
+ # This method is duplicated from enterprise-dist so we can access it here.
429
+ def cow_to_codename_arch(cow)
430
+ /^base-(.*)-(.*)\.cow$/.match(cow).captures
431
+ end
432
+
433
+ # This method is duplicated from enterprise-dist so we can access it here.
434
+ def mock_to_dist_version_arch(mock)
435
+ # We care about matching against two patterns here:
436
+ # pupent-3.4-el5-i386 <= old style with PE_VER baked into the mock name
437
+ # pupent-el5-i386 <= new style derived from a template
438
+ mock.match(/pupent(-\d\.\d)?-([a-z]*)(\d*)-([^-]*)/)[2..4]
439
+ end
440
+
441
+ def deb_build_targets
442
+ if self.vanagon_project
443
+ fail "ERROR: Could not find any deb targets. Try adding `deb_targets` to your build_defaults.yaml. If you don't want to build any debs, set this to an empty string." unless self.deb_targets
444
+ self.deb_targets.split(' ')
445
+ else
446
+ fail "ERROR: Could not find any deb targets. Try adding `cows` to your build_defaults.yaml. If you don't want to build any debs, set this to an empty string." unless self.cows
447
+ self.cows.split(' ').map do |cow|
448
+ codename, arch = self.cow_to_codename_arch(cow)
449
+ "#{codename}-#{arch}"
450
+ end
451
+ end
452
+ end
453
+
454
+ def rpm_build_targets
455
+ if self.vanagon_project
456
+ fail "ERROR: Could not find any rpm targets. Try adding `rpm_targets` to your build_defaults.yaml. If you don't want to build any rpms, set this to an empty string." unless self.rpm_targets
457
+ self.rpm_targets.split(' ')
458
+ else
459
+ fail "ERROR: Could not find any rpm targets. Try adding `final_mocks` to your build_defaults.yaml. If you don't want to build any rpms, set this to an empty string." unless self.final_mocks
460
+ self.final_mocks.split(' ').map do |mock|
461
+ platform, version, arch = self.mock_to_dist_version_arch(mock)
462
+ "#{platform}-#{version}-#{arch}"
463
+ end
464
+ end
465
+ end
466
+
467
+ def yum_target_path(feature_branch = false)
468
+ target_path = "#{Pkg::Config.yum_repo_path}/#{Pkg::Config.pe_version}"
469
+ # Target path is different for feature (PEZ) or release branches
470
+ if feature_branch || Pkg::Config.pe_feature_branch
471
+ return "#{target_path}/feature/repos/"
472
+ elsif Pkg::Config.pe_release_branch
473
+ return "#{target_path}/release/repos/"
474
+ else
475
+ return "#{target_path}/repos/"
476
+ end
477
+ end
478
+
479
+ def apt_target_path(feature_branch = false)
480
+ target_path = "#{Pkg::Config.apt_repo_path}/#{Pkg::Config.pe_version}"
481
+ # Target path is different for feature (PEZ) or release branches
482
+ if feature_branch || Pkg::Config.pe_feature_branch
483
+ return "#{target_path}/feature/repos/"
484
+ elsif Pkg::Config.pe_release_branch
485
+ return "#{target_path}/release/repos/"
486
+ else
487
+ return "#{target_path}/repos/"
488
+ end
489
+ end
490
+ end
491
+ end
492
+ end