1010import functools
1111import logging
1212import os
13+ from time import time
1314
1415import attr
1516import click
1617
1718from commoncode .cliutils import PluggableCommandLineOption
1819from commoncode .cliutils import DOC_GROUP
1920from commoncode .cliutils import SCAN_GROUP
21+ from commoncode .cliutils import CORE_GROUP
2022from commoncode .resource import Resource
2123from commoncode .resource import strip_first_path_segment
2224from plugincode .scan import scan_impl
@@ -133,6 +135,7 @@ class PackageScanner(ScanPlugin):
133135 codebase_attributes = dict (
134136 # a list of packages
135137 packages = attr .ib (default = attr .Factory (list ), repr = False ),
138+ package_timing = attr .ib (default = 0 , repr = False ),
136139 # a list of dependencies
137140 dependencies = attr .ib (default = attr .Factory (list ), repr = False ),
138141 )
@@ -192,6 +195,14 @@ class PackageScanner(ScanPlugin):
192195 help = 'Show the list of supported package manifest parsers and exit.' ,
193196 help_group = DOC_GROUP ,
194197 ),
198+ PluggableCommandLineOption (
199+ ('--package-timing' ,),
200+ is_flag = True ,
201+ default = False ,
202+ hidden = True ,
203+ help = 'Collect scan timing for package assembly.' ,
204+ help_group = CORE_GROUP ,
205+ ),
195206 ]
196207
197208 def is_enabled (self , package , system_package , package_only , ** kwargs ):
@@ -210,7 +221,7 @@ def get_scanner(self, package=True, system_package=False, package_only=False, **
210221 package_only = package_only ,
211222 )
212223
213- def process_codebase (self , codebase , strip_root = False , package_only = False , ** kwargs ):
224+ def process_codebase (self , codebase , strip_root = False , package_only = False , package_timing = False , ** kwargs ):
214225 """
215226 Populate the ``codebase`` top level ``packages`` and ``dependencies``
216227 with package and dependency instances, assembling parsed package data
@@ -270,7 +281,7 @@ def process_codebase(self, codebase, strip_root=False, package_only=False, **kwa
270281 logger_debug (f'packagedcode: process_codebase: add_license_from_sibling_file: modified: { modified } ' )
271282
272283 # Create codebase-level packages and dependencies
273- create_package_and_deps (codebase , strip_root = strip_root , ** kwargs )
284+ create_package_and_deps (codebase , strip_root = strip_root , package_timing = package_timing , ** kwargs )
274285
275286 if has_licenses :
276287 # This step is dependent on top level packages
@@ -367,11 +378,14 @@ def get_installed_packages(root_dir, processes=2, **kwargs):
367378 yield from packages_by_uid .values ()
368379
369380
370- def create_package_and_deps (codebase , package_adder = add_to_package , strip_root = False , ** kwargs ):
381+ def create_package_and_deps (codebase , package_adder = add_to_package , strip_root = False , package_timing = False , ** kwargs ):
371382 """
372383 Create and save top-level Package and Dependency from the parsed
373384 package data present in the codebase.
374385 """
386+ if package_timing :
387+ package_assembly_start_time = time ()
388+
375389 packages , dependencies = get_package_and_deps (
376390 codebase ,
377391 package_adder = package_adder ,
@@ -381,6 +395,8 @@ def create_package_and_deps(codebase, package_adder=add_to_package, strip_root=F
381395
382396 codebase .attributes .packages .extend (package .to_dict () for package in packages )
383397 codebase .attributes .dependencies .extend (dep .to_dict () for dep in dependencies )
398+ if package_timing :
399+ codebase .attributes .package_timing = time () - package_assembly_start_time
384400
385401
386402def get_package_and_deps (codebase , package_adder = add_to_package , strip_root = False , ** kwargs ):
0 commit comments