44import re
55from typing import List , Optional , Set , Match
66
7- def expand_tokens (argv : List [str ]) -> List [str ]:
7+ def expand_tokens (argv : List [str ], path ) -> List [str ]:
88 """
99 Expand environment variables in args
1010 """
11- pattern = re .compile (r"\$(\w+|\{[^}]*\})" )
12- def repl (m : Match ) -> str :
13- k = m .group (1 )
14- if k .startswith ("{" ) and k .endswith ("}" ):
15- k = k [1 :- 1 ]
11+ token_queries = [
12+ ("cwd" , r"\$\{\{this_dir\}\}" ), # ${{this_dir}}
13+ ("env1" , r"\$(\w+)" ), # $ENV_VAR
14+ ("env2" , r"\$\{(\w+)\}" ), # ${ENV_VAR}
15+ ]
16+ token_regex = re .compile (
17+ '|' .join ('(?P<%s>%s)' % pair for pair in token_queries )
18+ )
1619
17- v = os .environ .get (k , m .group (0 ))
18- return v
20+ def repl (m : Match ) -> str :
21+ if m .lastgroup in {"env1" , "env2" }:
22+ k = m .group (m .lastindex + 1 )
23+ if k in os .environ :
24+ v = os .environ .get (k )
25+ else :
26+ print (f"warning: environment variable '{ k } ' is not set" , file = sys .stderr )
27+ v = ""
28+ return v
29+ elif m .lastgroup == "cwd" :
30+ this_dir = os .path .normpath (os .path .dirname (path ))
31+ return this_dir
32+ else :
33+ raise RuntimeError
1934
20- return [pattern .sub (repl , arg ) for arg in argv ]
35+ return [token_regex .sub (repl , arg ) for arg in argv ]
2136
2237
2338def parse_argfile (path : str ) -> List [str ]:
@@ -27,7 +42,7 @@ def parse_argfile(path: str) -> List[str]:
2742
2843 with open (path , "r" , encoding = 'utf-8' ) as f :
2944 args = shlex .split (f .read (), comments = True )
30- args = expand_tokens (args )
45+ args = expand_tokens (args , path )
3146 return args
3247
3348
0 commit comments