@ThreadSafe public interface Scm
In order for an SCM to be usable by the system, it must implement:
It may also implement the following to enable additional system functionality:getBulkContentCommandFactory()
getCompareCommandFactory()
getExtendedCommandFactory()
getMirrorCommandFactory()
getPullRequestCommandFactory()
getRefCommandFactory()
SCMs which support additional functionality, or have custom factory types, are encouraged to provide a sub- interface extending from this one exposing that functionality. For example:
//Overrides the builder(Repository) method using a covariant return type to return a builder supporting both
//type-safe and free-form commands, instead of ScmCommandBuilder
public interface MyScmCommandBuilderFactory extends PluginCommandBuilderFactory {
//See the documentation for PluginCommandBuilderFactory
}
//Overrides methods using covariant return types to return an enhanced CancelableCommands instead of
//Commands
public interface MyScmCommandFactory extends PluginCommandFactory {
//See the documentation for PluginCommandFactory
}
//Overrides methods using covariant return types to return custom versions of the PluginCommandFactory
,
//PluginCommandBuilderFactory
and PluginPullRequestCommandFactory
interfaces
public interface MyScm extends Scm {
//Supports both free-form and type-safe builders
@Nonnull
@Override
MyScmCommandBuilderFactory getCommandBuilderFactory();
//Uses enhanced CancelableCommands
@Nonnull
@Override
MyScmCommandFactory getCommandFactory();
@Nonnull
@Override
MyScmPullRequestCommandFactory getPullRequestCommandFactory();
}
Notice that the getCommandBuilderFactory()
and getPullRequestCommandFactory()
have had their
annotations changed to @Nonnull
, indicating that MyScm
definitely supports both
builders and pull requests. This allows other plugin developers to know the features supported by the custom SCM
so they can leverage them fully.
SCM plugins are encouraged to define a separate component
for their Scm
implementations, but they
are required to define an scm
entry or the SCM will not be detected by the system. The following
example illustrates both directives:
<!-- Note: These should be in the SCM provider's atlassian-plugin.xml -->
<component key="myScm" class="com.example.DefaultMyScm" public="true">
<interface>com.example.MyScm</interface>
</component>
<scm key="scm" class="bean:myScm"/>
The public="true"
allows other plugins to import the component. This approach allows other plugin developers
to import the SCM directly 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="myScm" interface="com.example.MyScm"/>
For SCMs which define a component
for their Scm
, it is strongly encouraged that they reference
that component for their scm
directive, as shown above. This ensures a single instance of the Scm
is
constructed for use by other plugins and by the system.
Note: Implementors are strongly encouraged to extend from AbstractScm
. This interface
will change, over time, and any class implementing it directly will be broken by such changes. Extending
from the abstract class will help prevent such breakages.
Note: Implementations of this interface are required to be thread-safe. Implementations of related interfaces
such as PluginCommandBuilderFactory
, PluginCommandFactory
and PluginPullRequestCommandFactory
are not required to be thread-safe if distinct instances are returned for each call.
Warning: If a component
directive is defined but the scm
directive does not reference it and
instead defines class="com.example.MyScm"
, two instances will be created. The one created with the
component
directive may be imported by plugins (assuming it is public
; otherwise, it may never be
used anywhere!) and the one created with the scm
directive will be used by the system.
AbstractScm
Modifier and Type | Method and Description |
---|---|
default PluginBulkContentCommandFactory |
getBulkContentCommandFactory()
Retrieves a
PluginBulkContentCommandFactory , used to create commands tailored for getting
content from a repository in bulk. |
default PluginCommandBuilderFactory |
getCommandBuilderFactory()
Retrieves a
PluginCommandBuilderFactory , used to create command builders for
custom SCM commands. |
PluginCommandFactory |
getCommandFactory()
Retrieves a
PluginCommandFactory , used to create commands for performing standard SCM
operations such as retrieving commits and viewing diffs. |
default PluginCompareCommandFactory |
getCompareCommandFactory()
Retrieves a
PluginCompareCommandFactory , used to create commands tailored for comparing
refs. |
default com.atlassian.bitbucket.repository.MinimalRef |
getDefaultBranch(com.atlassian.bitbucket.repository.Repository repository)
Retrieves the configured default branch for the specified repository.
|
default PluginExtendedCommandFactory |
getExtendedCommandFactory()
Retrieves an
optional command factory , which enables additional system
features for SCMs which implement its commands. |
Set<com.atlassian.bitbucket.scm.ScmFeature> |
getFeatures()
Retrieves the
features that are supported by this SCM. |
String |
getId()
Retrieves a unique identifier for the SCM that is provided by the plugin.
|
default PluginIntegrityCheckCommandFactory |
getIntegrityCheckCommandFactory()
Retrieves a
PluginIntegrityCheckCommandFactory , used to create commands that
perform integrity checks on SCMs. |
default PluginMergeStrategies |
getMergeStrategies()
Retrieves a set of
merge strategies supported by the SCM. |
default PluginMirrorCommandFactory |
getMirrorCommandFactory()
Retrieves a
PluginMirrorCommandFactory , used to create commands tailored for mirroring
repositories. |
String |
getName()
Retrieves a well-known name for the SCM that is provided by the plugin.
|
default PluginPullRequestCommandFactory |
getPullRequestCommandFactory()
Retrieves a
PluginPullRequestCommandFactory , used to create commands tailored for use
supporting pull requests. |
default PluginRefCommandFactory |
getRefCommandFactory()
Retrieves a
PluginRefCommandFactory , used to create commands tailored for creating
branches and tags . |
ScmStatus |
getStatus()
Retrieves the current
status for the SCM. |
boolean |
isEmpty(com.atlassian.bitbucket.repository.Repository repository)
Retrieves a flag indicating whether the specified
Repository is empty, from the perspective of the SCM
implementation. |
@Nullable default PluginBulkContentCommandFactory getBulkContentCommandFactory()
PluginBulkContentCommandFactory
, used to create commands
tailored for getting
content from a repository in bulk.
Implementation Note: This method is optional. SCMs which do not support bulk content retrieval may
return null
.
null
if the
SCM does not support bulk content retrievalPluginBulkContentCommandFactory
,
ScmFeature.BULK_CONTENT
@Nullable default PluginCommandBuilderFactory getCommandBuilderFactory()
PluginCommandBuilderFactory
, used to create command builders
for
custom SCM commands.
Implementation Note: This method is optional. SCMs which do not support a ScmCommandBuilder
may return null
.
null
if the SCM does not support command buildersPluginCommandBuilderFactory
,
ScmFeature.COMMAND_BUILDERS
@Nonnull PluginCommandFactory getCommandFactory()
PluginCommandFactory
, used to create commands
for performing standard SCM
operations such as retrieving commits and viewing diffs. The commands created by the returned factory are used
to support normal system functionality; as a result, SCMs are required to provide an implementation.
Implementation Note: This method is required and may not return null
.
PluginCommandFactory
@Nullable default PluginCompareCommandFactory getCompareCommandFactory()
PluginCompareCommandFactory
, used to create commands
tailored for comparing
refs.
Implementation Note: This method is optional. SCMs which do not support comparing refs may return
null
.
null
if the SCM does not support itPluginCompareCommandFactory
,
ScmFeature.COMPARE
@Nonnull default com.atlassian.bitbucket.repository.MinimalRef getDefaultBranch(@Nonnull com.atlassian.bitbucket.repository.Repository 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. Regardless of whether the branch exists within the repository
or not, this method should return the configured default. If the default branch exists, SCMs may optionally
return a full Branch
instead of a MinimalRef
.
Implementors: The default implementation of this method will be removed in 9.0. SCMs are required to implement this accessor for themselves; they cannot rely on the default.
repository
- the repository to retrieve the configured default branch forPluginCommandFactory.defaultBranch(Repository)
@Nullable default PluginExtendedCommandFactory getExtendedCommandFactory()
optional command factory
, which enables additional system
features for SCMs which implement its commands. Each optional command is associated with an SCM feature
, and SCMs are free to implement any subset of the factory's methods. If the SCM does not implement
any optional features, the returned factory may be null
. However, SCM implementors are encouraged
to implement as many optional commands as they can.null
if the SCM
does not support any optional commands@Nonnull Set<com.atlassian.bitbucket.scm.ScmFeature> getFeatures()
features
that are supported by this SCM.
Since the system relies on optional features to provide some functionality, like branch compare and pull
requests, it relies on this set to disable functionality that requires features the SCM doesn't provide.
Similarly, plugin developers can use the returned features to control which optional features they try
to use, rather than checking for null
or handling UnsupportedOperationException
s.
null
@Nullable default PluginIntegrityCheckCommandFactory getIntegrityCheckCommandFactory()
PluginIntegrityCheckCommandFactory
, used to create commands
that
perform integrity checks on SCMs.null
if the SCM does not support integrity checks.@Nonnull String getId()
Identifiers should be unique to the SCM's type. Using the name of the SCM's binary is a good approach. For
example, a plugin implementing support for git might return "git"
as its identifier. This approach allows
the system to detect when multiple plugins are installed which implement git support, potentially leading to
unexpected behaviour from some repositories.
Implementation Note: This method is required and may not return null
.
@Nullable default PluginMergeStrategies getMergeStrategies()
merge strategies
supported by the SCM.
If the SCM supports pull requests
and selectable merge strategies, the
system will use the returned strategies
to allow administrators to configure the
default and enabled strategies for the "Merge" dialog.
SCMs which support selectable merge strategies
are required to return
at least one PluginMergeStrategy
. SCMs which support multiple merge strategies must
support the same set of strategies for merge commands and pull requests. SCMs must not support
different strategies for merge commands and pull requests.
Implementation Notes: This method is optional. SCMs which do not support selectable merge
strategies, or which don't support the merge command
or
pull requests
, may return null
.
null
if the SCM doesn't support selectable
strategiesScmFeature.MERGE_STRATEGIES
@Nullable default PluginMirrorCommandFactory getMirrorCommandFactory()
PluginMirrorCommandFactory
, used to create commands
tailored for mirroring
repositories.
Implementation Note: This method is optional. SCMs which do not support mirroring may return
null
. Repositories
using such SCMs will not be able to mirror repositories.
null
if the SCM
does not support mirroringPluginMirrorCommandFactory
,
ScmFeature.MIRRORS
@Nonnull String getName()
Most SCMs use binaries which do not match the well-known name of the SCM. For example, Subversion's binary is
svn
, and Mercurial's is hg
. This method should return the SCM's well-known name, suitable for
display in a user interface.
Implementation Note: This method is required and may not return null
.
@Nullable default PluginPullRequestCommandFactory getPullRequestCommandFactory()
PluginPullRequestCommandFactory
, used to create commands
tailored for use
supporting pull requests. Repositories
using an SCM which implements this method will have
the ability to create, view and merge pull requests.
Implementation Note: This method is optional. SCMs which do not support pull requests may return
null
. Repositories
using such SCMs will not be able to create pull requests.
null
if the SCM does not support pull requestsPluginPullRequestCommandFactory
,
ScmFeature.PULL_REQUESTS
@Nullable default PluginRefCommandFactory getRefCommandFactory()
PluginRefCommandFactory
, used to create commands
tailored for creating
branches
and tags
.
Implementation Note: This method is optional. SCMs which do not support mutable refs may return
null
. Repositories
using such SCMs will not be able create
branches
and tags
.
ScmFeature.REFS
@Nonnull ScmStatus getStatus()
status
for the SCM.
Available
SCMs are expected to be able to process requests. However, there may
be situations in which an SCM is unavailable. For example, if the plugin relies on a binary, or common library,
which is not installed on the host system, the SCM may be unavailable. When an SCM is unavailable, a message
explaining the reason must be provided on the returned ScmStatus
.
An SCM's status may be capable of changing over time. However, where possible, it is best for SCMs to determine
their status up front. An ScmStatusChangedEvent
should be raised if an SCM's status changes at runtime, but is not required. However, the system may not detect
the change to the SCM's status if it does not raise an event.
Implementation Note: This method is required and may not return null
.
ScmStatus
boolean isEmpty(@Nonnull com.atlassian.bitbucket.repository.Repository repository)
Repository
is empty, from the perspective of the SCM
implementation. Potential criteria for determining whether a repository is empty include:
Scm.isEmpty(Repository)
only mandates that a newly-created repository must be
considered empty.
How to determine whether a repository is "empty" depends on the SCM, as most SCMs create housekeeping files in their repositories to allow them to manage state. As a result, the system cannot simply test for the absence of any files. Instead, it calls this method to allow the SCM to perform the test.
Implementation Note: This method is required.
repository
- the repository to checktrue
if the repository is empty; otherwise, false
Copyright © 2024 Atlassian. All rights reserved.