# HG changeset patch # User Jan Vrany # Date 1478218967 0 # Node ID 3e832d54a4af6784243f970e0f11399fe0bf420f # Parent 68c8cccbdec54d369562eda802fc0ea07ca6d9d9 Added support for checking out a particular revision ...or tag or bookmark. For now it is implemented only for Mercurial SCM. If revision is not specified, then bookmark `master` is checked out. If there's no such bookmark and branch has multiple heads, then error is thrown. If it has only one head, that one is checked out. diff -r 68c8cccbdec5 -r 3e832d54a4af rakelib/hglib.rb --- a/rakelib/hglib.rb Thu Nov 03 22:27:02 2016 +0000 +++ b/rakelib/hglib.rb Fri Nov 04 00:22:47 2016 +0000 @@ -203,6 +203,23 @@ end end + # Return name of an active bookmark or nil if no bookmark + # is active + def bookmark() + filename = File.join(@path, '.hg', 'bookmarks.current') + if File.exist? filename then + file = File.open(filename, "r") + begin + bookmark = file.read.chomp + ensure + file.close() + end + return bookmark + else + return nil + end + end + # Return a hash "bookmark => revision" of all # bookmarks. def bookmarks(branch = nil) @@ -216,7 +233,7 @@ return bookmarks end - def pull(remote = 'default', user: nil, pass: nil, rev: nil) + def pull(remote = 'default', user: nil, pass: nil, rev: nil, bookmarks: []) authconf = [] if pass != nil then if user == nil then diff -r 68c8cccbdec5 -r 3e832d54a4af rakelib/rbspec.rb --- a/rakelib/rbspec.rb Thu Nov 03 22:27:02 2016 +0000 +++ b/rakelib/rbspec.rb Fri Nov 04 00:22:47 2016 +0000 @@ -333,7 +333,8 @@ property :repository, :class => Symbol - property :branch + property :branch, :class => String + property :revision, :class => String property :link, :values => [ true, false ], :default => true property :test, :values => [ true, false ], :default => false property :coverage, :values => [ true, false ], :default => false @@ -342,13 +343,13 @@ property :checkout, :default => (Proc.new do | pkg | info "Checking out #{pkg.name}..." checkout pkg.repository, pkg.directory, - :branch => pkg.branch, :package => pkg, :separator => pkg._separator + :branch => pkg.branch, :revision => pkg.revision, :package => pkg, :separator => pkg._separator end), :class => Proc property :update, :default => (Proc.new do | pkg | info "Updating #{pkg.name}..." update pkg.repository, pkg.directory, - :branch => pkg.branch, :package => pkg, :separator => pkg._separator + :branch => pkg.branch, :revision => pkg.revision, :package => pkg, :separator => pkg._separator end), :class => Proc property :stc_flags, :default => '+optinline +optinline2 -optContext', :class => String diff -r 68c8cccbdec5 -r 3e832d54a4af rakelib/scm.rb --- a/rakelib/scm.rb Thu Nov 03 22:27:02 2016 +0000 +++ b/rakelib/scm.rb Fri Nov 04 00:22:47 2016 +0000 @@ -56,8 +56,10 @@ end def self._update_hg(repository, directory, branch, root, **kwargs) + wc = root / directory separator = kwargs[:separator] || '.' + revision = kwargs[:revision] if directory != nil then url = "#{repository.canonical}/#{directory.gsub('/', separator)}" end @@ -79,7 +81,27 @@ if paths['default'] != paths['canonical'] then hg.pull('canonical') end - hg.update() + # If revision is not specified, then look for an active bookmark + # and update to it. If no bookmark is active, then look for bookmark + # `master`. If it exist, then update to `master`. If it + # does not, then update to tip or throw an error. + # The error is thrown if there's no bookmark `master` and + # branch has multiple heads since it's not clear which + # head rev to use. + if not revision then + revision = hg.bookmark() + if not revision then + bookmarks = hg.bookmarks(branch) + if (bookmarks.has_key? 'master') then + revision = 'master' + else + if (hg.heads(branch).size > 1) then + raise CheckoutException.new("HG: Cannot checkout #{directory}: branch #{branch} has multiple heads but no bookmark named 'master'!") + end + end + end + end + hg.update(revision || branch) rescue Exception => ex raise CheckoutException.new("HG: Cannot update #{wc}: #{ex.message}") end @@ -152,7 +174,7 @@ def self._checkout_hg(repository, directory, branch, root, **kwargs) separator = kwargs[:separator] || '.' - + revision = kwargs[:revision] hg = HG::Repository.init(root / directory) paths = { 'default' => "#{repository.upstream}/#{directory.gsub('/', separator)}", 'canonical' => "#{repository.canonical}/#{directory.gsub('/', separator)}" } @@ -161,7 +183,6 @@ end hg.paths = paths - begin if repository.staging then hg.pull('staging') @@ -170,7 +191,24 @@ if paths['default'] != paths['canonical'] then hg.pull('canonical') end - hg.update(branch) + # If revision is not specified, then look for bookmark + # `master`. If it exist, then check out `master`. If it + # does not, then checkout tip or throw an error. + # The error is thrown if there's no bookmark `master` and + # branch has multiple heads since it's not clear which + # head rev to use. + if not revision then + bookmarks = hg.bookmarks(branch) + if (bookmarks.has_key? 'master') then + revision = 'master' + else + if (hg.heads(branch).size > 1) then + raise CheckoutException.new("HG: Cannot checkout #{directory}: branch #{branch} has multiple heads but no bookmark named 'master'!") + end + end + end + + hg.update(revision || branch) #rescue Exception => e # raise CheckoutException.new("HG: Cannot clone from #{url}: #{e.message}") end