Skip to content

Commit

Permalink
Get User & Workspace Name, and compare them to LockedBy and LockedWhere
Browse files Browse the repository at this point in the history
 + Fix BranchName
  • Loading branch information
SRombauts committed Apr 14, 2016
1 parent e345d42 commit 9a1f055
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ void FPlasticSourceControlProvider::CheckPlasticAvailability()
// Find the path to the root Plastic directory (if any)
const FString PathToGameDir = FPaths::ConvertRelativePathToFull(FPaths::GameDir());
const bool bRepositoryFound = PlasticSourceControlUtils::FindRootDirectory(PathToGameDir, PathToRepositoryRoot);
// Get user name (from the global Plastic SCM client config)
PlasticSourceControlUtils::GetUserName(UserName);
if (bRepositoryFound)
{
// Get branch name
PlasticSourceControlUtils::GetBranchName(BranchName);
// Get workspace name and branch name
PlasticSourceControlUtils::GetWorkspaceName(PathToRepositoryRoot, WorkspaceName);
PlasticSourceControlUtils::GetBranchName(PathToRepositoryRoot, BranchName);
bPlasticRepositoryFound = true;
}
else
Expand Down Expand Up @@ -82,10 +85,11 @@ TSharedRef<FPlasticSourceControlState, ESPMode::ThreadSafe> FPlasticSourceContro
FText FPlasticSourceControlProvider::GetStatusText() const
{
FFormatNamedArguments Args;
Args.Add( TEXT("RepositoryName"), FText::FromString(PathToRepositoryRoot) );
Args.Add( TEXT("WorkspacePath"), FText::FromString(PathToRepositoryRoot) );
Args.Add( TEXT("BranchName"), FText::FromString(BranchName) );
Args.Add( TEXT("UserName"), FText::FromString(UserName) );

return FText::Format( NSLOCTEXT("Status", "Provider: Plastic\nEnabledLabel", "Workspace: {RepositoryName}\n{BranchName}"), Args );
return FText::Format( NSLOCTEXT("Status", "Provider: Plastic\nEnabledLabel", "Workspace: {WorkspacePath}\n{BranchName}\nUser: {UserName}"), Args );
}

/** Quick check if source control is enabled */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ class FPlasticSourceControlProvider : public ISourceControlProvider
return PathToRepositoryRoot;
}

/** Get the Plastic current user */
inline const FString& GetUserName() const
{
return UserName;
}

/** Get the Plastic current workspace */
inline const FString& GetWorkspaceName() const
{
return WorkspaceName;
}

/** Get the Name of the current branch */
inline const FString& GetBranchName() const
{
return BranchName;
}

/** Helper function used to update state cache */
TSharedRef<FPlasticSourceControlState, ESPMode::ThreadSafe> GetStateInternal(const FString& Filename);

Expand Down Expand Up @@ -89,7 +107,13 @@ class FPlasticSourceControlProvider : public ISourceControlProvider
void OutputCommandMessages(const class FPlasticSourceControlCommand& InCommand) const;

/** Path to the root of the Plastic repository: can be the GameDir itself, or any parent directory (found by the "Connect" operation) */
FString PathToRepositoryRoot;
FString PathToRepositoryRoot; // TODO rename to PathToWorkspaceRoot

/** Plastic current user */
FString UserName;

/** Plastic current workspace */
FString WorkspaceName;

/** Name of the current branch */
FString BranchName;
Expand Down
24 changes: 21 additions & 3 deletions Source/PlasticSourceControl/Private/PlasticSourceControlState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ TSharedPtr<class ISourceControlRevision, ESPMode::ThreadSafe> FPlasticSourceCont

