]> git.decadent.org.uk Git - dak.git/blobdiff - dak/external_overrides.py
Adjust to deal with the new Debian supplementaryGid
[dak.git] / dak / external_overrides.py
index a38fd5d2ac6cb7a679e11586e6d75dc23c7b30cb..40bdb80e67ac5ac7ff158d6daf422b68455f2cb5 100755 (executable)
@@ -33,21 +33,16 @@ def usage():
     print """Usage: dak external-overrides COMMAND
 Modify external overrides.
 
-  -h, --help show this help and exit.
+  -h, --help                    show this help and exit.
+  -f, --force                   allow processing of untouchable suites.
 
 Commands can use a long or abbreviated form:
 
-    remove KEY                 remove external overrides for KEY
-    rm KEY
+    import SUITE COMPONENT KEY  import external overrides for KEY
+    i SUITE COMPONENT KEY       NOTE: This will replace existing overrides.
 
-    import KEY                 import external overrides for KEY
-    i KEY                      NOTE: This will replace existing overrides.
-
-    show-key KEY               show external overrides for KEY
-    s-k KEY
-
-    show-package PACKAGE       show external overrides for PACKAGE
-    s-p PACKAGE
+    copy FROM TO                copy external overrides from suite FROM to TO
+                                NOTE: Needs --force for untouchable TO
 
 For the 'import' command, external overrides are read from standard input and
 should be given as lines of the form 'PACKAGE KEY VALUE'.
@@ -56,14 +51,93 @@ should be given as lines of the form 'PACKAGE KEY VALUE'.
 
 #############################################################################
 
-def external_overrides_import(key, file):
+class ExternalOverrideReader(object):
+    """
+    Parses an external override file
+    """
+    def __init__(self, fh):
+        self.fh = fh
+        self.package = None
+        self.key = None
+        self.value = []
+
+    def _flush(self):
+        """
+        Return the parsed line that is being built and start parsing a new line
+        """
+        res = self.package, self.key, "\n".join(self.value)
+        self.package = self.key = None
+        self.value = []
+        return res
+
+    def __iter__(self):
+        """
+        returns a (package, key, value) tuple for every entry in the external
+        override file
+        """
+        for line in self.fh:
+            if not line: continue
+            if line[0] in (" ", "\t"):
+                # Continuation line
+                self.value.append(line.rstrip())
+            else:
+                if self.package is not None:
+                    yield self._flush()
+
+                # New line
+                (self.package, self.key, value) = line.rstrip().split(None, 2)
+                self.value = [value]
+
+        if self.package is not None:
+            yield self._flush()
+
+#############################################################################
+
+def external_overrides_copy(from_suite_name, to_suite_name, force = False):
     session = DBConn().session()
 
-    session.query(ExternalOverride).filter_by(key=key).delete()
+    from_suite = get_suite(from_suite_name, session)
+    to_suite = get_suite(to_suite_name, session)
+
+    if from_suite is None:
+        print "E: source %s not found." % from_suite_name
+        session.rollback()
+        return False
+    if to_suite is None:
+        print "E: target %s not found." % to_suite_name
+        session.rollback()
+        return False
+
+    if not force and to_suite.untouchable:
+        print "E: refusing to touch untouchable suite %s (not forced)." % to_suite_name
+        session.rollback()
+        return False
+
+    session.query(ExternalOverride).filter_by(suite=to_suite).delete()
+    session.execute("""
+    INSERT INTO external_overrides (suite, component, package, key, value)
+      SELECT :to_suite, component, package, key, value FROM external_overrides WHERE suite = :from_suite
+    """, { 'from_suite': from_suite.suite_id, 'to_suite': to_suite.suite_id })
+
+    session.commit()
 
-    for line in file:
-        (package, key, value) = line.strip().split(None, 2)
+def external_overrides_import(suite_name, component_name, key, file, force = False):
+    session = DBConn().session()
+
+    suite = get_suite(suite_name, session)
+    component = get_component(component_name, session)
+
+    if not force and suite.untouchable:
+        print "E: refusing to touch untouchable suite %s (not forced)." % suite_name
+        session.rollback()
+        return False
+
+    session.query(ExternalOverride).filter_by(suite=suite,component=component,key=key).delete()
+
+    for package, key, value in ExternalOverrideReader(file):
         eo = ExternalOverride()
+        eo.suite = suite
+        eo.component = component
         eo.package = package
         eo.key = key
         eo.value = value
@@ -76,21 +150,29 @@ def external_overrides_import(key, file):
 def main():
     cnf = Config()
 
-    Arguments = [('h',"help","External-Overrides::Options::Help")]
+    Arguments = [('h',"help","External-Overrides::Options::Help"),
+                 ('f','force','External-Overrides::Options::Force')]
 
-    (command, arg) = apt_pkg.ParseCommandLine(cnf.Cnf, Arguments, sys.argv)
+    args = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
     try:
-        Options = cnf.SubTree("External-Overrides::Options")
+        Options = cnf.subtree("External-Overrides::Options")
     except KeyError:
         Options = {}
 
     if Options.has_key("Help"):
         usage()
 
-    logger = daklog.Logger(cnf, 'external-overrides')
+    force = False
+    if Options.has_key("Force") and Options["Force"]:
+        force = True
+
+    logger = daklog.Logger('external-overrides')
 
+    command = args[0]
     if command in ('import', 'i'):
-        external_overrides_import(arg, sys.stdin)
+        external_overrides_import(args[1], args[2], args[3], sys.stdin, force)
+    elif command in ('copy', 'c'):
+        external_overrides_copy(args[1], args[2], force)
     else:
         print "E: Unknown commands."