2023-02-16 12:57:06 +00:00
|
|
|
using CliWrap;
|
|
|
|
using CliWrap.Buffered;
|
|
|
|
|
|
|
|
namespace InnovEnergy.Lib.Utils;
|
|
|
|
|
|
|
|
public class FileSystem
|
|
|
|
{
|
|
|
|
|
|
|
|
private static readonly String ProcName = Utils.ExecutingProcessName;
|
|
|
|
private static readonly String TempPath = Path.GetTempPath();
|
|
|
|
|
|
|
|
private static Command Find { get; } = Cli.Wrap("find");
|
|
|
|
private static Command Stat { get; } = Cli.Wrap("stat");
|
|
|
|
private static Random Rng { get; } = new Random();
|
|
|
|
|
|
|
|
public static FileSystem Local { get; } = new FileSystem();
|
|
|
|
public static FileSystem OnHost(SshHost? host) => new FileSystem(host);
|
|
|
|
|
|
|
|
private SshHost? Host { get; }
|
|
|
|
|
|
|
|
private FileSystem(SshHost? host = null)
|
|
|
|
{
|
|
|
|
Host = host;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Task<IReadOnlyList<String>> GetFiles(String path)
|
|
|
|
{
|
|
|
|
return GetFiles(path, FileType.RegularFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Task<IReadOnlyList<String>> GetFilesRecursive(String path)
|
|
|
|
{
|
|
|
|
return GetFiles(path, FileType.RegularFile, maxDepth: Int16.MaxValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Task<IReadOnlyList<String>> GetDirectories(String path)
|
|
|
|
{
|
|
|
|
return GetFiles(path, FileType.Directory);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<IReadOnlyList<String>> GetFiles(String path, FileType fileType, Int32 maxDepth = 1)
|
|
|
|
{
|
|
|
|
var result = await Find
|
2023-04-13 12:30:01 +00:00
|
|
|
.WithArguments($"{path} -maxdepth {maxDepth} -type {(Char)fileType}")
|
2023-02-16 12:57:06 +00:00
|
|
|
.OnHost(Host)
|
|
|
|
.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
return result.StandardOutput.SplitLines();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Boolean FileExists(String path)
|
|
|
|
{
|
|
|
|
var stat = StatF(path);
|
|
|
|
|
|
|
|
return stat.ExitCode == 0 && stat.StandardOutput.Trim() == "regular file";
|
|
|
|
}
|
|
|
|
|
|
|
|
public Boolean DirectoryExists(String path)
|
|
|
|
{
|
|
|
|
var stat = StatF(path);
|
|
|
|
|
|
|
|
return stat.ExitCode == 0 && stat.StandardOutput.Trim() == "directory";
|
|
|
|
}
|
|
|
|
|
|
|
|
private BufferedCommandResult StatF(String path)
|
|
|
|
{
|
|
|
|
return Stat
|
|
|
|
.WithArguments($"-c %F {path}")
|
|
|
|
.OnHost(Host)
|
|
|
|
.ExecuteBufferedAsync()
|
|
|
|
.Task
|
|
|
|
.Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Obsolete]
|
|
|
|
public static Disposable<String> CreateTmpDir()
|
|
|
|
{
|
|
|
|
var path = GetRandomTempPath();
|
|
|
|
|
|
|
|
Directory.CreateDirectory(path);
|
|
|
|
|
|
|
|
void Dispose()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Directory.Delete(path, recursive: true);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// ignored
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Disposable.Create(path, Dispose);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Obsolete]
|
|
|
|
private static String GetRandomTempPath()
|
|
|
|
{
|
|
|
|
lock (Rng)
|
|
|
|
{
|
|
|
|
return $"{TempPath}{ProcName}.{Rng.Next():x8}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Obsolete]
|
|
|
|
public static Disposable<String> CreateTempFile(String fileName)
|
|
|
|
{
|
|
|
|
var dir = CreateTmpDir();
|
|
|
|
var file = dir.Value.AppendPath(fileName);
|
|
|
|
|
|
|
|
return Disposable.Create(file, dir.Dispose);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public enum FileType : Byte
|
|
|
|
{
|
|
|
|
BlockDevice = (Byte) 'b',
|
|
|
|
CharacterDevice = (Byte) 'c',
|
|
|
|
Directory = (Byte) 'd',
|
|
|
|
Pipe = (Byte) 'p',
|
|
|
|
RegularFile = (Byte) 'f',
|
|
|
|
SymbolicLink = (Byte) 'l',
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|