FName FPlasticSourceControlState::GetIconName() const
{
if (!IsCurrent())
{
return FName("Perforce.NotAtHeadRevision");
}

switch(WorkspaceState)
{
case EWorkspaceState::CheckedOut:
Expand All @@ -72,6 +77,8 @@ FName FPlasticSourceControlState::GetIconName() const
case EWorkspaceState::Changed:
case EWorkspaceState::Conflicted:
return FName("Perforce.NotAtHeadRevision");
case EWorkspaceState::LockedByOther:
return FName("Perforce.CheckedOutByOtherUser");
case EWorkspaceState::Private:
return FName("Perforce.NotInDepot");
case EWorkspaceState::Unknown:
Expand All @@ -84,6 +91,11 @@ FName FPlasticSourceControlState::GetIconName() const

FName FPlasticSourceControlState::GetSmallIconName() const
{
if (!IsCurrent())
{
return FName("Perforce.NotAtHeadRevision_Small");
}

switch(WorkspaceState)
{
case EWorkspaceState::CheckedOut:
Expand All @@ -98,6 +110,8 @@ FName FPlasticSourceControlState::GetSmallIconName() const
case EWorkspaceState::Changed:
case EWorkspaceState::Conflicted:
return FName("Perforce.NotAtHeadRevision_Small");
case EWorkspaceState::LockedByOther:
return FName("Perforce.CheckedOutByOtherUser_Small");
case EWorkspaceState::Private:
return FName("Perforce.NotInDepot_Small");
case EWorkspaceState::Unknown:
Expand Down Expand Up @@ -134,6 +148,8 @@ FText FPlasticSourceControlState::GetDisplayName() const
return LOCTEXT("Changed", "Changed");
case EWorkspaceState::Conflicted:
return LOCTEXT("ContentsConflict", "Contents Conflict");
case EWorkspaceState::LockedByOther:
return FText::Format(LOCTEXT("CheckedOutOther", "Checked out by: {0}"), FText::FromString(LockedBy));
case EWorkspaceState::Private:
return LOCTEXT("NotControlled", "Not Under Source Control");
}
Expand Down Expand Up @@ -224,9 +240,11 @@ bool FPlasticSourceControlState::IsCheckedOutOther(FString* Who) const
{
*Who = LockedBy;
}
// TODO return State == EPerforceState::CheckedOutOther; Does Plastic uses a specific state?
if(0 < LockedBy.Len()) UE_LOG(LogSourceControl, Log, TEXT("IsCheckedOutOther(%s)=%s"), *LocalFilename, *LockedBy);
return (0 < LockedBy.Len());
const bool bIsLockedByOther = WorkspaceState == EWorkspaceState::LockedByOther;

if (bIsLockedByOther) UE_LOG(LogSourceControl, Log, TEXT("IsCheckedOutOther(%s)=%d '%s' '%s'"), *LocalFilename, bIsLockedByOther, *LockedBy, *LockedWhere);

return bIsLockedByOther;
}

bool FPlasticSourceControlState::IsCurrent() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace EWorkspaceState
Deleted,
Changed, // Modified but not CheckedOut
Conflicted,
LockedByOther, // LockedBy with name of someone else than cm whoami
Private, // "Not Controlled"/"Not In Depot"/"Untraked"
};
}
Expand Down Expand Up @@ -71,9 +72,12 @@ class FPlasticSourceControlState : public ISourceControlState, public TSharedFro
/** File Id with which our local revision diverged from the remote revision */
FString PendingMergeBaseFileHash;

/** If another user has this file checked out, this contains his name. */
/** If a user (another or ourself) has this file locked, this contains his name. */
FString LockedBy;

/** Location of the locked file. */
FString LockedWhere;

/** State of the workspace */
EWorkspaceState::Type WorkspaceState;

Expand Down
61 changes: 50 additions & 11 deletions Source/PlasticSourceControl/Private/PlasticSourceControlUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,41 @@ bool FindRootDirectory(const FString& InPathToGameDir, FString& OutRepositoryRoo
return bFound;
}

void GetBranchName(FString& OutBranchName)
void GetUserName(FString& OutUserName)
{
TArray<FString> InfoMessages;
TArray<FString> ErrorMessages;
const bool bResults = RunCommandInternal(TEXT("whoami"), TArray<FString>(), TArray<FString>(), InfoMessages, ErrorMessages);
if (bResults && InfoMessages.Num() > 0)
{
OutUserName = InfoMessages[0];
}
}

void GetWorkspaceName(const FString& InRepositoryRoot, FString& OutWorkspaceName)
{
bool bResults;
TArray<FString> InfoMessages;
TArray<FString> ErrorMessages;
TArray<FString> Parameters;
Parameters.Add(InRepositoryRoot);
Parameters.Add(TEXT("--format={0}"));
const bool bResults = RunCommandInternal(TEXT("getworkspacefrompath"), Parameters, TArray<FString>(), InfoMessages, ErrorMessages);
if (bResults && InfoMessages.Num() > 0)
{
OutWorkspaceName = InfoMessages[0];
}
}

void GetBranchName(const FString& InRepositoryRoot, FString& OutBranchName)
{
TArray<FString> InfoMessages;
TArray<FString> ErrorMessages;
TArray<FString> Parameters;
Parameters.Add(InRepositoryRoot);
Parameters.Add(TEXT("--wkconfig"));
Parameters.Add(TEXT("--nochanges"));
Parameters.Add(TEXT("--nostatus"));
bResults = RunCommandInternal(TEXT("status"), Parameters, TArray<FString>(), InfoMessages, ErrorMessages);
const bool bResults = RunCommandInternal(TEXT("status"), Parameters, TArray<FString>(), InfoMessages, ErrorMessages);
if(bResults && InfoMessages.Num() > 0)
{
OutBranchName = InfoMessages[0];
Expand Down Expand Up @@ -486,7 +511,7 @@ static bool RunStatus(const TArray<FString>& InFiles, TArray<FString>& OutErrorM
return bResult;
}

// Parse the fileinfo output format "{RevisionChangeset};{RevisionHeadChangeset};{LockedBy}"
// Parse the fileinfo output format "{RevisionChangeset};{RevisionHeadChangeset};{LockedBy};{LockedWhere}"
class FPlasticFileinfoParser
{
public:
Expand All @@ -501,24 +526,32 @@ class FPlasticFileinfoParser
if (NbElmts >= 3)
{
LockedBy = MoveTemp(Fileinfos[2]);
if (NbElmts >=4)
{
LockedWhere = MoveTemp(Fileinfos[3]);
}
}
}
}

int32 RevisionChangeset;
int32 RevisionHeadChangeset;
FString LockedBy;
FString LockedWhere;
};

