require 'build-tool/vcs/svn' require 'build-tool/vcs/git' module BuildTool; module VCS class GitSvnConfiguration < GitConfiguration def name "git-svn" end attr_reader :externals def initialize super @externals = {} end def vcs( mod ) raise StandardError if @module and ! mod.equal?( @module ) @module = mod GitSvn.new( self ) end def add_external( local, target ) @externals[local] = target end def copy_configuration( other ) super @externals = {} # Do not copy the externals end attr_writer :repository def repository if @repository.nil? raise ConfigurationError, "No repository configured for module #{self.module.name}." end @repository end attr_writer :remote_path def remote_path if @remote_path.nil? return @module.name end @remote_path end def track_branch "git-svn" end end # # Implementation for the git-svn version control system. # class GitSvn < Base class GitSvnError < BuildTool::Error; end def initialize( *args ) super( *args ) end # ### ATTRIBUTES # def name "git-svn" end def fetching_supported? true end # ### METHOD # def checkedout? return false if !local_path_exist? if !Pathname.new( local_path ).join( ".git" ).exist? raise Base::VcsError, "Checkout path #{local_path} is not a git repo!" end return true end def clone if local_path_exist? raise GitSvnError, "Failed to create repository at '#{local_path}': Path exists" end # Create the directory FileUtils.mkdir_p( local_path ) if !$noop # Init the repository if 0 != ( git_svn "init #{config.repository.url}/#{remote_path}" ) raise GitSvnError, "Error while initializing the repo `git svn init '#{config.repository}/#{remote_path}'`: #{$?}" end fetch( "HEAD" ) end def configure git.configure end # Fetch from +repository+ # # Initializes the local clone if it does not exist. def fetch( revision = nil ) if !checkedout? and !$noop # Beware of looping clone end if revision cmd = "fetch -r#{revision}" else cmd = "fetch" end if ( rc = git_svn( cmd ) ) != 0 raise GitSvnError, "Error while fetching: #{rc}" end update_externals end def gc git.git( "gc" ) end def git if @git.nil? @git = Git.new( config ) end @git end # Call git-svn with command def git_svn( command, wd = local_path, &block ) self.class.execute( "git svn " + command, wd, &block ) end def prepare_for_access # If our server has an associated ssh-key, add it to the ssh-agent. return check_for_sshkey( config.repository.sshkey ) end def rebase if 0 != ( git.git "rebase #{config.track_branch}" ) raise GitSvnError, "Error while rebasing the repo with `#{config.track_branch}': #{$?}" end end def remote_path @config.remote_path end def update_externals config.externals.each do |local, remote| VCS::Svn::svn( "checkout #{remote}@HEAD #{local}", wd = local_path ) end end def[]( var ) case var when 'external' return @externals else # *TODO* raise correct exception raise NotImplementedError, "#{var}" end end def[]=( var, val ) case var when 'external' tmp = val.split( /#/ ) @externals[tmp[0]] = tmp[1] else # *TODO* raise correct exception raise NotImplementedError, "#{var}" end end end # class GitSvn end; end # module BuildTool::VCS