1#! /usr/bin/env python3
3"""
4Modify external overrides.
6@contact: Debian FTP Master <ftpmaster@debian.org>
7@copyright: 2011 Ansgar Burchardt <ansgar@debian.org>
8@license: GNU General Public License version 2 or later
9"""
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25from daklib.dbconn import *
26from daklib.config import Config
27from daklib import daklog
29import apt_pkg
30import sys
33def usage():
34 print("""Usage: dak external-overrides COMMAND
35Modify external overrides.
37 -h, --help show this help and exit.
38 -f, --force allow processing of untouchable suites.
40Commands can use a long or abbreviated form:
42 import SUITE COMPONENT KEY import external overrides for KEY
43 i SUITE COMPONENT KEY NOTE: This will replace existing overrides.
45 copy FROM TO copy external overrides from suite FROM to TO
46 NOTE: Needs --force for untouchable TO
48For the 'import' command, external overrides are read from standard input and
49should be given as lines of the form 'PACKAGE KEY VALUE'.
50""")
51 sys.exit()
53#############################################################################
56class ExternalOverrideReader:
57 """
58 Parses an external override file
59 """
61 def __init__(self, fh):
62 self.fh = fh
63 self.package = None
64 self.key = None
65 self.value = []
67 def _flush(self):
68 """
69 Return the parsed line that is being built and start parsing a new line
70 """
71 res = self.package, self.key, "\n".join(self.value)
72 self.package = self.key = None
73 self.value = []
74 return res
76 def __iter__(self):
77 """
78 returns a (package, key, value) tuple for every entry in the external
79 override file
80 """
81 for line in self.fh:
82 if not line:
83 continue
84 if line[0] in (" ", "\t"):
85 # Continuation line
86 self.value.append(line.rstrip())
87 else:
88 if self.package is not None:
89 yield self._flush()
91 # New line
92 (self.package, self.key, value) = line.rstrip().split(None, 2)
93 self.value = [value]
95 if self.package is not None:
96 yield self._flush()
98#############################################################################
101def external_overrides_copy(from_suite_name, to_suite_name, force=False):
102 session = DBConn().session()
104 from_suite = get_suite(from_suite_name, session)
105 to_suite = get_suite(to_suite_name, session)
107 if from_suite is None:
108 print("E: source %s not found." % from_suite_name)
109 session.rollback()
110 return False
111 if to_suite is None:
112 print("E: target %s not found." % to_suite_name)
113 session.rollback()
114 return False
116 if not force and to_suite.untouchable:
117 print("E: refusing to touch untouchable suite %s (not forced)." % to_suite_name)
118 session.rollback()
119 return False
121 session.query(ExternalOverride).filter_by(suite=to_suite).delete()
122 session.execute("""
123 INSERT INTO external_overrides (suite, component, package, key, value)
124 SELECT :to_suite, component, package, key, value FROM external_overrides WHERE suite = :from_suite
125 """, {'from_suite': from_suite.suite_id, 'to_suite': to_suite.suite_id})
127 session.commit()
130def external_overrides_import(suite_name, component_name, key, file, force=False):
131 session = DBConn().session()
133 suite = get_suite(suite_name, session)
134 component = get_component(component_name, session)
136 if not force and suite.untouchable:
137 print("E: refusing to touch untouchable suite %s (not forced)." % suite_name)
138 session.rollback()
139 return False
141 session.query(ExternalOverride).filter_by(suite=suite, component=component, key=key).delete()
143 for package, key, value in ExternalOverrideReader(file):
144 eo = ExternalOverride()
145 eo.suite = suite
146 eo.component = component
147 eo.package = package
148 eo.key = key
149 eo.value = value
150 session.add(eo)
152 session.commit()
154#############################################################################
157def main():
158 cnf = Config()
160 Arguments = [('h', "help", "External-Overrides::Options::Help"),
161 ('f', 'force', 'External-Overrides::Options::Force')]
163 args = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
164 try:
165 Options = cnf.subtree("External-Overrides::Options")
166 except KeyError:
167 Options = {}
169 if "Help" in Options: 169 ↛ 172line 169 didn't jump to line 172, because the condition on line 169 was never false
170 usage()
172 force = False
173 if "Force" in Options and Options["Force"]:
174 force = True
176 logger = daklog.Logger('external-overrides')
178 command = args[0]
179 if command in ('import', 'i'):
180 external_overrides_import(args[1], args[2], args[3], sys.stdin, force)
181 elif command in ('copy', 'c'):
182 external_overrides_copy(args[1], args[2], force)
183 else:
184 print("E: Unknown commands.")
187if __name__ == '__main__':
188 main()