vanagon 0.11.3 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '08bdc336ed173230734222c33f733c6c6e0998e9'
4
- data.tar.gz: 425755b48dc1ef81986dc1ed65ab12f1884aff55
3
+ metadata.gz: db5e799055a41530a8526f5b169598bd3d158f01
4
+ data.tar.gz: 541a9c6a444f670d0101b191cb6511108429d782
5
5
  SHA512:
6
- metadata.gz: 02b3231742bd7937b2f790de2600e9f52f6244b4c6d03f3f3d63f5ff0021b8e0ee09d9d7a27c32cb2842077a8fe65dbc80b1c87745782d13a9cc2deb0d30322d
7
- data.tar.gz: 9a268a0b5cfe23da58d0f47d9f4325efc9ed57c3c51130c12895a260cc15636aba58cdea6031fc43652282a3369e9f66e2cefb8302c75a55ead8fdc666f9badb
6
+ metadata.gz: 6782736f6b1733dab4b193dc3f1364591c41c5d5681e415f6f9b32d9fc6553ab59b18bce081ec90e7e960e2f65e50d0c7a2c3cd18bc9fd88907ad63fd1b09bd7
7
+ data.tar.gz: 622a7d7b4b5060eb1ccfc5ba0b5e4d9b5128e5a34b665868a090d312280d79bb546ba243a091efbeba3a4599abb6300275750f4c8807a49e6e0ce7e0d294797e
data/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  <!-- MarkdownTOC -->
5
5
 
