Skip to content

Commit

Permalink
Added ability to "fully" restart and download files in REPL via !down…
Browse files Browse the repository at this point in the history
…load and !restart full
  • Loading branch information
TheAndreiM committed Jul 14, 2024
1 parent 16b6b08 commit 123d19f
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 23 deletions.
1 change: 1 addition & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ task:
- JUKA_TOKEN: Linux_X86
setup_script:
- dpkg --add-architecture i386
- apt-get update
- apt-get install -y software-properties-common
- add-apt-repository universe
- apt-get update
Expand Down
48 changes: 43 additions & 5 deletions src/Juka/REPL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private static bool IsCommand(string line)

private static async Task HandleCommandAsync(string command)
{
switch (command.ToLower())
switch (command.Split(' ')[0].ToLower())
{
case "!menu":
DisplayMenu();
Expand All @@ -108,7 +108,35 @@ private static async Task HandleCommandAsync(string command)
await UpdateJuka();
break;
case "!restart":
RestartApplication();
string[] restartTypes = command.Split(' ');
if (restartTypes.Length > 1)
{
string restartType = restartTypes[1];
if (restartType == "full")
{
RestartApplication("full");
}
else
{
RestartApplication("normal");
}
}
else
{
RestartApplication("normal");
}
break;
case "!download":
string[] parts = command.Split(' ');
if (parts.Length > 1)
{
string url = parts[1];
await DownloadAFile(url);
}
else
{
Console.WriteLine("Invalid command format. Usage: !download [url]");
}
break;
case "!exit":
ExitRepl();
Expand Down Expand Up @@ -163,8 +191,9 @@ private static void DisplayMenu()
table.AddRow("!get", "[aqua]Get list of libraries for Juka[/]");
table.AddRow("!undo", "[blue]Undoes last entered command[/]");
table.AddRow("!redo", "[red]Redoes the undone command[/]");
table.AddRow("!download", "[aqua]Download a file from the web. Requires a url. [/]");
table.AddRow("!update", "[yellow]Update Juka to latest version[/]");
table.AddRow("!restart", "[fuchsia]Restart application[/]");
table.AddRow("!restart", "[fuchsia]Restart application. [/] Options: [/aqua]full[/] or [aqua]normal[/]");
table.AddRow("!exit", "[yellow]Exits REPL[/]");

AnsiConsole.Write(table);
Expand Down Expand Up @@ -223,11 +252,20 @@ private static async Task UpdateJuka()
DisplayPrompt();
}

private static async void RestartApplication()
private static async Task DownloadAFile(string url)
{
await SelfUpdate.DownloadURLAsync(url);
AnsiConsole.MarkupLine("[Green]Finished Downloading from: [/]" + url);
DisplayPrompt();
}



private static async void RestartApplication(string type)
{
IDictionary<string, string> info = SelfUpdate.GetSystemInfo();
string jukaexepath = info["dir"] + info["name"] + info["extension"];
await SelfUpdate.Restart(jukaexepath);
await SelfUpdate.Restart(jukaexepath,type);
}

private static void ExitRepl()
Expand Down
67 changes: 49 additions & 18 deletions src/Juka/SelfUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ public static async Task<string> Check()
return "";
}

public static async Task DownloadURLAsync(string url)
{
AnsiConsole.MarkupLine("[yellow]Downloading from [/]" + url);
using HttpResponseMessage? response2 = await new HttpClient().GetAsync(url);
await using Stream? streamToReadFrom = await response2.Content.ReadAsStreamAsync();


Uri uri = new Uri(url);
string fileName = Path.GetFileName(uri.LocalPath);


using (FileStream fileStream = File.Create(fileName))
{
streamToReadFrom.CopyTo(fileStream);
}

}




/// <summary>
/// Get system information
/// </summary>
Expand Down Expand Up @@ -206,7 +227,7 @@ public static async Task Update()

AnsiConsole.MarkupLine("[green]Updated to version: " + latestVersion + "[/]");

