diff --git a/src/Tgstation.Server.Host/Components/Configuration.cs b/src/Tgstation.Server.Host/Components/Configuration.cs index 9c5a127316..4c31b9eadd 100644 --- a/src/Tgstation.Server.Host/Components/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/Configuration.cs @@ -33,6 +33,11 @@ namespace Tgstation.Server.Host.Components /// readonly ISynchronousIOManager synchronousIOManager; + /// + /// The for + /// + readonly ISymlinkFactory symlinkFactory; + /// /// The for /// @@ -43,11 +48,13 @@ namespace Tgstation.Server.Host.Components /// /// The value of /// The value of + /// The value of /// The value of - public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ILogger logger) + public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, ILogger logger) { this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.synchronousIOManager = synchronousIOManager ?? throw new ArgumentNullException(nameof(synchronousIOManager)); + this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -171,7 +178,18 @@ namespace Tgstation.Server.Host.Components /// public Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { - throw new NotImplementedException(); + async Task SymlinkBase(bool files) + { + Task> task; + if (files) + task = ioManager.GetFiles(GameStaticFilesSubdirectory, cancellationToken); + else + task = ioManager.GetDirectories(GameStaticFilesSubdirectory, cancellationToken); + var entries = await task.ConfigureAwait(false); + await Task.WhenAll(entries.Select(x => symlinkFactory.CreateSymbolicLink(ioManager.ResolvePath(x), ioManager.ConcatPath(destination, x), cancellationToken))).ConfigureAwait(false); + } + + return Task.WhenAll(SymlinkBase(true), SymlinkBase(false)); } /// diff --git a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs index 21cf9db515..5a4bb9654f 100644 --- a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs +++ b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs @@ -213,10 +213,25 @@ namespace Tgstation.Server.Host.IO { path = ResolvePath(path); var results = new List(); - foreach(var I in Directory.EnumerateDirectories(path)) + cancellationToken.ThrowIfCancellationRequested(); + foreach (var I in Directory.EnumerateDirectories(path)) { - cancellationToken.ThrowIfCancellationRequested(); results.Add(I); + cancellationToken.ThrowIfCancellationRequested(); + } + return (IReadOnlyList)results; + }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); + + /// + public Task> GetFiles(string path, CancellationToken cancellationToken) => Task.Factory.StartNew(() => + { + path = ResolvePath(path); + var results = new List(); + cancellationToken.ThrowIfCancellationRequested(); + foreach (var I in Directory.EnumerateFiles(path)) + { + results.Add(I); + cancellationToken.ThrowIfCancellationRequested(); } return (IReadOnlyList)results; }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); diff --git a/src/Tgstation.Server.Host/IO/IIOManager.cs b/src/Tgstation.Server.Host/IO/IIOManager.cs index c317e70789..e5b6cdefde 100644 --- a/src/Tgstation.Server.Host/IO/IIOManager.cs +++ b/src/Tgstation.Server.Host/IO/IIOManager.cs @@ -72,6 +72,14 @@ namespace Tgstation.Server.Host.IO /// A resulting in the directories in Task> GetDirectories(string path, CancellationToken cancellationToken); + /// + /// Returns file names in a given + /// + /// The path to search for files + /// The for the operation + /// A resulting in the files in + Task> GetFiles(string path, CancellationToken cancellationToken); + /// /// Writes some to a file at overwriting previous content /// diff --git a/src/Tgstation.Server.Host/IO/ISymlinkFactory.cs b/src/Tgstation.Server.Host/IO/ISymlinkFactory.cs new file mode 100644 index 0000000000..b92269404b --- /dev/null +++ b/src/Tgstation.Server.Host/IO/ISymlinkFactory.cs @@ -0,0 +1,20 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Tgstation.Server.Host.IO +{ + /// + /// For creating filesystem symbolic links + /// + interface ISymlinkFactory + { + /// + /// Create a symbolic link + /// + /// The path to the hard target + /// The path to the link + /// The for the operation + /// A representing the running operation + Task CreateSymbolicLink(string targetPath, string linkPath, CancellationToken cancellationToken); + } +}