public interface

PluginCommandFactory

com.atlassian.bitbucket.scm.PluginCommandFactory

Class Overview

Provides backing functionality for the ScmCommandFactory.

This interface is intended to be implemented by plugin developers. Functionality provided by this interface is intended to be consumed using the ScmCommandFactory exposed by the ScmService. Only the system should ever deal with this interface directly.

All command types on this interface are required to have a working implementation, as this factory describes the basic SCM commands used by the system to provide day-to-day functionality.

ScmFeature#CROSS_REPOSITORY cross-repository support is optional. Where factory methods accept secondary repositories SCMs which do not support cross-repository operations should fail fast, throwing an UnsupportedOperationException rather than returning a Command; they should not return a command which throws that exception.

SCM implementations may also provide additional functionality to allow the system to offer enhanced features, such as pull requests. Such functionality is exposed by other interfaces:

SCMs which support additional functionality, or have custom Command types, are encouraged to provide a sub-interface extending from this one exposing that functionality. For example:

     //Extends Command to allow canceling it after it has been called and checking whether it's been canceled.
     public interface CancelableCommand<T> extends Command<T> {
         void cancel();

         boolean isCanceled();
     }

     //Overrides methods on the PluginCommandFactory interface using covariant return types to return the
     //enhanced CancelableCommand instead of simple Command
     public interface MyScmCommandFactory extends PluginCommandFactory {
         @Nonnull
         @Override
         CancelableCommand<List<Blame>> blame(@Nonnull Repository repository,
                                              @Nonnull BlameCommandParameters parameters,
                                              @Nonnull PageRequest pageRequest);

         //Overrides for other methods as appropriate
     }
 
The SCM plugin would then expose the class implementing their custom MyScmCommandFactory using a component directive:
     <!-- Note: This should be in the SCM provider's atlassian-plugin.xml -->
     <component key="myScmCommandFactory"
                class="com.example.DefaultMyScmCommandFactory"
                public="true">
         <interface>com.example.MyScmCommandFactory</interface>
     </component>
 
The public="true" allows other plugins to import the component. This approach allows other plugin developers to import the SCM plugin's command factory and leverage its enhanced functionality with a component-import directive:
     <!-- Note: This should be in the SCM consumer's atlassian-plugin.xml -->
     <component-import key="myScmCommandFactory"
                       interface="com.example.MyScmCommandFactory"/>
 

Summary

