You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Framework/AzToolsFramework/AzToolsFramework/SourceControl/SourceControlAPI.h

267 lines
12 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/base.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/string/string.h>
namespace AzToolsFramework
{
//! Name of the AZ Trace window for source control messages
static constexpr char SCC_WINDOW[] = "Source Control";
enum SourceControlStatus
{
SCS_OpSuccess, // No errors reported
SCS_OpNotSupported, // Operation not supported by the source control provider
SCS_CertificateInvalid, // Trust certificate is invalid
SCS_ProviderIsDown, // source control provider is down
SCS_ProviderNotFound, // source control provider not found
SCS_ProviderError, // there was an error processing your request
SCS_NUM_ERRORS, // add errors above this enum
};
enum SourceControlFlags
{
SCF_OutOfDate = (1 << 0), // the file was out of date
SCF_Writeable = (1 << 1), // the file is writable on disk
SCF_MultiCheckOut = (1 << 2), // this file allows multiple owners
SCF_OtherOpen = (1 << 3), // someone else has this file open
SCF_PendingAdd = (1 << 4), // file marked for add
SCF_PendingDelete = (1 << 5), // file marked for removal
SCF_OpenByUser = (1 << 6), // currently open for checkout / staging
SCF_Tracked = (1 << 7), // file is under source control
SCF_PendingMove = (1 << 8), // file marked for move
};
struct SourceControlFileInfo
{
SourceControlStatus m_status;
unsigned int m_flags;
AZStd::string m_filePath;
AZStd::string m_StatusUser; // informational - this is the user that caused the above status.
// secondary use of m_StatusUser is to signify that this file is being worked on by other users, simultaneously.
SourceControlFileInfo()
: m_status(SCS_ProviderIsDown)
, m_flags((SourceControlFlags)0)
{
}
SourceControlFileInfo(const char* fullFilePath)
: m_status(SCS_ProviderIsDown)
, m_filePath(fullFilePath)
, m_flags((SourceControlFlags)0)
{
}
SourceControlFileInfo(const SourceControlFileInfo& rhs)
{
*this = rhs;
}
SourceControlFileInfo(SourceControlFileInfo&& rhs)
: m_status(rhs.m_status)
, m_flags(rhs.m_flags)
, m_filePath(AZStd::move(rhs.m_filePath))
, m_StatusUser(AZStd::move(rhs.m_StatusUser))
{
}
SourceControlFileInfo& operator=(const SourceControlFileInfo& rhs)
{
m_status = rhs.m_status;
m_flags = rhs.m_flags;
m_filePath = rhs.m_filePath;
m_StatusUser = rhs.m_StatusUser;
return *this;
}
bool CompareStatus(SourceControlStatus status) const { return m_status == status; }
bool IsReadOnly() const { return !HasFlag(SCF_Writeable); }
bool IsLockedByOther() const { return HasFlag(SCF_OtherOpen) && !HasFlag(SCF_MultiCheckOut); }
bool IsManaged() const { return HasFlag(SCF_Tracked); }
bool HasFlag(SourceControlFlags flag) const { return ((m_flags & flag) != 0); }
};
// use bind if you need additional context.
typedef AZStd::function<void(bool success, SourceControlFileInfo info)> SourceControlResponseCallback;
typedef AZStd::function<void(bool success, AZStd::vector<SourceControlFileInfo> info)> SourceControlResponseCallbackBulk;
enum class SourceControlSettingStatus : int
{
Invalid,
PERFORCE_BEGIN,
Unset,
None,
Set,
Config,
PERFORCE_END,
};
struct SourceControlSettingInfo
{
SourceControlSettingStatus m_status = SourceControlSettingStatus::Invalid;
AZStd::string m_value;
AZStd::string m_context;
SourceControlSettingInfo() = default;
//! is this value actually present and usable?
bool IsAvailable() const
{
return (m_status != SourceControlSettingStatus::Invalid) && (m_status != SourceControlSettingStatus::Unset) && (!m_value.empty());
}
//! Are we able to actually change this value without messing with global env or registry?
bool IsSettable() const
{
if (m_status == SourceControlSettingStatus::Invalid)
{
return false;
}
return ((m_status == SourceControlSettingStatus::Unset) || (m_status == SourceControlSettingStatus::Set));
}
};
typedef AZStd::function<void(const SourceControlSettingInfo& info)> SourceControlSettingCallback;
enum class SourceControlState : int
{
Disabled,
ConfigurationInvalid,
Active,
};
//! SourceControlCommands
//! This bus handles messages relating to source control commands
//! source control commands are ASYNCHRONOUS
//! do not block the main thread waiting for a response, it is not okay
//! you will not get a message delivered unless you tick the tickbus anyway!
class SourceControlCommands
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; // there's only one source control listener right now
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; // theres only one source control listener right now
typedef AZStd::recursive_mutex MutexType;
virtual ~SourceControlCommands() {}
//! Get information on the file state
virtual void GetFileInfo(const char* fullFilePath, const SourceControlResponseCallback& respCallback) = 0;
//! Get information on the file state for multiple files. Path(s) may contain wildcards
virtual void GetBulkFileInfo(const AZStd::unordered_set<AZStd::string>& fullFilePaths, const SourceControlResponseCallbackBulk& respCallback) = 0;
//! Attempt to make a file ready for editing
virtual void RequestEdit(const char* fullFilePath, bool allowMultiCheckout, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to make a set of files ready for editing
virtual void RequestEditBulk(const AZStd::unordered_set<AZStd::string>& fullFilePaths, bool allowMultiCheckout, const SourceControlResponseCallbackBulk& respCallback) = 0;
//! Attempt to delete a file
virtual void RequestDelete(const char* fullFilePath, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to delete a file
//! @param skipReadOnly If source control is disabled and we're using the local file component, this will skip changes to files which are readonly
virtual void RequestDeleteExtended(const char* fullFilePath, bool skipReadOnly, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to delete multiple files. Path may contain wildcards
virtual void RequestDeleteBulk(const char* fullFilePath, const SourceControlResponseCallbackBulk& respCallback) = 0;
//! Attempt to delete multiple files. Path may contain wildcards
//! @param skipReadOnly If source control is disabled and we're using the local file component, this will skip changes to files which are readonly
virtual void RequestDeleteBulkExtended(const char* fullFilePath, bool skipReadOnly, const SourceControlResponseCallbackBulk& respCallback) = 0;
//! Attempt to revert a file
virtual void RequestRevert(const char* fullFilePath, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to get latest revision of a file
virtual void RequestLatest(const char* fullFilePath, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to rename or move a file
virtual void RequestRename(const char* sourcePathFull, const char* destPathFull, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to rename or move a file
//! @param skipReadOnly If source control is disabled and we're using the local file component, this will skip changes to files which are readonly
virtual void RequestRenameExtended(const char* sourcePathFull, const char* destPathFull, bool skipReadOnly, const SourceControlResponseCallback& respCallback) = 0;
//! Attempt to rename or move multiple files. Path may contain wildcards
virtual void RequestRenameBulk(const char* sourcePathFull, const char* destPathFull, const SourceControlResponseCallbackBulk& respCallback) = 0;
//! Attempt to rename or move multiple files. Path may contain wildcards
//! @param skipReadOnly If source control is disabled and we're using the local file component, this will skip changes to files which are readonly
virtual void RequestRenameBulkExtended(const char* sourcePathFull, const char* destPathFull, bool skipReadOnly, const SourceControlResponseCallbackBulk& respCallback) = 0;
};
using SourceControlCommandBus = AZ::EBus<SourceControlCommands>;
//! SourceControlConnectionRequests
//! This bus handles messages relating to source control connectivity
class SourceControlConnectionRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
typedef AZStd::recursive_mutex MutexType;
virtual ~SourceControlConnectionRequests() {}
//! Suspend / Resume source control operations
virtual void EnableSourceControl(bool enable) = 0;
//! Returns if source control operations are enabled
virtual bool IsActive() const = 0;
//! Enable or disable trust of an SSL connection
virtual void EnableTrust(bool enable, AZStd::string fingerprint) = 0;
//! Attempt to set connection setting 'key' to 'value'
virtual void SetConnectionSetting(const char* key, const char* value, const SourceControlSettingCallback& respCallBack) = 0;
//! Attempt to get connection setting by key
virtual void GetConnectionSetting(const char* key, const SourceControlSettingCallback& respCallBack) = 0;
//! Returns if source control is disabled, has invalid configurations, or enabled
virtual SourceControlState GetSourceControlState() const { return SourceControlState::Disabled; }
};
using SourceControlConnectionRequestBus = AZ::EBus<SourceControlConnectionRequests>;
//! SourceControlNotifications
//! Outgoing messages from source control
class SourceControlNotifications
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
typedef AZStd::recursive_mutex MutexType;
virtual ~SourceControlNotifications() {}
//! Request to trust source control key with provided fingerprint
virtual void RequestTrust(const char* /*fingerprint*/) {}
//! Notify listeners that our connectivity state has changed
virtual void ConnectivityStateChanged(const SourceControlState /*connected*/) {}
};
using SourceControlNotificationBus = AZ::EBus<SourceControlNotifications>;
}; // namespace AzToolsFramework