1+ import os
2+ import sys
3+ import subprocess
4+ import shutil
5+ import time
6+ from typing import Union
7+ from git import repo
8+ from git import TagReference
9+ from packaging import version
10+
11+ OUTPUT_DIR = "output"
12+
13+ class BranchAsTag :
14+ def __init__ (self , branch : str ) -> None :
15+ self .name = branch
16+
17+
18+ def tags_filter (tags : list [TagReference ]) -> list [TagReference ]:
19+ """Filter tag version above v1.1.0(include v1.1.0)
20+ """
21+ base_ver = version .parse ('1.1.0' )
22+ ret_tags = []
23+ for tag in tags :
24+ try :
25+ tag_ver = version .parse (tag .name )
26+ if tag_ver >= base_ver :
27+ ret_tags .append (tag )
28+ except :
29+ continue
30+ main = BranchAsTag ('main' )
31+ ret_tags .append (main )
32+ return ret_tags
33+
34+ def build_repo (pkpy_repo :repo .Repo , tag : Union [TagReference , BranchAsTag ]) -> float :
35+ """Build the repo with specific tag/branch static, copy excutable into
36+ the corresponding folder
37+ """
38+ pkpy_repo .git .checkout ('-f' , tag .name )
39+ # build dir {OUTPUT_DIR}/{tag}
40+ assert os .path .exists ('pocketpy' )
41+ if os .path .exists ('pocketpy/build' ):
42+ shutil .rmtree ('pocketpy/build' )
43+
44+ os .mkdir (f"{ OUTPUT_DIR } /pkpy-{ tag .name } " )
45+ # build the current version of pkpy
46+ try :
47+ subprocess .run ([sys .executable , 'prebuild.py' ], cwd = 'pocketpy' , stderr = subprocess .PIPE )
48+ except subprocess .CalledProcessError as e :
49+ print (f'prebuild.py run failed with return code { e .returncode } : { e .stderr } ' )
50+ cmake_cmd = [
51+ "cmake" ,
52+ "-B" , "build" ,
53+ "-S" , "." ,
54+ "-DPK_ENABLE_OS=ON" ,
55+ "-DPK_ENABLE_THREADS=OFF" ,
56+ "-DCMAKE_BUILD_TYPE=Release"
57+ ]
58+
59+ build_cmd = [
60+ "cmake" ,
61+ "--build" , "build" ,
62+ "--config" , "Release"
63+ ]
64+ start_time = time .perf_counter ()
65+ subprocess .run (cmake_cmd , cwd = 'pocketpy' , check = True )
66+ subprocess .run (build_cmd , cwd = 'pocketpy' , check = True )
67+ elapsed_time = time .perf_counter () - start_time
68+
69+ if sys .platform == 'win32' :
70+ shutil .copy (f'pocketpy/build/Release/main.exe' , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /main.exe" )
71+ dll_path = f'pocketpy/build/Release/pocketpy.dll'
72+ if os .path .exists (dll_path ):
73+ shutil .copy (dll_path , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /pocketpy.dll" )
74+ elif sys .platform == 'darwin' :
75+ shutil .copy ('pocketpy/build/main' , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /main" )
76+ dll_path = 'pocketpy/build/libpocketpy.dylib'
77+ if os .path .exists (dll_path ):
78+ shutil .copy (dll_path , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /libpocketpy.dylib" )
79+ else :
80+ shutil .copy ('pocketpy/build/main' , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /main" )
81+ dll_path = 'pocketpy/build/libpocketpy.so'
82+ if os .path .exists (dll_path ):
83+ shutil .copy (dll_path , f"{ OUTPUT_DIR } /pkpy-{ tag .name } /libpocketpy.so" )
84+
85+ return elapsed_time
86+
87+
88+ if __name__ == "__main__" :
89+ code = os .system ('git clone https://github.com/pocketpy/pocketpy.git' )
90+ if code != 0 :
91+ print ("Failed to clone the repository. Please check your network connection or the repository URL." )
92+ exit (1 )
93+
94+ pkpy_repo = repo .Repo ('pocketpy' )
95+
96+ tag_list = tags_filter (pkpy_repo .tags )
97+
98+ # build_repo also has OUTPUT_DIR path check, if the code run for the first time, log will need the following code
99+ if os .path .exists (OUTPUT_DIR ):
100+ shutil .rmtree (OUTPUT_DIR )
101+
102+ os .mkdir (OUTPUT_DIR )
103+
104+ with open (f'{ OUTPUT_DIR } /log.txt' , 'w' ) as fp :
105+ fp .write (f'Building pocketpy with shared compilation, v1.1.0 - latest release, including main branch version.\n ' )
106+ for tag in reversed (tag_list ):
107+ elapsed_time = build_repo (pkpy_repo , tag )
108+ fp .write (f'{ tag .name } :\t { elapsed_time :.2f} s\n ' )
109+ fp .flush ()
0 commit comments