@@ -679,9 +679,10 @@ def plan(self, source_path, query):
679
679
680
680
source_paths = []
681
681
build_plan = []
682
+ build_step = []
682
683
683
684
def step (* x ):
684
- build_plan .append (x )
685
+ build_step .append (x )
685
686
686
687
def hash (path ):
687
688
source_paths .append (path )
@@ -754,30 +755,30 @@ def commands_step(path, commands):
754
755
755
756
if path :
756
757
path = os .path .normpath (path )
758
+ step ("set:workdir" , path )
759
+
757
760
batch = []
758
761
for c in commands :
759
762
if isinstance (c , str ):
760
763
if c .startswith (":zip" ):
761
764
if path :
762
765
hash (path )
763
766
if batch :
764
- step ("sh" , path , "\n " .join (batch ))
767
+ step ("sh" , "\n " .join (batch ))
765
768
batch .clear ()
766
769
c = shlex .split (c )
767
- if len (c ) == 3 :
770
+ n = len (c )
771
+ if n == 3 :
768
772
_ , _path , prefix = c
769
773
prefix = prefix .strip ()
770
- _path = os .path .normpath (os . path . join ( path , _path ) )
774
+ _path = os .path .normpath (_path )
771
775
step ("zip:embedded" , _path , prefix )
772
- elif len ( c ) == 2 :
776
+ elif n == 2 :
773
777
_ , _path = c
774
- prefix = None
775
778
_path = os .path .normpath (_path )
776
- step ("zip:embedded" , _path , prefix )
777
- elif len (c ) == 1 :
778
- prefix = None
779
- _path = None
780
- step ("zip:embedded" , _path , prefix )
779
+ step ("zip:embedded" , _path )
780
+ elif n == 1 :
781
+ step ("zip:embedded" )
781
782
else :
782
783
raise ValueError (
783
784
":zip invalid call signature, use: "
@@ -786,11 +787,9 @@ def commands_step(path, commands):
786
787
else :
787
788
batch .append (c )
788
789
if batch :
789
- step ("sh" , path , "\n " .join (batch ))
790
+ step ("sh" , "\n " .join (batch ))
790
791
batch .clear ()
791
792
792
- step ("reset:workdir" )
793
-
794
793
for claim in claims :
795
794
if isinstance (claim , str ):
796
795
path = claim
@@ -877,12 +876,13 @@ def commands_step(path, commands):
877
876
hash (path_from_pattern )
878
877
else :
879
878
hash (path )
880
-
881
- if patterns :
882
- step ("clear:filter" )
883
879
else :
884
880
raise ValueError ("Unsupported source_path item: {}" .format (claim ))
885
881
882
+ if build_step :
883
+ build_plan .append (build_step )
884
+ build_step = []
885
+
886
886
self ._source_paths = source_paths
887
887
return build_plan
888
888
@@ -895,125 +895,145 @@ def execute(self, build_plan, zip_stream, query):
895
895
sh_work_dir = None
896
896
pf = None
897
897
898
- for action in build_plan :
899
- cmd = action [0 ]
900
- if cmd .startswith ("zip" ):
901
- ts = 0 if cmd == "zip:embedded" else None
902
- source_path , prefix = action [1 :]
903
- if not sh_work_dir :
904
- sh_work_dir = tf_work_dir
905
- log .debug ("WORKDIR: %s" , sh_work_dir )
906
- if source_path :
907
- if not os .path .isabs (source_path ):
908
- source_path = os .path .normpath (
909
- os .path .join (sh_work_dir , source_path )
910
- )
911
- else :
912
- source_path = sh_work_dir
913
- if os .path .isdir (source_path ):
914
- if pf :
915
- self ._zip_write_with_filter (
916
- zs , pf , source_path , prefix , timestamp = ts
917
- )
898
+ for step in build_plan :
899
+ # init step
900
+ sh_work_dir = tf_work_dir
901
+ if pf :
902
+ pf .reset ()
903
+ pf = None
904
+
905
+ log .debug ("STEPDIR: %s" , sh_work_dir )
906
+
907
+ # execute step actions
908
+ for action in step :
909
+ cmd = action [0 ]
910
+ if cmd .startswith ("zip" ):
911
+ ts = 0 if cmd == "zip:embedded" else None
912
+
913
+ source_path , prefix = None , None
914
+ n = len (action )
915
+ if n == 2 :
916
+ source_path = action [1 ]
917
+ elif n == 3 :
918
+ source_path , prefix = action [1 :]
919
+
920
+ if source_path :
921
+ if not os .path .isabs (source_path ):
922
+ source_path = os .path .normpath (
923
+ os .path .join (sh_work_dir , source_path )
924
+ )
918
925
else :
919
- zs .write_dirs (source_path , prefix = prefix , timestamp = ts )
920
- else :
921
- zs .write_file (source_path , prefix = prefix , timestamp = ts )
922
- elif cmd == "pip" :
923
- runtime , pip_requirements , prefix , tmp_dir = action [1 :]
924
- with install_pip_requirements (query , pip_requirements , tmp_dir ) as rd :
925
- if rd :
926
+ source_path = sh_work_dir
927
+ if os .path .isdir (source_path ):
926
928
if pf :
927
- self ._zip_write_with_filter (zs , pf , rd , prefix , timestamp = 0 )
928
- else :
929
- # XXX: timestamp=0 - what actually do with it?
930
- zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
931
- elif cmd == "poetry" :
932
- (
933
- runtime ,
934
- path ,
935
- poetry_export_extra_args ,
936
- prefix ,
937
- ) = action [1 :]
938
- log .info ("poetry_export_extra_args: %s" , poetry_export_extra_args )
939
- with install_poetry_dependencies (
940
- query , path , poetry_export_extra_args
941
- ) as rd :
942
- if rd :
943
- if pf :
944
- self ._zip_write_with_filter (zs , pf , rd , prefix , timestamp = 0 )
945
- else :
946
- # XXX: timestamp=0 - what actually do with it?
947
- zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
948
- elif cmd == "npm" :
949
- runtime , npm_requirements , prefix , tmp_dir = action [1 :]
950
- with install_npm_requirements (query , npm_requirements , tmp_dir ) as rd :
951
- if rd :
952
- if pf :
953
- self ._zip_write_with_filter (zs , pf , rd , prefix , timestamp = 0 )
929
+ self ._zip_write_with_filter (
930
+ zs , pf , source_path , prefix , timestamp = ts
931
+ )
954
932
else :
955
- # XXX: timestamp=0 - what actually do with it?
956
- zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
957
- elif cmd == "sh" :
958
- with tempfile .NamedTemporaryFile (mode = "w+t" , delete = True ) as temp_file :
959
- path , script = action [1 :]
960
-
961
- if not path :
962
- path = tf_work_dir
963
- if not os .path .isabs (path ):
964
- path = os .path .normpath (os .path .join (tf_work_dir , path ))
965
-
966
- if log .isEnabledFor (DEBUG2 ):
967
- log .debug ("exec shell script ..." )
968
- for line in script .splitlines ():
969
- sh_log .debug (line )
970
-
971
- script = "\n " .join (
972
- (
973
- script ,
974
- # NOTE: Execute `pwd` to determine the subprocess shell's
975
- # working directory after having executed all other commands.
976
- "retcode=$?" ,
977
- f"pwd >{ temp_file .name } " ,
978
- "exit $retcode" ,
933
+ zs .write_dirs (source_path , prefix = prefix , timestamp = ts )
934
+ else :
935
+ zs .write_file (source_path , prefix = prefix , timestamp = ts )
936
+ elif cmd == "pip" :
937
+ runtime , pip_requirements , prefix , tmp_dir = action [1 :]
938
+ with install_pip_requirements (
939
+ query , pip_requirements , tmp_dir
940
+ ) as rd :
941
+ if rd :
942
+ if pf :
943
+ self ._zip_write_with_filter (
944
+ zs , pf , rd , prefix , timestamp = 0
945
+ )
946
+ else :
947
+ # XXX: timestamp=0 - what actually do with it?
948
+ zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
949
+ elif cmd == "poetry" :
950
+ (
951
+ runtime ,
952
+ path ,
953
+ poetry_export_extra_args ,
954
+ prefix ,
955
+ ) = action [1 :]
956
+ log .info ("poetry_export_extra_args: %s" , poetry_export_extra_args )
957
+ with install_poetry_dependencies (
958
+ query , path , poetry_export_extra_args
959
+ ) as rd :
960
+ if rd :
961
+ if pf :
962
+ self ._zip_write_with_filter (
963
+ zs , pf , rd , prefix , timestamp = 0
964
+ )
965
+ else :
966
+ # XXX: timestamp=0 - what actually do with it?
967
+ zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
968
+ elif cmd == "npm" :
969
+ runtime , npm_requirements , prefix , tmp_dir = action [1 :]
970
+ with install_npm_requirements (
971
+ query , npm_requirements , tmp_dir
972
+ ) as rd :
973
+ if rd :
974
+ if pf :
975
+ self ._zip_write_with_filter (
976
+ zs , pf , rd , prefix , timestamp = 0
977
+ )
978
+ else :
979
+ # XXX: timestamp=0 - what actually do with it?
980
+ zs .write_dirs (rd , prefix = prefix , timestamp = 0 )
981
+ elif cmd == "sh" :
982
+ with tempfile .NamedTemporaryFile (
983
+ mode = "w+t" , delete = True
984
+ ) as temp_file :
985
+ script = action [1 ]
986
+
987
+ if log .isEnabledFor (DEBUG2 ):
988
+ log .debug ("exec shell script ..." )
989
+ for line in script .splitlines ():
990
+ sh_log .debug (line )
991
+
992
+ script = "\n " .join (
993
+ (
994
+ script ,
995
+ # NOTE: Execute `pwd` to determine the subprocess shell's
996
+ # working directory after having executed all other commands.
997
+ "retcode=$?" ,
998
+ f"pwd >{ temp_file .name } " ,
999
+ "exit $retcode" ,
1000
+ )
979
1001
)
980
- )
981
1002
982
- p = subprocess .Popen (
983
- script ,
984
- shell = True ,
985
- stdout = subprocess .PIPE ,
986
- stderr = subprocess .PIPE ,
987
- cwd = path ,
988
- )
1003
+ p = subprocess .Popen (
1004
+ script ,
1005
+ shell = True ,
1006
+ stdout = subprocess .PIPE ,
1007
+ stderr = subprocess .PIPE ,
1008
+ cwd = sh_work_dir ,
1009
+ )
989
1010
990
- call_stdout , call_stderr = p .communicate ()
991
- exit_code = p .returncode
992
- log .debug ("exit_code: %s" , exit_code )
993
- if exit_code != 0 :
994
- raise RuntimeError (
995
- "Script did not run successfully, exit code {}: {} - {}" .format (
996
- exit_code ,
997
- call_stdout .decode ("utf-8" ).strip (),
998
- call_stderr .decode ("utf-8" ).strip (),
1011
+ call_stdout , call_stderr = p .communicate ()
1012
+ exit_code = p .returncode
1013
+ log .debug ("exit_code: %s" , exit_code )
1014
+ if exit_code != 0 :
1015
+ raise RuntimeError (
1016
+ "Script did not run successfully, exit code {}: {} - {}" .format (
1017
+ exit_code ,
1018
+ call_stdout .decode ("utf-8" ).strip (),
1019
+ call_stderr .decode ("utf-8" ).strip (),
1020
+ )
999
1021
)
1000
- )
1001
1022
1002
- temp_file .seek (0 )
1003
- # NOTE: This var `sh_work_dir` is consumed in cmd == "zip" loop
1004
- sh_work_dir = temp_file .read ().strip ()
1023
+ temp_file .seek (0 )
1024
+ # NOTE: This var `sh_work_dir` is consumed in cmd == "zip" loop
1025
+ sh_work_dir = temp_file .read ().strip ()
1026
+ log .debug ("WORKDIR: %s" , sh_work_dir )
1027
+
1028
+ elif cmd == "set:workdir" :
1029
+ path = action [1 ]
1030
+ sh_work_dir = os .path .normpath (os .path .join (tf_work_dir , path ))
1005
1031
log .debug ("WORKDIR: %s" , sh_work_dir )
1006
1032
1007
- elif cmd == "reset:workdir" :
1008
- sh_work_dir = tf_work_dir
1009
- log .debug ("WORKDIR: %s" , sh_work_dir )
1010
- elif cmd == "set:filter" :
1011
- patterns = action [1 ]
1012
- pf = ZipContentFilter (args = self ._args )
1013
- pf .compile (patterns )
1014
- elif cmd == "clear:filter" :
1015
- pf .reset ()
1016
- pf = None
1033
+ elif cmd == "set:filter" :
1034
+ patterns = action [1 ]
1035
+ pf = ZipContentFilter (args = self ._args )
1036
+ pf .compile (patterns )
1017
1037
1018
1038
@staticmethod
1019
1039
def _zip_write_with_filter (
@@ -1616,11 +1636,11 @@ def prepare_command(args):
1616
1636
content_hash = content_hash .hexdigest ()
1617
1637
1618
1638
# Generate a unique filename based on the hash.
1619
- filename = os .path .join (artifacts_dir , "{}.zip" .format (content_hash ))
1639
+ zip_filename = os .path .join (artifacts_dir , "{}.zip" .format (content_hash ))
1620
1640
1621
1641
# Compute timestamp trigger
1622
1642
was_missing = False
1623
- filename_path = os .path .join (os .getcwd (), filename )
1643
+ filename_path = os .path .join (os .getcwd (), zip_filename )
1624
1644
if recreate_missing_package :
1625
1645
if os .path .exists (filename_path ):
1626
1646
st = os .stat (filename_path )
@@ -1633,7 +1653,7 @@ def prepare_command(args):
1633
1653
1634
1654
# Replace variables in the build command with calculated values.
1635
1655
build_data = {
1636
- "filename" : filename ,
1656
+ "filename" : zip_filename ,
1637
1657
"runtime" : runtime ,
1638
1658
"artifacts_dir" : artifacts_dir ,
1639
1659
"build_plan" : build_plan ,
@@ -1653,7 +1673,7 @@ def prepare_command(args):
1653
1673
# Output the result to Terraform.
1654
1674
json .dump (
1655
1675
{
1656
- "filename" : filename ,
1676
+ "filename" : zip_filename ,
1657
1677
"build_plan" : build_plan ,
1658
1678
"build_plan_filename" : build_plan_filename ,
1659
1679
"timestamp" : str (timestamp ),
0 commit comments