Rework support for scanning for SCMs in a source tree.

Review Request #12528 — Created Aug. 12, 2022 and submitted

Information

RBTools
release-4.x

Reviewers

When starting up a command, we scan for all available SCMs, running
through the list of registered SCMClients 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 a SCMClient or
errors out.

That work has lived in rbtools/clients/__init__.py, and had some
baked-in error handling, option validation, and sys.exit() calls, none
of which we want in rbtools.clients. Especially with upcoming work
being done on these code paths.

This change introduces a new rbtools.utils.source_tree module
containing scan_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, which local_path, and which RepositoryInfo. 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 into rbtools.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 and pyright for Type Annotation usage.

Summary ID
Rework support for scanning for SCMs in a source tree.
When starting up a command, we scan for all available SCMs, running through the list of registered `SCMClient`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 a `SCMClient` or errors out. That work has lived in `rbtools/clients/__init__.py`, and had some baked-in error handling, option validation, and `sys.exit()` calls, none of which we want in `rbtools.clients`. Especially with upcoming work being done on these code paths. This change introduces a new `rbtools.utils.source_tree` module containing `scan_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, which `local_path`, and which `RepositoryInfo`. 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 into `rbtools.commands` and the old version deprecated.
4d08eca449d2a97c7641b2c2ab5717f306265eaa
Description From Last Updated

'rbtools.utils.source_tree.logger' imported but unused Column: 1 Error code: F401

reviewbotreviewbot
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

chipx86
david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to release-4.x (9eff39f)