packaging 0.99.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.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +17 -0
  3. data/README-Solaris.md +117 -0
  4. data/README.md +1031 -0
  5. data/lib/packaging.rb +32 -0
  6. data/lib/packaging/artifactory.rb +278 -0
  7. data/lib/packaging/config.rb +392 -0
  8. data/lib/packaging/config/params.rb +366 -0
  9. data/lib/packaging/deb.rb +28 -0
  10. data/lib/packaging/deb/repo.rb +263 -0
  11. data/lib/packaging/gem.rb +112 -0
  12. data/lib/packaging/ips.rb +57 -0
  13. data/lib/packaging/msi.rb +89 -0
  14. data/lib/packaging/nuget.rb +39 -0
  15. data/lib/packaging/osx.rb +36 -0
  16. data/lib/packaging/paths.rb +238 -0
  17. data/lib/packaging/platforms.rb +480 -0
  18. data/lib/packaging/repo.rb +55 -0
  19. data/lib/packaging/retrieve.rb +46 -0
  20. data/lib/packaging/rpm.rb +5 -0
  21. data/lib/packaging/rpm/repo.rb +257 -0
  22. data/lib/packaging/tar.rb +154 -0
  23. data/lib/packaging/util.rb +146 -0
  24. data/lib/packaging/util/date.rb +15 -0
  25. data/lib/packaging/util/execution.rb +85 -0
  26. data/lib/packaging/util/file.rb +125 -0
  27. data/lib/packaging/util/git.rb +174 -0
  28. data/lib/packaging/util/git_tags.rb +73 -0
  29. data/lib/packaging/util/gpg.rb +62 -0
  30. data/lib/packaging/util/jenkins.rb +95 -0
  31. data/lib/packaging/util/misc.rb +69 -0
  32. data/lib/packaging/util/net.rb +368 -0
  33. data/lib/packaging/util/os.rb +17 -0
  34. data/lib/packaging/util/platform.rb +40 -0
  35. data/lib/packaging/util/rake_utils.rb +111 -0
  36. data/lib/packaging/util/serialization.rb +19 -0
  37. data/lib/packaging/util/ship.rb +171 -0
  38. data/lib/packaging/util/tool.rb +41 -0
  39. data/lib/packaging/util/version.rb +326 -0
  40. data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
  41. data/spec/fixtures/config/ext/project_data.yaml +2 -0
  42. data/spec/fixtures/config/params.yaml +2 -0
  43. data/spec/fixtures/configs/components/test_file.json +1 -0
  44. data/spec/fixtures/configs/components/test_file_2.json +0 -0
  45. data/spec/fixtures/configs/components/test_file_not_tagged.json +1 -0
  46. data/spec/fixtures/configs/components/test_file_wrong_ext.txt +0 -0
  47. data/spec/fixtures/configs/components/test_file_wrong_ext.wrong +0 -0
  48. data/spec/fixtures/util/pre_tasks.yaml +4 -0
  49. data/spec/lib/packaging/artifactory_spec.rb +171 -0
  50. data/spec/lib/packaging/config_spec.rb +556 -0
  51. data/spec/lib/packaging/deb/repo_spec.rb +148 -0
  52. data/spec/lib/packaging/deb_spec.rb +52 -0
  53. data/spec/lib/packaging/paths_spec.rb +153 -0
  54. data/spec/lib/packaging/platforms_spec.rb +153 -0
  55. data/spec/lib/packaging/repo_spec.rb +97 -0
  56. data/spec/lib/packaging/retrieve_spec.rb +61 -0
  57. data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
  58. data/spec/lib/packaging/tar_spec.rb +122 -0
  59. data/spec/lib/packaging/util/execution_spec.rb +56 -0
  60. data/spec/lib/packaging/util/file_spec.rb +139 -0
  61. data/spec/lib/packaging/util/git_spec.rb +160 -0
  62. data/spec/lib/packaging/util/git_tag_spec.rb +36 -0
  63. data/spec/lib/packaging/util/gpg_spec.rb +64 -0
  64. data/spec/lib/packaging/util/jenkins_spec.rb +112 -0
  65. data/spec/lib/packaging/util/misc_spec.rb +31 -0
  66. data/spec/lib/packaging/util/net_spec.rb +239 -0
  67. data/spec/lib/packaging/util/os_spec.rb +31 -0
  68. data/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
  69. data/spec/lib/packaging/util/ship_spec.rb +117 -0
  70. data/spec/lib/packaging/util/version_spec.rb +123 -0
  71. data/spec/lib/packaging_spec.rb +19 -0
  72. data/spec/spec_helper.rb +36 -0
  73. data/static_artifacts/PackageInfo.plist +3 -0
  74. data/tasks/00_utils.rake +216 -0
  75. data/tasks/30_metrics.rake +33 -0
  76. data/tasks/apple.rake +266 -0
  77. data/tasks/build.rake +12 -0
  78. data/tasks/clean.rake +5 -0
  79. data/tasks/config.rake +30 -0
  80. data/tasks/deb.rake +129 -0
  81. data/tasks/deb_repos.rake +28 -0
  82. data/tasks/deprecated.rake +130 -0
  83. data/tasks/doc.rake +20 -0
  84. data/tasks/education.rake +57 -0
  85. data/tasks/fetch.rake +57 -0
  86. data/tasks/gem.rake +146 -0
  87. data/tasks/jenkins.rake +494 -0
  88. data/tasks/jenkins_dynamic.rake +202 -0
  89. data/tasks/load_extras.rake +21 -0
  90. data/tasks/mock.rake +348 -0
  91. data/tasks/nightly_repos.rake +335 -0
  92. data/tasks/pe_deb.rake +12 -0
  93. data/tasks/pe_rpm.rake +13 -0
  94. data/tasks/pe_ship.rake +221 -0
  95. data/tasks/pe_sign.rake +13 -0
  96. data/tasks/pe_tar.rake +5 -0
  97. data/tasks/retrieve.rake +45 -0
  98. data/tasks/rpm.rake +66 -0
  99. data/tasks/rpm_repos.rake +29 -0
  100. data/tasks/ship.rake +752 -0
  101. data/tasks/sign.rake +226 -0
  102. data/tasks/tag.rake +8 -0
  103. data/tasks/tar.rake +34 -0
  104. data/tasks/update.rake +16 -0
  105. data/tasks/vanagon.rake +35 -0
  106. data/tasks/vendor_gems.rake +117 -0
  107. data/tasks/version.rake +33 -0
  108. data/tasks/z_data_dump.rake +65 -0
  109. data/templates/README +1 -0
  110. data/templates/downstream.xml.erb +47 -0
  111. data/templates/msi.xml.erb +197 -0
  112. data/templates/packaging.xml.erb +344 -0
  113. data/templates/repo.xml.erb +114 -0
  114. metadata +234 -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
+ 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,15 @@
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
+ end
15
+ 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 'Commiting 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