vanagon 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/git/basic_submodules.rb +53 -0
- data/lib/vanagon/component.rb +19 -13
- data/lib/vanagon/component/dsl.rb +6 -5
- data/lib/vanagon/component/source.rb +80 -53
- data/lib/vanagon/component/source/git.rb +129 -20
- data/lib/vanagon/component/source/http.rb +41 -73
- data/lib/vanagon/component/source/local.rb +105 -62
- data/lib/vanagon/platform/deb.rb +8 -0
- data/lib/vanagon/platform/rpm.rb +4 -0
- data/lib/vanagon/project/dsl.rb +3 -1
- data/lib/vanagon/utilities.rb +11 -54
- data/spec/fixtures/files/fake_file_ext.7z +0 -0
- data/spec/fixtures/files/fake_file_ext.bz +0 -0
- data/spec/fixtures/files/fake_file_ext.bz2 +0 -0
- data/spec/fixtures/files/fake_file_ext.cpio +0 -0
- data/spec/fixtures/files/fake_file_ext.gz +0 -0
- data/spec/fixtures/files/fake_file_ext.rar +0 -0
- data/spec/fixtures/files/fake_file_ext.tar +0 -0
- data/spec/fixtures/files/fake_file_ext.tar.bz2 +0 -0
- data/spec/fixtures/files/fake_file_ext.tar.xz +0 -0
- data/spec/fixtures/files/fake_file_ext.tbz +0 -0
- data/spec/fixtures/files/fake_file_ext.tbz2 +0 -0
- data/spec/fixtures/files/fake_file_ext.txz +0 -0
- data/spec/fixtures/files/fake_file_ext.xz +0 -0
- data/spec/fixtures/files/fake_file_ext.z +0 -0
- data/spec/lib/vanagon/component/source/git_spec.rb +25 -17
- data/spec/lib/vanagon/component/source/http_spec.rb +2 -24
- data/spec/lib/vanagon/component/source/{localsource_spec.rb → local_spec.rb} +8 -8
- data/spec/lib/vanagon/component/source_spec.rb +150 -67
- data/spec/lib/vanagon/platform_spec.rb +40 -21
- data/spec/lib/vanagon/project/dsl_spec.rb +28 -3
- data/spec/lib/vanagon/utilities_spec.rb +0 -44
- metadata +28 -13
@@ -1,16 +1,41 @@
|
|
1
1
|
require 'vanagon/utilities'
|
2
|
+
require 'vanagon/component/source/local'
|
2
3
|
require 'net/http'
|
3
4
|
require 'uri'
|
4
5
|
|
5
6
|
class Vanagon
|
6
7
|
class Component
|
7
8
|
class Source
|
8
|
-
class Http
|
9
|
+
class Http < Vanagon::Component::Source::Local
|
9
10
|
include Vanagon::Utilities
|
10
|
-
attr_accessor :url, :sum, :file, :extension, :workdir, :cleanup
|
11
11
|
|
12
|
-
#
|
13
|
-
|
12
|
+
# Accessors :url, :file, :extension, :workdir, :cleanup are inherited from Local
|
13
|
+
attr_accessor :sum
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def valid_url?(target_url) # rubocop:disable Metrics/AbcSize
|
17
|
+
uri = URI.parse(target_url.to_s)
|
18
|
+
return false unless ['http', 'https'].include? uri.scheme
|
19
|
+
|
20
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
21
|
+
http.request(Net::HTTP::Head.new(uri)) do |response|
|
22
|
+
case response
|
23
|
+
when Net::HTTPRedirection
|
24
|
+
# By parsing the location header, we get either an absolute
|
25
|
+
# URI or a URI with a relative `path`. Adding it to `uri`
|
26
|
+
# should correctly update the relative `path` or overwrite
|
27
|
+
# the entire URI if it's absolute.
|
28
|
+
location = URI.parse(response.header['location'])
|
29
|
+
valid_url?(uri + location)
|
30
|
+
when Net::HTTPSuccess
|
31
|
+
return true
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
14
39
|
|
15
40
|
# Constructor for the Http source type
|
16
41
|
#
|
@@ -18,7 +43,7 @@ class Vanagon
|
|
18
43
|
# @param sum [String] sum to verify the download against
|
19
44
|
# @param workdir [String] working directory to download into
|
20
45
|
# @raise [RuntimeError] an exception is raised is sum is nil
|
21
|
-
def initialize(url, sum
|
46
|
+
def initialize(url, sum:, workdir:, **options)
|
22
47
|
unless sum
|
23
48
|
fail "sum is required to validate the http source"
|
24
49
|
end
|
@@ -31,31 +56,34 @@ class Vanagon
|
|
31
56
|
# file as @file and the @extension for the file as a side effect.
|
32
57
|
def fetch
|
33
58
|
@file = download(@url)
|
34
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
def file
|
62
|
+
@file ||= fetch
|
35
63
|
end
|
36
64
|
|
37
65
|
# Verify the downloaded file matches the provided sum
|
38
66
|
#
|
39
67
|
# @raise [RuntimeError] an exception is raised if the sum does not match the sum of the file
|
40
68
|
def verify
|
41
|
-
puts "Verifying file: #{
|
42
|
-
actual = get_md5sum(File.join(
|
43
|
-
|
44
|
-
|
45
|
-
|
69
|
+
puts "Verifying file: #{file} against sum: '#{sum}'"
|
70
|
+
actual = get_md5sum(File.join(workdir, file))
|
71
|
+
return true if sum == actual
|
72
|
+
|
73
|
+
fail "Unable to verify '#{File.join(workdir, file)}': md5sum mismatch (expected '#{sum}', got '#{actual}'')"
|
46
74
|
end
|
47
75
|
|
48
76
|
# Downloads the file from @url into the @workdir
|
49
77
|
# @param target_url [String, URI, Addressable::URI] url of an http source to retrieve with GET
|
50
78
|
# @raise [RuntimeError, Vanagon::Error] an exception is raised if the URI scheme cannot be handled
|
51
|
-
def download(target_url, target_file = nil) # rubocop:disable Metrics/AbcSize
|
79
|
+
def download(target_url, target_file = nil, headers = { "Accept-Encoding" => "identity" }) # rubocop:disable Metrics/AbcSize
|
52
80
|
uri = URI.parse(target_url.to_s)
|
53
81
|
target_file ||= File.basename(uri.path)
|
54
82
|
|
55
83
|
puts "Downloading file '#{target_file}' from url '#{target_url}'"
|
56
84
|
|
57
85
|
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
58
|
-
http.request(Net::HTTP::Get.new(uri)) do |response|
|
86
|
+
http.request(Net::HTTP::Get.new(uri, headers)) do |response|
|
59
87
|
case response
|
60
88
|
when Net::HTTPRedirection
|
61
89
|
# By parsing the location header, we get either an absolute
|
@@ -81,66 +109,6 @@ class Vanagon
|
|
81
109
|
Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
82
110
|
raise Vanagon::Error.wrap(e, "Problem downloading #{target_file} from '#{@url}'. Please verify you have the correct uri specified.")
|
83
111
|
end
|
84
|
-
|
85
|
-
# Gets the command to extract the archive given if needed (uses @extension)
|
86
|
-
#
|
87
|
-
# @param tar [String] the tar command to use
|
88
|
-
# @return [String, nil] command to extract the source
|
89
|
-
# @raise [RuntimeError] an exception is raised if there is no known extraction method for @extension
|
90
|
-
def extract(tar)
|
91
|
-
if ARCHIVE_EXTENSIONS.include?(@extension)
|
92
|
-
case @extension
|
93
|
-
when ".tar.gz", ".tgz"
|
94
|
-
return "gunzip -c '#{@file}' | '#{tar}' xf -"
|
95
|
-
when ".zip"
|
96
|
-
return "unzip '#{@file}' || 7za x -r -tzip -o'#{File.basename(@file, '.zip')}' '#{@file}'"
|
97
|
-
end
|
98
|
-
else
|
99
|
-
# Extension does not appear to be an archive
|
100
|
-
return ':'
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Return the correct incantation to cleanup the source archive and source directory for a given source
|
105
|
-
#
|
106
|
-
# @return [String] command to cleanup the source
|
107
|
-
# @raise [RuntimeError] an exception is raised if there is no known extraction method for @extension
|
108
|
-
def cleanup
|
109
|
-
if ARCHIVE_EXTENSIONS.include?(@extension)
|
110
|
-
return "rm #{@file}; rm -r #{dirname}"
|
111
|
-
else
|
112
|
-
# Because dirname will be ./ here, we don't want to try to nuke it
|
113
|
-
return "rm #{@file}"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# Returns the extension for @file
|
118
|
-
#
|
119
|
-
# @return [String] the extension of @file
|
120
|
-
def get_extension
|
121
|
-
extension_match = @file.match(/.*(#{Regexp.union(ARCHIVE_EXTENSIONS)})/)
|
122
|
-
unless extension_match
|
123
|
-
if @file.split('.').last.include?('.')
|
124
|
-
return '.' + @file.split('.').last
|
125
|
-
else
|
126
|
-
# This is the case where the file has no extension
|
127
|
-
return @file
|
128
|
-
end
|
129
|
-
end
|
130
|
-
extension_match[1]
|
131
|
-
end
|
132
|
-
|
133
|
-
# The dirname to reference when building from the source
|
134
|
-
#
|
135
|
-
# @return [String] the directory that should be traversed into to build this source
|
136
|
-
# @raise [RuntimeError] if the @extension for the @file isn't currently handled by the method
|
137
|
-
def dirname
|
138
|
-
if ARCHIVE_EXTENSIONS.include?(@extension)
|
139
|
-
return @file.chomp(@extension)
|
140
|
-
else
|
141
|
-
return './'
|
142
|
-
end
|
143
|
-
end
|
144
112
|
end
|
145
113
|
end
|
146
114
|
end
|
@@ -1,31 +1,52 @@
|
|
1
1
|
require 'vanagon/utilities'
|
2
|
-
require 'net/http'
|
3
|
-
require 'uri'
|
4
2
|
|
5
3
|
class Vanagon
|
6
4
|
class Component
|
7
5
|
class Source
|
8
6
|
class Local
|
9
|
-
include Vanagon::Utilities
|
10
7
|
attr_accessor :url, :file, :extension, :workdir, :cleanup
|
11
8
|
|
12
9
|
# Extensions for files we intend to unpack during the build
|
13
|
-
ARCHIVE_EXTENSIONS =
|
10
|
+
ARCHIVE_EXTENSIONS = {
|
11
|
+
"7z" => %w(.7z),
|
12
|
+
"bzip2" => %w(.bz2 .bz),
|
13
|
+
"cpio" => %w(.cpio),
|
14
|
+
"gzip" => %w(.gz .z),
|
15
|
+
"rar" => %w(.rar),
|
16
|
+
"tar" => %w(.tar),
|
17
|
+
"tbz2" => %w(.tar.bz2 .tbz2 .tbz),
|
18
|
+
"tgz" => %w(.tar.gz .tgz),
|
19
|
+
"txz" => %w(.tar.xz .txz),
|
20
|
+
"xz" => %w(.xz),
|
21
|
+
"zip" => %w(.zip),
|
22
|
+
}.freeze
|
14
23
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
class << self
|
25
|
+
def valid_file?(target_file)
|
26
|
+
File.exist?(mangle(target_file.to_s))
|
27
|
+
end
|
28
|
+
|
29
|
+
# If a scheme is specified as "file://", this will return
|
30
|
+
# strip off the scheme and delimiters -- we need to do this because
|
31
|
+
# once upon a time we allowed specifying files with no strong
|
32
|
+
# specifications for where they should be located.
|
33
|
+
def mangle(path)
|
34
|
+
path.gsub(%r{^file://}, '')
|
35
|
+
end
|
36
|
+
|
37
|
+
def archive_extensions
|
38
|
+
ARCHIVE_EXTENSIONS.values.flatten
|
39
|
+
end
|
22
40
|
end
|
23
41
|
|
24
|
-
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
42
|
+
|
43
|
+
# Constructor for the File source type
|
44
|
+
#
|
45
|
+
# @param path [String] path of the local file to copy
|
46
|
+
# @param workdir [String] working directory to copy <path> to
|
47
|
+
def initialize(path, workdir:, **options)
|
48
|
+
@url = ::Pathname.new(mangle(path))
|
49
|
+
@workdir = ::Pathname.new(workdir)
|
29
50
|
end
|
30
51
|
|
31
52
|
# Local files need no checksum so this is a noop
|
@@ -36,21 +57,19 @@ class Vanagon
|
|
36
57
|
# Moves file from source to workdir
|
37
58
|
#
|
38
59
|
# @raise [RuntimeError, Vanagon::Error] an exception is raised if the URI scheme cannot be handled
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
else
|
50
|
-
raise Vanagon::Error, "Unable to parse '#{@url}' for local file path."
|
51
|
-
end
|
60
|
+
def copy
|
61
|
+
puts "Copying file '#{url.basename}' to workdir"
|
62
|
+
|
63
|
+
FileUtils.cp(url, file)
|
64
|
+
end
|
65
|
+
alias_method :fetch, :copy
|
66
|
+
|
67
|
+
def file
|
68
|
+
@file ||= workdir + File.basename(url)
|
69
|
+
end
|
52
70
|
|
53
|
-
|
71
|
+
def extension
|
72
|
+
@extension ||= extname
|
54
73
|
end
|
55
74
|
|
56
75
|
# Gets the command to extract the archive given if needed (uses @extension)
|
@@ -58,17 +77,40 @@ class Vanagon
|
|
58
77
|
# @param tar [String] the tar command to use
|
59
78
|
# @return [String, nil] command to extract the source
|
60
79
|
# @raise [RuntimeError] an exception is raised if there is no known extraction method for @extension
|
61
|
-
def extract(tar)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
def extract(tar = "tar") # rubocop:disable Metrics/AbcSize
|
81
|
+
# Extension does not appear to be an archive, so "extract" is a no-op
|
82
|
+
return ':' unless archive_extensions.include?(extension)
|
83
|
+
|
84
|
+
case decompressor
|
85
|
+
when "7z"
|
86
|
+
%(7z x "#{file}")
|
87
|
+
when "bzip2"
|
88
|
+
%(bunzip2 "#{file}")
|
89
|
+
when "cpio"
|
90
|
+
%(
|
91
|
+
mkdir "#{file.basename}" &&
|
92
|
+
pushd "#{file.basename}" 2>&1 > /dev/null &&
|
93
|
+
cpio -idv < "#{file}" &&
|
94
|
+
popd 2>&1 > /dev/null
|
95
|
+
).undent
|
96
|
+
when "gzip"
|
97
|
+
%(gunzip "#{file}")
|
98
|
+
when "rar"
|
99
|
+
%(unrar x "#{file}")
|
100
|
+
when "tar"
|
101
|
+
%(#{tar} xf "#{file}")
|
102
|
+
when "tbz2"
|
103
|
+
%(bunzip2 -c "#{file}" | #{tar} xf -)
|
104
|
+
when "tgz"
|
105
|
+
%(gunzip -c "#{file}" | #{tar} xf -)
|
106
|
+
when "txz"
|
107
|
+
%(unxz -d "#{file}" | #{tar} xvf -)
|
108
|
+
when "xz"
|
109
|
+
%(unxz "#{file}")
|
110
|
+
when "zip"
|
111
|
+
"unzip '#{file}' || 7za x -r -tzip -o'#{File.basename(file, '.zip')}' '#{file}'"
|
69
112
|
else
|
70
|
-
|
71
|
-
return ':'
|
113
|
+
raise Vanagon::Error, "Don't know how to decompress #{extension} archives"
|
72
114
|
end
|
73
115
|
end
|
74
116
|
|
@@ -77,28 +119,28 @@ class Vanagon
|
|
77
119
|
# @return [String] command to cleanup the source
|
78
120
|
# @raise [RuntimeError] an exception is raised if there is no known extraction method for @extension
|
79
121
|
def cleanup
|
80
|
-
|
81
|
-
return "rm #{@file}; rm -r #{dirname}"
|
82
|
-
else
|
83
|
-
# Because dirname will be ./ here, we don't want to try to nuke it
|
84
|
-
return "rm #{@file}"
|
85
|
-
end
|
122
|
+
archive? ? "rm #{file}; rm -r #{dirname}" : "rm #{file}"
|
86
123
|
end
|
87
124
|
|
88
125
|
# Returns the extension for @file
|
89
126
|
#
|
90
127
|
# @return [String] the extension of @file
|
91
|
-
def
|
92
|
-
extension_match =
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
128
|
+
def extname
|
129
|
+
extension_match = file.to_s.match %r{#{Regexp.union(archive_extensions)}\Z}
|
130
|
+
return extension_match.to_s if extension_match
|
131
|
+
File.extname(file)
|
132
|
+
end
|
133
|
+
|
134
|
+
def archive_extensions
|
135
|
+
self.class.archive_extensions
|
136
|
+
end
|
137
|
+
|
138
|
+
def archive?
|
139
|
+
archive_extensions.include?(extension)
|
140
|
+
end
|
141
|
+
|
142
|
+
def decompressor
|
143
|
+
@decompressor ||= ARCHIVE_EXTENSIONS.select { |k, v| v.include? extension }.keys.first
|
102
144
|
end
|
103
145
|
|
104
146
|
# The dirname to reference when building from the source
|
@@ -106,11 +148,12 @@ class Vanagon
|
|
106
148
|
# @return [String] the directory that should be traversed into to build this source
|
107
149
|
# @raise [RuntimeError] if the @extension for the @file isn't currently handled by the method
|
108
150
|
def dirname
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
151
|
+
archive? ? File.basename(file, extension) : './'
|
152
|
+
end
|
153
|
+
|
154
|
+
# Wrapper around the class method '.mangle'
|
155
|
+
def mangle(path)
|
156
|
+
self.class.mangle(path)
|
114
157
|
end
|
115
158
|
end
|
116
159
|
end
|
data/lib/vanagon/platform/deb.rb
CHANGED
@@ -47,6 +47,14 @@ class Vanagon
|
|
47
47
|
"#{project.name}_#{project.version}-#{project.release}#{@codename}_#{project.noarch ? 'all' : @architecture}.deb"
|
48
48
|
end
|
49
49
|
|
50
|
+
# Get the expected output dir for the debian packages. This allows us to
|
51
|
+
# use some standard tools to ship internally.
|
52
|
+
#
|
53
|
+
# @return [String] relative path to where debian packages should be staged
|
54
|
+
def output_dir(target_repo = "")
|
55
|
+
@output_dir ||= File.join("deb", @codename, target_repo)
|
56
|
+
end
|
57
|
+
|
50
58
|
# Returns the string to add a target repo to the platforms' provisioning
|
51
59
|
#
|
52
60
|
# @param definition [URI] A URI to a deb or list file
|
data/lib/vanagon/platform/rpm.rb
CHANGED
@@ -36,6 +36,10 @@ class Vanagon
|
|
36
36
|
"#{project.name}-#{project.version}-#{project.release}.#{project.noarch ? 'noarch' : @architecture}.rpm"
|
37
37
|
end
|
38
38
|
|
39
|
+
def output_dir(target_repo = "products")
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
39
43
|
def rpm_defines
|
40
44
|
defines = %(--define '_topdir $(tempdir)/rpmbuild' )
|
41
45
|
# RPM doesn't allow dashes in the os_name. This was added to
|
data/lib/vanagon/project/dsl.rb
CHANGED
@@ -144,8 +144,10 @@ class Vanagon
|
|
144
144
|
# and reachable from the current commit in that repository.
|
145
145
|
#
|
146
146
|
def version_from_git
|
147
|
-
version =
|
147
|
+
version = Git.open(File.expand_path("..", Vanagon::Driver.configdir)).describe('HEAD', tags: true)
|
148
148
|
@project.version = version.split('-').reject(&:empty?).join('.')
|
149
|
+
rescue Git::GitExecuteError
|
150
|
+
warn "Directory '#{dirname}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
|
149
151
|
end
|
150
152
|
|
151
153
|
# Sets the vendor for the project. Used in packaging artifacts.
|
data/lib/vanagon/utilities.rb
CHANGED
@@ -5,10 +5,15 @@ require 'json'
|
|
5
5
|
require 'digest'
|
6
6
|
require 'erb'
|
7
7
|
require 'timeout'
|
8
|
+
# This stupid library requires a capital 'E' in its name
|
9
|
+
# but it provides a wealth of useful constants
|
10
|
+
require 'English'
|
8
11
|
require 'vanagon/extensions/string'
|
9
12
|
|
10
13
|
class Vanagon
|
11
14
|
module Utilities
|
15
|
+
extend self
|
16
|
+
|
12
17
|
# Utility to get the md5 sum of a file
|
13
18
|
#
|
14
19
|
# @param file [String] file to md5sum
|
@@ -93,7 +98,7 @@ class Vanagon
|
|
93
98
|
# @raise [Vanagon::Error] If the command fails an exception is raised
|
94
99
|
def ex(command)
|
95
100
|
ret = %x(#{command})
|
96
|
-
unless
|
101
|
+
unless $CHILD_STATUS.success?
|
97
102
|
raise Vanagon::Error, "'#{command}' did not succeed"
|
98
103
|
end
|
99
104
|
ret
|
@@ -119,6 +124,7 @@ class Vanagon
|
|
119
124
|
return false
|
120
125
|
end
|
121
126
|
end
|
127
|
+
alias_method :which, :find_program_on_path
|
122
128
|
|
123
129
|
# Method to retry a ruby block and fail if the command does not succeed
|
124
130
|
# within the number of tries and timeout.
|
@@ -148,55 +154,6 @@ class Vanagon
|
|
148
154
|
raise Vanagon::Error, "Block failed maximum number of #{tries} tries"
|
149
155
|
end
|
150
156
|
|
151
|
-
# Simple wrapper around git command line executes the given commands and
|
152
|
-
# returns the results.
|
153
|
-
#
|
154
|
-
# @param command_string [String] The commands to be run
|
155
|
-
# @param raise_error [boolean] if this function should raise an error
|
156
|
-
# on a git failure
|
157
|
-
# @return [String] The output of the command
|
158
|
-
def git(command_string, raise_error = false)
|
159
|
-
git_bin = find_program_on_path('git')
|
160
|
-
output = %x(#{git_bin} #{command_string})
|
161
|
-
if raise_error
|
162
|
-
unless $?.success?
|
163
|
-
raise %(git #{command_string} failed)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
return output
|
167
|
-
end
|
168
|
-
|
169
|
-
# Determines if the given directory is a git repo or not
|
170
|
-
#
|
171
|
-
# @param directory [String] The directory to check
|
172
|
-
# @return [true, false] True if the directory is a git repo, false otherwise
|
173
|
-
def is_git_repo?(directory = Dir.pwd)
|
174
|
-
Dir.chdir(directory) do
|
175
|
-
git('rev-parse --git-dir > /dev/null 2>&1')
|
176
|
-
$?.success?
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# Determines a version for the given directory based on the git describe
|
181
|
-
# for the repository
|
182
|
-
#
|
183
|
-
# @param directory [String] The directory to use in versioning
|
184
|
-
# @return [String] The version of the directory accoring to git describe
|
185
|
-
# @raise [RuntimeError] If the given directory is not a git repo
|
186
|
-
def git_version(directory = Dir.pwd)
|
187
|
-
if is_git_repo?(directory)
|
188
|
-
Dir.chdir(directory) do
|
189
|
-
version = git('describe --tags 2> /dev/null').chomp
|
190
|
-
if version.empty?
|
191
|
-
warn "Directory '#{directory}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
|
192
|
-
end
|
193
|
-
return version
|
194
|
-
end
|
195
|
-
else
|
196
|
-
fail "Directory '#{directory}' is not a git repo, cannot get a version"
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
157
|
# Sends the desired file/directory to the destination using rsync
|
201
158
|
#
|
202
159
|
# @param source [String] file or directory to send
|
@@ -258,14 +215,14 @@ class Vanagon
|
|
258
215
|
puts "Executing '#{command}' on '#{target}'"
|
259
216
|
if return_command_output
|
260
217
|
ret = %x(#{ssh_command(port)} -T #{target} '#{command.gsub("'", "'\\\\''")}').chomp
|
261
|
-
if
|
218
|
+
if $CHILD_STATUS.success?
|
262
219
|
return ret
|
263
220
|
else
|
264
221
|
raise "Remote ssh command (#{command}) failed on '#{target}'."
|
265
222
|
end
|
266
223
|
else
|
267
224
|
Kernel.system("#{ssh_command(port)} -T #{target} '#{command.gsub("'", "'\\\\''")}'")
|
268
|
-
|
225
|
+
$CHILD_STATUS.success? or raise "Remote ssh command (#{command}) failed on '#{target}'."
|
269
226
|
end
|
270
227
|
end
|
271
228
|
|
@@ -281,14 +238,14 @@ class Vanagon
|
|
281
238
|
puts "Executing '#{command}' locally"
|
282
239
|
if return_command_output
|
283
240
|
ret = %x(#{command}).chomp
|
284
|
-
if
|
241
|
+
if $CHILD_STATUS.success?
|
285
242
|
return ret
|
286
243
|
else
|
287
244
|
raise "Local command (#{command}) failed."
|
288
245
|
end
|
289
246
|
else
|
290
247
|
Kernel.system(command)
|
291
|
-
|
248
|
+
$CHILD_STATUS.success? or raise "Local command (#{command}) failed."
|
292
249
|
end
|
293
250
|
end
|
294
251
|
end
|