using System.IO;
using System.Linq;
using Robust.Shared.ContentPack;
using Robust.Shared.Utility;
namespace Content.IntegrationTests.Utility;
public static partial class GameDataScrounger
{
///
/// Returns all files in a given content location that match a pattern.
///
/// The directory within the VFS to search
/// A glob pattern to use as a filter
/// Whether to search directories within the given directory.
/// A list of all files within the VFS directory matching the pattern.
public static string[] FilesInDirectory(string location, string pattern, bool recursive = true)
{
var path = GetContentPathOnDisk(location);
return Directory.EnumerateFiles(path,
pattern ?? "*",
recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
.ToArray();
}
///
/// Returns all files in a given content location that match a pattern, as their VFS paths.
///
/// The directory within the VFS to search
/// A glob pattern to use as a filter
/// Whether to search directories within the given directory.
/// A list of all file paths within the VFS directory matching the pattern.
public static ResPath[] FilesInDirectoryInVfs(string location, string pattern, bool recursive = true)
{
var path = GetContentPathOnDisk(location.TrimEnd('/'));
var resBasePath = ContentResources();
return Directory.EnumerateFiles(path,
pattern ?? "*",
recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
.Select(x => ResPath.FromRelativeSystemPath(x.Remove(0, resBasePath.Length)))
.ToArray();
}
///
/// Get the full directory path that the executable is located in.
///
private static string GetExecutableDirectory()
{
// TODO: remove this shitty hack, either through making it less hardcoded into shared,
// or by making our file structure less spaghetti somehow.
var assembly = typeof(IResourceManager).Assembly;
var location = assembly.Location;
if (location == string.Empty)
{
// See https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.location?view=net-5.0#remarks
// This doesn't apply to us really because we don't do that kind of publishing, but whatever.
throw new InvalidOperationException("Cannot find path of executable.");
}
return Path.GetDirectoryName(location)!;
}
///
/// Turns a relative path from the executable directory into a full path.
///
private static string ExecutableRelativeFile(string file)
{
return Path.GetFullPath(Path.Combine(GetExecutableDirectory(), file));
}
///
/// Mirrors a function in the engine for ease of maintenance.
///
private static string FindContentRootDir()
{
return "../../";
}
///
/// Mirrors a function in the engine for ease of maintenance.
///
private static string ContentResources()
{
return ExecutableRelativeFile($"{FindContentRootDir()}Resources");
}
///
/// Gets the real path of a path within the VFS.
///
/// The path to get the real filesystem path of.
/// The real filesystem path.
public static string GetContentPathOnDisk(string path)
{
Assert.That(path, Does.StartWith("/"), "Path must be rooted.");
return $"{ContentResources()}{path.ToString()}";
}
}