await Restart(jukaExePath);
await Restart(jukaExePath,"normal");
}
catch (Exception ex)
{
Expand All @@ -229,29 +250,39 @@ public static async Task Update()
}
}
}
public static async Task Restart(string jukaExePath)
public static async Task Restart(string jukaExePath, string type)
{
try
{
// Perform any cleanup or resource releasing before restarting
// Example: Save user data, close connections, etc.

ProcessStartInfo startInfo = new()
if(type == "full") {
try
{
FileName = jukaExePath,
UseShellExecute = true
};
// Perform any cleanup or resource releasing before restarting
// Example: Save user data, close connections, etc.

Process newProcess = Process.Start(startInfo);
ProcessStartInfo startInfo = new()
{
FileName = jukaExePath,
UseShellExecute = true
};

// Close the current process gracefully
await Task.Delay(1000); // Delay to ensure the new process starts
Environment.Exit(0);
Process newProcess = Process.Start(startInfo);

// Close the current process gracefully
await Task.Delay(1000); // Delay to ensure the new process starts
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine($"Error occurred during restart: {ex.Message}");
// Log the exception for troubleshooting
}
}
catch (Exception ex)
else
{
Console.WriteLine($"Error occurred during restart: {ex.Message}");
// Log the exception for troubleshooting
//Start process, friendly name is something like MyApp.exe (from current bin directory)
Process.Start(jukaExePath);

//Close the current process
Environment.Exit(0);
}
}
}
4 changes: 4 additions & 0 deletions src/JukaAzureFunction/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

namespace JukaAzureFunction;

/// <summary>
/// This code defines a Main method in the Program class.
/// It creates a new IHost using HostBuilder to configure a Functions Worker with NewtonsoftJson and then runs the host.
/// </summary>
public class Program
{
/// <summary>
Expand Down
25 changes: 25 additions & 0 deletions src/JukaCompiler/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class Compiler
private ServiceProvider _serviceProvider;
private HostBuilder _hostBuilder;


// Constructor for Compiler class that initializes service providers for error handling, system calls, file opening, C# operations, system clock, and available memory.
// It creates a new HostBuilder instance, configures services by adding singletons for various interfaces like ICompilerError, IJukaCallable, IFileOpener, ICSharp, ISystemClock, and others,
// and then builds a service provider to store these singletons. Finally, it builds the HostBuilder.
public Compiler()
{
_hostBuilder = new HostBuilder();
Expand All @@ -35,6 +39,11 @@ public Compiler()
_hostBuilder.Build();
}


// Compiles Juka code provided in 'data' and returns the console output after interpreting the statements or an error message if compilation fails.
// CompileJukaCode that compiles Juka code provided in the data string. It uses a Parser to parse the code and then interprets the statements.
// If successful, it returns the console output.
// If there's an error during compilation, it returns an error message with details about the exception.
public string CompileJukaCode(string data, bool isFile = true)
{
CheckServiceProvider();
Expand All @@ -54,6 +63,13 @@ public string CompileJukaCode(string data, bool isFile = true)
}
}


// Compiles a list of statements using the JukaInterpreter and Resolver, then sets up a main method runtime hook.
// Returns the console output after interpreting the statements or an exception message if an error occurs.
//This code defines a method named Compile that compiles a list of statements using a JukaInterpreter and a Resolver.
//It sets up a main method runtime hook, redirects console output to capture it, interprets the statements, and returns the console output as a string.
//If an exception occurs during interpretation, it returns the exception message.

private string Compile(List<Statement> statements)
{
JukaInterpreter interpreter = new(services: _serviceProvider);
Expand Down Expand Up @@ -81,6 +97,15 @@ private string Compile(List<Statement> statements)
}
}


/// <summary>
/// This code snippet sets up a runtime hook for the main method by identifying the main function from a list of statements.
/// It then creates a call to the main function and resolves it using a resolver object.
/// If the main function is not found, it throws an exception indicating that no main function is defined.
/// </summary>
/// <param name="statements"></param>
/// <param name="resolver"></param>
/// <exception cref="Exception"></exception>
private static void SetupMainMethodRuntimeHook(List<Statement> statements, Resolver resolver)
{
Statement.Function mainFunction = statements.OfType<Statement.Function>().FirstOrDefault(f => f.StmtLexemeName.Equals("main")) ?? throw new Exception("No main function is defined");
Expand Down
Loading

0 comments on commit 123d19f

Please sign in to comment.