Rework support for scanning for SCMs in a source tree.
Review Request #12528 — Created Aug. 12, 2022 and submitted — Latest diff uploaded
When starting up a command, we scan for all available SCMs, running
through the list of registeredSCMClient
s and seeing which match either
a remote or local repository. This work runs through a lot of checks,
attempts to handle collisions, and finally selects aSCMClient
or
errors out.That work has lived in
rbtools/clients/__init__.py
, and had some
baked-in error handling, option validation, andsys.exit()
calls, none
of which we want inrbtools.clients
. Especially with upcoming work
being done on these code paths.This change introduces a new
rbtools.utils.source_tree
module
containingscan_scmclients_for_path()
. This performs the same logic as
the old method, but with improved logging, error handling, and better
results.The caller can now tell whether a match was made, which
SCMClient
it
matched, whichlocal_path
, and whichRepositoryInfo
. It also returns
other candidates that were found but rejected during the scan, and which
hit unexpected errors.These last two bits are now used to provide better error information if
a match failed or if there were multiple matches.Upcoming changes to dependency management for clients will build upon
this to help provide dependency-specific error output.Performance is better with the new one. Rather than instantiating all
SCMClient
classes up-front, they're now lazily-instantiated. This
is most useful when an explicit repository type is specified.Debug logging has been improved to mark every scan-related task with a
[scan]
prefix, helping separate out that information from
client-specific information. We may eventually just want to use named
loggers instead of a prefix, but for now, this helps.
scan_usable_clients()
has been updated to wrap the new functionality.
In time, a version of this will be moved intorbtools.commands
and the
old version deprecated.
Added comprehensive test coverage for the new functionality. All tests
pass on Python 3.7 through 3.11.Checked all new code using
mypy
andpyright
for Type Annotation usage.