class Repo
Constants
- PUSH_REMOTE_NAME
When we create a temproary remote to push to, use this name.
Public Class Methods
Gets a list of branch names without actually cloning the repo.
# File lib/bub_bot/repo.rb, line 17 def self.branches(origin_remote) puts 'repo.branches' # git ls-remote returns a list of lines like this: # ea656e141760b0d8ba49d92506427322120ce945 refs/heads/some-branch-name ls_remote_output = `git ls-remote --heads #{origin_remote}` ls_remote_output.split("\n").map {|line| line.split('/').last } end
# File lib/bub_bot/repo.rb, line 7 def initialize(target, origin_remote, server) puts "target = #{target}" puts "remote = #{origin_remote}" puts "server = #{server}" @target = target @origin_remote = origin_remote @server = server end
Public Instance Methods
# File lib/bub_bot/repo.rb, line 72 def checkout(branch_name) clean cmd("remote set-branches origin '*'") fetch git.checkout(branch_name) end
# File lib/bub_bot/repo.rb, line 62 def clean # TODO: make sure there's no weird changes on the git repo git.clean(force: true) git.reset_hard end
# File lib/bub_bot/repo.rb, line 101 def dir "/tmp/bub_repos" end
# File lib/bub_bot/repo.rb, line 68 def fetch git.fetch end
# File lib/bub_bot/repo.rb, line 25 def git return @_git if @_git if Dir.exists?(repo_dir) && Dir.exists?(repo_dir + '/.git') puts "Repo exists!" @_git = Git.open(repo_dir) # TODO: handle other errors beside "dir doesn't exist" else puts "Cloning repo" @_git = Git.clone(@origin_remote, repo_dir_name, path: dir, :log => Logger.new(STDOUT)) puts 'here' end @_git end
# File lib/bub_bot/repo.rb, line 79 def pull git.pull end
Push is async
# File lib/bub_bot/repo.rb, line 41 def push(branch, remote, &on_complete) # TODO: handle people pushing while another push is still going, since we # have some shared state in the form of the filesystem puts 'Pushing' git.remotes.find{ |remote| remote.name == 'push_remote' }&.remove puts 'Maybe removed old remote' git.add_remote('push_remote', remote) puts 'added remote' puts "Pushing #{branch} to #{remote}" puts "about to git fetch origin for branch #{branch}" git.fetch('origin', branch: branch) puts 'about to finally push' git.push(remote, "+origin/#{branch}:master") puts 'Finished final push' on_complete.call if on_complete end
We name repo dirs after server + name (eg `burrito__core`). This lets multiple deploys to the same server (eg deploying both core and web to burrito at the same time) to work, as well as multiple deploys to the same target (eg deploying core on both burrito and gyro) to work.
Note that simultanious deploys to the same target and server (eg two deploys at once to burrito__core) won't work. Both deploys would use the same git working directory and step on eachother's toes. That's fine, though, because they'd also step on eachother's toes in the actual target environment. We should prevent this case in the UI.
# File lib/bub_bot/repo.rb, line 93 def repo_dir "#{dir}/#{repo_dir_name}" end
# File lib/bub_bot/repo.rb, line 97 def repo_dir_name "#{@server}__#{@target}" end
Private Instance Methods
The git library doesn't support everything, so sometimes we run arbitrary commands.
# File lib/bub_bot/repo.rb, line 108 def cmd(command) git_command = "git --git-dir=#{repo_dir}/.git --work-tree=#{repo_dir} #{command}" puts "Running #{git_command}" result = Kernel.system(git_command) puts "Result=#{result}" end