77
88import os
99import shutil
10- import logging
11- import textwrap
1210import asyncio
11+ import logging
12+ from configparser import NoOptionError
1313from git_fleximod import utils
1414from git_fleximod import cli
1515from git_fleximod .gitinterface import GitInterface
1616from git_fleximod .gitmodules import GitModules
1717from git_fleximod .submodule import Submodule
1818
19- # logger variable is global
20- logger = None
19+ logger = logging .getLogger (__name__ )
2120
2221
2322def fxrequired_allowed_values ():
24- return ["ToplevelRequired" , "ToplevelOptional" , "AlwaysRequired" , "AlwaysOptional" , "TopLevelRequired" , "TopLevelOptional" ]
23+ return [
24+ "ToplevelRequired" ,
25+ "ToplevelOptional" ,
26+ "AlwaysRequired" ,
27+ "AlwaysOptional" ,
28+ "TopLevelRequired" ,
29+ "TopLevelOptional" ,
30+ ]
2531
2632
2733def commandline_arguments (args = None ):
@@ -69,6 +75,7 @@ def commandline_arguments(args=None):
6975 options .components ,
7076 options .exclude ,
7177 options .force ,
78+ options .no_mods_details ,
7279 action ,
7380 )
7481
@@ -151,8 +158,8 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
151158
152159 if os .path .isdir (os .path .join (root_dir , path , ".git" )):
153160 with utils .pushd (sprep_repo ):
154- if os .path .isdir (os .path .join (topgit ,".git" )):
155- shutil .rmtree (os .path .join (topgit ,".git" ))
161+ if os .path .isdir (os .path .join (topgit , ".git" )):
162+ shutil .rmtree (os .path .join (topgit , ".git" ))
156163 shutil .move (".git" , topgit )
157164 with open (".git" , "w" ) as f :
158165 f .write ("gitdir: " + os .path .relpath (topgit ))
@@ -167,7 +174,6 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
167174 with utils .pushd (sprep_repo ):
168175 if os .path .isfile (sparsefile ):
169176 shutil .copy (sparsefile , gitsparse )
170-
171177
172178 # Finally checkout the repo
173179 sprepo_git .git_operation ("fetch" , "origin" , "--tags" )
@@ -177,7 +183,8 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
177183 rgit .config_set_value (f'submodule "{ name } "' , "active" , "true" )
178184 rgit .config_set_value (f'submodule "{ name } "' , "url" , url )
179185
180- def init_submodule_from_gitmodules (gitmodules , name , root_dir , logger ):
186+
187+ def init_submodule_from_gitmodules (gitmodules , name , root_dir , llogger ):
181188 path = gitmodules .get (name , "path" )
182189 url = gitmodules .get (name , "url" )
183190 assert path and url , f"Malformed .gitmodules file { path } { url } "
@@ -187,60 +194,72 @@ def init_submodule_from_gitmodules(gitmodules, name, root_dir, logger):
187194 fxurl = gitmodules .get (name , "fxDONOTUSEurl" )
188195 fxsparse = gitmodules .get (name , "fxsparse" )
189196 fxrequired = gitmodules .get (name , "fxrequired" )
190- return Submodule (root_dir , name , path , url , fxtag = tag , fxurl = fxurl , fxsparse = fxsparse , fxrequired = fxrequired , logger = logger )
197+ return Submodule (
198+ root_dir ,
199+ name ,
200+ path ,
201+ url ,
202+ fxtag = tag ,
203+ fxurl = fxurl ,
204+ fxsparse = fxsparse ,
205+ fxrequired = fxrequired ,
206+ logger = llogger ,
207+ )
208+
191209
192- def submodules_status (gitmodules , root_dir , toplevel = False , depth = 0 ):
210+ def submodules_status (
211+ gitmodules , root_dir , toplevel = False , depth = 0 , no_mods_details = False
212+ ):
193213 testfails = 0
194214 localmods = 0
195215 needsupdate = 0
196- wrapper = textwrap .TextWrapper (initial_indent = ' ' * (depth * 10 ), width = 120 ,subsequent_indent = ' ' * (depth * 20 ))
197216 for name in gitmodules .sections ():
198217 submod = init_submodule_from_gitmodules (gitmodules , name , root_dir , logger )
199-
200- result ,n , l , t = submod .status ()
218+
219+ result , n , l , t = submod .status (depth = depth , no_mods_details = no_mods_details )
201220 if toplevel or not submod .toplevel ():
202- print (wrapper . fill ( result ) )
221+ print (result )
203222 testfails += t
204223 localmods += l
205224 needsupdate += n
206225 subdir = os .path .join (root_dir , submod .path )
207226 if os .path .exists (os .path .join (subdir , ".gitmodules" )):
208227 gsubmod = GitModules (logger , confpath = subdir )
209- t ,l ,n = submodules_status (gsubmod , subdir , depth = depth + 1 )
228+ t , l , n = submodules_status (
229+ gsubmod , subdir , depth = depth + 1 , no_mods_details = no_mods_details
230+ )
210231 if toplevel or not submod .toplevel ():
211232 testfails += t
212233 localmods += l
213234 needsupdate += n
214-
235+
215236 return testfails , localmods , needsupdate
216237
217- def git_toplevelroot (root_dir , logger ):
218- rgit = GitInterface (root_dir , logger )
238+
239+ def git_toplevelroot (root_dir , llogger ):
240+ rgit = GitInterface (root_dir , llogger )
219241 _ , superroot = rgit .git_operation ("rev-parse" , "--show-superproject-working-tree" )
220242 return superroot
221243
244+
222245async def submodules_update (gitmodules , root_dir , requiredlist , force ):
223246 async def update_submodule (name , requiredlist , force ):
224247 submod = init_submodule_from_gitmodules (gitmodules , name , root_dir , logger )
225-
226- _ , needsupdate , localmods , testfails = submod .status ()
227248 if not submod .fxrequired :
228249 submod .fxrequired = "AlwaysRequired"
229- fxrequired = submod .fxrequired
250+ fxrequired = submod .fxrequired
230251 allowedvalues = fxrequired_allowed_values ()
231252 assert fxrequired in allowedvalues
232253
233254 superroot = git_toplevelroot (root_dir , logger )
234-
235- if (
236- fxrequired
237- and ((superroot and "Toplevel" in fxrequired )
238- or fxrequired not in requiredlist )
255+
256+ if fxrequired and (
257+ (superroot and "Toplevel" in fxrequired ) or fxrequired not in requiredlist
239258 ):
240259 if "Optional" in fxrequired and "Optional" not in requiredlist :
241260 if fxrequired .startswith ("Always" ):
242261 print (f"Skipping optional component { name :>20} " )
243- return # continue to next submodule
262+ return # continue to next submodule
244263 optional = "AlwaysOptional" in requiredlist
245264
246265 if fxrequired in requiredlist :
@@ -253,11 +272,16 @@ async def update_submodule(name, requiredlist, force):
253272 newrequiredlist = ["AlwaysRequired" ]
254273 if optional :
255274 newrequiredlist .append ("AlwaysOptional" )
256- await submodules_update (gitsubmodules , repodir , newrequiredlist , force = force )
275+ await submodules_update (
276+ gitsubmodules , repodir , newrequiredlist , force = force
277+ )
257278
258- tasks = [update_submodule (name , requiredlist , force ) for name in gitmodules .sections ()]
279+ tasks = [
280+ update_submodule (name , requiredlist , force ) for name in gitmodules .sections ()
281+ ]
259282 await asyncio .gather (* tasks )
260283
284+
261285def local_mods_output ():
262286 text = """\
263287 The submodules labeled with 'M' above are not in a clean state.
@@ -271,7 +295,8 @@ def local_mods_output():
271295"""
272296 print (text )
273297
274- def submodules_test (gitmodules , root_dir ):
298+
299+ def submodules_test (gitmodules , root_dir , no_mods_details = False ):
275300 """
276301 This function tests the git submodules based on the provided parameters.
277302
@@ -282,12 +307,15 @@ def submodules_test(gitmodules, root_dir):
282307 Parameters:
283308 gitmodules (ConfigParser): The gitmodules configuration.
284309 root_dir (str): The root directory for the git operation.
310+ no_mods_details (bool, optional): If True, suppress details on local mods in status output
285311
286312 Returns:
287313 int: The number of test failures.
288314 """
289315 # First check that fxtags are present and in sync with submodule hashes
290- testfails , localmods , needsupdate = submodules_status (gitmodules , root_dir )
316+ testfails , localmods , needsupdate = submodules_status (
317+ gitmodules , root_dir , no_mods_details = no_mods_details
318+ )
291319 print ("" )
292320 # Then make sure that urls are consistant with fxurls (not forks and not ssh)
293321 # and that sparse checkout files exist
@@ -315,14 +343,17 @@ def main():
315343 includelist ,
316344 excludelist ,
317345 force ,
346+ no_mods_details ,
318347 action ,
319348 ) = commandline_arguments ()
320349 # Get a logger for the package
321350 global logger
322351 logger = logging .getLogger (__name__ )
323352
324- logger .info ("action is {} root_dir={} file_name={}" .format (action , root_dir , file_name ))
325-
353+ logger .info (
354+ "action is {} root_dir={} file_name={}" .format (action , root_dir , file_name )
355+ )
356+
326357 if not root_dir or not os .path .isfile (os .path .join (root_dir , file_name )):
327358 if root_dir :
328359 file_path = utils .find_upwards (root_dir , file_name )
@@ -352,15 +383,17 @@ def main():
352383 if action == "update" :
353384 asyncio .run (submodules_update (gitmodules , root_dir , fxrequired , force ))
354385 elif action == "status" :
355- tfails , lmods , updates = submodules_status (gitmodules , root_dir , toplevel = True )
386+ tfails , lmods , updates = submodules_status (
387+ gitmodules , root_dir , toplevel = True , no_mods_details = no_mods_details
388+ )
356389 if tfails + lmods + updates > 0 :
357390 print (
358391 f" testfails = { tfails } , local mods = { lmods } , needs updates { updates } \n "
359392 )
360393 if lmods > 0 :
361394 local_mods_output ()
362395 elif action == "test" :
363- retval = submodules_test (gitmodules , root_dir )
396+ retval = submodules_test (gitmodules , root_dir , no_mods_details = no_mods_details )
364397 else :
365398 utils .fatal_error (f"unrecognized action request { action } " )
366399 return retval
0 commit comments