/// <summary> /// Make the <see cref="WindowsSwappableDmbProvider"/> active by replacing the live link with our <see cref="CompileJob"/>. /// </summary> /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param> /// <returns>A <see cref="Task"/> representing the running operation.</returns> public async Task MakeActive(CancellationToken cancellationToken) { // Note this comment from TGS3: // These next two lines should be atomic but this is the best we can do await ioManager.DeleteDirectory(LiveGameDirectory, cancellationToken).ConfigureAwait(false); await symlinkFactory.CreateSymbolicLink(baseProvider.PrimaryDirectory, ioManager.ResolvePath(LiveGameDirectory), cancellationToken).ConfigureAwait(false); }
public async Task TestFileWorks() { const string Text = "Hello world"; string f2 = null; var f1 = Path.GetTempFileName(); try { f2 = f1 + ".linked"; File.WriteAllText(f1, Text); await Assert.ThrowsExceptionAsync <ArgumentNullException>(() => symlinkFactory.CreateSymbolicLink(null, null, default)).ConfigureAwait(false); await Assert.ThrowsExceptionAsync <ArgumentNullException>(() => symlinkFactory.CreateSymbolicLink(f1, null, default)).ConfigureAwait(false); await symlinkFactory.CreateSymbolicLink(f1, f2, default).ConfigureAwait(false); Assert.IsTrue(File.Exists(f2)); var f2Contents = File.ReadAllText(f2); Assert.AreEqual(Text, f2Contents); } finally { File.Delete(f2); File.Delete(f1); } }
/// <inheritdoc /> public async Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { 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(task.Result.Select(async x => { var destPath = ioManager.ConcatPath(destination, ioManager.GetFileName(x)); logger.LogTrace("Symlinking {0} to {1}...", x, destPath); var fileExistsTask = ioManager.FileExists(destPath, cancellationToken); if (await ioManager.DirectoryExists(destPath, cancellationToken).ConfigureAwait(false)) { await ioManager.DeleteDirectory(destPath, cancellationToken).ConfigureAwait(false); } var fileExists = await fileExistsTask.ConfigureAwait(false); if (fileExists) { await ioManager.DeleteFile(destPath, cancellationToken).ConfigureAwait(false); } await symlinkFactory.CreateSymbolicLink(ioManager.ResolvePath(x), ioManager.ResolvePath(destPath), cancellationToken).ConfigureAwait(false); })).ConfigureAwait(false); } using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false)) { await EnsureDirectories(cancellationToken).ConfigureAwait(false); await Task.WhenAll(SymlinkBase(true), SymlinkBase(false)).ConfigureAwait(false); } }
/// <inheritdoc /> public async Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { async Task <IReadOnlyList <string> > GetIgnoreFiles() { var ignoreFileBytes = await ioManager.ReadAllBytes(StaticIgnorePath(), cancellationToken).ConfigureAwait(false); var ignoreFileText = Encoding.UTF8.GetString(ignoreFileBytes); var results = new List <string> { StaticIgnoreFile }; //we don't want to lose trailing whitespace on linux using (var reader = new StringReader(ignoreFileText)) { cancellationToken.ThrowIfCancellationRequested(); var line = await reader.ReadLineAsync().ConfigureAwait(false); if (!String.IsNullOrEmpty(line)) { results.Add(line); } } return(results); }; IReadOnlyList <string> ignoreFiles; 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(async x => { var fileName = ioManager.GetFileName(x); bool ignored; if (platformIdentifier.IsWindows) { //need to normalize ignored = ignoreFiles.Any(y => fileName.ToUpperInvariant() == y.ToUpperInvariant()); } else { ignored = ignoreFiles.Any(y => fileName == y); } if (ignored) { logger.LogTrace("Ignoring static file {0}...", fileName); return; } var destPath = ioManager.ConcatPath(destination, fileName); logger.LogTrace("Symlinking {0} to {1}...", x, destPath); var fileExistsTask = ioManager.FileExists(destPath, cancellationToken); if (await ioManager.DirectoryExists(destPath, cancellationToken).ConfigureAwait(false)) { await ioManager.DeleteDirectory(destPath, cancellationToken).ConfigureAwait(false); } var fileExists = await fileExistsTask.ConfigureAwait(false); if (fileExists) { await ioManager.DeleteFile(destPath, cancellationToken).ConfigureAwait(false); } await symlinkFactory.CreateSymbolicLink(ioManager.ResolvePath(x), ioManager.ResolvePath(destPath), cancellationToken).ConfigureAwait(false); })).ConfigureAwait(false); } using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false)) { await EnsureDirectories(cancellationToken).ConfigureAwait(false); ignoreFiles = await GetIgnoreFiles().ConfigureAwait(false); await Task.WhenAll(SymlinkBase(true), SymlinkBase(false)).ConfigureAwait(false); } }