evil commit

catch up repo to code status
This commit is contained in:
Robert Morrison 2023-07-05 23:07:39 +01:00
parent 79063f97ee
commit 4a959c53ea
Signed by: robert
GPG Key ID: 73E012EB3F4EC696
4 changed files with 125 additions and 67 deletions

View File

@ -61,6 +61,9 @@ public static partial class EdgeInstall
static Version GetCurrentVersion() static Version GetCurrentVersion()
{ {
// To get the current version we need to execute the installed microsoft edge.
// Before doing this we need to make sure we can execute microsoft edge.
return new("0.0.0.0-0"); return new("0.0.0.0-0");
} }

View File

@ -18,8 +18,7 @@ public static partial class EdgeInstall
// The default architecture to get // The default architecture to get
// likely will go unused until proper cli interface is added // likely will go unused until proper cli interface is added
private static readonly string _DefaultArch = "amd64"; //private static readonly string _DefaultArch = "amd64";
private static HttpClient _client = new HttpClient(); private static HttpClient _client = new HttpClient();
private static readonly string DataDir = private static readonly string DataDir =
@ -31,13 +30,23 @@ public static partial class EdgeInstall
public static async Task<int> Main() public static async Task<int> Main()
{ {
if (Environment.OSVersion.Platform != PlatformID.Unix)
{
Console.ForegroundColor = Color.Red;
Console.Error.WriteLine("ERROR: You are not running this on a *nix host this program is not designed for other system types");
Environment.Exit(1);
}
_client.BaseAddress = new Uri("https://packages.microsoft.com/repos/edge/"); _client.BaseAddress = new Uri("https://packages.microsoft.com/repos/edge/");
// Ensure DataDir exists. // Ensure DataDir exists.
// NOTE: Directory.CreateDirectory will ALWAYS create the entire path // NOTE: Directory.CreateDirectory will ALWAYS create the entire path
Directory.CreateDirectory(DataDir); Directory.CreateDirectory(DataDir);
BUGFIX_ansiDetection(); BUGFIX_ansiDetection(); // Ensure that Spectre.Console is forced to work properly.
// TODO: Add code to change this based on profile
// And also allow changing at runtime based on flags
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug() .MinimumLevel.Debug()
.WriteTo.File(Path.Combine(DataDir, ".EdgeInstaller.Log")) // Only ever log to the logfile .WriteTo.File(Path.Combine(DataDir, ".EdgeInstaller.Log")) // Only ever log to the logfile
@ -59,7 +68,7 @@ public static partial class EdgeInstall
RenderReleaseTable(data); RenderReleaseTable(data);
// only select arch if needed // Either prompt for architecture selection OR use th eonly one available
string TargetArch = data.Architectures.Count > 1 ? AnsiConsole.Prompt( string TargetArch = data.Architectures.Count > 1 ? AnsiConsole.Prompt(
new SelectionPrompt<string>() new SelectionPrompt<string>()
.Title("Choose Architecture") .Title("Choose Architecture")
@ -74,7 +83,6 @@ public static partial class EdgeInstall
// Check if the Release data we just grabbed is newer than the one that exists. // Check if the Release data we just grabbed is newer than the one that exists.
// NOTE: we only do this if our chosen architecture hasn't been downloaded // NOTE: we only do this if our chosen architecture hasn't been downloaded
bool NeedDownload = true; bool NeedDownload = true;
Log.Information("Reached Package download Stage"); Log.Information("Reached Package download Stage");
@ -82,18 +90,20 @@ public static partial class EdgeInstall
{ {
Log.Information("Checking for release.json"); Log.Information("Checking for release.json");
// we need to check the release since we have an existing package.gz // we need to check the release since we have an existing package.gz
if (File.Exists(Path.Combine(DataDir, "release.json")))
string JSONstring = File.ReadAllText(Path.Combine(DataDir, "release.json")); {
ReleaseData? oldData = JsonSerializer.Deserialize<ReleaseData>(JSONstring); string JSONstring = File.ReadAllText(Path.Combine(DataDir, "release.json"));
if (oldData is not null) ReleaseData? oldData = JsonSerializer.Deserialize<ReleaseData>(JSONstring);
{ if (oldData is not null)
// if equal then our data is the newest available {
if (DateTime.Compare(oldData.Date, data.Date) == 0) // if equal then our data is the newest available
{ if (DateTime.Compare(oldData.Date, data.Date) == 0)
Log.Information("Our packages.gz is up to date"); {
NeedDownload = false; Log.Information("Our packages.gz is up to date");
} NeedDownload = false;
} }
}
}
} }
@ -130,12 +140,14 @@ public static partial class EdgeInstall
}); });
string JSONdata = JsonSerializer.Serialize<ReleaseData>(data); string JSONdata = JsonSerializer.Serialize<ReleaseData>(data);
File.WriteAllText(Path.Combine(DataDir, "release.json"), JSONdata);
if (!ValidateChecksum(new FileInfo(filename), gzFile.Checksum)) if (!ValidateChecksum(new FileInfo(filename), gzFile.Checksum))
{ {
AnsiConsole.WriteLine("[red b]ERROR: Release data checksum invalid[]");
File.Delete(filename); File.Delete(filename);
Environment.Exit(1); Environment.Exit(1);
} }
File.WriteAllText(Path.Combine(DataDir, "release.json"), JSONdata); // only do this if what we downloaded was valid.
// Otherwise we will skip downloading in the future
} }
string PackagesFile = Path.Combine(Archdir, "Packages.gz"); string PackagesFile = Path.Combine(Archdir, "Packages.gz");
@ -148,9 +160,11 @@ public static partial class EdgeInstall
foreach (var line in PackagesString.Split('\n')) foreach (var line in PackagesString.Split('\n'))
{ {
Log.Debug("PackageLine: {line}",line);
if (line == "") if (line == "")
{ {
string PackageString = sb.ToString(); string PackageString = sb.ToString();
Log.Debug("Making Package from:\n{PackageString}",PackageString);
if (PackageString == "") if (PackageString == "")
{ {
continue; // The last "package" will be empty continue; // The last "package" will be empty
@ -275,59 +289,90 @@ public static partial class EdgeInstall
Environment.Exit(1); Environment.Exit(1);
} }
using (XZStream dataXZStream = new(dataStream)) using (XZStream dataXZStream = new(dataStream))
{ using (TarReader reader = new(dataXZStream))
using (TarReader reader = new(dataXZStream)) {
{ while (true)
while (true) {
{ var tarEntry = reader.GetNextEntry();
var tarEntry = reader.GetNextEntry(); if (tarEntry is null)
if (tarEntry is null) {
{ break; // TarReader returns null when we hit the end of the stream
break; // TarReader returns null when we hit the end of the stream }
}
AnsiConsole.MarkupLineInterpolated($"TarEntry {tarEntry.Name}"); AnsiConsole.MarkupLineInterpolated($"Extracting TarEntry {tarEntry.Name}");
// work out where we need to put the extracted file // work out where we need to put the extracted file
var filepath = Path.Combine(versionDir, tarEntry.Name); var filepath = Path.Combine(versionDir, tarEntry.Name);
if (tarEntry.EntryType == TarEntryType.Directory) if (tarEntry.EntryType == TarEntryType.Directory)
{ {
// createDirectory doesn't fail if already exists // createDirectory doesn't fail if already exists
Directory.CreateDirectory(filepath); Directory.CreateDirectory(filepath);
continue; continue;
} }
if (tarEntry.LinkName != "") if (tarEntry.LinkName != "")
{ {
// Handle links manually // Handle links manually
if (File.Exists(filepath)) if (File.Exists(filepath))
{ {
File.Delete(filepath); File.Delete(filepath);
} }
File.CreateSymbolicLink(filepath, tarEntry.LinkName); File.CreateSymbolicLink(filepath, tarEntry.LinkName);
continue; // we are done with this file so keep going continue; // we are done with this file so keep going
} }
tarEntry.ExtractToFile(filepath, overwrite: true); tarEntry.ExtractToFile(filepath, overwrite: true);
} }
} }
}
// Now assuming nothing broke before now we can copy the files into the system directories.
// WARN: This is dangerous stuff and involves making system calls.
// NOTE: be sure when calling to other programs to wait until they exit.
var Mover = new ProcessStartInfo();
Mover.FileName = "pkexec";
Mover.Arguments = $"cp -dri {versionDir}/opt {versionDir}/usr /";
Mover.UseShellExecute = true;
var pr = Process.Start(Mover);
pr?.WaitForExit();
} }
} }
// Patch the startup program to allow using UserFlags
string startScript = Path.Combine(versionDir , "opt/microsoft/msedge/microsoft-edge");
Log.Information("Patching {startScript}",startScript);
using (var scriptStream = File.Open(startScript,FileMode.Open))
using (var scriptRead = new StreamReader(scriptStream))
using (var scriptWrite = new StreamWriter(scriptStream))
{
var newscriptString = new StringBuilder();
var currentScriptString = scriptRead.ReadToEnd();
if (currentScriptString is null)
{
return 1;
}
List<string> currentScriptSplit = currentScriptString.Split("\n").ToList();
currentScriptSplit.RemoveRange(currentScriptSplit.Count - 3,3);
currentScriptSplit.Add("if [ -r \"${XDG_CONFIG_HOME}/microsoft-edge-stable-flags.conf\" ]; then");
currentScriptSplit.Add(" EDGE_USER_FLAGS=\"$(cat \"$XDG_CONFIG_HOME/microsoft-edge-stable-flags.conf\")\"");
currentScriptSplit.Add("fi");
currentScriptSplit.Add("");
currentScriptSplit.Add("");
currentScriptSplit.Add("# Note: exec -a below is a bashism");
currentScriptSplit.Add("exec -a \"$0\" \"$HERE/msedge\" $EDGE_USER_FLAGS \"$@\"");
newscriptString.AppendJoin("\n",currentScriptSplit);
scriptStream.Position = 0;
scriptStream.SetLength(0);
AnsiConsole.MarkupLineInterpolated($"[grey]{newscriptString.ToString()}[/]");
scriptWrite.Write(newscriptString.ToString());
scriptStream.Flush();
}
// Now assuming nothing broke before now we can copy the files into the system directories.
// WARN: This is dangerous stuff and involves making system calls.
// NOTE: be sure when calling to other programs to wait until they exit.
var Mover = new ProcessStartInfo();
Mover.FileName = "pkexec";
Mover.Arguments = $"cp -drv {versionDir}/opt {versionDir}/usr /";
Mover.UseShellExecute = true;
var pr = Process.Start(Mover);
pr?.WaitForExit();
return 0; return 0;
} }
@ -335,7 +380,6 @@ public static partial class EdgeInstall
- Check version - Check version
- Offer update - Offer update
- Make SENSIBLE backup - Make SENSIBLE backup
- Do install
= if install fails revert backup = if install fails revert backup
*/ */
} }

