TArray< TSharedRef<ISourceControlLabel> > FPerforceSourceControlProvider::GetLabels( const FString& InMatchingSpec ) const { TArray< TSharedRef<ISourceControlLabel> > Labels; FPerforceSourceControlModule& PerforceSourceControl = FModuleManager::LoadModuleChecked<FPerforceSourceControlModule>("PerforceSourceControl"); FScopedPerforceConnection ScopedConnection(EConcurrency::Synchronous, PerforceSourceControl.AccessSettings().GetConnectionInfo()); if(ScopedConnection.IsValid()) { FPerforceConnection& Connection = ScopedConnection.GetConnection(); FP4RecordSet Records; TArray<FString> Parameters; TArray<FText> ErrorMessages; Parameters.Add(TEXT("-E")); Parameters.Add(InMatchingSpec); bool bConnectionDropped = false; if(Connection.RunCommand(TEXT("labels"), Parameters, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped)) { ParseGetLabelsResults(Records, Labels); } else { // output errors if any for (int32 ErrorIndex = 0; ErrorIndex < ErrorMessages.Num(); ++ErrorIndex) { FMessageLog("SourceControl").Warning(ErrorMessages[ErrorIndex]); } } } return Labels; }
bool FPerforceConnection::AutoDetectWorkspace(const FPerforceConnectionInfo& InConnectionInfo, FString& OutWorkspaceName) { bool Result = false; FMessageLog SourceControlLog("SourceControl"); //before even trying to summon the window, try to "smart" connect with the default server/username TArray<FText> ErrorMessages; FPerforceConnection Connection(InConnectionInfo); TArray<FString> ClientSpecList; Connection.GetWorkspaceList(InConnectionInfo, FOnIsCancelled(), ClientSpecList, ErrorMessages); //if only one client spec matched (and default connection info was correct) if (ClientSpecList.Num() == 1) { OutWorkspaceName = ClientSpecList[0]; FFormatNamedArguments Arguments; Arguments.Add( TEXT("WorkspaceName"), FText::FromString(OutWorkspaceName) ); SourceControlLog.Info(FText::Format(LOCTEXT("ClientSpecAutoDetect", "Auto-detected Perforce client spec: '{WorkspaceName}'"), Arguments)); Result = true; } else if (ClientSpecList.Num() > 0) { SourceControlLog.Warning(LOCTEXT("AmbiguousClientSpecLine1", "Source Control unable to auto-login due to ambiguous client specs")); SourceControlLog.Warning(LOCTEXT("AmbiguousClientSpecLine2", " Please select a client spec in the Perforce settings dialog")); SourceControlLog.Warning(LOCTEXT("AmbiguousClientSpecLine3", " If you are unable to work with source control, consider checking out the files by hand temporarily")); // List out the clientspecs that were found to be ambiguous SourceControlLog.Info(LOCTEXT("AmbiguousClientSpecListTitle", "Ambiguous client specs...")); for (int32 Index = 0; Index < ClientSpecList.Num(); Index++) { FFormatNamedArguments Arguments; Arguments.Add( TEXT("ClientSpecName"), FText::FromString(ClientSpecList[Index]) ); SourceControlLog.Info(FText::Format(LOCTEXT("AmbiguousClientSpecListItem", "...{ClientSpecName}"), Arguments)); } } return Result; }
bool FPerforceSourceControlLabel::Sync( const TArray<FString>& InFilenames ) const { bool bCommandOK = false; FPerforceSourceControlModule& PerforceSourceControl = FModuleManager::LoadModuleChecked<FPerforceSourceControlModule>("PerforceSourceControl"); FScopedPerforceConnection ScopedConnection(EConcurrency::Synchronous, PerforceSourceControl.AccessSettings().GetConnectionInfo()); if(ScopedConnection.IsValid()) { FPerforceConnection& Connection = ScopedConnection.GetConnection(); FP4RecordSet Records; TArray<FText> ErrorMessages; TArray<FString> Parameters; for(const auto& Filename : InFilenames) { Parameters.Add(Filename + TEXT("@") + Name); } bool bConnectionDropped = false; bCommandOK = Connection.RunCommand(TEXT("sync"), Parameters, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped); if(!bCommandOK) { // output errors if any for (int32 ErrorIndex = 0; ErrorIndex < ErrorMessages.Num(); ++ErrorIndex) { FMessageLog("SourceControl").Error(ErrorMessages[ErrorIndex]); } } } return bCommandOK; }
bool FPerforceSourceControlLabel::GetFileRevisions( const TArray<FString>& InFiles, TArray< TSharedRef<ISourceControlRevision, ESPMode::ThreadSafe> >& OutRevisions ) const { bool bCommandOK = false; FPerforceSourceControlModule& PerforceSourceControl = FModuleManager::LoadModuleChecked<FPerforceSourceControlModule>("PerforceSourceControl"); FScopedPerforceConnection ScopedConnection(EConcurrency::Synchronous, PerforceSourceControl.AccessSettings().GetConnectionInfo()); if(ScopedConnection.IsValid()) { FPerforceConnection& Connection = ScopedConnection.GetConnection(); FP4RecordSet Records; TArray<FString> Parameters; TArray<FText> ErrorMessages; for(auto Iter(InFiles.CreateConstIterator()); Iter; Iter++) { Parameters.Add(*Iter + TEXT("@") + Name); } bool bConnectionDropped = false; bCommandOK = Connection.RunCommand(TEXT("files"), Parameters, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped); if(bCommandOK) { ParseFilesResults(Records, OutRevisions, Connection.ClientRoot); } else { // output errors if any for (int32 ErrorIndex = 0; ErrorIndex < ErrorMessages.Num(); ++ErrorIndex) { FMessageLog("SourceControl").Error(ErrorMessages[ErrorIndex]); } } } return bCommandOK; }
void FPerforceConnection::EstablishConnection(const FPerforceConnectionInfo& InConnectionInfo) { #if USE_P4_API // Verify Input. ServerName and UserName are required if ( InConnectionInfo.Port.IsEmpty() || InConnectionInfo.UserName.IsEmpty() ) { return; } //Connection assumed successful bEstablishedConnection = true; UE_LOG(LogSourceControl, Verbose, TEXT("Attempting P4 connection: %s/%s"), *InConnectionInfo.Port, *InConnectionInfo.UserName); P4Client.SetProtocol("tag", ""); P4Client.SetProtocol("enableStreams", ""); //Set configuration based params P4Client.SetPort(TCHAR_TO_ANSI(*InConnectionInfo.Port)); Error P4Error; if(InConnectionInfo.Password.Len() > 0) { UE_LOG(LogSourceControl, Verbose, TEXT(" ... applying password" )); P4Client.DefinePassword(TCHAR_TO_ANSI(*InConnectionInfo.Password), &P4Error); if(P4Error.Test()) { StrBuf ErrorMessage; P4Error.Fmt(&ErrorMessage); UE_LOG(LogSourceControl, Error, TEXT("P4ERROR: Could not set password.")); UE_LOG(LogSourceControl, Error, TEXT("%s"), ANSI_TO_TCHAR(ErrorMessage.Text())); } } if(InConnectionInfo.HostOverride.Len() > 0) { UE_LOG(LogSourceControl, Verbose, TEXT(" ... overriding host" )); P4Client.SetHost(TCHAR_TO_ANSI(*InConnectionInfo.HostOverride)); } UE_LOG(LogSourceControl, Verbose, TEXT(" ... connecting" )); //execute the connection to perforce using the above settings P4Client.Init(&P4Error); //ensure the connection is valid UE_LOG(LogSourceControl, Verbose, TEXT(" ... validating connection" )); if (P4Error.Test()) { bEstablishedConnection = false; StrBuf ErrorMessage; P4Error.Fmt(&ErrorMessage); UE_LOG(LogSourceControl, Error, TEXT("P4ERROR: Invalid connection to server.")); UE_LOG(LogSourceControl, Error, TEXT("%s"), ANSI_TO_TCHAR(ErrorMessage.Text())); } else { TArray<FString> Params; TArray<FText> ErrorMessages; FP4RecordSet Records; bool bConnectionDropped = false; const bool bStandardDebugOutput = false; const bool bAllowRetry = true; UE_LOG(LogSourceControl, Verbose, TEXT(" ... checking unicode status" )); if (RunCommand(TEXT("info"), Params, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped, bStandardDebugOutput, bAllowRetry)) { // Get character encoding bIsUnicode = Records[0].Find(TEXT("unicode")) != NULL; if(bIsUnicode) { P4Client.SetTrans(CharSetApi::UTF_8); UE_LOG(LogSourceControl, Verbose, TEXT(" server is unicode" )); } // Now we know our unicode status we can gather the client root P4Client.SetUser(FROM_TCHAR(*InConnectionInfo.UserName, bIsUnicode)); if(InConnectionInfo.Password.Len() > 0) { Login(InConnectionInfo); } if (InConnectionInfo.Ticket.Len()) { P4Client.SetPassword(FROM_TCHAR(*InConnectionInfo.Ticket, bIsUnicode)); } if (InConnectionInfo.Workspace.Len()) { P4Client.SetClient(FROM_TCHAR(*InConnectionInfo.Workspace, bIsUnicode)); } P4Client.SetCwd(FROM_TCHAR(*FPaths::RootDir(), bIsUnicode)); // Gather the client root UE_LOG(LogSourceControl, Verbose, TEXT(" ... getting info" )); bConnectionDropped = false; if (RunCommand(TEXT("info"), Params, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped, bStandardDebugOutput, bAllowRetry)) { UE_LOG(LogSourceControl, Verbose, TEXT(" ... getting clientroot" )); ClientRoot = Records[0](TEXT("clientRoot")); //make sure all slashes point the same way ClientRoot = ClientRoot.Replace(TEXT("\\"), TEXT("/")); } } } #endif }
void FPerforceSourceControlProvider::GetWorkspaceList(const FPerforceConnectionInfo& InConnectionInfo, TArray<FString>& OutWorkspaceList, TArray<FText>& OutErrorMessages) { //attempt to ask perforce for a list of client specs that belong to this user FPerforceConnection Connection(InConnectionInfo); Connection.GetWorkspaceList(InConnectionInfo, FOnIsCancelled(), OutWorkspaceList, OutErrorMessages); }