6
6
  - [What is Vanagon?](#what-is-vanagon)
7
+ - [How is it pronounced?](#how-is-it-pronounced)
7
8
  - [Runtime Requirements](#runtime-requirements)
8
9
  - [Local Host:](#local-host)
9
10
  - [Remote Build Target:](#remote-build-target)
@@ -39,6 +40,10 @@ creates a master makefile for the project, and configures, builds, and installs
39
40
  all components. The result is an environment where you can work on individual
40
41
  components, then rebuild the project and test the installed artifacts.
41
42
 
43
+ ### How is it pronounced?
44
+
45
+ Vanagon (/ˈvænəgɪn/) sounds like "van again." It does not sound like "van wagon" or "van and gone."
46
+
42
47
  ## Runtime Requirements
43
48
 
44
49
  Vanagon carries two sets of requirements: requirements for the local host where Vanagon is run, and for the remote target where compilation and packaging happens.
data/bin/build CHANGED
@@ -11,7 +11,7 @@ targets = ARGV[2]
11
11
 
12
12
  if project.nil? or platforms.nil?
13
13
  warn "project and platform are both required arguments."
14
- puts optparse
14
+ $stderr.puts optparse
15
15
  exit 1
16
16
  end
17
17
 
@@ -11,11 +11,11 @@ platforms = ARGV[1]
11
11
 
12
12
  if project.nil? or platforms.nil?
13
13
  warn "project and platform are both required arguments."
14
- puts optparse
14
+ $stderr.puts optparse
15
15
  exit 1
16
16
  end
17
17
 
18
18
  platforms.split(',').each do |platform|
19
19
  driver = Vanagon::Driver.new(platform, project, options)
20
- puts JSON.generate(driver.build_host_info)
20
+ $stdout.puts JSON.generate(driver.build_host_info)
21
21
  end
data/bin/devkit CHANGED
@@ -11,7 +11,7 @@ components = ARGV.drop(2)
11
11
 
12
12
  if project.nil? or platform.nil?
13
13
  warn "project and platform are both required arguments."
14
- puts optparse
14
+ $stderr.puts optparse
15
15
  exit 1
16
16
  end
17
17
 
@@ -14,12 +14,12 @@ platforms = ARGV[1]
14
14
 
15
15
  unless project or platforms
16
16
  warn "project and platform are both required arguments."
17
- puts optparse
17
+ $stderr.puts optparse
18
18
  exit 1
19
19
  end
20
20
 
21
21
  platforms.split(',').each do |platform|
22
22
  driver = Vanagon::Driver.new(platform, project, options)
23
23
  components = driver.project.components.map(&:to_hash)
24
- puts JSON.pretty_generate(components)
24
+ $stdout.puts JSON.pretty_generate(components)
25
25
  end
data/bin/render CHANGED
@@ -13,7 +13,7 @@ targets = ARGV[2]
13
13
 
14
14
  if project.nil? or platforms.nil?
15
15
  warn "project and platform are both required arguments."
16
- puts optparse
16
+ $stderr.puts optparse
17
17
  exit 1
18
18
  end
19
19
 
@@ -1,6 +1,7 @@
1
- require 'vanagon/component/source'
2
1
  require 'vanagon/component/dsl'
3
2
  require 'vanagon/component/rules'
3
+ require 'vanagon/component/source'
4
+ require 'vanagon/component/source/rewrite'
4
5
 
5
6
  class Vanagon
6
7
  class Component
@@ -18,6 +19,7 @@ class Vanagon
18
19
  attr_accessor :sources
19
20
  attr_accessor :patches
20
21
  attr_accessor :url
22
+ attr_accessor :mirrors
21
23
  attr_accessor :license
22
24
 
23
25
  # holds an OpenStruct describing all of the particular details about
@@ -114,14 +116,13 @@ class Vanagon
114
116
  # @raise if the instance_eval on Component fails, the exception is reraised
115
117
  def self.load_component(name, configdir, settings, platform)
116
118
  compfile = File.join(configdir, "#{name}.rb")
117
- code = File.read(compfile)
118
119
  dsl = Vanagon::Component::DSL.new(name, settings, platform)
119
- dsl.instance_eval(code, __FILE__, __LINE__)
120
+ dsl.instance_eval(File.read(compfile), compfile, 1)
120
121
  dsl._component
121
122
  rescue => e
122
- puts "Error loading project '#{name}' using '#{compfile}':"
123
- puts e
124
- puts e.backtrace.join("\n")
123
+ $stderr.puts "Error loading project '#{name}' using '#{compfile}':"
124
+ $stderr.puts e
125
+ $stderr.puts e.backtrace.join("\n")
125
126
  raise e
126
127
  end
127
128
 
@@ -190,16 +191,74 @@ class Vanagon
190
191
  @files.select(&:configfile?)
191
192
  end
192
193
 
194
+ # @return [Set] a list of unique mirror URIs that should be used to
195
+ # retrieve the upstream source before attempting to retrieve from
196
+ # whatever URI was defined for #uri.
197
+ def mirrors
198
+ @mirrors ||= Set.new [deprecated_rewrite_url].compact
199
+ end
200
+
201
+ # Retrieve upstream source file from a mirror, by randomly iterating
202
+ # through #mirrors until there's no more mirrors left. Will #warn
203
+ # if the mirror's URI cannot be resolved or if the URI cannot
204
+ # be retrieved. Does not suppress any errors from
205
+ # Vanagon::Component::Source.
206
+ #
207
+ # @return [Boolean] return True if the source can be retrieved,
208
+ # or False otherwise. This is because because each subclass of
209
+ # Vanagon::Component::Source returns an inconsistent value
210
+ # if #fetch is successful.
211
+ def fetch_mirrors(options)
212
+ mirrors.to_a.shuffle.each do |mirror|
213
+ begin
214
+ $stderr.puts %(Attempting to fetch from mirror URL "#{mirror}")
215
+ @source = Vanagon::Component::Source.source(mirror, options)
216
+ return true if source.fetch
217
+ rescue SocketError
218
+ # SocketError means that there was no DNS/name resolution
219
+ # for whatever remote protocol the mirror tried to use.
220
+ warn %(Unable to resolve mirror URL "#{mirror}")
221
+ rescue RuntimeError
222
+ # Source retrieval does not consistently return a meaningful
223
+ # namespaced error message, which means we're brute-force rescuing
224
+ # RuntimeError. Not a good look, and we should fix this.
225
+ warn %(Unable to retrieve mirror URL "#{mirror}")
226
+ end
227
+ end
228
+ false
229
+ end
230
+
231
+ # Retrieve upstream source file from the canonical URL.
232
+ # Does not suppress any errors from Vanagon::Component::Source.
233
+ #
234
+ # @return [Boolean] return True if the source can be retrieved,
235
+ # or False otherwise
236
+ def fetch_url(options)
237
+ $stderr.puts %(Attempting to fetch from canonical URL "#{url}")
238
+ @source = Vanagon::Component::Source.source(url, options)
239
+ # Explicitly coerce the return value of #source.fetch,
240
+ # because each subclass of Vanagon::Component::Source returns
241
+ # an inconsistent value if #fetch is successful.
242
+ !!source.fetch
243
+ end
244
+
245
+ # This method is deprecated and private. It will return
246
+ # a rewritten URL if there's any value for #url.
247
+ def deprecated_rewrite_url
248
+ return nil unless url
249
+ Vanagon::Component::Source::Rewrite.parse_and_rewrite(url)
250
+ end
251
+ private :deprecated_rewrite_url
252
+
193
253
  # Fetches the primary source for the component. As a side effect, also sets
194
254
  # @extract_with, @dirname and @version for the component for use in the
195
255
  # makefile template
196
256
  #
197
257
  # @param workdir [String] working directory to put the source into
198
- def get_source(workdir) # rubocop:disable Metrics/AbcSize
258
+ def get_source(workdir) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
199
259
  opts = options.merge({ workdir: workdir })
200
- if url
201
- @source = Vanagon::Component::Source.source(url, opts)
202
- source.fetch
260
+ if url || !mirrors.empty?
261
+ fetch_mirrors(opts) || fetch_url(opts)
203
262
  source.verify
204
263
  extract_with << source.extract(platform.tar) if source.respond_to? :extract
205
264
 
@@ -276,11 +276,20 @@ class Vanagon
276
276
  @component.version = ver
277
277
  end
278
278
 
279
- # Sets the url for the source of this component
279
+ # Sets the canonical URL or URI for the upstream source of this component
280
280
  #
281
- # @param the_url [String] the url to the source for this component
282
- def url(the_url)
283
- @component.url = the_url
281
+ # @param uri [String, URI] a URL or URI describing a canonical location
282
+ # for a component's source code or artifact
283
+ def url(uri)
284
+ @component.url = uri.to_s
285
+ end
286
+
287
+ # Sets a mirror url for the source of this component
288
+ #
289
+ # @param url [String] a mirror url to use as the source for this component.
290
+ # Can be called more than once to add multiple mirror URLs.
291
+ def mirror(url)
292
+ @component.mirrors << url
284
293
  end
285
294
 
286
295
  def sum(value)
@@ -7,85 +7,26 @@ class Vanagon
7
7
  class Component
8
8
  class Source
9
9
  SUPPORTED_PROTOCOLS = %w[file http https git].freeze
10
- @rewrite_rules = {}
11
10
 
12
11
  class << self
13
- attr_reader :rewrite_rules
14
-
15
- def register_rewrite_rule(protocol, rule)
16
- if rule.is_a?(String) || rule.is_a?(Proc)
17
- if SUPPORTED_PROTOCOLS.include?(protocol)
18
- @rewrite_rules[protocol] = rule
19
- else
20
- raise Vanagon::Error, "#{protocol} is not a supported protocol for rewriting"
21
- end
22
- else
23
- raise Vanagon::Error, "String or Proc is required as a rewrite_rule."
24
- end
25
- end
26
-
27
- def rewrite(url, protocol)
28
- # Vanagon did not originally distinguish between http and https
29
- # when looking up rewrite rules; this is no longer true, but it
30
- # means that we should try to preserve old, dumb behavior until
31
- # the rewrite engine is removed.
32
- return rewrite(url, "http") if protocol == "https"
33
-
34
- rule = @rewrite_rules[protocol]
35
- if rule
36
- if rule.is_a?(Proc)
37
- return proc_rewrite(rule, url)
38
- elsif rule.is_a?(String)
39
- return string_rewrite(rule, url)
40
- end
41
- end
42
-
43
- return url
44
- end
45
-
46
- def proc_rewrite(rule, url)
47
- if rule.arity == 1
48
- rule.call(url)
49
- else
50
- raise Vanagon::Error, "Unable to use provided rewrite rule. Expected Proc with one argument, Proc has #{rule.arity} arguments"
51
- end
52
- end
53
-
54
- def string_rewrite(rule, original_url)
55
- url = original_url.to_s
56
- target_match = url.match(/.*\/([^\/]*)$/)
57
- if target_match
58
- target = target_match[1]
59
- return File.join(rule, target)
60
- else
61
- raise Vanagon::Error, "Unable to apply url rewrite to '#{url}', expected to find at least one '/' in the url."
62
- end
63
- end
64
-
65
- def parse_and_rewrite(uri)
66
- url = URI.parse(uri)
67
- return url unless url.scheme
68
- rewrite(url.to_s, url.scheme)
69
- end
70
-
71
12
  # Basic factory to hand back the correct {Vanagon::Component::Source} subtype to the component
72
13
  #
73
14
  # @param url [String] URI of the source file (includes git@... style links)
74
15
  # @param options [Hash] hash of the options needed for the subtype
75
16
  # @param workdir [String] working directory to fetch the source into
76
17
  # @return [Vanagon::Component::Source] the correct subtype for the given source
77
- def source(uri, **options) # rubocop:disable Metrics/AbcSize
18
+ def source(uri, **options)
78
19
  # First we try git
79
- if Vanagon::Component::Source::Git.valid_remote?(parse_and_rewrite(uri))
80
- return Vanagon::Component::Source::Git.new parse_and_rewrite(uri),
20
+ if Vanagon::Component::Source::Git.valid_remote?(uri)
21
+ return Vanagon::Component::Source::Git.new uri,
81
22
  sum: options[:sum],
82
23
  ref: options[:ref],
83
24
  workdir: options[:workdir]
84
25
  end
85
26
 
86
27
  # Then we try HTTP
87
- if Vanagon::Component::Source::Http.valid_url?(parse_and_rewrite(uri))
88
- return Vanagon::Component::Source::Http.new parse_and_rewrite(uri),
28
+ if Vanagon::Component::Source::Http.valid_url?(uri)
29
+ return Vanagon::Component::Source::Http.new uri,
89
30
  sum: options[:sum],
90
31
  workdir: options[:workdir],
91
32
  # Default sum_type is md5 if unspecified:
@@ -71,7 +71,7 @@ class Vanagon
71
71
  # There is no md5 to manually verify here, so this is a noop.
72
72
  def verify
73
73
  # nothing to do here, so just tell users that and return
74
- puts "Nothing to verify for '#{dirname}' (using Git reference '#{ref}')"
74
+ $stderr.puts "Nothing to verify for '#{dirname}' (using Git reference '#{ref}')"
75
75
  end
76
76
 
77
77
  # The dirname to reference when building from the repo
@@ -117,9 +117,9 @@ class Vanagon
117
117
  # Clone a remote repo, make noise about it, and fail entirely
118
118
  # if we're unable to retrieve the remote repo
119
119
  def clone!
120
- puts "Cloning Git repo '#{url}'"
121
- puts "Successfully cloned '#{dirname}'" if clone
122
- rescue Git::GitExecuteError
120
+ $stderr.puts "Cloning Git repo '#{url}'"
121
+ $stderr.puts "Successfully cloned '#{dirname}'" if clone
122
+ rescue ::Git::GitExecuteError
123
123
  raise Vanagon::InvalidRepo, "Unable to clone from '#{url}'"
124
124
  end
125
125
  private :clone!
@@ -127,7 +127,7 @@ class Vanagon
127
127
  # Checkout desired ref/sha, make noise about it, and fail
128
128
  # entirely if we're unable to checkout that given ref/sha
129
129
  def checkout!
130
- puts "Checking out '#{ref}'' from Git repo '#{dirname}'"
130
+ $stderr.puts "Checking out '#{ref}'' from Git repo '#{dirname}'"
131
131
  clone.checkout(ref)
132
132
  rescue ::Git::GitExecuteError
133
133
  raise Vanagon::CheckoutFailed, "unable to checkout #{ref} from '#{url}'"
@@ -137,7 +137,7 @@ class Vanagon
137
137
  # Attempt to update submodules, and do not panic
138
138
  # if there are no submodules to initialize
139
139
  def update_submodules
140
- puts "Attempting to update submodules for repo '#{dirname}'"
140
+ $stderr.puts "Attempting to update submodules for repo '#{dirname}'"
141
141
  clone.update_submodules(init: true)
142
142
  end
143
143
  private :update_submodules
@@ -78,7 +78,7 @@ class Vanagon
78
78
  #
79
79
  # @raise [RuntimeError] an exception is raised if the sum does not match the sum of the file
80
80
  def verify # rubocop:disable Metrics/AbcSize
81
- puts "Verifying file: #{file} against sum: '#{sum}'"
81
+ $stderr.puts "Verifying file: #{file} against sum: '#{sum}'"
82
82
  actual = get_sum(File.join(workdir, file), sum_type)
83
83
  return true if sum == actual
84
84
 
@@ -92,7 +92,7 @@ class Vanagon
92
92
  uri = URI.parse(target_url.to_s)
93
93
  target_file ||= File.basename(uri.path)
94
94
 
95
- puts "Downloading file '#{target_file}' from url '#{target_url}'"
95
+ $stderr.puts "Downloading file '#{target_file}' from url '#{target_url}'"
96
96
 
97
97
  Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
98
98
  http.request(Net::HTTP::Get.new(uri, headers)) do |response|
@@ -39,7 +39,6 @@ class Vanagon
39
39
  end
40
40
  end
41
41
 
42
-
43
42
  # Constructor for the File source type
44
43
  #
45
44
  # @param path [String] path of the local file to copy
@@ -58,7 +57,7 @@ class Vanagon
58
57
  #
59
58
  # @raise [RuntimeError, Vanagon::Error] an exception is raised if the URI scheme cannot be handled
60
59
  def copy
61
- puts "Copying file '#{url.basename}' to workdir"
60
+ $stderr.puts "Copying file '#{url.basename}' to workdir"
62
61
 
63
62
  FileUtils.cp_r(url, file)
64
63
  end
@@ -0,0 +1,85 @@
1
+ require 'vanagon/component/source'
2
+
3
+ class Vanagon
4
+ class Component
5
+ class Source
6
+ # This class has been extracted from Vanagon::Component::Source for the
7
+ # sake of isolation and in service of its pending removal. Rewrite rules
8
+ # should be considered deprecated. The removal will be carried out before
9
+ # Vanagon 1.0.0 is released.
10
+ class Rewrite
11
+ @rewrite_rules = {}
12
+
13
+ class << self
14
+ attr_reader :rewrite_rules
15
+
16
+ # @deprecated Please use the component DSL method #mirror(<URI>)
17
+ # instead. This method will be removed before Vanagon 1.0.0.
18
+ def register_rewrite_rule(protocol, rule)
19
+ warn <<-HERE.undent
20
+ rewrite rule support is deprecated and will be removed before Vanagon 1.0.0.
21
+ Rewritten URLs will be automatically converted into mirror URLs for now but
22
+ please use the component DSL method '#mirror url' to define new mirror URL
23
+ sources for a given component.
24
+ HERE
25
+ if rule.is_a?(String) || rule.is_a?(Proc)
26
+ if Vanagon::Component::Source::SUPPORTED_PROTOCOLS.include?(protocol)
27
+ @rewrite_rules[protocol] = rule
28
+ else
29
+ raise Vanagon::Error, "#{protocol} is not a supported protocol for rewriting"
30
+ end
31
+ else
32
+ raise Vanagon::Error, "String or Proc is required as a rewrite_rule."
33
+ end
34
+ end
35
+
36
+ def rewrite(url, protocol)
37
+ # Vanagon did not originally distinguish between http and https
38
+ # when looking up rewrite rules; this is no longer true, but it
39
+ # means that we should try to preserve old, dumb behavior until
40
+ # the rewrite engine is removed.
41
+ return rewrite(url, "http") if protocol == "https"
42
+
43
+ rule = @rewrite_rules[protocol]
44
+ if rule
45
+ if rule.is_a?(Proc)
46
+ return proc_rewrite(rule, url)
47
+ elsif rule.is_a?(String)
48
+ return string_rewrite(rule, url)
49
+ end
50
+ end
51
+
52
+ return url
53
+ end
54
+
55
+ def proc_rewrite(rule, url)
56
+ if rule.arity == 1
57
+ rule.call(url)
58
+ else
59
+ raise Vanagon::Error, "Unable to use provided rewrite rule. Expected Proc with one argument, Proc has #{rule.arity} arguments"
60
+ end
61
+ end
62
+
63
+ def string_rewrite(rule, original_url)
64
+ url = original_url.to_s
65
+ target_match = url.match(/.*\/([^\/]*)$/)
66
+ if target_match
67
+ target = target_match[1]
68
+ return File.join(rule, target)
69
+ else
70
+ raise Vanagon::Error, "Unable to apply url rewrite to '#{url}', expected to find at least one '/' in the url."
71
+ end
72
+ end
73
+
74
+ # @deprecated Please use the component DSL method #mirror(<URI>)
75
+ # instead. This method will be removed before Vanagon 1.0.0.
76
+ def parse_and_rewrite(uri)
77
+ url = URI.parse(uri)
78
+ return url unless url.scheme
79
+ rewrite(url.to_s, url.scheme)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end