mirror of
https://gitlab.acidiclight.dev/sociallydistant/sociallydistant.git
synced 2025-01-22 17:41:49 -05:00
Add support for file overwriting in shell
This commit is contained in:
parent
b369e0f212
commit
0d8ed59f2c
7 changed files with 111 additions and 12 deletions
|
@ -76,7 +76,7 @@ namespace OS.FileSystems.Host
|
|||
{
|
||||
string fullPath = Path.Combine(hostPath, name);
|
||||
if (!File.Exists(fullPath))
|
||||
File.Create(fullPath);
|
||||
File.Create(fullPath).Dispose();
|
||||
|
||||
entry = new HostFileEntry(this, fullPath);
|
||||
return true;
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace OS.FileSystems
|
|||
return currentEntry;
|
||||
}
|
||||
|
||||
private IFileEntry? FindFileEntry(ReadOnlySpan<string> path, IUser? reader = null)
|
||||
private IFileEntry? FindFileEntry(ReadOnlySpan<string> path, IUser? reader = null, bool create = false)
|
||||
{
|
||||
reader ??= this.user;
|
||||
|
||||
|
@ -105,7 +105,10 @@ namespace OS.FileSystems
|
|||
if (fileEntry.Name == filename)
|
||||
return fileEntry;
|
||||
}
|
||||
|
||||
|
||||
if (create && parentDirectory.TryCreateFile(reader, filename, out IFileEntry? newFile) && newFile != null)
|
||||
return newFile;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -178,7 +181,7 @@ namespace OS.FileSystems
|
|||
public Stream OpenWrite(string path)
|
||||
{
|
||||
string[] parts = PathUtility.Split(path);
|
||||
IFileEntry? file = FindFileEntry(parts);
|
||||
IFileEntry? file = FindFileEntry(parts, create: true);
|
||||
|
||||
if (file == null)
|
||||
throw new FileNotFoundException();
|
||||
|
|
50
Assets/Scripts/UI/Shell/FileOutputConsole.cs
Normal file
50
Assets/Scripts/UI/Shell/FileOutputConsole.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System.IO;
|
||||
using OS.Devices;
|
||||
|
||||
namespace UI.Shell
|
||||
{
|
||||
public class FileOutputConsole :
|
||||
ITextConsole,
|
||||
IDisposable
|
||||
{
|
||||
private readonly ITextConsole input;
|
||||
private readonly Stream fileStream;
|
||||
private readonly StreamWriter fileWriter;
|
||||
|
||||
public FileOutputConsole(ITextConsole input, Stream output)
|
||||
{
|
||||
this.input = input;
|
||||
this.fileStream = output;
|
||||
|
||||
this.fileWriter = new StreamWriter(fileStream);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
fileWriter.Dispose();
|
||||
fileStream.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearScreen()
|
||||
{
|
||||
fileWriter.Flush();
|
||||
fileStream.Position = 0;
|
||||
fileStream.SetLength(0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WriteText(string text)
|
||||
{
|
||||
fileWriter.Write(text);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryDequeueSubmittedInput(out string input)
|
||||
{
|
||||
return this.input.TryDequeueSubmittedInput(out input);
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/UI/Shell/FileOutputConsole.cs.meta
Normal file
3
Assets/Scripts/UI/Shell/FileOutputConsole.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9a4a394e1f59409ca8bd9be2c65f373f
|
||||
timeCreated: 1677107497
|
|
@ -5,5 +5,8 @@ namespace UI.Shell
|
|||
{
|
||||
string GetVariableValue(string name);
|
||||
void SetVariableValue(string name, string newValue);
|
||||
|
||||
string CurrentWorkingDirectory { get; }
|
||||
string CurrentHomeDirectory { get; }
|
||||
}
|
||||
}
|
|
@ -34,6 +34,13 @@ namespace UI.Shell
|
|||
/// <inheritdoc />
|
||||
public bool IsExecutionHalted => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string CurrentWorkingDirectory => process?.WorkingDirectory ?? "/";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string CurrentHomeDirectory => process?.User?.Home ?? "/";
|
||||
|
||||
|
||||
public InteractiveShell(MonoBehaviour unityBehaviour)
|
||||
{
|
||||
this.unityBehaviour = unityBehaviour;
|
||||
|
@ -487,6 +494,11 @@ namespace UI.Shell
|
|||
public IArgumentEvaluator[] ArgumentList { get; }
|
||||
public FileRedirectionType RedirectionType { get; }
|
||||
public string FilePath { get; }
|
||||
|
||||
public string FullFilePath
|
||||
{
|
||||
get => PathUtility.Combine(shell.CurrentWorkingDirectory, FilePath);
|
||||
}
|
||||
|
||||
public CommandData(InteractiveShell shell,string name, IEnumerable<IArgumentEvaluator> argumentSource, FileRedirectionType redirectionType, string path)
|
||||
{
|
||||
|
@ -534,23 +546,51 @@ namespace UI.Shell
|
|||
// Evaluate arguments now.
|
||||
string[] args = ArgumentList.Select(x => x.GetArgumentText(this.shell)).ToArray();
|
||||
|
||||
// TODO: File redirection. Should be easy.
|
||||
|
||||
if (shell.ProcessBuiltIn(shellProcess, console, Name, args))
|
||||
// Get the vfs
|
||||
var vfs = shellProcess.User.Computer.GetFileSystem(shellProcess.User);
|
||||
|
||||
// What console are we going to send to the command?
|
||||
ITextConsole realConsole = console;
|
||||
|
||||
switch (this.RedirectionType)
|
||||
{
|
||||
case FileRedirectionType.Overwrite:
|
||||
realConsole = new FileOutputConsole(console, vfs.OpenWrite(this.FullFilePath));
|
||||
break;
|
||||
}
|
||||
|
||||
if (shell.ProcessBuiltIn(shellProcess, realConsole, Name, args))
|
||||
{
|
||||
if (realConsole is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Process text arguments to make sure we remove their trailing spaces
|
||||
ShellUtility.TrimTrailingSpaces(ref args);
|
||||
|
||||
ISystemProcess? commandProcess = FindProgram(shellProcess, console, Name, args);
|
||||
ISystemProcess? commandProcess = FindProgram(shellProcess, realConsole, Name, args);
|
||||
if (commandProcess == null)
|
||||
console.WriteText($"sh: {Name}: command not found" + Environment.NewLine);
|
||||
|
||||
// special case for commands that kill the process IMMEDIATELY
|
||||
// on the same frame this was called
|
||||
if (commandProcess != null && !commandProcess.IsAlive)
|
||||
{
|
||||
if (realConsole is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
void handleKilled(ISystemProcess proc)
|
||||
{
|
||||
if (realConsole is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
proc.Killed -= handleKilled;
|
||||
}
|
||||
|
||||
if (commandProcess != null)
|
||||
commandProcess.Killed += handleKilled;
|
||||
return commandProcess;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ MonoBehaviour:
|
|||
m_MinSize: {x: 300, y: 200}
|
||||
m_MaxSize: {x: 24288, y: 16192}
|
||||
vertical: 0
|
||||
controlID: 5913
|
||||
controlID: 7072
|
||||
--- !u!114 &2
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 52
|
||||
|
@ -141,7 +141,7 @@ MonoBehaviour:
|
|||
m_MinSize: {x: 200, y: 200}
|
||||
m_MaxSize: {x: 16192, y: 16192}
|
||||
vertical: 1
|
||||
controlID: 5914
|
||||
controlID: 7073
|
||||
--- !u!114 &4
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 52
|
||||
|
@ -166,7 +166,7 @@ MonoBehaviour:
|
|||
m_MinSize: {x: 200, y: 100}
|
||||
m_MaxSize: {x: 16192, y: 8096}
|
||||
vertical: 0
|
||||
controlID: 5915
|
||||
controlID: 7074
|
||||
--- !u!114 &5
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 52
|
||||
|
@ -226,7 +226,7 @@ MonoBehaviour:
|
|||
scrollPos: {x: 0, y: 0}
|
||||
m_SelectedIDs:
|
||||
m_LastClickedID: 0
|
||||
m_ExpandedIDs: 30fbffff
|
||||
m_ExpandedIDs: b0c7fefffcc7feff40c9feff50c9feff5cc9feff80c9feffdce2feff28e3feff6ce4feff7ce4feff88e4fefface4feff20ecfeff6cecfeffb0edfeffc0edfeffccedfefff0edfeff30fbffff
|
||||
m_RenameOverlay:
|
||||
m_UserAcceptedRename: 0
|
||||
m_Name:
|
||||
|
|
Loading…
Reference in a new issue