+
+def filename_regex_substitution(f):
+ """
+ This is a decorator to apply to functions that take a name and return
+ (filename, RegexObject) tuples. It converts it into a function
+ that takes a name and returns another function (that does substitution)
+ which takes a deployment and modifies its files to replace explicit
+ values with their generic WIZARD_* equivalents. The final function returns
+ the number of replacements made.
+
+ The regular expression requires a very specific form, essentially ()()()
+ (with the second subgroup being the value to be replaced).
+
+ Its Haskell-style type signature would be::
+
+ (String -> ([Filename], Regex)) -> (String -> (Deployment -> IO Int))
+
+ For convenience purposes, we also accept Filename, in which case it is treated
+ as a single item list.
+ """
+ def g(key, var):
+ files, regex = f(var)
+ if isinstance(files, str):
+ files = (files,)
+ def h(deployment):
+ base = deployment.location
+ subs = 0
+ for file in files:
+ file = os.path.join(base, file)
+ contents = open(file, "r").read()
+ contents, n = regex.subn("\\1" + key + "\\3", contents)
+ subs += n
+ open(file, "w").write(contents)
+ return subs
+ return h
+ return g
+