mirror of
https://ghfast.top/https://github.com/discourse/docker_manager.git
synced 2026-05-23 00:04:03 +08:00
gjs, helper invocation case, typos, latest license template, unnecessary tracking, concatClass, unnecessary service injection, new imports, whitespace, pure function helper, htmlSafe calling convention, this. in template, unused vars in ruby, update linting, qunit-dom
219 lines
5.9 KiB
Ruby
219 lines
5.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module GitHelpers
|
|
CLONE_FULL = :full
|
|
CLONE_SHALLOW = :shallow
|
|
CLONE_TREELESS = :treeless
|
|
|
|
class RemoteGitRepo
|
|
attr_reader :url, :root_path, :work_path, :remote_path
|
|
|
|
@@caches = {}
|
|
|
|
def initialize(initial_branch: "main", cache_key: nil, force: false, &blk)
|
|
@initial_branch = initial_branch
|
|
@local_clone_count = 0
|
|
@root_path = Dir.mktmpdir
|
|
@remote_path = File.join(@root_path, "remote.git")
|
|
@work_path = File.join(@root_path, "work")
|
|
@url = "file://#{@remote_path}"
|
|
|
|
if !force
|
|
@@caches[cache_key] ||= self.class.new(initial_branch:, cache_key:, force: true, &blk)
|
|
FileUtils.cp_r(@@caches[cache_key].root_path + "/.", @root_path)
|
|
Dir.chdir(@work_path) { git "remote set-url origin #{@url}" }
|
|
return
|
|
end
|
|
|
|
Dir.mkdir(@remote_path)
|
|
Dir.chdir(@remote_path) do
|
|
git "init --bare --initial-branch=#{initial_branch}"
|
|
git "config core.sharedrepository 1"
|
|
git "config receive.denyNonFastforwards true"
|
|
git "config receive.denyCurrentBranch ignore"
|
|
git "config uploadpack.allowFilter true"
|
|
git "config commit.gpgsign false"
|
|
end
|
|
|
|
Dir.mkdir(@work_path)
|
|
Dir.chdir(@work_path) do
|
|
git "init . --initial-branch=#{initial_branch}"
|
|
git "config commit.gpgsign false"
|
|
git "remote add origin #{@url}"
|
|
|
|
File.write("README.md", "This is a git repo for testing docker_manager.")
|
|
File.write("version.txt", "")
|
|
|
|
git "add ."
|
|
git "commit -m 'Initial commit'"
|
|
git "push --set-upstream origin #{initial_branch}"
|
|
end
|
|
|
|
yield(self) if block_given?
|
|
end
|
|
|
|
def destroy
|
|
FileUtils.rm_rf(@root_path)
|
|
end
|
|
|
|
def create_local_clone(method:)
|
|
path = File.join(@root_path, "local_#{@local_clone_count}")
|
|
|
|
Dir.mkdir(path)
|
|
Dir.chdir(path) do
|
|
case (method)
|
|
when CLONE_FULL
|
|
git "clone #{@url} ."
|
|
when CLONE_SHALLOW
|
|
git "clone --depth 1 #{@url} ."
|
|
when CLONE_TREELESS
|
|
git "clone --filter=tree:0 #{@url} ."
|
|
end
|
|
|
|
yield(method(:git)) if block_given?
|
|
end
|
|
|
|
@local_clone_count += 1
|
|
LocalGitRepo.new(path, method)
|
|
end
|
|
|
|
def in_working_directory
|
|
Dir.chdir(@work_path) { yield(method(:git)) }
|
|
end
|
|
|
|
def in_remote_repo
|
|
Dir.chdir(@remote_path) { yield(method(:git)) }
|
|
end
|
|
|
|
def commit(filename:, commits:, branch: nil)
|
|
branch ||= @initial_branch
|
|
|
|
Dir.chdir(@work_path) do
|
|
git "checkout #{branch}"
|
|
|
|
commits.each do |commit|
|
|
env = commit[:date] ? build_env(date: commit[:date]) : nil
|
|
File.write(filename, commit[:content])
|
|
|
|
git "add #{filename}"
|
|
git "commit -m 'Update #{filename} with #{commit[:content].truncate(10)}'", env: env
|
|
|
|
if commit[:tags]
|
|
commit[:tags].each do |tag|
|
|
if git("tag -l #{tag}", raise_exception: false)
|
|
git "tag -d #{tag}"
|
|
git "push --delete origin #{tag}"
|
|
end
|
|
|
|
git "tag -a #{tag} -m 'Tagging #{tag}'"
|
|
end
|
|
end
|
|
end
|
|
|
|
git "push --follow-tags"
|
|
end
|
|
end
|
|
|
|
def create_branches(*branch_names)
|
|
Dir.chdir(@work_path) do
|
|
branch_names.each do |branch|
|
|
git "checkout #{@initial_branch}"
|
|
git "checkout -b #{branch}"
|
|
git "push --set-upstream origin #{branch}"
|
|
end
|
|
end
|
|
end
|
|
|
|
def delete_branches(*branch_names)
|
|
Dir.chdir(@work_path) do
|
|
branch_names.each do |branch|
|
|
git "checkout #{@initial_branch}"
|
|
git "branch -d #{branch}"
|
|
git "push origin --delete #{branch}"
|
|
end
|
|
end
|
|
end
|
|
|
|
def rename_branch(old_name:, new_name:)
|
|
Dir.chdir(@work_path) do
|
|
git "checkout #{old_name}"
|
|
git "branch -m #{new_name}"
|
|
git "push origin -u #{new_name}"
|
|
|
|
if old_name == @initial_branch
|
|
Dir.chdir(@remote_path) { git "symbolic-ref HEAD refs/heads/#{new_name}" }
|
|
end
|
|
|
|
git "push origin --delete #{old_name}"
|
|
end
|
|
end
|
|
|
|
def rebase(source_branch:, target_branch:)
|
|
Dir.chdir(@work_path) do
|
|
git "checkout #{target_branch}"
|
|
git "rebase #{source_branch}"
|
|
git "push --force"
|
|
end
|
|
end
|
|
|
|
def delete_tags(*tag_names)
|
|
Dir.chdir(@work_path) do
|
|
tag_names.each do |tag|
|
|
git "tag -d #{tag}"
|
|
git "push --delete origin #{tag}"
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def git(command, env: "", raise_exception: true)
|
|
env = build_env if command.start_with?("commit") && env.blank?
|
|
stdout, stderr, status = Open3.capture3("#{env} git #{command}".strip)
|
|
|
|
if status.success? || !raise_exception
|
|
stdout.presence
|
|
else
|
|
raise RuntimeError.new("stderr while running #{command}: #{stderr}")
|
|
end
|
|
end
|
|
|
|
def build_env(name: "Alice", email: "alice@example.com", date: "2023-03-06T20:27:03Z")
|
|
"GIT_AUTHOR_NAME='#{name}' GIT_AUTHOR_EMAIL='#{email}' GIT_AUTHOR_DATE='#{date}' " \
|
|
"GIT_COMMITTER_NAME='#{name}' GIT_COMMITTER_EMAIL='#{email}' GIT_COMMITTER_DATE='#{date}'"
|
|
end
|
|
end
|
|
|
|
class LocalGitRepo
|
|
attr_reader :path
|
|
|
|
def initialize(path, clone_method)
|
|
@path = path
|
|
@clone_method = clone_method
|
|
end
|
|
|
|
def git(*commands)
|
|
Dir.chdir(@path) do
|
|
commands.map do |command|
|
|
stdout, _, status = Open3.capture3("git #{command}".strip)
|
|
status.success? ? stdout : (raise RuntimeError)
|
|
end
|
|
end
|
|
end
|
|
|
|
def commit_count
|
|
git("rev-list --all --count").first.to_i
|
|
end
|
|
|
|
def checkout(ref)
|
|
if @clone_method == CLONE_SHALLOW
|
|
git "remote set-branches origin #{ref}"
|
|
git "fetch --depth 1 origin #{ref}"
|
|
else
|
|
git "fetch origin #{ref}"
|
|
end
|
|
|
|
git "-c advice.detachedHead=false checkout #{ref}"
|
|
end
|
|
end
|
|
end
|