3
3
import re
4
4
5
5
6
+ ###############################################################################################
7
+ ###
8
+ ### print, with the ability to replace strings, or suppress lines
9
+ ###
10
+
11
+
6
12
def output (* args , ** kwargs ):
7
13
"""
8
14
Prints the given arguments after performing replacements and suppressions.
@@ -41,21 +47,142 @@ def output(*args, **kwargs):
41
47
print (* str_args , file = file , end = end )
42
48
43
49
44
- def command_regexp (command ):
45
- """
46
- Processes a file based on the given predicates, replacements, and suppressions.
47
- Args:
48
- filename (str): The name of the file to process.
49
- predicate_list (list): A list of predicates to match in the file.
50
- replace_list (list): A list of tuples where the first element of each tuple is replaced with the second element in the output.
51
- suppress_list (list): A list of strings. If any string in this list is found in the output, the line is not printed.
52
- Returns:
53
- None
54
- """
55
- return rf"^\[\s*{ command } \s+(\w+)\s*\]\s*:\s*(.*)"
50
+ ###############################################################################################
51
+ ###
52
+ ### processing logic for optional argument in lines
53
+ ###
54
+
55
+
56
+ def remove_text_between_brackets (text ):
57
+ return re .sub (r"\[.*?\]" , "" , text )
58
+
59
+
60
+ def extract_text_between_brackets (text ):
61
+ return re .findall (r"\[(.*?)\]" , text )
62
+
63
+
64
+ def specialize_option (text , replacement ):
65
+ return re .sub (r"\[.*?\]" , replacement , text )
66
+
67
+
68
+ ###############################################################################################
69
+ ###
70
+ ### process a line either suppressing or expanding options
71
+ ###
72
+
73
+
74
+ def updown_process_line (
75
+ line , lineno , filename , replace_list , suppress_list , expand_options
76
+ ):
77
+ if not expand_options :
78
+ output (
79
+ remove_text_between_brackets (line ),
80
+ replace_list = replace_list ,
81
+ suppress_list = suppress_list ,
82
+ )
83
+ else :
84
+ options = extract_text_between_brackets (line )
85
+ if len (options ) == 0 :
86
+ output (
87
+ line ,
88
+ replace_list = replace_list ,
89
+ suppress_list = suppress_list ,
90
+ )
91
+ return
92
+ if len (options ) > 1 :
93
+ output (
94
+ "echo 'cross product of options not yet supported anot line {line} of {filename}'\n exit 1" ,
95
+ suppress_list = None ,
96
+ replace_list = None ,
97
+ )
98
+ exit (1 )
99
+ for option in options [0 ].split ("|" ):
100
+ output (
101
+ specialize_option (line , option ),
102
+ replace_list = replace_list ,
103
+ suppress_list = suppress_list ,
104
+ )
105
+
56
106
107
+ ###############################################################################################
108
+ ###
109
+ ### process an updown command
110
+ ###
57
111
58
- def updown_processor (filename , predicate_list , replace_list , suppress_list ):
112
+
113
+ def process_command (
114
+ line , lineno , filename , predicate_list , replace_list , suppress_list
115
+ ) -> bool :
116
+
117
+ command = r"^\[\s*(\w+)\s+(\w+)\s*\]\s*:\s*(.*)"
118
+ match = re .search (command , line )
119
+
120
+ if not match :
121
+ # We have not processed this line as a command
122
+ return False
123
+
124
+ keyword = match .group (1 )
125
+ predicate = match .group (2 )
126
+ trailing_command = match .group (3 )
127
+
128
+ if predicate not in predicate_list :
129
+ # We have processed this line as a command
130
+ return True
131
+
132
+ if keyword == "shell" :
133
+ output (
134
+ trailing_command ,
135
+ replace_list = replace_list ,
136
+ suppress_list = suppress_list ,
137
+ )
138
+ elif keyword == "prefix" :
139
+ output (
140
+ trailing_command [:- 1 ],
141
+ end = "" ,
142
+ replace_list = replace_list ,
143
+ suppress_list = suppress_list ,
144
+ )
145
+ elif keyword == "skip" :
146
+ if trailing_command == "begin" :
147
+ output (
148
+ "if false; then" ,
149
+ replace_list = replace_list ,
150
+ suppress_list = suppress_list ,
151
+ )
152
+ elif trailing_command == "end" :
153
+ output (
154
+ "fi" ,
155
+ replace_list = replace_list ,
156
+ suppress_list = suppress_list ,
157
+ )
158
+ else :
159
+ output (
160
+ f"echo 'error in line { lineno } of { filename } '\n exit 1;" ,
161
+ suppress_list = None ,
162
+ replace_list = None ,
163
+ )
164
+ exit (1 )
165
+ elif keyword == "end" :
166
+ output (
167
+ "exit 0" ,
168
+ replace_list = replace_list ,
169
+ suppress_list = suppress_list ,
170
+ )
171
+ exit (0 )
172
+
173
+ # We have processed this line as a command
174
+ return True
175
+
176
+
177
+ ###############################################################################################
178
+ ###
179
+ ### updown processing of the input file
180
+ ###
181
+
182
+
183
+ def updown_processor (
184
+ filename , predicate_list , replace_list , suppress_list , expand_options
185
+ ):
59
186
"""
60
187
Processes a file based on the given predicates, replacements, and suppressions.
61
188
Args:
@@ -69,72 +196,34 @@ def updown_processor(filename, predicate_list, replace_list, suppress_list):
69
196
with open (filename , "r" ) as file :
70
197
lines = file .readlines ()
71
198
print_flag = False
199
+
72
200
output ("set -eou pipefail" , replace_list = None , suppress_list = None )
73
- for i , line in enumerate (lines ):
74
- shell = command_regexp ("shell" )
75
- prefix = command_regexp ("prefix" )
76
- skip = command_regexp ("skip" )
77
- end = command_regexp ("end" )
78
- if match := re .search (shell , line ):
79
- # Extract the matched groups
80
- predicate = match .group (1 )
81
- trailing_command = match .group (2 )
82
- if predicate in predicate_list :
83
- output (
84
- trailing_command ,
85
- replace_list = replace_list ,
86
- suppress_list = suppress_list ,
87
- )
88
- elif match := re .search (prefix , line ):
89
- # Extract the matched groups
90
- predicate = match .group (1 )
91
- trailing_command = match .group (2 )
92
- if predicate in predicate_list :
93
- output (
94
- trailing_command ,
95
- end = "" ,
96
- replace_list = replace_list ,
97
- suppress_list = suppress_list ,
98
- )
99
- elif match := re .search (skip , line ):
100
- # Extract the matched groups
101
- predicate = match .group (1 )
102
- trailing_command = match .group (2 )
103
- if predicate in predicate_list :
104
- if trailing_command == "begin" :
105
- output (
106
- "if false; then" ,
107
- replace_list = replace_list ,
108
- suppress_list = suppress_list ,
109
- )
110
- elif trailing_command == "end" :
111
- output (
112
- "fi" ,
113
- replace_list = replace_list ,
114
- suppress_list = suppress_list ,
115
- )
116
- else :
117
- output (
118
- f"echo 'error in line { i } of { filename } '\n exit 1;" ,
119
- suppress_list = None ,
120
- replace_list = None ,
121
- )
122
- exit (1 )
123
- elif match := re .search (end , line ):
124
- # Extract the matched groups
125
- predicate = match .group (1 )
126
- trailing_command = match .group (2 )
127
- if predicate in predicate_list :
128
- output (
129
- "exit 0" ,
130
- replace_list = replace_list ,
131
- suppress_list = suppress_list ,
132
- )
133
- return
201
+
202
+ for lineno , line in enumerate (lines ):
203
+ # clip trailing newline
204
+ if line .endswith ("\n " ):
205
+ line = line [:- 1 ]
206
+
207
+ if process_command (
208
+ line = line ,
209
+ lineno = lineno ,
210
+ filename = filename ,
211
+ predicate_list = predicate_list ,
212
+ replace_list = replace_list ,
213
+ suppress_list = suppress_list ,
214
+ ):
215
+ pass
134
216
elif line .startswith ("```" ):
135
217
print_flag = not print_flag
136
218
elif print_flag :
137
- output (line , end = "" , replace_list = replace_list , suppress_list = suppress_list )
219
+ updown_process_line (
220
+ line = line ,
221
+ lineno = lineno ,
222
+ filename = filename ,
223
+ expand_options = expand_options ,
224
+ replace_list = replace_list ,
225
+ suppress_list = suppress_list ,
226
+ )
138
227
139
228
output (
140
229
"echo 'reached end of file without exit command'\n exit 1;" ,
@@ -143,28 +232,46 @@ def updown_processor(filename, predicate_list, replace_list, suppress_list):
143
232
)
144
233
145
234
146
- # Initialize the ArgumentParser object
147
- parser = argparse .ArgumentParser ()
148
- # Add arguments
149
- parser .add_argument ("-f" , "--filename" , help = "Input filename" , default = "README.md" )
150
- parser .add_argument ("-p" , "--predicate" , help = "Input predicates" , default = "" )
151
- parser .add_argument ("-r" , "--replace" , help = "Input replace pairs" , default = "" )
152
- parser .add_argument ("-s" , "--suppress" , help = "Input suppress strings" , default = "" )
153
- args = parser .parse_args ()
154
- # Get filename
155
- filename = args .filename
156
- # Check if file exists
157
- if not os .path .isfile (filename ):
158
- output (f"echo 'File { filename } does not exist.'\n exit 1;" )
159
- exit (1 )
160
- # Get predicates, split by comma, and add "default"
161
- predicate_list = args .predicate .split ("," ) if args .predicate else []
162
- predicate_list .append ("default" )
163
- # Get replace pairs, split by comma, and turn into a list of tuples
164
- replace_list = (
165
- [tuple (pair .split (":" )) for pair in args .replace .split ("," )] if args .replace else []
166
- )
167
- # Get suppress strings, split by comma
168
- suppress_list = args .suppress .split ("," ) if args .suppress else []
169
- # Call updown_processor function
170
- updown_processor (filename , predicate_list , replace_list , suppress_list )
235
+ ###############################################################################################
236
+ ###
237
+ ### updown processing of the input file
238
+ ###
239
+
240
+
241
+ def main ():
242
+ # Initialize the ArgumentParser object
243
+ parser = argparse .ArgumentParser ()
244
+ # Add arguments
245
+ parser .add_argument ("-f" , "--filename" , help = "Input filename" , default = "README.md" )
246
+ parser .add_argument ("-p" , "--predicate" , help = "Input predicates" , default = "" )
247
+ parser .add_argument ("-r" , "--replace" , help = "Input replace pairs" , default = "" )
248
+ parser .add_argument ("-s" , "--suppress" , help = "Input suppress strings" , default = "" )
249
+ parser .add_argument (
250
+ "-e" , "--expand-options" , action = "store_true" , help = "Expand options flag"
251
+ )
252
+ args = parser .parse_args ()
253
+ # Get filename
254
+ filename = args .filename
255
+ # Check if file exists
256
+ if not os .path .isfile (filename ):
257
+ output (f"echo 'File { filename } does not exist.'\n exit 1;" )
258
+ exit (1 )
259
+ # Get predicates, split by comma, and add "default"
260
+ predicate_list = args .predicate .split ("," ) if args .predicate else []
261
+ predicate_list .append ("default" )
262
+ # Get replace pairs, split by comma, and turn into a list of tuples
263
+ replace_list = (
264
+ [tuple (pair .split (":" )) for pair in args .replace .split ("," )]
265
+ if args .replace
266
+ else []
267
+ )
268
+ # Get suppress strings, split by comma
269
+ suppress_list = args .suppress .split ("," ) if args .suppress else []
270
+ # Call updown_processor function
271
+ updown_processor (
272
+ filename , predicate_list , replace_list , suppress_list , args .expand_options
273
+ )
274
+
275
+
276
+ if __name__ == "__main__" :
277
+ main ()
0 commit comments