vanagon 0.7.1 → 0.8.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/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
|