Public Methods
@Nonnull Command<Page<Blame>> blame(Repository repository, BlameCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of Blame, providing attribution for each line in the specified file, calculated from the specified starting commit.
@Nonnull Command<Page<Branch>> branches(Repository repository, BranchesCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of branches.
@Nonnull Command<Void> branches(Repository repository, BranchesCommandParameters parameters, BranchCallback callback)
Streams branches in the specified repository to the provided BranchCallback callback.
@Nonnull Command<Page<Change>> changes(Repository repository, ChangesCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of changes between two commits.
@Nonnull Command<Void> changes(Repository repository, ChangesCommandParameters parameters, ChangeCallback callback)
Streams changes between two commits to the provided ChangeCallback callback.
@Nonnull Command<Page<Changeset>> changesets(Repository repository, ChangesetsCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of changesets given a set of ChangesetsCommandParameters#getCommitIds commit IDs, where each changeset includes the first page of changes between a requested commit and its first parent.
@Nonnull Command<Commit> commit(Repository repository, CommitCommandParameters parameters)
Retrieves the requested commit or, if a path was also supplied, retrieves the first commit to modify that path prior to the requested commit.
@Nonnull Command<Void> commits(Repository repository, CommitsCommandParameters parameters, CommitCallback callback)
Streams commits which match the provided CommitsCommandParameters paramters to the provided callback.
@Nonnull Command<Page<Commit>> commits(Repository repository, CommitsCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of commits which match the provided CommitsCommandParameters paramters.
@Nonnull Command<MinimalCommit> commonAncestor(Repository repository, CommonAncestorCommandParameters parameters)
Retrieves the common ancestor for the provided commits
@Nonnull Command<Void> create(Repository repository)
Creates and initializes the repository on disk, performing any SCM-specific configuration that is appropriate for new repositories.
@Nonnull Command<Branch> defaultBranch(Repository repository)
Retrieves the default Branch for the specified repository.
@Nonnull AsyncCommand<Void> delete(Repository repository, DeleteCommandParameters parameters)
Deletes the repository, allowing the underlying SCM to carry out any special processing necessary to clean up repository storage.
@Nonnull Command<Void> diff(Repository repository, DiffCommandParameters parameters, DiffContentCallback callback)
Streams the diff between two commits to the provided DiffContentCallback callback.
@Nonnull Command<Void> directory(Repository repository, DirectoryCommandParameters parameters, ContentTreeCallback callback, PageRequest pageRequest)
Streams a directory listing for the requested path at the specified commit.
@Nonnull Command<Void> file(Repository repository, FileCommandParameters parameters, FileContentCallback callback, PageRequest pageRequest)
Streams lines from the requested path at the specified commit, for non-binary files.
@Nonnull Command<Void> heads(Repository repository, RefCallback callback)
Streams all of the heads in the specified repository.
@Nonnull Command<Void> rawFile(Repository repository, RawFileCommandParameters parameters, TypeAwareOutputSupplier outputSupplier)
Streams the raw bytes for the requested file at the specified commit to OutputStream returned by the provided supplier.
@Nonnull Command<Ref> resolveRef(Repository repository, ResolveRefCommandParameters parameters)
Resolves the specified ResolveRefCommandParameters#getRefId() refId, which may be a: If a name is provided, it must be considered as either an ID or a display ID.
@Nonnull Command<Map<StringRef>> resolveRefs(Repository repository, ResolveRefsCommandParameters parameters)
Resolves one or more branches, tags and/or refs.
@Nonnull Command<Void> tags(Repository repository, TagsCommandParameters parameters, TagCallback callback)
Streams Tag tags in the specified repository to the provided TagCallback callback.
@Nonnull Command<Page<Tag>> tags(Repository repository, TagsCommandParameters parameters, PageRequest pageRequest)
Retrieves a page of tags.
@Nonnull Command<Void> traverseCommits(Repository repository, TraversalCallback callback)
Streams all of the commits in the repository reachable from any branch or tag in topological order.
@Nonnull Command<ContentTreeNode.Type> type(Repository repository, TypeCommandParameters parameters)
Retrieves the type for the requested path at the specified commit.

Public Methods

@Nonnull public Command<Page<Blame>> blame (Repository repository, BlameCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of Blame, providing attribution for each line in the specified file, calculated from the specified starting commit.

Parameters
repository the repository to calculate blame in
parameters parameters describing the file and starting commit to use
pageRequest describes the page of blame to retrieve
Returns
  • a command which, when executed, will return a page of blame

@Nonnull public Command<Page<Branch>> branches (Repository repository, BranchesCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of branches.

Parameters
repository the repository to retrieve branches from
parameters parameters describing any filter to apply, and the order to retrieve branches in
pageRequest describes the page of branches to retrieve
Returns
  • a command which, when called, will retrieve a page of branches

@Nonnull public Command<Void> branches (Repository repository, BranchesCommandParameters parameters, BranchCallback callback)

Streams branches in the specified repository to the provided BranchCallback callback.

Parameters
repository the repository to stream branches from
parameters parameters describing any filter to apply, and the order to stream branches in
callback a callback to receive the streamed branches
Returns
  • a command which, when executed, will stream branches

@Nonnull public Command<Page<Change>> changes (Repository repository, ChangesCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of changes between two commits.

If the ChangesCommandParameters#getSinceId() sinceId is not specified, the first ancestor of the ChangesCommandParameters#getUntilId() untilId must be used automatically. If the until commit is the first commit in the repository, and has no ancestors, each file included in that commit should be returned as newly added.

Parameters
repository the repository to retrieve changes from
parameters parameters describing the two commits to compute changes for, as well as limits to apply
pageRequest describes the page of changes to retrieve
Returns
  • a command which, when executed, will retrieve a page of changes

@Nonnull public Command<Void> changes (Repository repository, ChangesCommandParameters parameters, ChangeCallback callback)

Streams changes between two commits to the provided ChangeCallback callback.

If the ChangesCommandParameters#getSinceId() sinceId is not specified, the first ancestor of the ChangesCommandParameters#getUntilId() untilId must be used automatically. If the until commit is the first commit in the repository, and has no ancestors, each file included in that commit should be streamed as newly added.

Parameters
repository the repository to stream changes from
parameters parameters describing the two commits to compute changes for, as well as limits to apply
callback a callback to receive the streamed changes
Returns
  • a command which, when executed, will stream changes

@Nonnull public Command<Page<Changeset>> changesets (Repository repository, ChangesetsCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of changesets given a set of ChangesetsCommandParameters#getCommitIds commit IDs, where each changeset includes the first page of changes between a requested commit and its first parent.

Parameters
repository the repository to retrieve changesets from
parameters parameters describing the changesets to retrieve
pageRequest describes the page of changesets to retrieve
Returns
  • a command which, when executed, will retrieve a page of changesets

@Nonnull public Command<Commit> commit (Repository repository, CommitCommandParameters parameters)

Retrieves the requested commit or, if a path was also supplied, retrieves the first commit to modify that path prior to the requested commit. If the requested commit modified the path, it will be returned.

Parameters
repository the repository to retrieve the commit from
parameters parameters describing the commit to retrieve
Returns
  • a command which, when executed, will return the specified commit

@Nonnull public Command<Void> commits (Repository repository, CommitsCommandParameters parameters, CommitCallback callback)

Streams commits which match the provided CommitsCommandParameters paramters to the provided callback.

Implementors: SCMs are required to support this operation. However, they are not required to support CommitsCommandParameters#getSecondaryRepository() secondary repositories unless they offer ScmFeature#CROSS_REPOSITORY cross-repository support. If a secondary repository is provided and cross- repository operations are not supported, implementations should throw an UnsupportedOperationException.

Parameters
repository the repository to retrieve commits from
parameters parameters describing the commits to retrieve
callback a callback to receive the streamed commits
Returns
  • a command which, when executed, will stream commits to the provided callback
Throws
UnsupportedOperationException if a CommitsCommandParameters#getSecondaryRepository() secondary repository is provided an ScmFeature#CROSS_REPOSITORY cross- repository operations are not supported
See Also
  • ScmFeature#CROSS_REPOSITORY

@Nonnull public Command<Page<Commit>> commits (Repository repository, CommitsCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of commits which match the provided CommitsCommandParameters paramters.

Implementors: SCMs are required to support this operation. However, they are not required to support CommitsCommandParameters#getSecondaryRepository() secondary repositories unless they offer ScmFeature#CROSS_REPOSITORY cross-repository support. If a secondary repository is provided and cross- repository operations are not supported, implementations should throw an UnsupportedOperationException.

Parameters
repository the repository to retrieve commits from
parameters parameters describing the commits to retrieve
pageRequest describes the page of commits to retrieve
Returns
  • a command which, when executed, will retrieve a page of commits
Throws
UnsupportedOperationException if a CommitsCommandParameters#getSecondaryRepository() secondary repository is provided an ScmFeature#CROSS_REPOSITORY cross- repository operations are not supported
See Also
  • ScmFeature#CROSS_REPOSITORY

@Nonnull public Command<MinimalCommit> commonAncestor (Repository repository, CommonAncestorCommandParameters parameters)

Retrieves the common ancestor for the provided commits

Parameters
repository the repository to retrieve the common ancestor from
Returns
  • a command which, when executed, returns the common ancestor of the provided commits. If the provided commits do not have a common ancestor, the command should return null.

@Nonnull public Command<Void> create (Repository repository)

Creates and initializes the repository on disk, performing any SCM-specific configuration that is appropriate for new repositories. repository does not exist on disk when this method is called. The SCM is expected to create it with contents that are appropriate for an empty, new repository.

Parameters
repository the repository to create
Returns
  • a command which, when executed, will create and initialize the specified repository

@Nonnull public Command<Branch> defaultBranch (Repository repository)

Retrieves the default Branch for the specified repository.

Each repository in an SCM is required to have a default branch. However, that branch is not actually required to exist within the repository. If the default branch does not exist, the returned command must throw NoDefaultBranchException; it may not return null.

Parameters
repository the repository to retrieve the default branch for
Returns
  • a command which, when executed, will return the repository's default branch, or throw NoDefaultBranchException if the default branch does not exist

@Nonnull public AsyncCommand<Void> delete (Repository repository, DeleteCommandParameters parameters)

Deletes the repository, allowing the underlying SCM to carry out any special processing necessary to clean up repository storage.

Note: By the time this method is called, the repository has already been deleted from the database, and the associated database transaction has been committed.

Warning: This method is irreversible. It should never be called by a plugin. It is intended solely for use by the system.

Parameters
repository the repository to delete
parameters additional parameters, such as IDs for forks of the deleted repository
Returns
  • a command which, when executed, will delete the repository's storage

@Nonnull public Command<Void> diff (Repository repository, DiffCommandParameters parameters, DiffContentCallback callback)

Streams the diff between two commits to the provided DiffContentCallback callback.

If the DiffCommandParameters#getSinceId() sinceId is not specified, the diff must be calculated to the first ancestor of the DiffCommandParameters#getUntilId() untilId. If the until commit is the first commit in the repository, and has no ancestors, content for each file included in that commit should be streamed as newly added.

Diff implementations are required to honor the following settings:

  • DiffCommandParameters#getContextLines() context line count
  • DiffCommandParameters#getMaxLineLength() line length
  • DiffCommandParameters#getMaxLines() line count
Diff implementations are not required to honor any DiffCommandParameters#getWhitespace() whitespace modes they do not natively support.

Parameters
repository the repository to stream the diff from
parameters parameters describing the two commits to diff, and additional settings for controlling the shape and content of the streamed diff
callback a callback to receive the streamed diff
Returns
  • a command which, when executed, will stream the diff between two commits

@Nonnull public Command<Void> directory (Repository repository, DirectoryCommandParameters parameters, ContentTreeCallback callback, PageRequest pageRequest)

Streams a directory listing for the requested path at the specified commit.

When a DirectoryCommandParameters#isRecursive() recursive listing is requested, implementations must only stream non-directory entries. If the SCM tracks empty directories, they must be omitted.

For non-recursive listings, implementations are encouraged to collapse subdirectories which only have a single entry. For example, consider the following directory structure:


 src/
   main/
     java/
       com/
         example/
           MyClass.java
     resources/
 pom.xml
 
A listing at "/" (or ""), in addition to streaming new SimplePath("pom.xml), may stream either of the following values:
  • new SimplePath("src"), or
  • new SimplePath("src/main"
Because "src" contains only a single subdirectory, "main", the two may be collapsed if the implementation is capable of doing so efficiently. Implementations are not required to do so, however.

A listing at "src/main", in addition to streaming new SimplePath("resources") may stream either of the following values:

  • new SimplePath("java"), or
  • new SimplePath("java/com/example/MyClass.java")

If DirectoryCommandParameters#isWithSizes() file sizes are requested, SCMs which can efficiently include them should do so. If the SCM's internal representation for directory data makes file sizes expensive to retrieve (such as requiring the entire file to be streamed and its bytes counted, in the worst case), the SCM should omit size data even if it is requested.

Parameters
repository the repository to stream the directory listing from
parameters parameters describing the directory to list and the commit to list them at
callback a callback to receive the streamed list of files, subdirectories and submodules
pageRequest describes the page of the directory listing to stream
Returns
  • a command which, when executed, will stream the requested page of the specified directory listing

@Nonnull public Command<Void> file (Repository repository, FileCommandParameters parameters, FileContentCallback callback, PageRequest pageRequest)

Streams lines from the requested path at the specified commit, for non-binary files.

When the command is executed, if the requested path identifies a binary file, such as an image or PDF, the SCM should call onBinary().

For SCMs which support multiple file encodings:

  • If the encoding is recorded in the SCM's metadata, it should be used
  • Otherwise, the SCM should perform its own best-effort encoding detection
ContentDetectionUtils offers static methods for performing binary and encoding detection. It may be accessed from the following Maven dependency:

 <dependency>
     <groupId>com.atlassian.bitbucket.server</groupId>
     <artifactId>bitbucket-scm-common</artifactId>
     <scope>provided</scope>
 </dependency>
 

Implementations are required to honor FileCommandParameters#getMaxLineLength() max line lengths. If any line in a file exceeds that length, it must be truncated to constrain memory usage.

If FileCommandParameters#isAnnotated() annotations are requested, the implementation must compute the blame(Repository, BlameCommandParameters, PageRequest) for each line on the requested page and, after streaming those lines, offer the blame to the callback.

Parameters
repository the repository to stream the file from
parameters parameters describing the file to stream and the commit to stream it at
callback a callback to receive the parsed and limited file content
pageRequest describes the page of the file to stream
Returns
  • a command which, when executed, will stream the requested page of the specified file

@Nonnull public Command<Void> heads (Repository repository, RefCallback callback)

Streams all of the heads in the specified repository.

Implementors: A "head" in this context is any type of ref that would normally be retrieved by the SCM. At a minimum, this should be every branch and every tag in the repository. If the SCM has additional standard refs, they should be included. If the SCM supports optional or nonstandard ref namespaces, any refs stored there should not be included.

Parameters
repository the repository to stream heads for
callback a callback to receive the streamed heads
Returns
  • a command which, when called, will stream all of the heads in the specified repository

@Nonnull public Command<Void> rawFile (Repository repository, RawFileCommandParameters parameters, TypeAwareOutputSupplier outputSupplier)

Streams the raw bytes for the requested file at the specified commit to OutputStream returned by the provided supplier.

Prior to streaming bytes, SCM implementations are required to perform best-effort MIME type detection on the file, and to pass the detected type to the supplier. The Java java.net.URLConnection URLConnection class offers some static methods to facilitate such detection. ContentDetectionUtils.detectContentType(BufferedInputStream, String) may also be useful. It may be accessed from the following Maven dependency:


 <dependency>
     <groupId>com.atlassian.bitbucket.server</groupId>
     <artifactId>bitbucket-scm-common</artifactId>
     <scope>provided</scope>
 </dependency>
 

Parameters
repository the repository to stream the file from
parameters parameters describing the file to stream, and the commit to stream it at
outputSupplier provides an OutputStream to stream the file to, after its MIME type is supplied
Returns
  • a command which, when executed, will stream the raw bytes of the requested file at the specified commit to the provided callback, after first supplying its MIME type

@Nonnull public Command<Ref> resolveRef (Repository repository, ResolveRefCommandParameters parameters)

Resolves the specified ResolveRefCommandParameters#getRefId() refId, which may be a:

If a name is provided, it must be considered as either an ID or a display ID. The most exact match should be preferred. For SCMs which have namespaces, like Git's "refs/heads" and "refs/tags", names which are not fully qualified should be considered in every possible namespace. For example, "master" can be matched to "refs/heads/master" or "refs/tags/master".

If a hash is provided, it may only be resolved to a branch or tag if it identifies the tip commit. If the hash identifies a commit that is not the tip of a branch or tag, the returned command must return null.

When a hash or name is provided and resolves to multiple branches, tags or a combination of both, SCM implementors are encouraged to choose a tag over a branch, and to return the "first" branch or tag alphabetically. However, this is not enforced and is not considered part of the contract.

If the parameters specify a ResolveRefCommandParameters#getType() ref type, the provided ID must only be resolved against refs of that type. If a ref of a different type matches, it may not be returned. Implementations are encouraged to optimize their lookups when a type is provided.

Parameters
repository the repository to resolve the ref in
parameters parameters describing the ref to resolve, optionally including a type hint
Returns
  • a command which, when executed, will attempt to resolve the provided ID to a Branch or Tag

@Nonnull public Command<Map<StringRef>> resolveRefs (Repository repository, ResolveRefsCommandParameters parameters)

Resolves one or more branches, tags and/or refs.

Implementations may only resolve ResolveRefsCommandParameters#getBranchIds() branch IDs and ResolveRefsCommandParameters#getTagIds() tag IDs against branches and Tag tags, respectively. If a ref a different type matches, it may not be returned.

ResolveRefsCommandParameters#getRefIds Ref IDs may be resolved against refs of any type. When an ID resolves to multiple branches, tags or a combination of both, SCM implementors are encouraged to choose a tag over a branch, and to return the "first" branch or tag alphabetically. However, this is not enforced, and is not considered part of the contract.

Parameters
repository the repository to resolve the refs in
parameters parameters describing the branches, tags and refs to resolve
Returns
  • a command which, when executed, will resolve the specified IDs and return a map linking each successfully-resolved ID to the ref it resolved to

@Nonnull public Command<Void> tags (Repository repository, TagsCommandParameters parameters, TagCallback callback)

Streams Tag tags in the specified repository to the provided TagCallback callback.

Parameters
repository the repository to stream tags from
parameters parameters describing any filter to apply, and the order to stream tags in
callback a callback to receive the streamed tags
Returns
  • a command which, when executed, will stream tags

@Nonnull public Command<Page<Tag>> tags (Repository repository, TagsCommandParameters parameters, PageRequest pageRequest)

Retrieves a page of tags.

Parameters
repository the repository to retrieve tags from
parameters parameters describing any filter to apply, and the order to retrieve tags in
pageRequest describes the page of tags to retrieve
Returns
  • a command which, when called, will retrieve a page of tags

@Nonnull public Command<Void> traverseCommits (Repository repository, TraversalCallback callback)

Streams all of the commits in the repository reachable from any branch or tag in topological order. Topological order means no parent is output before all of its descendants have been output. It does not require that descendants be streamed in date order, but SCMs may optionally do so (so long as topological order is retained).

Parameters
repository the repository to traverse commits for
callback the callback to receive the streamed commits
Returns
  • a command which, when executed, will stream all of the commits in the repository, topologically ordered

@Nonnull public Command<ContentTreeNode.Type> type (Repository repository, TypeCommandParameters parameters)

Retrieves the type for the requested path at the specified commit. The same path may have different types at different commits as the repository's contents change.

The command may not return null for any reason. If the specified commit does not exist in the repository, the returned command must throw NoSuchCommitException. If the requested path does not exist in the specified commit, the returned command must throw NoSuchPathException.

Parameters
repository the repository to retrieve the type from
parameters parameters describing the commit and path to retrieve the type for
Returns
  • a command which, when executed, will return the type of the requested path at the specified commit