View File

@ -4,6 +4,5 @@ A dumb package manager, soon to be outfitted with the ability to fully
extract .deb packages. extract .deb packages.
## TODO: ## TODO:
- Add archive extraction code
- Add install functionality - Add install functionality
- Refactor some classes to make them neater - Refactor some classes to make them neater

View File

@ -51,6 +51,13 @@ public sealed partial class ReleaseData
.Split(": ").Last() // We only want items after the label .Split(": ").Last() // We only want items after the label
.Split(" ", StringSplitOptions.RemoveEmptyEntries) .Split(" ", StringSplitOptions.RemoveEmptyEntries)
.ToList(); .ToList();
// Cope with files being in binary-arch sometimes.
List<string> BinArchs = new();
foreach (var arch in Architectures)
{
BinArchs.Add("binary-" + arch);
}
Architectures.AddRange(BinArchs);
Log.Debug("Extracted architectures {@architectures}", Architectures); Log.Debug("Extracted architectures {@architectures}", Architectures);
@ -109,11 +116,16 @@ public sealed partial class ReleaseData
* should never cause any issues. * should never cause any issues.
*/ */
{ {
if (PackageFiles.Where(file => file.filename.Contains(arch)).Count() == 0) if (PackageFiles.Where(file => file.filename.Contains($"main/{arch}/")).Count() == 0) // match on "/arch/"
{ {
Log.Debug("removing /{arch}/", arch);
Architectures.Remove(arch); Architectures.Remove(arch);
} }
} }
if (Architectures.Count == 0)
{
throw new Exception("Architectures is null");
}
} }