271 lines
8.0 KiB
C#
271 lines
8.0 KiB
C#
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EpicGames.Core;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace UnrealGameSync
|
|
{
|
|
public class FilterSettings
|
|
{
|
|
public List<Guid> IncludeCategories { get; init; } = new List<Guid>();
|
|
public List<Guid> ExcludeCategories { get; init; } = new List<Guid>();
|
|
public List<string> View { get; init; } = new List<string>();
|
|
public bool? AllProjects { get; set; }
|
|
public bool? AllProjectsInSln { get; set; }
|
|
public bool? UprojectSpecificSln { get; set; }
|
|
|
|
public void Reset()
|
|
{
|
|
IncludeCategories.Clear();
|
|
ExcludeCategories.Clear();
|
|
View.Clear();
|
|
AllProjects = null;
|
|
AllProjectsInSln = null;
|
|
UprojectSpecificSln = null;
|
|
}
|
|
|
|
public void SetCategories(Dictionary<Guid, bool> categories)
|
|
{
|
|
IncludeCategories.Clear();
|
|
IncludeCategories.AddRange(categories.Where(x => x.Value).Select(x => x.Key));
|
|
|
|
ExcludeCategories.Clear();
|
|
ExcludeCategories.AddRange(categories.Where(x => !x.Value).Select(x => x.Key));
|
|
}
|
|
|
|
public Dictionary<Guid, bool> GetCategories()
|
|
{
|
|
Dictionary<Guid, bool> categories = new Dictionary<Guid, bool>();
|
|
foreach (Guid includeCategory in IncludeCategories)
|
|
{
|
|
categories[includeCategory] = true;
|
|
}
|
|
foreach (Guid excludeCategory in ExcludeCategories)
|
|
{
|
|
categories[excludeCategory] = false;
|
|
}
|
|
return categories;
|
|
}
|
|
}
|
|
|
|
public class GlobalSettings
|
|
{
|
|
public string? LatestVersion { get; set; }
|
|
public DateTime LastVersionCheck { get; set; }
|
|
public PerforceSyncOptions Perforce { get; set; } = new PerforceSyncOptions();
|
|
public FilterSettings Filter { get; set; } = new FilterSettings();
|
|
public bool AutoResolveConflicts { get; set; } = true;
|
|
public bool AlwaysClobberFiles { get; set; } = false;
|
|
public bool AlwaysDeleteFiles { get; set; } = false;
|
|
public bool AllowUEFNProjects { get; set; } = false;
|
|
}
|
|
|
|
public class GlobalSettingsFile
|
|
{
|
|
public FileReference File { get; }
|
|
public GlobalSettings Global { get; }
|
|
|
|
public UserProjectSettings FindOrAddProjectSettings(ProjectInfo projectInfo, UserWorkspaceSettings settings, ILogger logger)
|
|
{
|
|
FileReference configFile;
|
|
if (projectInfo.LocalFileName.HasExtension(".uprojectdirs"))
|
|
{
|
|
configFile = FileReference.Combine(UserSettings.GetConfigDir(settings.RootDir), "project.json");
|
|
}
|
|
else
|
|
{
|
|
configFile = FileReference.Combine(UserSettings.GetConfigDir(settings.RootDir), $"project_{projectInfo.LocalFileName.GetFileNameWithoutExtension()}.json");
|
|
}
|
|
|
|
UserSettings.CreateConfigDir(configFile.Directory);
|
|
|
|
UserProjectSettings? projectSettings;
|
|
if (!UserProjectSettings.TryLoad(configFile, out projectSettings))
|
|
{
|
|
projectSettings = new UserProjectSettings(configFile);
|
|
ImportProjectSettings(projectInfo, projectSettings);
|
|
projectSettings.Save(logger);
|
|
}
|
|
return projectSettings;
|
|
}
|
|
|
|
protected virtual void ImportProjectSettings(ProjectInfo projectInfo, UserProjectSettings projectSettings)
|
|
{
|
|
}
|
|
|
|
protected virtual void ImportWorkspaceSettings(DirectoryReference rootDir, string clientName, string branchPath, UserWorkspaceSettings workspaceSettings)
|
|
{
|
|
}
|
|
|
|
protected virtual void ImportWorkspaceState(DirectoryReference rootDir, string clientName, string branchPath, WorkspaceState workspaceState)
|
|
{
|
|
}
|
|
|
|
public GlobalSettingsFile(FileReference file, GlobalSettings global)
|
|
{
|
|
File = file;
|
|
Global = global;
|
|
}
|
|
|
|
public static GlobalSettingsFile Create(FileReference file)
|
|
{
|
|
GlobalSettings? data;
|
|
if (!Utility.TryLoadJson(file, out data))
|
|
{
|
|
data = new GlobalSettings();
|
|
}
|
|
return new GlobalSettingsFile(file, data);
|
|
}
|
|
|
|
public virtual bool Save(ILogger logger)
|
|
{
|
|
try
|
|
{
|
|
Utility.SaveJson(File, Global);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Unable to save {File}: {Message}", File, ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public WorkspaceStateWrapper FindOrAddWorkspaceState(UserWorkspaceSettings settings)
|
|
{
|
|
return FindOrAddWorkspaceState(settings.RootDir, settings.ClientName, settings.BranchPath);
|
|
}
|
|
|
|
public WorkspaceStateWrapper FindOrAddWorkspaceState(DirectoryReference rootDir, string clientName, string branchPath)
|
|
{
|
|
return new WorkspaceStateWrapper(rootDir, () =>
|
|
{
|
|
WorkspaceState state = new WorkspaceState();
|
|
ImportWorkspaceState(rootDir, clientName, branchPath, state);
|
|
return state;
|
|
});
|
|
}
|
|
|
|
public WorkspaceStateWrapper FindOrAddWorkspaceState(ProjectInfo projectInfo, UserWorkspaceSettings settings)
|
|
{
|
|
WorkspaceStateWrapper wrapper = FindOrAddWorkspaceState(projectInfo.LocalRootPath, projectInfo.ClientName, projectInfo.BranchPath);
|
|
wrapper.Modify(x => x.UpdateCachedProjectInfo(projectInfo, settings.LastModifiedTimeUtc));
|
|
return wrapper;
|
|
}
|
|
|
|
public UserWorkspaceSettings FindOrAddWorkspaceSettings(DirectoryReference rootDir, string? serverAndPort, string? userName, string clientName, string branchPath, string projectPath, ILogger logger)
|
|
{
|
|
ProjectInfo.ValidateBranchPath(branchPath);
|
|
ProjectInfo.ValidateProjectPath(projectPath);
|
|
|
|
UserWorkspaceSettings? settings;
|
|
if (!UserWorkspaceSettings.TryLoad(rootDir, out settings))
|
|
{
|
|
settings = new UserWorkspaceSettings();
|
|
settings.RootDir = rootDir;
|
|
ImportWorkspaceSettings(rootDir, clientName, branchPath, settings);
|
|
}
|
|
|
|
settings.Init(serverAndPort, userName, clientName, branchPath, projectPath);
|
|
settings.Save(logger);
|
|
|
|
return settings;
|
|
}
|
|
|
|
public static string[] GetCombinedSyncFilter(
|
|
Dictionary<Guid, WorkspaceSyncCategory> uniqueIdToFilter,
|
|
string roleName,
|
|
IDictionary<string, Preset> roles,
|
|
FilterSettings globalFilter,
|
|
FilterSettings workspaceFilter,
|
|
ConfigSection? perforceSection)
|
|
{
|
|
ISet<string> lines = new HashSet<string>();
|
|
foreach (string viewLine in Enumerable.Concat(globalFilter.View, workspaceFilter.View).Select(x => x.Trim()).Where(x => x.Length > 0 && !x.StartsWith(";", StringComparison.Ordinal)))
|
|
{
|
|
lines.Add(viewLine);
|
|
}
|
|
|
|
if (roles.TryGetValue(roleName, out Preset? role))
|
|
{
|
|
foreach (string roleView in role.Views)
|
|
{
|
|
lines.Add(roleView);
|
|
}
|
|
}
|
|
|
|
Dictionary<Guid, bool> globalCategoryIdToSetting = globalFilter.GetCategories();
|
|
Dictionary<Guid, bool> workspaceCategoryIdToSetting = workspaceFilter.GetCategories();
|
|
|
|
HashSet<Guid> enabled = new HashSet<Guid>();
|
|
foreach (WorkspaceSyncCategory filter in uniqueIdToFilter.Values)
|
|
{
|
|
bool enable = filter.Enable;
|
|
|
|
if (globalCategoryIdToSetting.TryGetValue(filter.UniqueId, out bool globalEnable))
|
|
{
|
|
enable = globalEnable;
|
|
}
|
|
|
|
if (workspaceCategoryIdToSetting.TryGetValue(filter.UniqueId, out bool workspaceEnable))
|
|
{
|
|
enable = workspaceEnable;
|
|
}
|
|
|
|
// role override anything set at the global or workspace level
|
|
if (role != null)
|
|
{
|
|
if (role.Categories.TryGetValue(filter.UniqueId, out RoleCategory? roleCategory))
|
|
{
|
|
enable = roleCategory.Enabled;
|
|
}
|
|
}
|
|
|
|
if (enable)
|
|
{
|
|
EnableFilter(filter.UniqueId, enabled, uniqueIdToFilter);
|
|
}
|
|
}
|
|
|
|
foreach (WorkspaceSyncCategory filter in uniqueIdToFilter.Values.OrderBy(x => x.Name))
|
|
{
|
|
if (!enabled.Contains(filter.UniqueId))
|
|
{
|
|
foreach (string path in filter.Paths.Select(x => "-" + x.Trim()))
|
|
{
|
|
lines.Add(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there are no filtering lines then we can assume that AdditionalPathsToSync is covered and we do not
|
|
// need to add them manually.
|
|
if (lines.Count > 0 && perforceSection != null)
|
|
{
|
|
IEnumerable<string> additionalPaths = perforceSection.GetValues("AdditionalPathsToSync", Array.Empty<string>());
|
|
lines.UnionWith(additionalPaths);
|
|
}
|
|
|
|
return lines.ToArray();
|
|
}
|
|
|
|
static void EnableFilter(Guid uniqueId, HashSet<Guid> enabled, Dictionary<Guid, WorkspaceSyncCategory> uniqueIdToFilter)
|
|
{
|
|
if (enabled.Add(uniqueId))
|
|
{
|
|
WorkspaceSyncCategory? category;
|
|
if (uniqueIdToFilter.TryGetValue(uniqueId, out category))
|
|
{
|
|
foreach (Guid requiresUniqueId in category.Requires)
|
|
{
|
|
EnableFilter(requiresUniqueId, enabled, uniqueIdToFilter);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|