/lib/bitbucket-backup/repository.rb
Ruby | 158 lines | 106 code | 30 blank | 22 comment | 7 complexity | c9af5c845e64f21a7da59b7713de115b MD5 | raw file
Possible License(s): 0BSD
- require "fileutils"
- require "cgi"
- require "open3"
- module Bitbucket
- module Backup
- class Repository
- # @return [Hash]
- # the hash of repo data from the Bitbucket API.
- #
- attr_reader :repo
-
- # @return [String]
- # the plain-text password for the repo.
- #
- attr_reader :password
-
- # @return [String]
- # the absolute path of the directory to backup the repo to.
- #
- attr_reader :backup_root
-
- # Creates a new repo.
- #
- # @param [Hash] repo
- # the hash of repo data from the Bitbucket API.
- #
- # @param [String] password
- # the plain-text passsword for the repo.
- #
- # @param [String] backup_root
- # the absolute path of the directory to backup the repo to.
- #
- def initialize(repo, password, backup_root)
- @repo = repo
- @password = password
- @backup_root = backup_root
- end
-
- # Performs a backup of the repository.
- #
- def backup
- puts "Backing up: #{repo["slug"]}."
-
- unless Bitbucket::Backup.have_scm_tool?(repo["scm"])
- puts "Warning: #{repo["scm"]} not found on PATH. Skipping..."
-
- return
- end
-
- backup_src
-
- backup_wiki
- end
-
- private
- def backup_src
- clone_or_update(:type => :src)
- end
-
- def backup_wiki
- clone_or_update(:type => :wiki) if repo["has_wiki"]
- end
-
- def clone_or_update(options)
- path = dir_for_repo(options)
- uri = uri_for_repo(options)
-
- if File.exist?(path)
- run_incremental_backup(path, uri)
- else
- run_full_backup(uri, path)
- end
- end
-
- def is_repo?(path)
- FileUtils.cd(path)
-
- case repo["scm"]
- when "hg"
- Open3.popen3("hg status")
- when "git"
- Open3.popen3("git status")
- end
-
- return $.
- end
-
- def run_incremental_backup(path, uri)
- unless is_repo?(path)
- puts "Warning: file already exists but is not a repo!! Skipping..."
-
- return false
- end
-
- FileUtils.cd(path)
-
- case repo["scm"]
- when "hg"
- system "hg pull -u #{uri}"
- when "git"
- system "git pull #{uri}"
- end
- end
-
- def run_full_backup(uri, dest)
- case repo["scm"]
- when "hg"
- system "hg clone #{uri} #{dest}"
- when "git"
- system "git clone #{uri} #{dest}"
- end
- end
-
- def dir_for_repo(options)
- if options.nil? || options[:type].nil?
- raise RuntimeError
- end
-
- path = nil
-
- case options[:type]
- when :src
- path = File.expand_path("#{backup_root}/#{repo["slug"]}/src")
- when :wiki
- path = File.expand_path("#{backup_root}/#{repo["slug"]}/wiki")
- end
-
- return path
- end
-
- def uri_for_repo(options)
- base_uri = nil
- uri = nil
- ext = nil
-
- if repo["scm"] == "git"
- ext = ".git"
- end
-
- if repo["is_private"]
- base_uri = "https://#{repo["owner"]}:#{CGI.escape(password)}@bitbucket.org/#{repo["owner"]}/#{repo["slug"]}#{ext}"
- else
- base_uri = "https://bitbucket.org/#{repo["owner"]}/#{repo["slug"]}#{ext}"
- end
-
- case options[:type]
- when :src
- uri = base_uri
- when :wiki
- uri = "#{base_uri}/wiki"
- end
-
- return uri
- end
- end
- end
- end