summaryrefslogtreecommitdiff
path: root/morphlib/cmdline_parse_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/cmdline_parse_utils.py')
-rw-r--r--morphlib/cmdline_parse_utils.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/morphlib/cmdline_parse_utils.py b/morphlib/cmdline_parse_utils.py
new file mode 100644
index 00000000..c5e08ec1
--- /dev/null
+++ b/morphlib/cmdline_parse_utils.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+# Copyright © 2015 Codethink Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+from itertools import groupby as _groupby
+from itertools import takewhile as _takewhile
+
+from cliapp import AppException as _AppException
+
+
+from .utils import word_join_list as _word_join_list
+
+
+def _split(iterable, split_token):
+ sequence = []
+ for token in iterable:
+ if token == split_token:
+ yield tuple(sequence)
+ sequence = []
+ else:
+ sequence.append(token)
+ if sequence:
+ yield tuple(sequence)
+
+
+class SystemsSpecsParseWrongNumber(_AppException):
+ def __init__(self, specs, definitions_names):
+ self.specs = specs
+ self.definitions_names = definitions_names
+ msg = 'From expected definition specs {expected};'.format(
+ expected=_word_join_list(map(repr, definitions_names)))
+ if len(specs) < len(definitions_names):
+ missing_spec_names = definitions_names[len(specs):]
+ super(SystemsSpecsParseWrongNumber, self).__init__(
+ '{msg} missing {missing}'.format(
+ msg=msg,
+ missing=_word_join_list(map(repr, missing_spec_names))))
+ else:
+ super(SystemsSpecsParseWrongNumber, self).__init__(
+ '{msg} {extra} extra specs given'.format(
+ msg=msg,
+ extra=len(specs) - len(definitions_names)))
+
+
+class SystemsSpecsParseWrongFormat(_AppException):
+ def __init__(self, definition_list_name_list, malformed_definition_lists):
+ self.definition_list_name_list = definition_list_name_list
+ self.malformed_definition_lists = malformed_definition_lists
+ errors = []
+ for spec, name, i in malformed_definition_lists:
+ pre = 'Spec {i} named {name!r}'.format(i=i, name=name)
+ if not spec:
+ errors.append(pre + ' is empty, want REPO REF SYSTEM...')
+ elif len(spec) == 1:
+ errors.append(pre + ' missing REF, want REPO REF SYSTEM...')
+ super(SystemsSpecsParseWrongFormat, self).__init__(
+ 'From expected definition specs {expected}:\n\t{errors}'.format(
+ expected=_word_join_list(map(repr, definition_list_name_list)),
+ errors='\n\t'.join(errors)))
+
+
+def parse_definition_lists(definition_list_name_list, args):
+ specs = tuple(_split(args, '-'))
+ if len(specs) != len(definition_list_name_list):
+ raise SystemsSpecsParseWrongNumber(specs, definition_list_name_list)
+
+ malformed_definition_lists = []
+ specinfo = enumerate(zip(definition_list_name_list, specs), start=1)
+ for i, (definition_list_name, definitions_spec) in specinfo:
+ if len(definitions_spec) < 2:
+ malformed_definition_lists.append(
+ (definitions_spec, definition_list_name, i))
+ if malformed_definition_lists:
+ raise SystemsSpecsParseWrongFormat(definition_list_name_list,
+ malformed_definition_lists)
+
+ return ((spec[0], spec[1], spec[2:]) for spec in specs)