Net-Game/Library/PackageCache/com.unity.collab-proxy@50ac96531b63/Editor/Hub/Operations/CreateWorkspace.cs
2025-03-28 08:33:16 -04:00

270 lines
8.6 KiB
C#

using System;
using System.Threading;
using UnityEditor;
using Codice.Client.Common.EventTracking;
using Codice.CM.Common;
using Codice.LogWrapper;
using PlasticGui;
using PlasticGui.Help.Conditions;
using PlasticGui.WebApi.Responses;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.Configuration;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.Views.CreateWorkspace;
using Unity.PlasticSCM.Editor.WebApi;
namespace Unity.PlasticSCM.Editor.Hub.Operations
{
internal class CreateWorkspace
{
internal static void LaunchOperation(
OperationParams parameters)
{
CreateWorkspace createWorkspaceOperation =
new CreateWorkspace();
createWorkspaceOperation.CreateWorkspaceOperation(
parameters);
}
internal static WorkspaceInfo CreateWorkspaceForRepSpec(
RepositorySpec repositorySpec,
string wkPath,
ILog log)
{
CreateWorkspaceDialogUserAssistant assistant =
CreateWorkspaceDialogUserAssistant.ForWkPathAndName(
PlasticGuiConfig.Get().Configuration.DefaultWorkspaceRoot,
PlasticGui.Plastic.API.GetAllWorkspacesArray());
assistant.RepositoryChanged(
repositorySpec.ToString(),
string.Empty,
string.Empty);
WorkspaceInfo wkInfo = PlasticGui.Plastic.API.CreateWorkspace(
wkPath,
assistant.GetProposedWorkspaceName(),
repositorySpec.ToString());
log.DebugFormat("Created workspace {0} on {1}",
wkInfo.Name,
wkInfo.ClientPath);
return wkInfo;
}
void CreateWorkspaceOperation(
OperationParams parameters)
{
RefreshAsset.BeforeLongAssetOperation();
try
{
ThreadPool.QueueUserWorkItem(
CreateWorkspaceIfNeeded,
parameters);
while (mStatus != Status.Finished)
{
if (mDisplayProgress)
{
DisplayProgress(
mStatus, parameters.Repository);
}
Thread.Sleep(150);
}
}
finally
{
EditorUtility.ClearProgressBar();
RefreshAsset.AfterLongAssetOperation();
if (!mOperationFailed)
{
PlasticPlugin.Enable();
ShowWindow.Plastic();
}
}
}
void CreateWorkspaceIfNeeded(object state)
{
OperationParams parameters = (OperationParams)state;
try
{
if (FindWorkspace.HasWorkspace(parameters.WorkspaceFullPath))
{
// each domain reload, the package is reloaded.
// way need to check if we already created it
return;
}
mDisplayProgress = true;
mStatus = Status.ConfiguringCredentials;
TokenExchangeResponse tokenExchangeResponse =
AutoConfig.PlasticCredentials(
parameters.AccessToken,
parameters.RepositorySpec.Server);
if (tokenExchangeResponse.Error != null)
{
mOperationFailed = true;
LogTokenExchangeErrorInConsole(
tokenExchangeResponse.Error);
return;
}
mStatus = Status.CreatingWorkspace;
TrackFeatureUseEvent.For(
parameters.RepositorySpec, TrackFeatureUseEvent.
Features.UnityPackage.CreateWorkspaceFromHub);
WorkspaceInfo wkInfo = CreateWorkspaceForRepSpec(
parameters.RepositorySpec,
parameters.WorkspaceFullPath,
mLog);
mStatus = Status.PerformingInitialCheckin;
PerformInitialCheckinIfRepositoryIsEmpty(
wkInfo, parameters.RepositorySpec,
PlasticGui.Plastic.API, mLog);
}
catch (Exception ex)
{
LogException(ex);
LogExceptionErrorInConsole(ex);
mOperationFailed = true;
}
finally
{
mStatus = Status.Finished;
}
}
static void PerformInitialCheckinIfRepositoryIsEmpty(
WorkspaceInfo wkInfo,
RepositorySpec repositorySpec,
IPlasticAPI plasticApi,
ILog log)
{
try
{
bool isEmptyRepository = IsEmptyRepositoryCondition.
Evaluate(wkInfo, repositorySpec, plasticApi);
if (!isEmptyRepository)
return;
PerformInitialCheckin.PerformCheckinPackagesAndProjectSettingsFolders(
wkInfo, false, plasticApi);
log.DebugFormat("Created initial checkin on repository '{0}'",
repositorySpec.ToString());
}
catch (Exception ex)
{
// create the initial checkin if it's possible, otherwise
// just log the exception (no error shown for the user)
LogException(ex);
}
}
static void DisplayProgress(
Status status,
string repository)
{
string progressMessage = GetProgressString(status);
float progressPercent = (int)status / (float)Status.Finished;
EditorUtility.DisplayProgressBar(
string.Format("{0} {1}",
PlasticLocalization.GetString(
PlasticLocalization.Name.CreatingWorkspaceProgress),
repository),
progressMessage, progressPercent);
}
static void LogTokenExchangeErrorInConsole(ErrorResponse.ErrorFields error)
{
UnityEngine.Debug.LogErrorFormat(
PlasticLocalization.GetString(
PlasticLocalization.Name.ErrorCreatingWorkspaceForProject),
string.Format("Unable to get TokenExchangeResponse: {0} [code {1}]",
error.Message, error.ErrorCode));
}
static void LogExceptionErrorInConsole(Exception ex)
{
UnityEngine.Debug.LogErrorFormat(
PlasticLocalization.GetString(
PlasticLocalization.Name.ErrorCreatingWorkspaceForProject),
ex.Message);
}
static void LogException(Exception ex)
{
mLog.WarnFormat("Message: {0}", ex.Message);
mLog.DebugFormat(
"StackTrace:{0}{1}",
Environment.NewLine, ex.StackTrace);
}
static string GetProgressString(Status status)
{
switch (status)
{
case Status.Starting:
return PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspaceProgressStarting);
case Status.ConfiguringCredentials:
return PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspaceProgressConfiguringCredentials);
case Status.CreatingWorkspace:
return PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspaceProgressCreatingWorkspace);
case Status.PerformingInitialCheckin:
return PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspaceProgressPerformingInitialCheckin);
case Status.Finished:
return PlasticLocalization.GetString(
PlasticLocalization.Name.CreateWorkspaceProgressFinished);
}
return string.Empty;
}
CreateWorkspace()
{
}
enum Status : int
{
Starting = 1,
ConfiguringCredentials = 2,
CreatingWorkspace = 3,
PerformingInitialCheckin = 4,
Finished = 5
};
volatile Status mStatus = Status.Starting;
volatile bool mOperationFailed = false;
volatile bool mDisplayProgress;
static readonly ILog mLog = PlasticApp.GetLogger("CreateWorkspace");
}
}