b193e84974
Signed-off-by: Rémy Coutable <remy@rymai.me>
190 lines
5.9 KiB
Ruby
190 lines
5.9 KiB
Ruby
require 'rainbow/ext/string'
|
|
|
|
module Gitlab
|
|
TaskFailedError = Class.new(StandardError)
|
|
TaskAbortedByUserError = Class.new(StandardError)
|
|
|
|
module TaskHelpers
|
|
# Ask if the user wants to continue
|
|
#
|
|
# Returns "yes" the user chose to continue
|
|
# Raises Gitlab::TaskAbortedByUserError if the user chose *not* to continue
|
|
def ask_to_continue
|
|
answer = prompt("Do you want to continue (yes/no)? ".color(:blue), %w{yes no})
|
|
raise Gitlab::TaskAbortedByUserError unless answer == "yes"
|
|
end
|
|
|
|
# Check which OS is running
|
|
#
|
|
# It will primarily use lsb_relase to determine the OS.
|
|
# It has fallbacks to Debian, SuSE, OS X and systems running systemd.
|
|
def os_name
|
|
os_name = run_command(%W(lsb_release -irs))
|
|
os_name ||= if File.readable?('/etc/system-release')
|
|
File.read('/etc/system-release')
|
|
end
|
|
os_name ||= if File.readable?('/etc/debian_version')
|
|
debian_version = File.read('/etc/debian_version')
|
|
"Debian #{debian_version}"
|
|
end
|
|
os_name ||= if File.readable?('/etc/SuSE-release')
|
|
File.read('/etc/SuSE-release')
|
|
end
|
|
os_name ||= if os_x_version = run_command(%W(sw_vers -productVersion))
|
|
"Mac OS X #{os_x_version}"
|
|
end
|
|
os_name ||= if File.readable?('/etc/os-release')
|
|
File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1]
|
|
end
|
|
os_name.try(:squish!)
|
|
end
|
|
|
|
# Prompt the user to input something
|
|
#
|
|
# message - the message to display before input
|
|
# choices - array of strings of acceptable answers or nil for any answer
|
|
#
|
|
# Returns the user's answer
|
|
def prompt(message, choices = nil)
|
|
begin
|
|
print(message)
|
|
answer = STDIN.gets.chomp
|
|
end while choices.present? && !choices.include?(answer)
|
|
answer
|
|
end
|
|
|
|
# Runs the given command and matches the output against the given pattern
|
|
#
|
|
# Returns nil if nothing matched
|
|
# Returns the MatchData if the pattern matched
|
|
#
|
|
# see also #run_command
|
|
# see also String#match
|
|
def run_and_match(command, regexp)
|
|
run_command(command).try(:match, regexp)
|
|
end
|
|
|
|
# Runs the given command
|
|
#
|
|
# Returns '' if the command was not found
|
|
# Returns the output of the command otherwise
|
|
#
|
|
# see also #run_and_match
|
|
def run_command(command)
|
|
output, _ = Gitlab::Popen.popen(command)
|
|
output
|
|
rescue Errno::ENOENT
|
|
'' # if the command does not exist, return an empty string
|
|
end
|
|
|
|
# Runs the given command and raises a Gitlab::TaskFailedError exception if
|
|
# the command does not exit with 0
|
|
#
|
|
# Returns the output of the command otherwise
|
|
def run_command!(command)
|
|
output, status = Gitlab::Popen.popen(command)
|
|
|
|
raise Gitlab::TaskFailedError unless status.zero?
|
|
|
|
output
|
|
end
|
|
|
|
def uid_for(user_name)
|
|
run_command(%W(id -u #{user_name})).chomp.to_i
|
|
end
|
|
|
|
def gid_for(group_name)
|
|
begin
|
|
Etc.getgrnam(group_name).gid
|
|
rescue ArgumentError # no group
|
|
"group #{group_name} doesn't exist"
|
|
end
|
|
end
|
|
|
|
def warn_user_is_not_gitlab
|
|
unless @warned_user_not_gitlab
|
|
gitlab_user = Gitlab.config.gitlab.user
|
|
current_user = run_command(%W(whoami)).chomp
|
|
unless current_user == gitlab_user
|
|
puts " Warning ".color(:black).background(:yellow)
|
|
puts " You are running as user #{current_user.color(:magenta)}, we hope you know what you are doing."
|
|
puts " Things may work\/fail for the wrong reasons."
|
|
puts " For correct results you should run this as user #{gitlab_user.color(:magenta)}."
|
|
puts ""
|
|
end
|
|
@warned_user_not_gitlab = true
|
|
end
|
|
end
|
|
|
|
# Tries to configure git itself
|
|
#
|
|
# Returns true if all subcommands were successfull (according to their exit code)
|
|
# Returns false if any or all subcommands failed.
|
|
def auto_fix_git_config(options)
|
|
if !@warned_user_not_gitlab
|
|
command_success = options.map do |name, value|
|
|
system(*%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value}))
|
|
end
|
|
|
|
command_success.all?
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def all_repos
|
|
Gitlab.config.repositories.storages.each do |name, path|
|
|
IO.popen(%W(find #{path} -mindepth 2 -maxdepth 2 -type d -name *.git)) do |find|
|
|
find.each_line do |path|
|
|
yield path.chomp
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def repository_storage_paths_args
|
|
Gitlab.config.repositories.storages.values
|
|
end
|
|
|
|
def user_home
|
|
Rails.env.test? ? Rails.root.join('tmp/tests') : Gitlab.config.gitlab.user_home
|
|
end
|
|
|
|
def checkout_or_clone_tag(tag:, repo:, target_dir:)
|
|
if Dir.exist?(target_dir)
|
|
checkout_tag(tag, target_dir)
|
|
else
|
|
clone_repo(repo, target_dir)
|
|
end
|
|
|
|
reset_to_tag(tag, target_dir)
|
|
end
|
|
|
|
def clone_repo(repo, target_dir)
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{target_dir}])
|
|
end
|
|
|
|
def checkout_tag(tag, target_dir)
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch --tags --quiet])
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} checkout --quiet #{tag}])
|
|
end
|
|
|
|
def reset_to_tag(tag_wanted, target_dir)
|
|
tag =
|
|
begin
|
|
# First try to checkout without fetching
|
|
# to avoid stalling tests if the Internet is down.
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- #{tag_wanted}])
|
|
rescue Gitlab::TaskFailedError
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch origin])
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- origin/#{tag_wanted}])
|
|
end
|
|
|
|
if tag
|
|
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} reset --hard #{tag.strip}])
|
|
else
|
|
raise Gitlab::TaskFailedError
|
|
end
|
|
end
|
|
end
|
|
end
|