Implement SymlinkStaticFilesTo

This commit is contained in:
Cyberboss
2018-07-23 13:30:46 -04:00
parent c0e78c1a2a
commit 51a8d774ab
4 changed files with 65 additions and 4 deletions
@@ -33,6 +33,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly ISynchronousIOManager synchronousIOManager;
/// <summary>
/// The <see cref="ISymlinkFactory"/> for <see cref="Configuration"/>
/// </summary>
readonly ISymlinkFactory symlinkFactory;
/// <summary>
/// The <see cref="ILogger"/> for <see cref="Configuration"/>
/// </summary>
@@ -43,11 +48,13 @@ namespace Tgstation.Server.Host.Components
/// </summary>
/// <param name="ioManager">The value of <see cref="ioManager"/></param>
/// <param name="synchronousIOManager">The value of <see cref="synchronousIOManager"/></param>
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/></param>
/// <param name="logger">The value of <see cref="logger"/></param>
public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ILogger<Configuration> logger)
public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, ILogger<Configuration> 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
/// <inheritdoc />
public Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken)
{
throw new NotImplementedException();
async Task SymlinkBase(bool files)
{
Task<IReadOnlyList<string>> 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));
}
/// <inheritdoc />
@@ -213,10 +213,25 @@ namespace Tgstation.Server.Host.IO
{
path = ResolvePath(path);
var results = new List<string>();
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<string>)results;
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
/// <inheritdoc />
public Task<IReadOnlyList<string>> GetFiles(string path, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
{
path = ResolvePath(path);
var results = new List<string>();
cancellationToken.ThrowIfCancellationRequested();
foreach (var I in Directory.EnumerateFiles(path))
{
results.Add(I);
cancellationToken.ThrowIfCancellationRequested();
}
return (IReadOnlyList<string>)results;
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
@@ -72,6 +72,14 @@ namespace Tgstation.Server.Host.IO
/// <returns>A <see cref="Task{TResult}"/> resulting in the directories in <paramref name="path"/></returns>
Task<IReadOnlyList<string>> GetDirectories(string path, CancellationToken cancellationToken);
/// <summary>
/// Returns file names in a given <paramref name="path"/>
/// </summary>
/// <param name="path">The path to search for files</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the files in <paramref name="path"/></returns>
Task<IReadOnlyList<string>> GetFiles(string path, CancellationToken cancellationToken);
/// <summary>
/// Writes some <paramref name="contents"/> to a file at <paramref name="path"/> overwriting previous content
/// </summary>
@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;
namespace Tgstation.Server.Host.IO
{
/// <summary>
/// For creating filesystem symbolic links
/// </summary>
interface ISymlinkFactory
{
/// <summary>
/// Create a symbolic link
/// </summary>
/// <param name="targetPath">The path to the hard target</param>
/// <param name="linkPath">The path to the link</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task CreateSymbolicLink(string targetPath, string linkPath, CancellationToken cancellationToken);
}
}