/** Parse the array of strings results of a 'cm fileinfo --format="{RevisionChangeset};{RevisionHeadChangeset};{LockedBy}"' command
/** Parse the array of strings results of a 'cm fileinfo --format="{RevisionChangeset};{RevisionHeadChangeset};{LockedBy};{LockedWhere}"' command
*
* Example cm fileinfo results:
16;16;False;;
14;14;False;;
16;16;False;;
16;16;;
14;15;;
17;17;srombauts;Workspace_2
*/
static void ParseFileinfoResults(const TArray<FString>& InFiles, const TArray<FString>& InResults, TArray<FPlasticSourceControlState>& InOutStates)
{
FPlasticSourceControlModule& PlasticSourceControl = FModuleManager::LoadModuleChecked<FPlasticSourceControlModule>("PlasticSourceControl");
FPlasticSourceControlProvider& Provider = PlasticSourceControl.GetProvider();

// Iterate on all files and all status of the result (assuming no more line of results than number of files)
for (int32 IdxResult = 0; IdxResult < InResults.Num(); IdxResult++)
{
Expand All @@ -530,9 +563,15 @@ static void ParseFileinfoResults(const TArray<FString>& InFiles, const TArray<FS
FileState.LocalRevisionChangeset = FileinfoParser.RevisionChangeset;
FileState.DepotRevisionChangeset = FileinfoParser.RevisionHeadChangeset;
FileState.LockedBy = MoveTemp(FileinfoParser.LockedBy);
FileState.LockedWhere = MoveTemp(FileinfoParser.LockedWhere);

if ((0 < FileState.LockedBy.Len()) && ((FileState.LockedBy != Provider.GetUserName()) || (FileState.LockedWhere != Provider.GetWorkspaceName())))
{
FileState.WorkspaceState = EWorkspaceState::LockedByOther;
}

// TODO debug log
UE_LOG(LogSourceControl, Log, TEXT("%s: %d;%d '%s'"), *File, FileState.LocalRevisionChangeset, FileState.DepotRevisionChangeset, *FileState.LockedBy);
UE_LOG(LogSourceControl, Log, TEXT("%s: %d;%d '%s'(%s)"), *File, FileState.LocalRevisionChangeset, FileState.DepotRevisionChangeset, *FileState.LockedBy, *FileState.LockedWhere);
}
}

Expand All @@ -541,7 +580,7 @@ static bool RunFileinfo(const TArray<FString>& InFiles, TArray<FString>& OutErro
{
TArray<FString> Results;
TArray<FString> Parameters;
Parameters.Add(TEXT("--format=\"{RevisionChangeset};{RevisionHeadChangeset};{LockedBy}\""));
Parameters.Add(TEXT("--format=\"{RevisionChangeset};{RevisionHeadChangeset};{LockedBy};{LockedWhere}\""));

TArray<FString> ErrorMessages;
const bool bResult = RunCommand(TEXT("fileinfo"), Parameters, InFiles, Results, ErrorMessages);
Expand All @@ -558,7 +597,7 @@ static bool RunFileinfo(const TArray<FString>& InFiles, TArray<FString>& OutErro
bool RunUpdateStatus(const TArray<FString>& InFiles, TArray<FString>& OutErrorMessages, TArray<FPlasticSourceControlState>& OutStates)
{
bool bResult;

// Run a "status" command for each file to get workspace states
bResult = RunStatus(InFiles, OutErrorMessages, OutStates);

Expand Down
18 changes: 16 additions & 2 deletions Source/PlasticSourceControl/Private/PlasticSourceControlUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,25 @@ void Terminate();
*/
bool FindRootDirectory(const FString& InPathToGameDir, FString& OutRepositoryRoot);

/**
* Get Plastic SCM current user
* @param OutUserName Name of the Plastic SCM user configured globaly
*/
void GetUserName(FString& OutUserName);

/**
* Get Plastic workspace name
* @param InRepositoryRoot The workspace from where to run the command - usually the Game directory (can be empty)
* @param OutWorkspaceName Name of the current workspace
*/
void GetWorkspaceName(const FString& InRepositoryRoot, FString& OutWorkspaceName);

/**
* Get Plastic current checked-out branch
* @param OutBranchName Name of the current checked-out branch (if any, ie. not in detached HEAD)
* @param InRepositoryRoot The workspace from where to run the command - usually the Game directory (can be empty)
* @param OutBranchName Name of the current checked-out branch (if any, ie. not in detached HEAD)
*/
void GetBranchName(FString& OutBranchName);
void GetBranchName(const FString& InRepositoryRoot, FString& OutBranchName);

/**
* Run a Plastic command - output is a string TArray.
Expand Down

0 comments on commit 9a1f055

Please sign in to comment.