0103d5be96
These are data columns that store runtime configuration of build needed to execute it on runner and within pipeline. The definition of this data is that once used, and when no longer needed (due to retry capability) they can be freely removed. They use `jsonb` on PostgreSQL, and `text` on MySQL (due to lacking support for json datatype on old enough version).
129 lines
3.4 KiB
Ruby
129 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Utils
|
|
extend self
|
|
|
|
# Ensure that the relative path will not traverse outside the base directory
|
|
def check_path_traversal!(path)
|
|
raise StandardError.new("Invalid path") if path.start_with?("..#{File::SEPARATOR}") ||
|
|
path.include?("#{File::SEPARATOR}..#{File::SEPARATOR}") ||
|
|
path.end_with?("#{File::SEPARATOR}..")
|
|
|
|
path
|
|
end
|
|
|
|
# Run system command without outputting to stdout.
|
|
#
|
|
# @param cmd [Array<String>]
|
|
# @return [Boolean]
|
|
def system_silent(cmd)
|
|
Popen.popen(cmd).last.zero?
|
|
end
|
|
|
|
def force_utf8(str)
|
|
str.force_encoding(Encoding::UTF_8)
|
|
end
|
|
|
|
def ensure_utf8_size(str, bytes:)
|
|
raise ArgumentError, 'Empty string provided!' if str.empty?
|
|
raise ArgumentError, 'Negative string size provided!' if bytes.negative?
|
|
|
|
truncated = str.each_char.each_with_object(+'') do |char, object|
|
|
if object.bytesize + char.bytesize > bytes
|
|
break object
|
|
else
|
|
object.concat(char)
|
|
end
|
|
end
|
|
|
|
truncated + ('0' * (bytes - truncated.bytesize))
|
|
end
|
|
|
|
# Append path to host, making sure there's one single / in between
|
|
def append_path(host, path)
|
|
"#{host.to_s.sub(%r{\/+$}, '')}/#{path.to_s.sub(%r{^\/+}, '')}"
|
|
end
|
|
|
|
# A slugified version of the string, suitable for inclusion in URLs and
|
|
# domain names. Rules:
|
|
#
|
|
# * Lowercased
|
|
# * Anything not matching [a-z0-9-] is replaced with a -
|
|
# * Maximum length is 63 bytes
|
|
# * First/Last Character is not a hyphen
|
|
def slugify(str)
|
|
return str.downcase
|
|
.gsub(/[^a-z0-9]/, '-')[0..62]
|
|
.gsub(/(\A-+|-+\z)/, '')
|
|
end
|
|
|
|
# Converts newlines into HTML line break elements
|
|
def nlbr(str)
|
|
ActionView::Base.full_sanitizer.sanitize(+str, tags: []).gsub(/\r?\n/, '<br>').html_safe
|
|
end
|
|
|
|
def remove_line_breaks(str)
|
|
str.gsub(/\r?\n/, '')
|
|
end
|
|
|
|
def to_boolean(value)
|
|
return value if [true, false].include?(value)
|
|
return true if value =~ /^(true|t|yes|y|1|on)$/i
|
|
return false if value =~ /^(false|f|no|n|0|off)$/i
|
|
|
|
nil
|
|
end
|
|
|
|
def boolean_to_yes_no(bool)
|
|
if bool
|
|
'Yes'
|
|
else
|
|
'No'
|
|
end
|
|
end
|
|
|
|
def random_string
|
|
Random.rand(Float::MAX.to_i).to_s(36)
|
|
end
|
|
|
|
# See: http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
|
# Cross-platform way of finding an executable in the $PATH.
|
|
#
|
|
# which('ruby') #=> /usr/bin/ruby
|
|
def which(cmd, env = ENV)
|
|
exts = env['PATHEXT'] ? env['PATHEXT'].split(';') : ['']
|
|
|
|
env['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
exts.each do |ext|
|
|
exe = File.join(path, "#{cmd}#{ext}")
|
|
return exe if File.executable?(exe) && !File.directory?(exe)
|
|
end
|
|
end
|
|
|
|
nil
|
|
end
|
|
|
|
def bytes_to_megabytes(bytes)
|
|
bytes.to_f / Numeric::MEGABYTE
|
|
end
|
|
|
|
# Used in EE
|
|
# Accepts either an Array or a String and returns an array
|
|
def ensure_array_from_string(string_or_array)
|
|
return string_or_array if string_or_array.is_a?(Array)
|
|
|
|
string_or_array.split(',').map(&:strip)
|
|
end
|
|
|
|
def deep_indifferent_access(data)
|
|
if data.is_a?(Array)
|
|
data.map(&method(:deep_indifferent_access))
|
|
elsif data.is_a?(Hash)
|
|
data.with_indifferent_access
|
|
else
|
|
data
|
|
end
|
|
end
|
|
end
|
|
end
|