22from dataclasses import dataclass
33from argparse import ArgumentParser
44from subprocess import run , PIPE , STDOUT
5- from typing import List , Optional
5+ from typing import List , Optional , Union
6+ from pathlib import Path
7+
68import os
79import sys
810
1113class Args :
1214 output : Optional [str ]
1315 inputs : List [str ]
16+ exec : Path
1417 command : List [str ]
15- wd : str
18+ wd : Path
1619
1720
1821def parse_args () -> Args :
1922 parser = ArgumentParser ()
20- parser .add_argument ("-o" , "--output" , metavar = "FILE:ALIAS" ,
21- help = "expected output file to extract from the working directory" )
23+ parser .add_argument (
24+ "-o" ,
25+ "--output" ,
26+ metavar = "FILE:ALIAS" ,
27+ help = "expected output file to extract from the working directory" ,
28+ )
2229 parser .add_argument ("-d" , "--working-directory" , required = True )
23- parser .add_argument ("-i" , "--input" , nargs = "+" ,
24- help = "files to put in the context" , metavar = "FILE:ALIAS" )
30+ parser .add_argument (
31+ "-i" ,
32+ "--input" ,
33+ nargs = "+" ,
34+ help = "files to put in the context" ,
35+ metavar = "FILE:ALIAS" ,
36+ )
2537 parser .add_argument ("command" , nargs = "+" )
2638
2739 args = parser .parse_args ()
2840
2941 return Args (
3042 output = args .output ,
3143 inputs = args .input ,
32- command = args .command ,
33- wd = args .working_directory ,
44+ exec = Path (args .command [0 ]),
45+ command = args .command [1 :],
46+ wd = Path (args .working_directory ),
3447 )
3548
49+
3650# When run with `bazel run` directly when working directly is not the user's working directory
3751
3852
3953def chdir ():
4054 user_dir = os .getenv ("BUILD_WORKING_DIRECTORY" )
4155
4256 if user_dir :
43- print (f"chdir: { user_dir } " )
4457 os .chdir (user_dir )
4558
4659
@@ -50,7 +63,7 @@ def split_once_or_double(s: str, delimiter: str) -> List[str]:
5063 return parts if len (parts ) == 2 else [s , s ]
5164
5265
53- def copy_file (src : str , dst : str ):
66+ def copy_file (src : Union [ str , Path ], dst : Union [ str , Path ] ):
5467 with open (dst , "wb" ) as out :
5568 with open (src , "rb" ) as input :
5669 out .write (input .read ())
@@ -61,31 +74,29 @@ def main():
6174
6275 args = parse_args ()
6376
64- if os . path .exists (args . command [ 0 ] ):
65- args .command [ 0 ] = os . path . abspath ( args . command [ 0 ] )
77+ if args . exec .exists ():
78+ args .exec = args . exec . absolute ( )
6679
67- os . makedirs ( args .wd , exist_ok = True )
80+ args .wd . mkdir ( parents = True , exist_ok = True )
6881
6982 for input in args .inputs :
7083 src , alias = split_once_or_double (input , ":" )
71- dst = os .path .abspath (os .path .join (args .wd , alias ))
72-
73- os .makedirs (os .path .dirname (dst ), exist_ok = True )
84+ dst = args .wd .joinpath (alias ).absolute ()
85+ dst .parent .mkdir (parents = True , exist_ok = True )
7486
75- try :
76- os .link (src , dst )
77- except PermissionError :
78- copy_file (src , dst )
87+ copy_file (src , dst )
7988
80- p = run (args .command , stderr = STDOUT , stdout = PIPE , cwd = args .wd )
89+ p = run ([ args . exec ] + args .command , stderr = STDOUT , stdout = PIPE , cwd = args .wd )
8190
8291 if p .returncode != 0 :
83- print (p .stdout .decode ())
92+ print (
93+ f"Command exited with { p .returncode } :\n { p .stdout .decode ()} " , file = sys .stderr
94+ )
8495 sys .exit (p .returncode )
8596
8697 if args .output :
8798 file , alias = split_once_or_double (args .output , ":" )
88- copy_file (os . path . join ( args .wd , alias ), file )
99+ copy_file (args .wd . joinpath ( alias ), file )
89100 os .chmod (file , 0o644 )
90101
91102
0 commit comments