rbtools.clients.base.scmclient¶
Base class for interfacing with source code management tools.
Added in version 4.0.
Module Attributes
A generic type variable for BaseSCMClient subclasses. |
Classes
|
A base class for interfacing with a source code management tool. |
A commit in a commit history. |
|
A commit message from a local repository. |
|
The result of a diff operation. |
|
|
A Patcher provided by a SCMClient. |
A revision specification parsed from command line arguments. |
- class rbtools.clients.base.scmclient.BaseSCMClient(config: RBToolsConfig | None = None, options: argparse.Namespace | None = None)[source]¶
Bases:
objectA base class for interfacing with a source code management tool.
These are used for fetching repository information and generating diffs.
Callers must run
setup()orhas_dependencies()before calling methods on this tool.Changed in version 4.0:
Moved from
rbtools.clientsintorbtools.clients.base.scmclientand renamed fromSCMClienttoBaseSCMClient.A call to
setup()orhas_dependencies()will be required starting in RBTools 5.0.
- __firstlineno__ = 470¶
- __init__(config: RBToolsConfig | None = None, options: argparse.Namespace | None = None) None[source]¶
Initialize the client.
- Parameters:
config (
rbtools.config.config.RBToolsConfig, optional) – The loaded user config.options (
argparse.Namespace, optional) – The parsed command line arguments.
- __static_attributes__ = ('_diff_tool', '_has_deps', '_p_num_regex', 'capabilities', 'config', 'is_setup', 'options')¶
- amend_commit_description(message: str, revisions: SCMClientRevisionSpec | None = None) None[source]¶
Update a commit message to the given string.
- Parameters:
message (
str) – The commit message to use when amending the commit.revisions (
dict, optional) – A dictionary of revisions, as returned byparse_revision_spec(). This provides compatibility with SCMs that allow modifications of multiple changesets at any given time, and will amend the change referenced by thetipkey.
- Raises:
rbtools.clients.errors.AmendError – The amend operation failed.
- apply_patch(patch_file: str, *, base_path: str, base_dir: str, p: str | None = None, revert: bool = False) PatchResult[source]¶
Apply the patch and return a PatchResult indicating its success.
- Parameters:
patch_file (
str) – The name of the patch file to apply.base_path (
str) – The base path that the diff was generated in.base_dir (
str) – The path of the current working directory relative to the root of the repository.p (
str, optional) – The prefix level of the diff.revert (
bool, optional) – Whether the patch should be reverted rather than applied.
- Returns:
The result of the patch operation.
- Return type:
rbtools.clients.base.patch.PatchResult
- apply_patch_for_empty_files(patch: bytes, *, p_num: str, revert: bool = False) bool[source]¶
Return whether any empty files in the patch are applied.
- Parameters:
- Returns:
Trueif there are empty files in the patch.Falseif there were no empty files, or if an error occurred while applying the patch.- Return type:
- can_get_file_content: bool = False¶
Whether the tool can get files at specific revisions.
Added in version 5.0.
- Type:
- capabilities: Capabilities | None¶
Capabilities returned by the server.
This will be
Noneif not set by the server.
- check_dependencies() None[source]¶
Check whether the base dependencies needed are available.
This is responsible for checking for any command line tools or Python modules required to consider this client as an option when scanning repositories or selecting a specific client.
This should not check for diff implementations or anything specific about a local filesystem. It’s merely a first-pass dependency check.
This function is normally called via
setup()(which will re-raise any exceptions here) orhas_dependencies(). It doesn’t need to be called manually unless attempting to re-generate the exception.Subclasses can log any failed checks in the debug log, to help with debugging missing tools. If checking against multiple possible names, they may also record information needed to locate the matching executable for future operations.
It’s recommended to use
rbtools.utils.checks.check_install()to help with executable dependency checks.Added in version 4.0.
- Raises:
rbtools.clients.errors.SCMClientDependencyError – One or more required dependencies are missing.
- check_options() None[source]¶
Verify the command line options.
This is expected to be overridden by subclasses, if they need to do specific validation of the command line.
- Raises:
rbtools.clients.errors.OptionsCheckError – The supplied command line options were incorrect. In particular, if a file has history scheduled with the commit, the user needs to explicitly choose what behavior they want.
- config: RBToolsConfig¶
User configuration.
Any user configuration loaded via
.reviewboardrcfiles. This may be empty.
- create_commit(*, message: str, author: PatchAuthor | None, run_editor: bool, files: Sequence[str] | None = None, all_files: bool = False) None[source]¶
Create a commit based on the provided message and author.
Derived classes should override this method if they wish to support committing changes to their repositories.
Changed in version 6.0: The
authorcan now beNone, for cases where author information is not available (e.g. authors who have private profiles).- Parameters:
message (
str) – The commit message to use.author (
rbtools.diffs.patches.PatchAuthor) –The author of the commit.
Changed in version 6.0: This can now be
None, for cases where author information is not available (e.g. authors who have private profiles).run_editor (
bool) – Whether to run the user’s editor on the commit message before committing.files (
listofstr, optional) – The list of filenames to commit.all_files (
bool, optional) – Whether to commit all changed files, ignoring thefilesargument.
- Raises:
NotImplementedError – The client does not support creating commits.
rbtools.clients.errors.CreateCommitError – The commit message could not be created. It may have been aborted by the user.
- delete_branch(branch_name: str, *, merged_only: bool = True) None[source]¶
Delete the specified branch.
- Parameters:
- Raises:
rbtools.clients.errors.SCMError – An error occurred while deleting the branch.
- diff(revisions: SCMClientRevisionSpec | None, *, include_files: Sequence[str] | None = None, exclude_patterns: Sequence[str] | None = None, no_renames: bool = False, repository_info: RepositoryInfo | None = None, extra_args: Sequence[str] | None = None, with_parent_diff: bool = True) SCMClientDiffResult[source]¶
Perform a diff using the given revisions.
Callers should make sure that the appropriate diff tool is installed by calling
rbtools.diffs.tools.registry.get_diff_tool()and passingrequires_diff_toolif it’s a list.This is expected to be overridden by subclasses, which should:
Set
requires_diff_toolbased on the client’s needs.Optionally use
optionsfor any client-specific diff functionality.Call
get_diff_tool()early, if needed.
Subclasses that need to support special arguments should use
options.Changed in version 4.0:
All arguments except
revisionsmust be specified as keyword arguments.Subclasses should now use
requires_diff_toolandget_diff_tool()instead of manually invoking diff tools.
- Parameters:
revisions (
dict) – A dictionary of revisions, as returned byparse_revision_spec().include_files (
listofstr, optional) – A list of files to whitelist during the diff generation.exclude_patterns (
listofstr, optional) – A list of shell-style glob patterns to blacklist during diff generation.no_renames (
bool, optional) – Whether to avoid rename detection.repository_info (
rbtools.clients.base.repository.RepositoryInfo, optional) – The repository info structure.extra_args (
list, unused) – Additional arguments to be passed to the diff generation.with_parent_diff (
bool, optional) – Whether or not to compute a parent diff.
- Returns:
A dictionary containing keys documented in
SCMClientDiffResult.- Return type:
- find_matching_server_repository(repositories: RepositoryListResource) tuple[RepositoryItemResource | None, RepositoryInfoResource | None][source]¶
Find a match for the repository on the server.
Added in version 3.0.
- Parameters:
repositories (
rbtools.api.resource.RepositoryListResource) – The fetched repositories.- Returns:
A 2-tuple of matching repository information:
- Tuple:
0 (
rbtools.api.resource.RepositoryItemResource) – The matching repository resource, if found.If not found, this will be
None.1 (
rbtools.api.resource.RepositoryInfoResource) – The matching repository information resource, if found.If not found, this will be
None.
- Return type:
- get_changenum(revisions: SCMClientRevisionSpec) str | None[source]¶
Return the change number for the given revisions.
This is only used when the client is supposed to send a change number to the server (such as with Perforce).
- Parameters:
revisions (
dict) – A revisions dictionary as returned byparse_revision_spec().- Returns:
The change number to send to the Review Board server.
- Return type:
- get_commit_history(revisions: SCMClientRevisionSpec) Sequence[SCMClientCommitHistoryItem] | None[source]¶
Return the commit history between the given revisions.
Derived classes must override this method if they support posting with history.
- get_commit_message(revisions: SCMClientRevisionSpec) SCMClientCommitMessage | None[source]¶
Return the commit message from the commits in the given revisions.
This pulls out the first line from the commit messages of the given revisions. That is then used as the summary.
- Parameters:
revisions (
dict) – A dictionary as returned byparse_revision_spec().- Returns:
A dictionary containing keys found in
SCMClientCommitMessage.This may be
None, if no commit message is found.- Return type:
- get_current_bookmark() str[source]¶
Return the current bookmark of this repository.
This must be implemented for any tool which has
can_bookmark.- Returns:
The name of the currently checked-out bookmark.
- Return type:
- get_current_branch() str[source]¶
Return the repository branch name of the current directory.
Derived classes should override this method if they are able to determine the current branch of the working directory.
- Returns:
A string with the name of the current branch. If the branch is unable to be determined, returns
None.- Return type:
- get_diff_tool() BaseDiffTool | None[source]¶
Return a diff tool for use with this client.
This can be used by subclasses, and by callers that want to check if a compatible diff tool is available before calling
diff().The value is cached for the client.
Added in version 4.0.
- Returns:
The diff instance, if a compatible instance is found.
This will be
Noneifrequires_diff_toolisFalse.- Return type:
rbtools.diffs.tools.base.BaseDiffTool- Raises:
TypeError –
requires_diff_toolwas an unsupported type.rbtools.diffs.tools.errors.MissingDiffToolError – No compatible diff tool could be found.
- get_file_content(*, filename: str, revision: str) bytes[source]¶
Return the contents of a file at a given revision.
This may be implemented by subclasses in order to support uploading binary files to diffs.
Added in version 5.0.
- get_file_size(*, filename: str, revision: str) int[source]¶
Return the size of a file at a given revision.
This may optionally be implemented by subclasses if the SCM supports fetching file sizes.
Added in version 5.0.
- get_local_path() str | None[source]¶
Return the local path to the working tree.
This is expected to be overridden by subclasses.
Added in version 3.0.
- Returns:
The filesystem path of the repository on the client system.
- Return type:
- get_patcher(**kwargs: Unpack[PatcherKwargs]) SCMClientPatcher[source]¶
Return a patcher for this client.
Added in version 5.1.
- get_raw_commit_message(revisions: SCMClientRevisionSpec) str[source]¶
Extract the commit messages on the commits in the given revisions.
Derived classes should override this method in order to allow callers to fetch commit messages. This is needed for description guessing.
If a derived class is unable to fetch the description,
Noneshould be returned.Callers that need to differentiate the summary from the description should instead use get_commit_message().
- get_repository_info() RepositoryInfo | None[source]¶
Return repository information for the current working tree.
This is expected to be overridden by subclasses.
Added in version 3.0.
- Returns:
The repository info structure.
- Return type:
- get_repository_name() str | None[source]¶
Return any repository name configured in the repository.
This is used as a fallback from the standard config options, for repository types that support configuring the name in repository metadata.
Added in version 3.0.
- Returns:
The configured repository name, or None.
- Return type:
- get_server_tool_names(capabilities: Capabilities | None) str | None[source]¶
Return the list of supported tool names on the server.
Added in version 5.0.1.
- Parameters:
capabilities (
rbtools.api.capabilities.Capabilities) – The server capabilities, if present.- Returns:
A comma-separated list of server-side tool names to match with.
- Return type:
- get_tree_matches_review_request(review_request: ReviewRequestItemResource, *, revisions: SCMClientRevisionSpec, **kwargs) bool | None[source]¶
Return whether a review request matches revisions or tree state.
This works along with review request matching in tools like rbt post to match state in a review request (such as in
extra_data) with the state in the local tree (such as the local branch or SCM-specific identifiers other than a commit ID).Subclasses can override this to implement their own matching logic. By default, no additional logic is implemented.
Added in version 3.1.
- Parameters:
review_request (
rbtools.api.resource.ReviewRequestItemResource) – The review request being matched.revisions (
dict) – A dictionary of revisions, as returned byparse_revision_spec().**kwargs (
dict, unused) – Additional keyword arguments, for future expansion.
- Returns:
Trueif the review request is considered an exact match.Falseif the review request should be explicitly discarded as a possible match.Noneif a match could not be determined based on available information.- Return type:
- has_dependencies(expect_checked: bool = False) bool[source]¶
Return whether all dependencies for the client are available.
Either this or
setup()must be called before any operations are performed with this client.Added in version 4.0.
- Parameters:
expect_checked (
bool, optional) –Whether the caller expects that dependency checking has already been done.
If
True, and dependencies have not yet been checked viacheck_dependencies(), this will raise a deprecation warning.Starting in RBTools 4.0, this will raise an exception if
check_dependencies()hasn’t yet been called.- Returns:
Trueif dependencies are all available.Falseif one or more are not.- Return type:
- Raises:
rbtools.clients.errors.SCMError – The method was called without having previously checked for dependencies.
- has_pending_changes() bool[source]¶
Return whether there are changes waiting to be committed.
Derived classes should override this method if they wish to support checking for pending changes.
- Returns:
Trueif the working directory has been modified or if changes have been staged in the index.- Return type:
- is_remote_only() bool[source]¶
Return whether this repository is operating in remote-only mode.
For some SCMs and some operations, it may be possible to operate exclusively with a remote server and have no working directory.
Added in version 3.0.
- Returns:
Whether this repository is operating in remote-only mode.
- Return type:
- is_setup: bool¶
Whether the client is set up and ready for operations.
Operations may fail or crash if this is
False.Callers must call
setup()orhas_dependencies()before performing operations using this client.Added in version 4.0.
- Type:
- merge(*, target: str, destination: str, message: str, author: PatchAuthor | None, squash: bool = False, run_editor: bool = False, close_branch: bool = True) None[source]¶
Merge the target branch with destination branch.
Changed in version 6.0: The
authorcan now beNone, for cases where author information is not available (e.g. authors who have private profiles).- Parameters:
target (
str) – The name of the branch to merge.destination (
str) – The name of the branch to merge into.message (
str) – The commit message to use.author (
rbtools.diffs.patches.PatchAuthor) –The author of the commit.
Changed in version 6.0: This can now be
None, for cases where author information is not available (e.g. authors who have private profiles).squash (
bool, optional) – Whether to squash the commits or do a plain merge.run_editor (
bool, optional) – Whether to run the user’s editor on the commit message before committing.close_branch (
bool, optional) – Whether to close/delete the merged branch.
- Raises:
rbtools.clients.errors.MergeError – An error occurred while merging the branch.
- options: argparse.Namespace | None¶
Command line arguments passed to this client.
This may be empty, and makes assumptions about which command line arguments are registered with a command. It’s intended for use within RBTools.
This may be
None.- Type:
- parse_revision_spec(revisions: Sequence[str] | None = None) SCMClientRevisionSpec[source]¶
Parse the given revision spec.
The ‘revisions’ argument is a list of revisions as specified by the user. Items in the list do not necessarily represent a single revision, since the user can use SCM-native syntaxes such as “r1..r2” or “r1:r2”. SCMTool-specific overrides of this method are expected to deal with such syntaxes.
- Parameters:
revisions (
listofstr, optional) – A list of revisions as specified by the user. Items in the list do not necessarily represent a single revision, since the user can use SCM-native syntaxes such asr1..r2orr1:r2. SCMTool-specific overrides of this method are expected to deal with such syntaxes.- Returns:
A dictionary containing keys found in
SCMClientRevisionSpec.Additional keys may be included by subclasses for their own internal use.
These will be used to generate the diffs to upload to Review Board (or print). The diff for review will include the changes in (base, tip], and the parent diff (if necessary) will include (parent, base].
If a single revision is passed in, this will return the parent of that revision for “base” and the passed-in revision for “tip”.
If zero revisions are passed in, this will return revisions relevant for the “current change”. The exact definition of what “current” means is specific to each SCMTool backend, and documented in the implementation classes.
- Return type:
- Raises:
rbtools.clients.errors.InvalidRevisionSpecError – The given revisions could not be parsed.
rbtools.clients.errors.TooManyRevisionsError – The specified revisions list contained too many revisions.
- patcher_cls¶
The Patcher class used to apply patches.
Added in version 5.1: This replaces the old
apply_patch()andapply_patch_for_empty_files()methods from earlier releases.alias of
SCMClientPatcher
- push_upstream(remote_branch: str) None[source]¶
Push the current branch to upstream.
- Parameters:
remote_branch (
str) – The name of the branch to push to.- Raises:
rbtools.client.errors.PushError – The branch was unable to be pushed.
- requires_diff_tool: bool | Sequence[str] = False¶
Whether this tool requires a command line diff tool.
This may be a boolean or a list.
If a boolean, then this must be
Falseif no command line tool is required, orTrueif any command line tool supported by RBTools is available (in which case the SCMClient is responsible for ensuring compatibility).If a list, then this must be a list of registered diff tool IDs that are compatible.
Added in version 4.0.
- scan_for_server(repository_info: RepositoryInfo) str | None[source]¶
Find the server path.
This will search for the server name in the .reviewboardrc config files. These are loaded with the current directory first, and searching through each parent directory, and finally $HOME/.reviewboardrc last.
- Parameters:
repository_info (
rbtools.clients.base.repository.RepositoryInfo) – The repository information structure.- Returns:
The Review Board server URL, if available.
- Return type:
- scmclient_id: str = ''¶
The unique ID of the client.
Added in version 4.0: This will be required in RBTools 5.0.
- Type:
- server_tool_ids: ClassVar[Sequence[str] | None] = None¶
A comma-separated list of SCMClient IDs on the server.
This supersedes
server_tool_nameswhen running on a version of Review Board that supports passing tool IDs to the repositories list API.Added in version 5.0.1.
- Type:
- server_tool_names: ClassVar[str | None] = None¶
A comma-separated list of SCMClient names on the server.
Added in version 3.0.
- Type:
- setup() None[source]¶
Set up the client.
This will perform checks to ensure the client can be used. Callers should make sure to either call this method or
has_dependencies()before performing any other operations on this client.If checks succeed,
is_setupwill beTrue, and operations using this client can be performed.If checks fail, an exception may be raised, and
is_setupwill beFalse.Note that this will not check
requires_diff_tool, as that is only required for certain operations. Checking for a compatible diff tool is the responsibility of the caller whenever working with diffs.Added in version 4.0.
- Raises:
rbtools.clients.errors.SCMClientDependencyError – One or more required dependencies are missing.
- strip_p_num_slashes(file_or_files: _TStripPrefixArg, p_num: int) _TStripPrefixArg[source]¶
Strip the smallest prefix containing p_num slashes from filenames.
To match the behavior of the patch -pX option, adjacent slashes are counted as a single slash.
Added in version 6.0: Renamed from
_strip_p_num_slashes.
- supports_changesets: bool = False¶
Whether the SCM uses server-side changesets
Added in version 3.0.
- Type:
- supports_diff_exclude_patterns: bool = False¶
Whether the SCM client supports excluding files from the diff.
- Type:
- supports_diff_extra_args: bool = False¶
Whether the SCM client’s diff method takes the
extra_argsparameter.- Type:
- supports_empty_files() bool[source]¶
Return whether the server supports added/deleted empty files.
- Returns:
Trueif the Review Board server supports added or deleted empty files.- Return type:
- supports_no_renames: bool = False¶
Whether the SCM client can generate diffs without renamed files.
- Type:
- class rbtools.clients.base.scmclient.SCMClientCommitHistoryItem[source]¶
Bases:
TypedDictA commit in a commit history.
This class helps provide type hinting to results from
BaseSCMClient.get_commit_history().Added in version 4.0.
- __firstlineno__ = 185¶
- __static_attributes__ = ()¶
- committer_date: NotRequired[str | None]¶
The date the commit was made.
- Type:
- committer_email: NotRequired[str | None]¶
The e-mail address of the person or entity who committed the change.
- Type:
- committer_name: NotRequired[str | None]¶
The name of the person or entity who committed the change.
- Type:
- class rbtools.clients.base.scmclient.SCMClientCommitMessage[source]¶
Bases:
TypedDictA commit message from a local repository.
This class helps provide type hinting to results from
BaseSCMClient.get_commit_message().Added in version 4.0.
- __firstlineno__ = 250¶
- __static_attributes__ = ()¶
- description: NotRequired[str | None]¶
The description of a commit message.
This should generally match the remainder of the commit message after the summary, if any content remains.
- Type:
- class rbtools.clients.base.scmclient.SCMClientDiffResult[source]¶
Bases:
TypedDictThe result of a diff operation.
This class helps provide type hinting to results from
BaseSCMClient.diff().Added in version 4.0.
- __firstlineno__ = 123¶
- __static_attributes__ = ()¶
- base_commit_id: NotRequired[str | None]¶
The ID of the commit that the change is based on, if available.
This is necessary for some hosting services that don’t provide individual file access.
- Type:
- changenum: NotRequired[str | None]¶
The change number to include when posting, if available.
- Type:
- commit_id: NotRequired[str | None]¶
The commit ID to include when posting, if available.
- Type:
- diff: bytes | None¶
The contents of the diff to upload.
This should be
Noneor an empty string if diff generation fails.- Type:
- parent_diff: NotRequired[bytes | None]¶
The contents of the parent diff, if available.
- Type:
- class rbtools.clients.base.scmclient.SCMClientPatcher(*, scmclient: TSCMClient, **kwargs: Unpack[PatcherKwargs])[source]¶
Bases:
Generic[TSCMClient],PatcherA Patcher provided by a SCMClient.
SCMClients that define custom patchers can subclass this to implement a new patcher. It takes care of storing initial state for the patcher based on the SCMClient, providing access to the parent SCMClient instance, and generating commits from patches.
Added in version 5.1.
- __firstlineno__ = 278¶
- __init__(*, scmclient: TSCMClient, **kwargs: Unpack[PatcherKwargs]) None[source]¶
Initialize the patcher.
- Parameters:
scmclient (
BaseSCMClient) – The SCMClient object.**kwargs (
PatcherKwargs) – Keyword arguments for the patcher.
- __static_attributes__ = ('can_commit', 'can_patch_empty_files', 'scmclient')¶
- create_commit(*, patch_result: PatchResult, run_commit_editor: bool) None[source]¶
Create a commit based on a patch result.
This will invoke the SCMClient’s logic for committing files from a patch.
- Parameters:
patch_result (
rbtools.diffs.patches.PatchResult) – The patch result containing the patch/patches to commit.run_commit_editor (
bool) – Whether to run the configured commit editor to alter the commit message.
- Raises:
rbtools.diffs.errors.ApplyPatchResult – There was an error attempting to commit the patch.
- scmclient: TSCMClient¶
The SCMClient that owns the patcher.
- class rbtools.clients.base.scmclient.SCMClientRevisionSpec[source]¶
Bases:
TypedDictA revision specification parsed from command line arguments.
This class helps provide type hinting to results from
BaseSCMClient.parse_revision_spec().The dictionary may include other arbitrary keys.
Added in version 4.0.
- __firstlineno__ = 61¶
- __static_attributes__ = ()¶
- base: ForwardRef('Any', module='rbtools.clients.base.scmclient')¶
A revision to use as the base of the resulting diff.
The value is considered an opaque value, dependent on the SCMClient.
This is required.
- Type:
- commit_id: ForwardRef('NotRequired[Any]', module='rbtools.clients.base.scmclient')¶
The commit ID of the single commit being posted, if not using a range.
This is optional.
- Type:
- extra: ForwardRef('NotRequired[Mapping[str, Any] | None]', module='rbtools.clients.base.scmclient')¶
Any extra revision state not used above.
If a SCMClient needs to provide information in addition or instead of the above, they should populate this field, rather than placing the information in the main revision dictionary. This helps ensure a stable, typed interface for all revision data.
Added in version 4.0.
- parent_base: ForwardRef('NotRequired[Any]', module='rbtools.clients.base.scmclient')¶
The revision to use as the base of a parent diff.
The value is considered an opaque value, dependent on the SCMClient.
This is optional.
- Type:
- class rbtools.clients.base.scmclient.TSCMClient[source]¶
A generic type variable for BaseSCMClient subclasses.
Added in version 5.1.
alias of TypeVar(‘TSCMClient’, bound=
BaseSCMClient)