1+ #! python3
2+
3+ import os
4+ import sys
5+ import argparse
6+ import re
7+
8+ import typing
9+
10+ def main (
11+ package : str ,
12+ from_manifest : bool ,
13+ path_manifest : str ,
14+ * args , ** kwargs
15+ ) -> bool :
16+ # for all the files that are called code.py in the components folder
17+ # stamp on the second line of the file by not overwriting the first line
18+ for root , dirs , files in os .walk ("./py/components/" ):
19+ for file in files :
20+ if file == "code.py" :
21+ path = os .path .join (root , file )
22+ with open (path , "r" ) as f :
23+ lines = f .readlines ()
24+ # check if the line # r: package_name is already in the first 10 lines
25+ if any ([re .search (r"# r: .+==" , line ) for line in lines [:10 ]]):
26+ print (f"File { path } is already stamped with the package version." )
27+ return False
28+ with open (path , "w" ) as f :
29+ f .write (lines [0 ])
30+ f .write (f"# r: { package } =={ kwargs ['version' ]} \n " )
31+ for line in lines [1 :]:
32+ f .write (line )
33+ print ("Done stamping components with version number of the pypi package." )
34+ return True
35+
36+
37+ if __name__ == "__main__" :
38+ parser = argparse .ArgumentParser (
39+ description = "Add the # r : package==version for ghusers components release."
40+ )
41+ parser .add_argument (
42+ "--package" ,
43+ type = str ,
44+ help = "The package name."
45+ )
46+ parser .add_argument (
47+ "--source" ,
48+ type = str ,
49+ required = False ,
50+ default = "./py/components/" ,
51+ help = "The path to component folders."
52+ )
53+ parser .add_argument (
54+ "--from-manifest" ,
55+ action = 'store_true' ,
56+ default = False ,
57+ help = "Whether to update the version from the manifest file's version."
58+ )
59+ parser .add_argument (
60+ "--path-manifest" ,
61+ type = str ,
62+ required = False ,
63+ default = "./manifest.yml" ,
64+ help = "The path to the manifest file."
65+ )
66+ parser .add_argument (
67+ "--version" ,
68+ type = str ,
69+ required = False ,
70+ help = "The version number to update and overwrite in the code base."
71+ )
72+
73+ args = parser .parse_args ()
74+
75+ if args .package is None :
76+ parser .print_help ()
77+ sys .exit (1 )
78+
79+ parse_errors = []
80+
81+ _manifest_version = None
82+ if args .from_manifest :
83+ if not os .path .isfile (args .path_manifest ):
84+ parse_errors .append (f"Path to manifest file is invalid: { args .path_manifest } " )
85+ with open (args .path_manifest , "r" ) as f :
86+ manifest = f .read ()
87+ match = re .search (r"version: (\d+\.\d+\.\d+)" , manifest )
88+ if match :
89+ _manifest_version = match .group (1 )
90+ if _manifest_version is None :
91+ parse_errors .append ("Could not find the version number in the manifest file." )
92+ args .version = _manifest_version
93+ is_version_ok = True
94+ _version = args .version
95+ if not re .match (r"^\d+\.\d+\.\d+$" , _version ) \
96+ or _version .count ("." ) < 2 \
97+ or len (_version ) < 5 :
98+ is_version_ok = False
99+ parse_errors .append ("Version must be in the format: Major.Minor.Patch" )
100+
101+ is_source_populated = True
102+ if not os .path .isdir (args .source ):
103+ is_source_populated = False
104+ parse_errors .append (f"Path to source folder is invalid: { args .source } " )
105+ nbr_pycode_files = 0
106+ for root , dirs , files in os .walk (args .source ):
107+ for file in files :
108+ if file == "code.py" :
109+ nbr_pycode_files += 1
110+ if nbr_pycode_files == 0 :
111+ is_source_populated = False
112+ parse_errors .append (f"Source folder is empty or does not contain components: { args .source } " )
113+
114+ print ("Flagerizer checks:" )
115+ if _manifest_version is not None :
116+ print (f"\t [x] Version from manifest: { _manifest_version } " )
117+ else :
118+ print (f"\t [ ] Version from manifest: { _manifest_version } " )
119+ if is_version_ok :
120+ print ("\t [x] Correct version format" )
121+ else :
122+ print (f"\t [ ] Correct version format" )
123+ if is_source_populated :
124+ print (f"\t [x] Source folder is populated { args .source } with { nbr_pycode_files } components" )
125+ else :
126+ print (f"\t [ ] Source folder is populated" )
127+
128+ if parse_errors .__len__ () != 0 :
129+ for error in parse_errors :
130+ print (error )
131+ sys .exit (1 )
132+
133+ print ("Stamping components with version number of the pypi package:" )
134+ print (f"\t # r: { args .package } =={ _version } " )
135+
136+ res = main (
137+ package = args .package ,
138+ from_manifest = args .from_manifest ,
139+ path_manifest = args .path_manifest ,
140+ version = _version
141+ )
142+
143+ if res :
144+ print ("[x] Done flagerizing components." )
145+ else :
146+ print ("[ ] Failed flagerizing components." )
147+ sys .exit (1 )
0 commit comments