packaging 0.88.77
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +17 -0
- data/README-Solaris.md +117 -0
- data/README.md +977 -0
- data/lib/packaging.rb +32 -0
- data/lib/packaging/archive.rb +126 -0
- data/lib/packaging/artifactory.rb +651 -0
- data/lib/packaging/artifactory/extensions.rb +94 -0
- data/lib/packaging/config.rb +492 -0
- data/lib/packaging/config/params.rb +387 -0
- data/lib/packaging/config/validations.rb +13 -0
- data/lib/packaging/deb.rb +28 -0
- data/lib/packaging/deb/repo.rb +264 -0
- data/lib/packaging/gem.rb +70 -0
- data/lib/packaging/metrics.rb +15 -0
- data/lib/packaging/nuget.rb +39 -0
- data/lib/packaging/paths.rb +376 -0
- data/lib/packaging/platforms.rb +507 -0
- data/lib/packaging/repo.rb +155 -0
- data/lib/packaging/retrieve.rb +75 -0
- data/lib/packaging/rpm.rb +5 -0
- data/lib/packaging/rpm/repo.rb +254 -0
- data/lib/packaging/sign.rb +8 -0
- data/lib/packaging/sign/deb.rb +9 -0
- data/lib/packaging/sign/dmg.rb +41 -0
- data/lib/packaging/sign/ips.rb +57 -0
- data/lib/packaging/sign/msi.rb +124 -0
- data/lib/packaging/sign/rpm.rb +115 -0
- data/lib/packaging/tar.rb +163 -0
- data/lib/packaging/util.rb +146 -0
- data/lib/packaging/util/date.rb +20 -0
- data/lib/packaging/util/execution.rb +85 -0
- data/lib/packaging/util/file.rb +125 -0
- data/lib/packaging/util/git.rb +174 -0
- data/lib/packaging/util/git_tags.rb +73 -0
- data/lib/packaging/util/gpg.rb +66 -0
- data/lib/packaging/util/jenkins.rb +95 -0
- data/lib/packaging/util/misc.rb +69 -0
- data/lib/packaging/util/net.rb +410 -0
- data/lib/packaging/util/os.rb +17 -0
- data/lib/packaging/util/platform.rb +40 -0
- data/lib/packaging/util/rake_utils.rb +112 -0
- data/lib/packaging/util/serialization.rb +19 -0
- data/lib/packaging/util/ship.rb +300 -0
- data/lib/packaging/util/tool.rb +41 -0
- data/lib/packaging/util/version.rb +334 -0
- data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
- data/spec/fixtures/config/ext/project_data.yaml +2 -0
- data/spec/fixtures/configs/components/test_file.json +1 -0
- data/spec/fixtures/configs/components/test_file_2.json +0 -0
- data/spec/fixtures/configs/components/test_file_not_tagged.json +1 -0
- data/spec/fixtures/configs/components/test_file_wrong_ext.txt +0 -0
- data/spec/fixtures/configs/components/test_file_wrong_ext.wrong +0 -0
- data/spec/fixtures/util/pre_tasks.yaml +4 -0
- data/spec/lib/packaging/artifactory_spec.rb +221 -0
- data/spec/lib/packaging/config_spec.rb +576 -0
- data/spec/lib/packaging/deb/repo_spec.rb +157 -0
- data/spec/lib/packaging/deb_spec.rb +52 -0
- data/spec/lib/packaging/gem_spec.rb +86 -0
- data/spec/lib/packaging/paths_spec.rb +418 -0
- data/spec/lib/packaging/platforms_spec.rb +178 -0
- data/spec/lib/packaging/repo_spec.rb +135 -0
- data/spec/lib/packaging/retrieve_spec.rb +100 -0
- data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
- data/spec/lib/packaging/sign_spec.rb +133 -0
- data/spec/lib/packaging/tar_spec.rb +116 -0
- data/spec/lib/packaging/util/execution_spec.rb +56 -0
- data/spec/lib/packaging/util/file_spec.rb +139 -0
- data/spec/lib/packaging/util/git_spec.rb +160 -0
- data/spec/lib/packaging/util/git_tag_spec.rb +36 -0
- data/spec/lib/packaging/util/gpg_spec.rb +64 -0
- data/spec/lib/packaging/util/jenkins_spec.rb +112 -0
- data/spec/lib/packaging/util/misc_spec.rb +31 -0
- data/spec/lib/packaging/util/net_spec.rb +259 -0
- data/spec/lib/packaging/util/os_spec.rb +31 -0
- data/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
- data/spec/lib/packaging/util/ship_spec.rb +199 -0
- data/spec/lib/packaging/util/version_spec.rb +123 -0
- data/spec/lib/packaging_spec.rb +19 -0
- data/spec/spec_helper.rb +22 -0
- data/static_artifacts/PackageInfo.plist +3 -0
- data/tasks/00_utils.rake +214 -0
- data/tasks/30_metrics.rake +33 -0
- data/tasks/apple.rake +268 -0
- data/tasks/archive.rake +69 -0
- data/tasks/build.rake +12 -0
- data/tasks/clean.rake +5 -0
- data/tasks/config.rake +35 -0
- data/tasks/deb.rake +129 -0
- data/tasks/deb_repos.rake +28 -0
- data/tasks/deprecated.rake +130 -0
- data/tasks/doc.rake +20 -0
- data/tasks/education.rake +57 -0
- data/tasks/fetch.rake +60 -0
- data/tasks/gem.rake +159 -0
- data/tasks/jenkins.rake +538 -0
- data/tasks/jenkins_dynamic.rake +202 -0
- data/tasks/load_extras.rake +21 -0
- data/tasks/mock.rake +348 -0
- data/tasks/nightly_repos.rake +286 -0
- data/tasks/pe_deb.rake +12 -0
- data/tasks/pe_rpm.rake +13 -0
- data/tasks/pe_ship.rake +226 -0
- data/tasks/pe_sign.rake +13 -0
- data/tasks/pe_tar.rake +5 -0
- data/tasks/retrieve.rake +52 -0
- data/tasks/rpm.rake +66 -0
- data/tasks/rpm_repos.rake +29 -0
- data/tasks/ship.rake +692 -0
- data/tasks/sign.rake +154 -0
- data/tasks/tag.rake +8 -0
- data/tasks/tar.rake +28 -0
- data/tasks/update.rake +16 -0
- data/tasks/vanagon.rake +35 -0
- data/tasks/vendor_gems.rake +117 -0
- data/tasks/version.rake +33 -0
- data/tasks/z_data_dump.rake +65 -0
- data/templates/README +1 -0
- data/templates/downstream.xml.erb +47 -0
- data/templates/msi.xml.erb +197 -0
- data/templates/packaging.xml.erb +346 -0
- data/templates/repo.xml.erb +117 -0
- metadata +287 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
# Utility methods used by the various rake tasks
|
2
|
+
module Pkg::Util
|
3
|
+
require 'erb'
|
4
|
+
require 'benchmark'
|
5
|
+
require 'base64'
|
6
|
+
require 'io/console'
|
7
|
+
require 'packaging/util/date'
|
8
|
+
require 'packaging/util/execution'
|
9
|
+
require 'packaging/util/file'
|
10
|
+
require 'packaging/util/git'
|
11
|
+
require 'packaging/util/gpg'
|
12
|
+
require 'packaging/util/jenkins'
|
13
|
+
require 'packaging/util/misc'
|
14
|
+
require 'packaging/util/net'
|
15
|
+
require 'packaging/util/os'
|
16
|
+
require 'packaging/util/platform'
|
17
|
+
require 'packaging/util/serialization'
|
18
|
+
require 'packaging/util/ship'
|
19
|
+
require 'packaging/util/tool'
|
20
|
+
require 'packaging/util/rake_utils'
|
21
|
+
require 'packaging/util/version'
|
22
|
+
require 'packaging/util/git_tags'
|
23
|
+
|
24
|
+
def self.boolean_value(var)
|
25
|
+
return true if var == true || ( var.is_a?(String) && ( var.downcase == 'true' || var.downcase =~ /^y$|^yes$/))
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.in_project_root(&blk)
|
30
|
+
result = nil
|
31
|
+
fail "Cannot execute in project root if Pkg::Config.project_root is not set" unless Pkg::Config.project_root
|
32
|
+
|
33
|
+
Dir.chdir Pkg::Config.project_root do
|
34
|
+
result = blk.call
|
35
|
+
end
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
# Utility to get the contents of an Environment variable
|
40
|
+
#
|
41
|
+
# @param var [String] The name of the environment variable to return
|
42
|
+
# @return [String, Boolean, Hash, Array, nil] The contents of ENV[var]
|
43
|
+
def self.get_var(var)
|
44
|
+
self.check_var(var, ENV[var])
|
45
|
+
ENV[var]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Utility to check if a variable is set
|
49
|
+
#
|
50
|
+
# @param varname [String] the name of the variable to be checked
|
51
|
+
# @param var [String, Boolean, Hash, Array, nil] the contents of the variable to be checked
|
52
|
+
# @return [String, Boolean, Hash, Array, nil] the contents of var
|
53
|
+
# @raise [RuntimeError] raises an exception if the variable is not set and is required
|
54
|
+
def self.check_var(varname, var)
|
55
|
+
fail "Requires #{varname} be set!" if var.nil?
|
56
|
+
var
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.require_library_or_fail(library, library_name = nil)
|
60
|
+
library_name ||= library
|
61
|
+
begin
|
62
|
+
require library
|
63
|
+
rescue LoadError
|
64
|
+
fail "Could not load #{library_name}. #{library_name} is required by the packaging repo for this task"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.base64_encode(string)
|
69
|
+
Base64.encode64(string).strip
|
70
|
+
end
|
71
|
+
|
72
|
+
# Utility to retrieve command line input
|
73
|
+
# @param noecho [Boolean, nil] if we are retrieving command line input with or without privacy. This is mainly
|
74
|
+
# for sensitive information like passwords.
|
75
|
+
def self.get_input(echo = true)
|
76
|
+
fail "Cannot get input on a noninteractive terminal" unless $stdin.tty?
|
77
|
+
|
78
|
+
system 'stty -echo' unless echo
|
79
|
+
$stdin.gets.chomp!
|
80
|
+
ensure
|
81
|
+
system 'stty echo'
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.rand_string
|
85
|
+
rand.to_s.split('.')[1]
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.ask_yes_or_no(force = false)
|
89
|
+
unless force
|
90
|
+
return Pkg::Util.boolean_value(Pkg::Config.answer_override) unless Pkg::Config.answer_override.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
answer = Pkg::Util.get_input
|
94
|
+
return true if answer =~ /^y$|^yes$/
|
95
|
+
return false if answer =~ /^n$|^no$/
|
96
|
+
puts "Nope, try something like yes or no or y or n, etc:"
|
97
|
+
Pkg::Util.ask_yes_or_no
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.confirm_ship(files)
|
101
|
+
$stdout.puts "Artifacts will be shipped to the following hosts:"
|
102
|
+
Pkg::Util.filter_configs('host').each { |key, value| puts "#{key}: #{value}" }
|
103
|
+
$stdout.puts "Does this look right?? [y,n]"
|
104
|
+
Pkg::Util.ask_yes_or_no(true)
|
105
|
+
$stdout.puts "The following files have been built and are ready to ship:"
|
106
|
+
files.each { |file| puts "\t#{file}\n" unless File.directory?(file) }
|
107
|
+
$stdout.puts "Ship these files?? [y,n]"
|
108
|
+
Pkg::Util.ask_yes_or_no(true)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.filter_configs(filter = nil)
|
112
|
+
return Pkg::Config.instance_values.select { |key, _| key.match(/#{filter}/) } if filter
|
113
|
+
Pkg::Config.instance_values
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
# Construct a probably-correct (or correct-enough) URI for
|
118
|
+
# tools like ssh or rsync. Currently lacking support for intuitive
|
119
|
+
# joins, ports, protocols, fragments, or 75% of what Addressable::URI
|
120
|
+
# or URI would provide out of the box. The "win" here is that
|
121
|
+
# the returned String should "just work".
|
122
|
+
# @private pseudo_uri
|
123
|
+
# @return [String, nil] a string representing either a hostname:/path pair,
|
124
|
+
# a hostname without a path, or a path without a hostname. Returns nil
|
125
|
+
# if it is unable to construct a useful URI-like string.
|
126
|
+
# @param [Hash] opts fragments used to build the pseudo URI
|
127
|
+
# @option opts [String] :path URI-ish path component
|
128
|
+
# @option opts [String] :host URI-ish host component
|
129
|
+
def self.pseudo_uri(opts = {})
|
130
|
+
options = { path: nil, host: nil }.merge(opts)
|
131
|
+
|
132
|
+
# Prune empty values to determine what is returned
|
133
|
+
options.delete_if { |_, v| v.to_s.empty? }
|
134
|
+
return nil if options.empty?
|
135
|
+
|
136
|
+
[options[:host], options[:path]].compact.join(':')
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.deprecate(old_cmd, new_cmd = nil)
|
140
|
+
msg = "!! #{old_cmd} is deprecated."
|
141
|
+
if new_cmd
|
142
|
+
msg << " Please use #{new_cmd} instead."
|
143
|
+
end
|
144
|
+
$stdout.puts("\n#{msg}\n")
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Utilities for managing/querying date/time
|
2
|
+
|
3
|
+
module Pkg::Util::Date
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def timestamp(separator = nil)
|
7
|
+
if s = separator
|
8
|
+
format = "%Y#{s}%m#{s}%d#{s}%H#{s}%M#{s}%S"
|
9
|
+
else
|
10
|
+
format = "%Y-%m-%d %H:%M:%S"
|
11
|
+
end
|
12
|
+
Time.now.strftime(format)
|
13
|
+
end
|
14
|
+
|
15
|
+
def today
|
16
|
+
format = "%m/%d/%Y"
|
17
|
+
Time.now.strftime(format)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Utility methods for handling system calls and interactions
|
2
|
+
|
3
|
+
module Pkg::Util::Execution
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Alias to $?.success? that makes success? slightly easier to test and stub
|
8
|
+
# If immediately run, $? will not be instanciated, so only call success? if
|
9
|
+
# $? exists, otherwise return nil
|
10
|
+
def success?(statusobject = $?)
|
11
|
+
return statusobject.success?
|
12
|
+
end
|
13
|
+
|
14
|
+
# ex combines the behavior of `%x{cmd}` and rake's `sh "cmd"`. `%x{cmd}` has
|
15
|
+
# the benefit of returning the standard out of an executed command, enabling us
|
16
|
+
# to query the file system, e.g. `contents = %x{ls}`. The drawback to `%x{cmd}`
|
17
|
+
# is that on failure of a command (something returned non-zero) the return of
|
18
|
+
# `%x{cmd}` is just an empty string. As such, we can't know if we succeeded.
|
19
|
+
# Rake's `sh "cmd"`, on the other hand, will raise a RuntimeError if a command
|
20
|
+
# does not return 0, but doesn't return any of the stdout from the command -
|
21
|
+
# only true or false depending on its success or failure. With `ex(cmd)` we
|
22
|
+
# purport to both return the results of the command execution (ala `%x{cmd}`)
|
23
|
+
# while also raising an exception if a command does not succeed (ala `sh "cmd"`).
|
24
|
+
def ex(command, debug = false)
|
25
|
+
puts "Executing '#{command}'..." if debug
|
26
|
+
ret = `#{command}`
|
27
|
+
unless Pkg::Util::Execution.success?
|
28
|
+
raise RuntimeError
|
29
|
+
end
|
30
|
+
|
31
|
+
if debug
|
32
|
+
puts "Command '#{command}' returned:"
|
33
|
+
puts ret
|
34
|
+
end
|
35
|
+
|
36
|
+
ret
|
37
|
+
end
|
38
|
+
|
39
|
+
# Turns out trying to change ex to use Open3 is SUPER DANGEROUS and destructive
|
40
|
+
# in ways I hadn't imagined. I'm going to add a new method here instead and start
|
41
|
+
# converting code to use that so I don't break more than I plan to.
|
42
|
+
def capture3(command, debug = false)
|
43
|
+
require 'open3'
|
44
|
+
puts "Executing '#{command}'..." if debug
|
45
|
+
stdout, stderr, ret = Open3.capture3(command)
|
46
|
+
unless Pkg::Util::Execution.success?(ret)
|
47
|
+
raise "#{stdout}#{stderr}"
|
48
|
+
end
|
49
|
+
|
50
|
+
if debug
|
51
|
+
puts "Command '#{command}' returned:"
|
52
|
+
puts stdout
|
53
|
+
end
|
54
|
+
|
55
|
+
return stdout, stderr, ret
|
56
|
+
end
|
57
|
+
|
58
|
+
# Loop a block up to the number of attempts given, exiting when we receive success
|
59
|
+
# or max attempts is reached. Raise an exception unless we've succeeded.
|
60
|
+
def retry_on_fail(args, &blk)
|
61
|
+
success = false
|
62
|
+
exception = ''
|
63
|
+
|
64
|
+
if args[:times].respond_to?(:times) and block_given?
|
65
|
+
args[:times].times do |i|
|
66
|
+
if args[:delay]
|
67
|
+
sleep args[:delay]
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
blk.call
|
72
|
+
success = true
|
73
|
+
break
|
74
|
+
rescue => err
|
75
|
+
puts "An error was encountered evaluating block. Retrying.."
|
76
|
+
exception = err.to_s + "\n" + err.backtrace.join("\n")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
fail "retry_on_fail requires and arg (:times => x) where x is an Integer/Fixnum, and a block to execute"
|
81
|
+
end
|
82
|
+
fail "Block failed maximum of #{args[:times]} tries. Exiting..\nLast failure was: #{exception}" unless success
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# Utility methods for handling files and directories
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Pkg::Util::File
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def exist?(file)
|
8
|
+
::File.exist?(file)
|
9
|
+
end
|
10
|
+
alias_method :exists?, :exist?
|
11
|
+
|
12
|
+
def directory?(file)
|
13
|
+
::File.directory?(file)
|
14
|
+
end
|
15
|
+
|
16
|
+
def mktemp
|
17
|
+
mktemp = Pkg::Util::Tool.find_tool('mktemp', :required => true)
|
18
|
+
stdout, _, _ = Pkg::Util::Execution.capture3("#{mktemp} -d -t pkgXXXXXX")
|
19
|
+
stdout.strip
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty_dir?(dir)
|
23
|
+
File.exist?(dir) and File.directory?(dir) and Dir["#{dir}/**/*"].empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an array of all the directories at the top level of #{dir}
|
27
|
+
#
|
28
|
+
def directories(dir)
|
29
|
+
if File.directory?(dir)
|
30
|
+
Dir.chdir(dir) do
|
31
|
+
Dir.glob("*").select { |entry| File.directory?(entry) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array of all files with #{ext} inside #{dir}
|
37
|
+
def files_with_ext(dir, ext)
|
38
|
+
Dir.glob("#{dir}/**/*#{ext}")
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def file_exists?(file, args = { :required => false })
|
43
|
+
exists = File.exist? file
|
44
|
+
if !exists and args[:required]
|
45
|
+
fail "Required file #{file} could not be found"
|
46
|
+
end
|
47
|
+
exists
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_writable?(file, args = { :required => false })
|
51
|
+
writable = File.writable? file
|
52
|
+
if !writable and args[:required]
|
53
|
+
fail "File #{file} is not writable"
|
54
|
+
end
|
55
|
+
writable
|
56
|
+
end
|
57
|
+
|
58
|
+
alias :get_temp :mktemp
|
59
|
+
|
60
|
+
def erb_string(erbfile, b = binding)
|
61
|
+
template = File.read(erbfile)
|
62
|
+
message = ERB.new(template, nil, "-")
|
63
|
+
message.result(b)
|
64
|
+
end
|
65
|
+
|
66
|
+
def erb_file(erbfile, outfile = nil, remove_orig = false, opts = { :binding => binding })
|
67
|
+
outfile ||= File.join(mktemp, File.basename(erbfile).sub(File.extname(erbfile), ""))
|
68
|
+
output = erb_string(erbfile, opts[:binding])
|
69
|
+
File.open(outfile, 'w') { |f| f.write output }
|
70
|
+
puts "Generated: #{outfile}"
|
71
|
+
FileUtils.rm_rf erbfile if remove_orig
|
72
|
+
outfile
|
73
|
+
end
|
74
|
+
|
75
|
+
def untar_into(source, target = nil, options = "")
|
76
|
+
tar = Pkg::Util::Tool.find_tool('tar', :required => true)
|
77
|
+
# We only accept a writable directory as a target
|
78
|
+
if target and !target.empty? and file_writable?(target) and File.directory?(target)
|
79
|
+
target_opts = "-C #{target}"
|
80
|
+
end
|
81
|
+
if file_exists?(source, :required => true)
|
82
|
+
stdout, _, _ = Pkg::Util::Execution.capture3(%Q(#{tar} #{options} #{target_opts} -xf #{source}))
|
83
|
+
stdout
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def install_files_into_dir(file_patterns, workdir)
|
88
|
+
install = []
|
89
|
+
# We need to add our list of file patterns from the configuration; this
|
90
|
+
# used to be a list of "things to copy recursively", which would install
|
91
|
+
# editor backup files and other nasty things.
|
92
|
+
#
|
93
|
+
# This handles that case correctly, with a deprecation warning, to augment
|
94
|
+
# our FileList with the right things to put in place.
|
95
|
+
#
|
96
|
+
# Eventually, when all our projects are migrated to the new standard, we
|
97
|
+
# can drop this in favour of just pushing the patterns directly into the
|
98
|
+
# FileList and eliminate many lines of code and comment.
|
99
|
+
Dir.chdir(Pkg::Config.project_root) do
|
100
|
+
file_patterns.each do |pattern|
|
101
|
+
if File.directory?(pattern) and !Pkg::Util::File.empty_dir?(pattern)
|
102
|
+
install << Dir[pattern + "/**/*"]
|
103
|
+
else
|
104
|
+
install << Dir[pattern]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
install.flatten!
|
108
|
+
|
109
|
+
# Transfer all the files and symlinks into the working directory...
|
110
|
+
install = install.select { |x| File.file?(x) or File.symlink?(x) or Pkg::Util::File.empty_dir?(x) }
|
111
|
+
|
112
|
+
install.each do |file|
|
113
|
+
if Pkg::Util::File.empty_dir?(file)
|
114
|
+
FileUtils.mkpath(File.join(workdir, file), :verbose => false)
|
115
|
+
else
|
116
|
+
FileUtils.mkpath(File.dirname(File.join(workdir, file)), :verbose => false)
|
117
|
+
FileUtils.cp(file, File.join(workdir, file), :verbose => false, :preserve => true)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
Pkg::Util::Version.versionbump(workdir) if Pkg::Config.update_version_file
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
# Utility methods for handling git
|
4
|
+
module Pkg::Util::Git
|
5
|
+
class << self
|
6
|
+
# Git utility to create a new git commit
|
7
|
+
def commit_file(file, message = 'changes')
|
8
|
+
fail_unless_repo
|
9
|
+
puts 'Committing changes:'
|
10
|
+
puts
|
11
|
+
diff, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} diff HEAD #{file}")
|
12
|
+
puts diff
|
13
|
+
stdout, = Pkg::Util::Execution.capture3(%(#{Pkg::Util::Tool::GIT} commit #{file} -m "Commit #{message} in #{file}" &> #{Pkg::Util::OS::DEVNULL}))
|
14
|
+
stdout
|
15
|
+
end
|
16
|
+
|
17
|
+
# Git utility to create a new git tag
|
18
|
+
def tag(version)
|
19
|
+
fail_unless_repo
|
20
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} tag -s -u #{Pkg::Util::Gpg.key} -m '#{version}' #{version}")
|
21
|
+
stdout
|
22
|
+
end
|
23
|
+
|
24
|
+
# Git utility to create a new git bundle
|
25
|
+
# rubocop:disable Metrics/AbcSize
|
26
|
+
def bundle(treeish, appendix = Pkg::Util.rand_string, temp = Pkg::Util::File.mktemp)
|
27
|
+
fail_unless_repo
|
28
|
+
Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} bundle create #{temp}/#{Pkg::Config.project}-#{Pkg::Config.version}-#{appendix} #{treeish} --tags")
|
29
|
+
Dir.chdir(temp) do
|
30
|
+
Pkg::Util::Execution.capture3("#{Pkg::Util::Tool.find_tool('tar')} -czf #{Pkg::Config.project}-#{Pkg::Config.version}-#{appendix}.tar.gz #{Pkg::Config.project}-#{Pkg::Config.version}-#{appendix}")
|
31
|
+
FileUtils.rm_rf("#{Pkg::Config.project}-#{Pkg::Config.version}-#{appendix}")
|
32
|
+
end
|
33
|
+
"#{temp}/#{Pkg::Config.project}-#{Pkg::Config.version}-#{appendix}.tar.gz"
|
34
|
+
end
|
35
|
+
|
36
|
+
def pull(remote, branch)
|
37
|
+
fail_unless_repo
|
38
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} pull #{remote} #{branch}")
|
39
|
+
stdout
|
40
|
+
end
|
41
|
+
|
42
|
+
# Check if we are currently working on a tagged commit.
|
43
|
+
def tagged?
|
44
|
+
ref_type == 'tag'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Reports if a ref and its corresponding git repo points to
|
48
|
+
# a git tag.
|
49
|
+
#
|
50
|
+
# @param url [string] url of repo grabbed from json file
|
51
|
+
# @param ref [string] ref grabbed from json file
|
52
|
+
def remote_tagged?(url, ref)
|
53
|
+
reference = Pkg::Util::Git_tag.new(url, ref)
|
54
|
+
reference.tag?
|
55
|
+
end
|
56
|
+
|
57
|
+
# Checks out a specified ref. The ref must exist in the current repo.
|
58
|
+
# This also removes any uncommitted changes
|
59
|
+
def checkout(ref)
|
60
|
+
Pkg::Util.in_project_root do
|
61
|
+
_, _, ret = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} reset --hard ; #{Pkg::Util::Tool::GIT} checkout #{ref}")
|
62
|
+
Pkg::Util::Execution.success?(ret) || raise("Could not checkout #{ref} git branch to build package from...exiting")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the value of `git describe`. If this is not a git repo or
|
67
|
+
# `git describe` fails because there is no tag, this will return false
|
68
|
+
def describe(extra_opts = ['--tags', '--dirty'])
|
69
|
+
Pkg::Util.in_project_root do
|
70
|
+
stdout, _, ret = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} describe #{Array(extra_opts).join(' ')}")
|
71
|
+
if Pkg::Util::Execution.success?(ret)
|
72
|
+
stdout.strip
|
73
|
+
else
|
74
|
+
false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# return the sha of HEAD on the current branch
|
80
|
+
# You can specify the length you want from the sha. Default is 40, the
|
81
|
+
# length for sha1. If you specify anything higher, it will still return 40
|
82
|
+
# characters. Ideally, you're not going to specify anything under 7 characters,
|
83
|
+
# but I'll leave that discretion up to you.
|
84
|
+
def sha(length = 40)
|
85
|
+
Pkg::Util.in_project_root do
|
86
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} rev-parse --short=#{length} HEAD")
|
87
|
+
stdout.strip
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Return the ref type of HEAD on the current branch
|
92
|
+
def ref_type
|
93
|
+
Pkg::Util.in_project_root do
|
94
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} cat-file -t #{describe('')}")
|
95
|
+
stdout.strip
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# If HEAD is a tag, return the tag. Otherwise return the sha of HEAD.
|
100
|
+
def sha_or_tag(length = 40)
|
101
|
+
if ref_type == 'tag'
|
102
|
+
describe
|
103
|
+
else
|
104
|
+
sha(length)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Return true if we're in a git repo, otherwise false
|
109
|
+
def repo?
|
110
|
+
Pkg::Util.in_project_root do
|
111
|
+
_, _, ret = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} rev-parse --git-dir")
|
112
|
+
Pkg::Util::Execution.success?(ret)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# rubocop:disable Style/GuardClause
|
117
|
+
def fail_unless_repo
|
118
|
+
unless repo?
|
119
|
+
raise "Pkg::Config.project_root (#{Pkg::Config.project_root}) is not \
|
120
|
+
a valid git repository"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return the basename of the project repo
|
125
|
+
def project_name
|
126
|
+
Pkg::Util.in_project_root do
|
127
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} config --get remote.origin.url")
|
128
|
+
stdout.split('/')[-1].chomp('.git').chomp
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Return the name of the current branch
|
133
|
+
def branch_name
|
134
|
+
Pkg::Util.in_project_root do
|
135
|
+
stdout, = Pkg::Util::Execution.capture3("#{Pkg::Util::Tool::GIT} rev-parse --abbrev-ref HEAD")
|
136
|
+
stdout.strip
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def source_dirty?
|
141
|
+
describe.include?('dirty')
|
142
|
+
end
|
143
|
+
|
144
|
+
def fail_on_dirty_source
|
145
|
+
if source_dirty?
|
146
|
+
raise "The source tree is dirty, e.g. there are uncommited changes. \
|
147
|
+
Please commit/discard changes and try again."
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
##########################################################################
|
152
|
+
# DEPRECATED METHODS
|
153
|
+
#
|
154
|
+
def git_commit_file(file, message = "changes")
|
155
|
+
Pkg::Util.deprecate('Pkg::Util::Git.git_commit_file', 'Pkg::Util::Git.commit_file')
|
156
|
+
Pkg::Util::Git.commit_file(file, message)
|
157
|
+
end
|
158
|
+
|
159
|
+
def git_tag(version)
|
160
|
+
Pkg::Util.deprecate('Pkg::Util::Git.git_tag', 'Pkg::Util::Git.tag')
|
161
|
+
Pkg::Util::Git.tag(version)
|
162
|
+
end
|
163
|
+
|
164
|
+
def git_bundle(treeish, appendix = Pkg::Util.rand_string, temp = Pkg::Util::File.mktemp)
|
165
|
+
Pkg::Util.deprecate('Pkg::Util::Git.git_bundle', 'Pkg::Util::Git.bundle')
|
166
|
+
Pkg::Util::Git.bundle(treeish, appendix, temp)
|
167
|
+
end
|
168
|
+
|
169
|
+
def git_pull(remote, branch)
|
170
|
+
Pkg::Util.deprecate('Pkg::Util::Git.git_pull', 'Pkg::Util::Git.pull')
|
171
|
+
Pkg::Util::Git.pull(remote, branch)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|