blob: f306109d7809024b51fc7f7868f67fbcad09402c [file] [log] [blame]
Andrew Geissler1fe918a2020-05-15 14:16:47 -05001#!/usr/bin/env python3
Richard Marian Thomaiyar14fddef2018-07-13 23:55:56 +05302
3#Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org>
4
5import argparse, os, shutil, sys, tempfile, traceback
6from os import path
7
8
9
10def get_config(lines):
11 """
12 From a sequence of lines retrieve the question file name, question identifier
13 pairs.
14 """
15 for l in lines:
16 if not l.startswith("#"):
17 try:
18 (coord, value) = l.split("=")
19 try:
20 (fname, ident) = coord.split(".")
21 yield fname, ident
22 except ValueError as e:
23 raise ValueError("Badly formatted coordinates %s in line %s." % (coord, l.strip()))
24 except ValueError as e:
25 raise ValueError("Skipping badly formatted line %s, %s" % (l.strip(), e))
26
27
28
29def check_contains(line, name):
30 """
31 Check if the value field for REQUIRE_DISTRO contains the given name.
32 @param name line The REQUIRE_DISTRO line
33 @param name name The name to look for in the value field of the line.
34 """
35 try:
36 (label, distros) = line.split(":")
37 return name in distros.split()
38 except ValueError as e:
39 raise ValueError("Error splitting REQUIRE_DISTRO line: %s" % e)
40
41
42
43def add_requires(the_ident, distro, lines):
44
45 """
46 Yield a sequence of lines the same as lines except that where
47 the_ident matches a question identifier change the REQUIRE_DISTRO so that
48 it includes the specified distro.
49
50 @param name the_ident The question identifier to be matched.
51 @param name distro The distribution to added to the questions REQUIRE_DISTRO
52 field.
53 @param lines The sequence to be processed.
54 """
55 for l in lines:
56 yield l
57 if l.startswith("LABEL:"):
58 try:
59 (label, ident) = l.split(":")
60 if ident.strip() == the_ident:
61 break
62 except ValueError as e:
63 raise ValueError("Unexpected line %s in questions file." % l.strip())
64 for l in lines:
65 if l.startswith("REQUIRE_DISTRO"):
66 if not check_contains(l, distro):
67 yield l.rstrip() + " " + distro + "\n"
68 else:
69 yield l
70 break;
71 else:
72 yield l
73 for l in lines:
74 yield l
75
76
77
78def xform_file(qfile, distro, qlabel):
79 """
80 Transform a Questions file.
81 @param name qfile The designated questions file.
82 @param name distro The distribution to add to the required distributions.
83 @param name qlabel The question label for which the distro is to be added.
84 """
85 questions_in = open(qfile)
Andrew Geissler1fe918a2020-05-15 14:16:47 -050086 questions_out = tempfile.NamedTemporaryFile(mode="w+", delete=False)
Richard Marian Thomaiyar14fddef2018-07-13 23:55:56 +053087 for l in add_requires(qlabel, distro, questions_in):
88 questions_out.write(l)
89 questions_out.close()
90 questions_in.close()
91 shutil.copystat(qfile, questions_out.name)
92 os.remove(qfile)
93 shutil.move(questions_out.name, qfile)
94
95
96
97def handle_args(parser):
98 parser.add_argument('config_file',
99 help = "Configuration file path.")
100 parser.add_argument('questions_dir',
101 help = "Directory containing Questions files.")
102 parser.add_argument('--distro', '-d',
103 help = "The distribution, the default is Yocto.",
104 default = "Yocto")
105 parser.add_argument('--debug', '-b',
106 help = "Print debug information.",
107 action = 'store_true')
108 return parser.parse_args()
109
110
111
112def check_args(args):
113 args.config_file = os.path.abspath(args.config_file)
114 args.questions_dir = os.path.abspath(args.questions_dir)
115
116 if not os.path.isdir(args.questions_dir):
117 raise ValueError("Specified Questions directory %s does not exist or is not a directory." % args.questions_dir)
118
119 if not os.path.isfile(args.config_file):
120 raise ValueError("Specified configuration file %s not found." % args.config_file)
121
122
123
124def main():
125 opts = handle_args(argparse.ArgumentParser(description="A simple script that sets required questions based on the question/answer pairs in a configuration file."))
126
127 try:
128 check_args(opts)
129 except ValueError as e:
130 if opts.debug:
131 traceback.print_exc()
132 else:
133 sys.exit("Fatal error:\n%s" % e)
134
135
136 try:
137 config_in = open(opts.config_file)
138 for qfile, qlabel in get_config(config_in):
139 questions_file = os.path.join(opts.questions_dir, qfile + ".txt")
140 xform_file(questions_file, opts.distro, qlabel)
141 config_in.close()
142
143 except IOError as e:
144 if opts.debug:
145 traceback.print_exc()
146 else:
147 sys.exit("Fatal error reading or writing file:\n%s" % e)
148 except ValueError as e:
149 if opts.debug:
150 traceback.print_exc()
151 else:
152 sys.exit("Fatal error:\n%s" % e)
153
154
155
156if __name__ == "__main__":
157 main()