configuration: small reorganization of the clone and checkout code

The goal is to make reuse easier later on.
2 files changed, 73 insertions(+), 48 deletions(-)

M hgext3rd/confman/commands.py
M hgext3rd/confman/configuration.py
M hgext3rd/confman/commands.py +3 -18
@@ 83,24 83,9 @@ def ensureconf(ui, repo, *args, **opts):
 
     failedrepos = []
     for section, secconf, managed in confman.iterrepos():
-        layout = secconf['layout']
-        ui.write(section + '\n', label='confman.section')
-        snapshot = snaps.get(layout)
-        wctx = managed.workingctx()
-        if wctx.hex == snapshot:
-            continue  # already up to date
-        if managed.check_dirty(section):
-            failedrepos.append(section)
-            continue
-        track = secconf.get('track')
-        rev = snapshot or track or 'default'
-        if managed.revsingle(rev, skiperror=True) == wctx:
-            if wctx.branch != track:
-                # branch tracks must always be pulled
-                continue
-        if opts.get('keep_descendant') and managed.is_on_descendant(rev):
-            continue
-        if not managed.update_or_pull_and_update(section, secconf, rev):
+        try:
+            confman.checkout_section(section, snaps, opts.get('keep_descendant', False))
+        except Exception:
             failedrepos.append(section)
 
     if failedrepos:

          
M hgext3rd/confman/configuration.py +70 -30
@@ 179,45 179,85 @@ class configurationmanager(object):
                 return newuri
         return uri
 
-    def fill_missing(self):
-        "Try to clone the missing managed repositories if possible"
+    def clone_section(self, section):
         from .managed import repoclassbyconf
 
         ui = self.ui
+
+        conf = self.confs[section]
+
+        dest = self.pathfromsection(section)
+        if not os.path.exists(dest):
+            os.makedirs(dest)
+        source = conf['pulluri'].format(**conf)
+        ui.status('cloning %s from %s to %s\n' % (section, source, dest))
+        try:
+            path = self.pathfromsection(section)
+            repoclassbyconf(conf, path, self.hggit).clone(
+                self, source, dest, self.confs[section]
+            )
+        except Exception as err:
+            # the clone operation did fail
+            self.failed.add(section)
+            ui.write('%s\n' % err, label='confman.dirty')
+            ui.debug(str(err))
+            shutil.rmtree(dest)
+            raise
+
+        # if managed is a sub configuration, we add the rootpath
+        # to its hgrc which allows to work from the managed confman
+        if conf.get('expand') is not None:
+            frompath = os.path.join(dest, '.hg')
+            key = 'hgrc.confman.rootpath'
+            if key in conf:
+                ui.info('there is already a %s' % key)
+            conf[key] = os.path.relpath(self.rootpath, frompath)
+        if set(conf) - set(CONFMANENTRIES):
+            # let's write down those options
+            self.handle_hgrc(section, conf)
+
+    def checkout_section(self, section, snaps, keep_descendant=False):
+        "clone or update a repository to the configured target"
+        ui = self.ui
+
+        secconf = self.confs[section]
+        managed = self.repofromsection(section)
+        if managed is None:
+            # we need a clone
+            self.clone_section(section)
+            managed = self.repofromsection(section)
+
+        layout = secconf['layout']
+        ui.write(section + '\n', label='confman.section')
+        snapshot = snaps.get(layout)
+        wctx = managed.workingctx()
+        if wctx.hex == snapshot:
+            return  # already up to date
+        if managed.check_dirty(section):
+            raise RuntimeError("could not checkout section %s" % section)
+        track = secconf.get('track')
+        rev = snapshot or track or 'default'
+        if managed.revsingle(rev, skiperror=True) == wctx:
+            if wctx.branch != track:
+                # branch tracks must always be pulled
+                return
+        if keep_descendant and managed.is_on_descendant(rev):
+            return
+        if not managed.update_or_pull_and_update(section, secconf, rev):
+            raise RuntimeError("could not checkout section %s" % section)
+
+    def fill_missing(self):
+        "Try to clone the missing managed repositories if possible"
+
         # catches simple rev ids but NOT revexprs
         for section, conf, managed in self.iterrepos(skipmissing=False):
             if managed is not None:
                 continue
 
-            dest = self.pathfromsection(section)
-            if not os.path.exists(dest):
-                os.makedirs(dest)
-            source = conf['pulluri'].format(**conf)
-            ui.status('cloning %s from %s to %s\n' % (section, source, dest))
             try:
-                path = self.pathfromsection(section)
-                repoclassbyconf(conf, path, self.hggit).clone(
-                    self, source, dest, self.confs[section]
-                )
-            except Exception as err:
-                # the clone operation did fail
-                self.failed.add(section)
-                ui.write('%s\n' % err, label='confman.dirty')
-                ui.debug(str(err))
-                shutil.rmtree(dest)
-                continue
-
-            # if managed is a sub configuration, we add the rootpath
-            # to its hgrc which allows to work from the managed confman
-            if conf.get('expand') is not None:
-                frompath = os.path.join(dest, '.hg')
-                key = 'hgrc.confman.rootpath'
-                if key in conf:
-                    ui.info('there is already a %s' % key)
-                conf[key] = os.path.relpath(self.rootpath, frompath)
-            if set(conf) - set(CONFMANENTRIES):
-                # let's write down those options
-                self.handle_hgrc(section, conf)
+                self.clone_section(section)
+            except Exception:
+                pass
 
     @util.cachefunc
     def levelstatus(self, section, level):