Merge branch 'master' into 3118-docker-fixes
[arvados.git] / crunch_scripts / subst.py
1 import os
2 import glob
3
4 def search(c):
5     DEFAULT = 0
6     DOLLAR = 1
7
8     i = 0
9     state = DEFAULT
10     start = None
11     depth = 0
12     while i < len(c):
13         if c[i] == '\\':
14             i += 1
15         elif state == DEFAULT:
16             if c[i] == '$':
17                 state = DOLLAR
18                 if depth == 0:
19                     start = i
20             elif c[i] == ')':
21                 if depth == 1:
22                     return [start, i]
23                 if depth > 0:
24                     depth -= 1
25         elif state == DOLLAR:
26             if c[i] == '(':
27                 depth += 1
28             state = DEFAULT
29         i += 1
30     if depth != 0:
31         raise Exception("Substitution error, mismatched parentheses {}".format(c))
32     return None
33
34 def sub_file(v):
35     return os.path.join(os.environ['TASK_KEEPMOUNT'], v)
36
37 def sub_dir(v):
38     d = os.path.dirname(v)
39     if d == '':
40         d = v
41     return os.path.join(os.environ['TASK_KEEPMOUNT'], d)
42
43 def sub_basename(v):
44     return os.path.splitext(os.path.basename(v))[0]
45
46 def sub_glob(v):
47     return glob.glob(v)[0]
48
49 default_subs = {"file ": sub_file,
50                 "dir ": sub_dir,
51                 "basename ": sub_basename,
52                 "glob ": sub_glob}
53
54 def do_substitution(p, c, subs=default_subs):
55     while True:
56         #print("c is", c)
57         m = search(c)
58         if m != None:
59             v = do_substitution(p, c[m[0]+2 : m[1]])
60             var = True
61             for sub in subs:
62                 if v.startswith(sub):
63                     r = subs[sub](v[len(sub):])
64                     var = False
65                     break
66             if var:
67                 r = p[v]
68
69             c = c[:m[0]] + r + c[m[1]+1:]
70         else:
71             return c