rakelib/vcs.rb
author Jan Vrany <jan.vrany@fit.cvut.cz>
Sun, 29 May 2016 07:14:09 +0000
changeset 23 7dad21b22558
parent 0 f46260ba26b1
child 57 405eb7c27b31
permissions -rw-r--r--
Added support to build under MSYS2 environment * Automatically setup build environment for MSYS2 if C:\MSYS64 is present and lean. * Fixed `checkout_svn` to work with MSYS2 version of SubVersion. For some reason that version of `svn.exe` does not like Windows absolute filenames starting with 'device letter'. In that case the actually directory for checkout is messed up. To workaround, always use relative paths when specifying workiing copy path * Added Borland's `make.exe` to `bin` as Smalltalk/X Windows makefiles still uses it. Triple sigh here.

module Rake
end

module Rake::StX
end

module Rake::Stx::VCS

  class CheckoutException < Exception
  end # class CheckoutException


  def self._check_type(type)
    if (type != :cvs and type != :svn and type != :git and type != :hg and type != :hgsvn and type != :hgcvs)
      raise CheckoutException.new("Unknown version control system type (#{type})")
    end
  end

  def self.update(type, repository, directory, *params)
    self._check_type(type)
    if params.size() > 0
      p = params.last
    else
      p = {}
    end
    root = p[:root] || BUILD_DIR
    wc = root / directory
    if (! File.exist? wc)
      self.checkout(type, repository, directory, *params)
      return
    end
    case type
      when :svn    then _update_svn(wc)
      when :cvs    then _update_cvs(wc)
      when :git    then _update_git(wc, repository, directory, *params)
      when :hg     then _update_hg(wc, repository, directory, *params)
      when :hgsvn  then _update_hg_svn(wc)
      when :hgcvs  then _update_hg_cvs(wc)
    end
  end

  def self._update_hg_svn(wc)
    _update_hg(wc)
  end

  def self._update_hg_cvs(wc)
    if (File.exist? wc / '.hg')
        _update_hg(wc)
    else
        _update_cvs(wc)
    end
  end

  def self._update_git_svn(wc)
    cmd = %W{git svn rebase}
    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    FileUtils::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("GIT-SVN: Cannot update #{wc}")
        end
      end
    end
  end

  def self._update_hg(wc, repository = nil, directory = nil, *params)
    url = ''
    if repository != nil and directory != nil then
      if params.size() > 0
        p = params.last
      else
        p = {}
      end
      separator = p[:separator] || '.'
      url = "#{repository}/#{directory.gsub('/', separator)}"
    end
    cmd = %W{hg pull #{url}}

    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    Rake::FileUtilsExt::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("HG: Cannot pull #{wc}")
        end
      end
    end

    # Get bookmark if any...
    bookmark = nil
    Rake::FileUtilsExt::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
    	bookmarks = `hg log --template "{bookmarks}" -r "p1()"`
    	puts "bookmarks: >>#{bookmarks}<<"
    	bookmark = bookmarks.split(' ')[0]
      end
    end

    cmd = %W{hg update}
    puts "bookmark: #{bookmark}"
    if bookmark && bookmark != '' then

    	cmd << '-r' << "#{bookmark}"
    end
    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    Rake::FileUtilsExt::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("HG: Cannot update #{wc}")
        end
      end
    end

  end


  def self._update_svn(wc)
    d = wc
    while ((File.basename d) != '/')
        if File.exist?(d / '.hg' / 'svn')
            _update_hg(d)
            return
        end
        if File.exist?(d / '.git' / 'svn')
            _update_git_svn(d)
            return
        end
        d = File.expand_path('..', d)
    end
    cmd = %W{svn update}
    # If we're running on Jenkins, force their version:
    # if ENV['HUDSON_URL'] or ENV['JENKINS_URL']
    #   cmd << ' --accept' << 'theirs-full'
    # end
    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    Rake::FileUtilsExt::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("SVN: Cannot update #{wc}")
        end
      end
    end
	cmd = %W{svn upgrade}
	system(*cmd)

    cmd = %W{svn --non-interactive --trust-server-cert update}
    # If we're running on Jenkins, force their version:
    # if ENV['HUDSON_URL'] or ENV['JENKINS_URL']
    #   cmd << ' --accept' << 'theirs-full'
    # end
    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
    Rake::FileUtilsExt::chdir(wc) do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("SVN: Cannot update #{wc}")
        end
      end
    end
  end

  def self._update_cvs(wc)
    if not File.exist?(wc / 'CVS')
      return
    end
    cmd = %W{cvs -z 9 update -A -d}
    info "executing cmd: '#{cmd.join(' ')}}' in '#{wc}'"
    if File.directory?(wc)
      Rake::FileUtilsExt::chdir(wc) do
        Rake::FileUtilsExt::when_writing(cmd) do
          if (not system(*cmd))
            raise CheckoutException.new("CVS: Cannot update #{wc}")
          end
        end
      end
    end
  end

  def self.checkout(type, repository, directory, *params)
    self._check_type(type)
    if params.size() > 0
      p = params.last
    else
      p = {}
    end
    root = p[:root] || BUILD_DIR
    branch = p[:branch]
    if branch == nil
      if type == :svn
        branch = 'trunk'
      elsif type == :hg
        branch = 'default'
      end
    end

    wc = root / directory
    if (File.exist? wc)
      self.update(type, repository, directory, *params)
      return
    end

    if (not File.exists? File.dirname(wc))
      begin
        FileUtils.mkdir_p(File.dirname(wc))
      rescue => ex
        raise CheckoutException.new("Cannot create directory for working copy (#{ex})")
      end
    end
    case type
      when :svn    then _checkout_svn(repository, directory, branch, root, *params)
      when :cvs    then _checkout_cvs(repository, directory, branch, root, *params)
      when :git    then _checkout_git(repository, directory, branch, root, *params)
      when :hg     then _checkout_hg(repository, directory, branch, root, *params)
      when :hgsvn  then _checkout_hg_svn(repository, directory, branch, root, *params)
      when :hgcvs  then _checkout_hg_cvs(repository, directory, branch, root, *params)
    end

  end

  def self._checkout_svn(repository, directory, branch, root, *params)
    url = "#{repository}/#{directory}/#{branch}"
    cmd = %W{svn --non-interactive --trust-server-cert co #{url} #{directory}}
    info "executing cmd: '#{cmd}'"
    FileUtils.chdir root do
      Rake::FileUtilsExt::when_writing(cmd) do
        if (not system(*cmd))
          raise CheckoutException.new("SVN: Cannot checkout from #{url}")
        end
      end
    end
  end

  def self._checkout_hg_impl(repository, package, directory, branch, root, *params)
    url = "#{repository}/#{package}"
    cmd = %W{hg clone #{url} #{root / directory}}
    info "executing cmd: '#{cmd}'"
    Rake::FileUtilsExt::when_writing(cmd) do
      if (not system(*cmd))
        raise CheckoutException.new("HG: Cannot clone from #{url}")
      end
    end
    cmd = %W{hg update #{branch}}
    info "executing cmd: '#{cmd}'"
    Rake::FileUtilsExt::when_writing(cmd) do
      Rake::FileUtilsExt::chdir(root / directory) do
        if (not system(*cmd))
          raise CheckoutException.new("HG: Cannot switch to branch #{branch}")
        end
      end
    end
  end

  def self._checkout_hg_svn(repository, directory, branch, root, *params)
    b = branch
    if b && b.start_with?('branches/')
        b = b.slice('branches/'.size..-1)
    end
    _checkout_hg_impl(repository, directory, directory, b, root, *params)
  end

  def self._checkout_hg_cvs(repository, directory, branch, root, *params)
    raise Exception.new("Cannot checkout HG-CVS repository - you must create WC manually")
  end

  def self._checkout_hg(repository, directory, branch, root, *params)
    if params.size() > 0
      p = params.last
    else
      p = {}
    end
    separator = p[:separator] || '.'

    _checkout_hg_impl(repository, directory.gsub('/', separator), directory, branch, root)
  end

  def self._checkout_cvs(repository, directory, branch, root, *params)
    cmd = %W{cvs -z 9 -d #{repository} co #{directory}}
    info "executing cmd: '#{cmd}' in '#{root}'"
    Rake::FileUtilsExt::when_writing(cmd) do
      Rake::FileUtilsExt::chdir root do
        if (not system(*cmd))
          raise CheckoutException.new("CVS: Cannot checkout #{directory}from #{repository}")
        end
      end
    end
  end
end # module Rake::Stx::VCS

def checkout(repo_name, directory, *params)
  # repository should be symbolic name
  if (repo = project().repository?(repo_name))
    Rake::Stx::VCS.checkout(repo.type, repo.url, directory, *params)
  else
    error("checkout(): No repository found (#{repo_name})")
  end
end

def update(repo_name, directory, *params)
  # repository should be symbolic name
  if (repo = project().repository?(repo_name))
    Rake::Stx::VCS.update(repo.type, repo.url, directory, *params)
  else
    error("update(): No repository found (#{repo_name})")
  end
end

def cvs(repository, directory, *params)
  Rake::Stx::VCS.checkout(:cvs, repository, directory, *params)
end

def svn(repository, directory, *params)
  Rake::Stx::VCS.checkout(:svn, repository, directory, *params)
end

def hg(repository, directory, *params)
  Rake::Stx::VCS.checkout(:hg, repository, directory, *params)
end

def git(repository, directory, *params)
  Rake::Stx::VCS.checkout(:git, repository, directory, *params)
end