C#: Move `NestPaths` to `Semmle.Util`

This commit is contained in:
Tom Hvitved 2023-08-22 11:44:55 +02:00
Родитель 3d8231be1b
Коммит 2429a5383d
4 изменённых файлов: 78 добавлений и 86 удалений

Просмотреть файл

@ -1,52 +0,0 @@
using Xunit;
using Semmle.Util.Logging;
using Semmle.Util;
namespace Semmle.Extraction.Tests
{
public class TrapWriterTests
{
[Fact]
public void NestedPaths()
{
string tempDir = System.IO.Path.GetTempPath();
string root1, root2, root3;
if (Win32.IsWindows())
{
root1 = "E:";
root2 = "e:";
root3 = @"\";
}
else
{
root1 = "/E_";
root2 = "/e_";
root3 = "/";
}
using var logger = new LoggerMock();
Assert.Equal($@"C:\Temp\source_archive\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", "def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", "def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\E_\source\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", $@"{root1}\source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\e_\source\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", $@"{root2}\source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\source\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\source\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\diskstation\share\source\def.cs", TrapWriter.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}{root3}diskstation\share\source\def.cs").Replace('/', '\\'));
}
private sealed class LoggerMock : ILogger
{
public void Dispose() { }
public void Log(Severity s, string text) { }
}
}
}

Просмотреть файл

@ -216,7 +216,7 @@ namespace Semmle.Extraction
private void ArchiveContents(PathTransformer.ITransformedPath transformedPath, string contents)
{
var dest = NestPaths(logger, archive, transformedPath.Value);
var dest = FileUtils.NestPaths(logger, archive, transformedPath.Value);
var tmpSrcFile = Path.GetTempFileName();
File.WriteAllText(tmpSrcFile, contents, utf8);
try
@ -231,38 +231,6 @@ namespace Semmle.Extraction
}
}
public static string NestPaths(ILogger logger, string? outerpath, string innerpath)
{
var nested = innerpath;
if (!string.IsNullOrEmpty(outerpath))
{
// Remove all leading path separators / or \
// For example, UNC paths have two leading \\
innerpath = innerpath.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
if (innerpath.Length > 1 && innerpath[1] == ':')
innerpath = innerpath[0] + "_" + innerpath.Substring(2);
nested = Path.Combine(outerpath, innerpath);
}
try
{
var directoryName = Path.GetDirectoryName(nested);
if (directoryName is null)
{
logger.Log(Severity.Warning, "Failed to get directory name from path '" + nested + "'.");
throw new InvalidOperationException();
}
Directory.CreateDirectory(directoryName);
}
catch (PathTooLongException)
{
logger.Log(Severity.Warning, "Failed to create parent directory of '" + nested + "': Path too long.");
throw;
}
return nested;
}
private static string TrapExtension(CompressionMode compression)
{
switch (compression)
@ -280,7 +248,7 @@ namespace Semmle.Extraction
if (string.IsNullOrEmpty(folder))
folder = Directory.GetCurrentDirectory();
return NestPaths(logger, folder, filename);
return FileUtils.NestPaths(logger, folder, filename);
}
}
}

Просмотреть файл

@ -1,5 +1,6 @@
using Xunit;
using Semmle.Util;
using Semmle.Util.Logging;
namespace SemmleTests.Semmle.Util
{
@ -16,5 +17,47 @@ namespace SemmleTests.Semmle.Util
Assert.Equal(Win32.IsWindows() ? @"foo\bar" : "foo/bar", FileUtils.ConvertToNative("foo/bar"));
}
[Fact]
public void NestedPaths()
{
string root1, root2, root3;
if (Win32.IsWindows())
{
root1 = "E:";
root2 = "e:";
root3 = @"\";
}
else
{
root1 = "/E_";
root2 = "/e_";
root3 = "/";
}
using var logger = new LoggerMock();
Assert.Equal($@"C:\Temp\source_archive\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", "def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", "def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\E_\source\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", $@"{root1}\source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\e_\source\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", $@"{root2}\source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\source\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\source\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}source\def.cs").Replace('/', '\\'));
Assert.Equal(@"C:\Temp\source_archive\diskstation\share\source\def.cs", FileUtils.NestPaths(logger, @"C:\Temp\source_archive", $@"{root3}{root3}diskstation\share\source\def.cs").Replace('/', '\\'));
}
private sealed class LoggerMock : ILogger
{
public void Dispose() { }
public void Log(Severity s, string text) { }
}
}
}

Просмотреть файл

@ -5,6 +5,7 @@ using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Semmle.Util.Logging;
namespace Semmle.Util
{
@ -110,5 +111,37 @@ namespace Semmle.Util
/// </summary>
public static void DownloadFile(string address, string fileName) =>
DownloadFileAsync(address, fileName).Wait();
public static string NestPaths(ILogger logger, string? outerpath, string innerpath)
{
var nested = innerpath;
if (!string.IsNullOrEmpty(outerpath))
{
// Remove all leading path separators / or \
// For example, UNC paths have two leading \\
innerpath = innerpath.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
if (innerpath.Length > 1 && innerpath[1] == ':')
innerpath = innerpath[0] + "_" + innerpath.Substring(2);
nested = Path.Combine(outerpath, innerpath);
}
try
{
var directoryName = Path.GetDirectoryName(nested);
if (directoryName is null)
{
logger.Log(Severity.Warning, "Failed to get directory name from path '" + nested + "'.");
throw new InvalidOperationException();
}
Directory.CreateDirectory(directoryName);
}
catch (PathTooLongException)
{
logger.Log(Severity.Warning, "Failed to create parent directory of '" + nested + "': Path too long.");
throw;
}
return nested;
}
}
}