Commits

Martin Vejnár committed 57f20a4

Added 'hg depupdate' command.

The command is an extension of the original 'hg depsclone'.
The REV parameter may be omitted, in which case the .hgdeps
file is searched for a revision number representing the nearest
ancestor of the current revision.

Additionaly, the command properly tracks the positions and types
of the fetched dependencies.

  • Participants
  • Parent commits 1f45006

Comments (0)

Files changed (1)

             config.save()
 
 
-def deps_clone(ui, repo, tag, **opts):
-    '''make a copy of repository dependencies
-
-    Create a copy of a given repository dependency list.
-
-    This command will copy all the dependencies of the given name into
-    the destination directories previously registered with the 'deps'
-    command.
-
-    For Mercurial repository dependencies, remote clone options can be
-    given through the configuration file:
-
-    [deps]
-    aliases = libfoo
-    alias.libfoo = /path/to/libfoo
-    alias.libfoo.options = --pull --uncompressed
-
-    See 'clone' options for more details.
+def depupdate(ui, repo, rev=None):
+    '''update dependencies to a configured state
+    
+    Loads the dependency list from .hgdeps file and applies it.
+    
+    The .hgdeps file contains a set of named dependency lists.
+    If given, the REV parameter is used to lookup the list.
+    Should the lookup fail, REV is assumed to identify a revision.
+    If REV is not specified, current revision is used.
+    
+    The long and the short form of a revision identifier are both used
+    to lookup the dependency list. If the lookup fails, the search continues
+    with the parent revision. The search terminates at the first merge.
+    
+    If a dependency list is successfully retrieved, the dependencies
+    are updated as if by using the 'hg dep' commnad.
     '''
-    config = _get_config(ui, repo)
-
-    deps = config.tag(tag)
-    for d in deps:
-        if d.alias not in config.aliases:
-            raise util.Abort(_("alias '%s' is not registered" % d.alias))
-        alias = config.aliases[d.alias]
-        alias.clone(ui, d.rev, d.dest)
-
+    
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        
+        config = _get_config(ui, repo)
+        if rev is not None and config.has_tag(rev):
+            tag = rev
+        else:
+            if rev is None:
+                parents = repo[None].parents()
+                if len(parents) != 1:
+                    raise util.Abort(_('cannot guess target revision on a merged working copy'))
+                chctx = parents[0]
+            else:
+                chctx = repo[repo.lookup(rev)]
+            
+            while chctx is not None:
+                tag = mercurial.node.hex(chctx.node())
+                if config.has_tag(tag):
+                    break
+                tag = mercurial.node.short(chctx.node())
+                if config.has_tag(tag):
+                    break
+                
+                parents = chctx.parents()
+                if len(parents) != 1:
+                    chctx = None
+                else:
+                    chctx = parents[0]
+            else:
+                tag = None
+        
+        if tag is None:
+            raise util.Abort(_('failed to find a suitable target tag'))
+        
+        deplist = config.tag(tag)
+        
+        manifest = _load_manifest(repo)
+        try:
+            for item in manifest.values():
+                if item.dest:
+                    scmhandler = _get_scm_handler(ui, repo, manifest, item.alias_name)
+                    scmhandler.move(dest=None)
+            
+            for dependency in deplist:
+                scmhandler = _get_scm_handler(ui, repo, manifest, dependency.alias, config.aliases)
+                scmhandler.fetch(config.aliases, dependency.rev)
+                scmhandler.update(dependency.rev)
+                scmhandler.move(dependency.dest)
+        finally:
+            manifest.save(repo)
+    finally:
+        if lock: lock.release()
+        if wlock: wlock.release()
+ 
 def depalias(ui, repo, alias, location, type):
     '''bind an alias to a source location
     
             raise util.Abort(_("in alias '%s', %s"
                                % (name, inst.args[0])))
 
-    def clone(self, ui, rev, dest):
-        # create all intermediate directories
-        if os.path.exists(dest):
-            raise util.Abort(_('Directory exists: %s' % dest))
-        os.makedirs(dest)
-        os.rmdir(dest)
-        if self.scmtype == 'hg':
-            self._hg_clone(ui, rev, dest)
-        elif self.scmtype == 'cmd':
-            self._cmd_clone(ui, rev, dest)
-        else:
-            raise util.Abort(_('Unknown repository type: %s' % self.scmtype))
-    
     def is_versioned(self):
         return self._versioned_text is not None
     
         else:
             return '%s %s %s\n' % (self.name, self.scmtype, self.location)
 
-    def _hg_clone(self, ui, rev, dest):
-        ui.status(_('obtaining revision %s from %s to %s\n'
-                    % (rev, self.location, dest)))
-        cmdutil.setremoteconfig(ui, self._opts)
-        hg.clone(ui, self.location, dest,
-                 pull = self._opts['pull'],
-                 stream = self._opts['uncompressed'],
-                 rev = [rev],
-                 update = True)
-
-    def _cmd_clone(self, ui, rev, dest):
-        s = Template(self.location)
-        cmd = s.substitute(rev = rev, dest = dest)
-
-        ui.status(_('running %s\n' % cmd))
-        os.system(cmd)
-
     def __eq__(self, a):
         return (self.name == a.name) \
             and (self.scmtype == a.scmtype) \
              ('', 'remove', None, "remove name's dependencies"),
              ('d', 'dest', '', 'destination directory for the dependency')],
             'hg deps [-a ALIAS -r REV -d DEST] [NAME]'),
-    'depsclone': (deps_clone, [], 'hg depsclone NAME'),
+    
+    'depupdate|depup|depsclone': (depupdate, [], '[NAME]'), 
     
     'depalias':
         (depalias, [