1+
2+ from distutils .dir_util import copy_tree
3+
4+ import base64
5+ import glob
6+ import hashlib
7+ import json
8+ import os
9+ import shutil
10+ import subprocess
11+ import sys
12+ import tempfile
13+ import zipfile
14+
15+ def build (src_dir ):
16+ with tempfile .TemporaryDirectory () as build_dir :
17+ copy_tree (src_dir , build_dir )
18+ if os .path .exists (os .path .join (src_dir , 'requirements.txt' )):
19+ subprocess .run (
20+ [sys .executable ,
21+ '-m' ,
22+ 'pip' ,
23+ 'install' ,
24+ '--ignore-installed' ,
25+ '--target' , build_dir ,
26+ '-r' , os .path .join (build_dir , 'requirements.txt' )],
27+ check = True ,
28+ capture_output = True
29+ )
30+ artifact = tempfile .NamedTemporaryFile (delete = False )
31+ make_archive (build_dir , artifact )
32+ return artifact .name
33+
34+
35+ def make_archive (src_dir , archive_file ):
36+ with zipfile .ZipFile (archive_file , 'w' ) as archive :
37+ for root , dirs , files in os .walk (src_dir ):
38+ for file in files :
39+ if file .endswith ('.pyc' ):
40+ break
41+ metadata = zipfile .ZipInfo (
42+ os .path .join (root , file ).replace (src_dir , '' )
43+ )
44+ with open (os .path .join (root , file ), 'rb' ) as f :
45+ data = f .read ()
46+ archive .writestr (
47+ metadata ,
48+ data
49+ )
50+
51+ def get_hash (archive_file ):
52+ '''
53+ Return base64 encoded sha256 hash of archive file
54+ '''
55+ with open (archive_file , 'rb' ) as f :
56+ h = hashlib .sha256 ()
57+ h .update (f .read ())
58+ return base64 .standard_b64encode (h .digest ()).decode ('utf-8' , 'strict' )
59+
60+
61+ if __name__ == '__main__' :
62+ query = json .loads (sys .stdin .read ())
63+ archive = build (query ['src_dir' ])
64+ print (json .dumps ({'archive' : archive , "base64sha256" :get_hash (archive )}))
0 commit comments