public static Process NewJulia(out string tmpFilename, string script, bool?localDepot = null) { string julia = FindJulia(false); if (string.IsNullOrEmpty(julia) || !File.Exists(julia)) { tmpFilename = null; return(null); } bool local = localDepot ?? (JuliaIsLocal || Mode != AhornHelperMode.System); if (local) { string depot = Path.Combine(RootPath, "julia-depot"); if (!Directory.Exists(depot)) { Directory.CreateDirectory(depot); } Environment.SetEnvironmentVariable("JULIA_DEPOT_PATH", depot); } else { Environment.SetEnvironmentVariable("JULIA_DEPOT_PATH", string.IsNullOrEmpty(OrigJuliaDepotPath) ? Path.PathSeparator.ToString() : OrigJuliaDepotPath); } string env = local ? AhornEnvPath : AhornGlobalEnvPath; Environment.SetEnvironmentVariable("AHORN_ENV", env); Environment.SetEnvironmentVariable("AHORN_GLOBALENV", AhornGlobalEnvPath); if (!Directory.Exists(env)) { Directory.CreateDirectory(env); } tmpFilename = Path.GetTempFileName(); File.WriteAllText(tmpFilename, PrefixGlobal + script); return(ProcessHelper.Wrap(julia, "\"" + tmpFilename + "\"")); }
public override IEnumerator Run(bool beta) { yield return(Status("Preparing installation of Julia", false, "", false)); string root = AhornHelper.RootPath; string tmp = Path.Combine(root, "tmp"); if (!Directory.Exists(tmp)) { Directory.CreateDirectory(tmp); } string julia = Path.Combine(root, "julia"); if (Directory.Exists(julia)) { Directory.Delete(julia, true); } if (PlatformHelper.Is(Platform.Windows)) { string zipPath = Path.Combine(tmp, "juliadownload.zip"); if (File.Exists(zipPath)) { File.Delete(zipPath); } string url; if (PlatformHelper.Is(Platform.Bits64)) { url = beta ? "https://julialang-s3.julialang.org/bin/winnt/x64/1.6/julia-1.6.0-rc3-win64.zip" : "https://julialang-s3.julialang.org/bin/winnt/x64/1.5/julia-1.5.4-win64.zip"; } else { url = beta ? "https://julialang-s3.julialang.org/bin/winnt/x86/1.6/julia-1.6.0-rc3-win32.zip" : "https://julialang-s3.julialang.org/bin/winnt/x86/1.5/julia-1.5.4-win32.zip"; } try { yield return(Status($"Downloading {url}", false, "download", false)); using (FileStream zipStream = File.Open(zipPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) { yield return(Download(url, 0, zipStream)); zipStream.Seek(0, SeekOrigin.Begin); yield return(Status("Unzipping Julia", false, "download", false)); using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read)) { yield return(Unpack(zip, julia, beta ? "julia-1.6.0-rc3/" : "julia-1.5.4/")); } } } finally { if (File.Exists(zipPath)) { File.Delete(zipPath); } } string launcher = Path.Combine(root, "launch-local-julia.bat"); if (File.Exists(launcher)) { File.Delete(launcher); } File.WriteAllText(launcher, @" @echo off setlocal EnableDelayedExpansion set ""JULIA_DEPOT_PATH=%~dp0\julia-depot"" set ""AHORN_GLOBALENV=%LocalAppData%\Ahorn\env"" set ""AHORN_ENV=%~dp0\ahorn-env"" ""%~dp0\julia\bin\julia.exe"" %* " .TrimStart().Replace("\r\n", "\n").Replace("\n", "\r\n") ); } else if (PlatformHelper.Is(Platform.Linux)) { string tarPath = Path.Combine(tmp, "juliadownload.tar.gz"); if (File.Exists(tarPath)) { File.Delete(tarPath); } string url; string lsPath = ProcessHelper.Read("which", "ls", out _).Trim().Split('\n').FirstOrDefault()?.Trim(); bool musl = !string.IsNullOrEmpty(lsPath) && ProcessHelper.Read("ldd", lsPath, out _).Contains("musl"); if (PlatformHelper.Is(Platform.ARM)) { url = beta ? "https://julialang-s3.julialang.org/bin/linux/aarch64/1.6/julia-1.6.0-rc3-linux-aarch64.tar.gz" : "https://julialang-s3.julialang.org/bin/linux/aarch64/1.5/julia-1.5.4-linux-aarch64.tar.gz"; } else if (musl) { url = beta ? "https://julialang-s3.julialang.org/bin/musl/x64/1.6/julia-1.6.0-rc3-musl-x86_64.tar.gz" : "https://julialang-s3.julialang.org/bin/musl/x64/1.5/julia-1.5.4-musl-x86_64.tar.gz"; } else if (PlatformHelper.Is(Platform.Bits64)) { url = beta ? "https://julialang-s3.julialang.org/bin/linux/x64/1.6/julia-1.6.0-rc3-linux-x86_64.tar.gz" : "https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.4-linux-x86_64.tar.gz"; } else { url = beta ? "https://julialang-s3.julialang.org/bin/linux/x86/1.6/julia-1.6.0-rc3-linux-i686.tar.gz" : "https://julialang-s3.julialang.org/bin/linux/x86/1.5/julia-1.5.4-linux-i686.tar.gz"; } try { yield return(Status($"Downloading {url}", false, "download", false)); using (FileStream tarStream = File.Open(tarPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) yield return(Download(url, 0, tarStream)); yield return(Status("Extracting Julia", false, "download", false)); yield return(Status("", false, "download", false)); using (Process process = ProcessHelper.Wrap("tar", $"-xvf \"{tarPath}\" -C \"{root}\"")) { process.Start(); for (string line; (line = process.StandardOutput.ReadLine()) != null;) { yield return(Status(line, false, "download", true)); } process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("tar encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } yield return(Status("Julia archive extracted", false, "download", true)); } yield return(Status("Moving Julia", false, "download", false)); Directory.Move(Path.Combine(root, beta ? "julia-1.6.0-rc3" : "julia-1.5.4"), julia); } finally { if (File.Exists(tarPath)) { File.Delete(tarPath); } } string launcher = Path.Combine(root, "launch-local-julia.sh"); if (File.Exists(launcher)) { File.Delete(launcher); } File.WriteAllText(launcher, @" #!/bin/sh ROOTDIR=$(dirname ""$0"") export JULIA_DEPOT_PATH=""${ROOTDIR}/julia-depot"" if [ ! -z ""${XDG_CONFIG_HOME}"" ]; then export AHORN_GLOBALENV=""${XDG_CONFIG_HOME}/Ahorn/env"" else export AHORN_GLOBALENV=""${HOME}/.config/Ahorn/env"" fi export AHORN_ENV=""${ROOTDIR}/ahorn-env"" ""${ROOTDIR}/julia/bin/julia"" $@ " .TrimStart().Replace("\r\n", "\n") ); ProcessHelper.Read("chmod", $"a+x \"{launcher}\"", out _); } else if (PlatformHelper.Is(Platform.MacOS)) { string dmgPath = Path.Combine(tmp, "juliadownload.dmg"); if (File.Exists(dmgPath)) { File.Delete(dmgPath); } string mount = Path.Combine(tmp, "juliamount"); if (Directory.Exists(mount)) { Directory.Delete(mount); } string url = beta ? "https://julialang-s3.julialang.org/bin/mac/x64/1.6/julia-1.6.0-rc3-mac64.dmg" : "https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.4-mac64.dmg"; bool mounted = false; try { yield return(Status($"Downloading {url}", false, "download", false)); using (FileStream dmgStream = File.Open(dmgPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) yield return(Download(url, 0, dmgStream)); yield return(Status("Mounting Julia", false, "download", false)); using (Process process = ProcessHelper.Wrap("hdiutil", $"attach -mountpoint \"{mount}\" \"{dmgPath}\"")) { process.Start(); for (string line; (line = process.StandardOutput.ReadLine()) != null;) { yield return(Status(line, false, "download", false)); } process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("hdiutil attach encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } } mounted = true; yield return(Status("Copying Julia", false, "download", false)); yield return(Status("", false, "download", false)); using (Process process = ProcessHelper.Wrap("cp", $"-rvf \"{Path.Combine(mount, beta ? "Julia-1.6.app" : "Julia-1.5.app", "Contents", "Resources", "julia")}\" \"{julia}\"")) { process.Start(); for (string line; (line = process.StandardOutput.ReadLine()) != null;) { yield return(Status(line, false, "download", true)); } process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("cp encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } yield return(Status("Julia copied", false, "download", true)); } yield return(Status("Unmounting Julia", false, "download", false)); using (Process process = ProcessHelper.Wrap("hdiutil", $"detach \"{mount}\"")) { process.Start(); for (string line; (line = process.StandardOutput.ReadLine()) != null;) { yield return(Status(line, false, "download", false)); } process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("hdiutil detach encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } } mounted = false; } finally { if (mounted) { try { using (Process process = ProcessHelper.Wrap("hdiutil", $"detach \"{mount}\"")) { process.Start(); process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("hdiutil detach encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } } } catch (Exception e) { Console.Error.WriteLine("Error unmounting Julia dmg in installer finally clause"); Console.Error.WriteLine(e); } } if (File.Exists(dmgPath)) { File.Delete(dmgPath); } if (Directory.Exists(mount)) { Directory.Delete(mount); } } string launcher = Path.Combine(root, "launch-local-julia.sh"); if (File.Exists(launcher)) { File.Delete(launcher); } File.WriteAllText(launcher, @" #!/bin/sh ROOTDIR=$(dirname ""$0"") export JULIA_DEPOT_PATH=""${ROOTDIR}/julia-depot"" if [ ! -z ""${XDG_CONFIG_HOME}"" ]; then export AHORN_GLOBALENV=""${XDG_CONFIG_HOME}/Ahorn/env"" else export AHORN_GLOBALENV=""${HOME}/.config/Ahorn/env"" fi export AHORN_ENV=""${ROOTDIR}/ahorn-env"" ""${ROOTDIR}/julia/bin/julia"" $@ " .TrimStart().Replace("\r\n", "\n") ); ProcessHelper.Read("chmod", $"a+x \"{launcher}\"", out _); } else { throw new PlatformNotSupportedException($"Unsupported platform: {PlatformHelper.Current}"); } }
public override IEnumerator Run() { yield return(Status("Preparing installation of Ahorn-VHD", false, "", false)); if (!PlatformHelper.Is(Platform.Windows | Platform.Bits64)) { yield return(Status("Unsupported platform.", 1f, "error", false)); throw new PlatformNotSupportedException($"Platform not supported: {PlatformHelper.Current}"); } string vhd = AhornHelper.VHDPath; if (File.Exists(vhd)) { yield return(Status("Ahorn-VHD already exists - please delete it before reinstalling.", 1f, "error", false)); throw new Exception("Ahorn-VHD already exists."); } string archive = vhd + ".7z"; bool tmpPerm = File.Exists(archive); try { if (tmpPerm) { yield return(Status($"{Path.GetFileName(archive)} already exists - reusing and preserving", false, "", false)); } else { const string url = "https://0x0ade.ga/ahornvhd/files/ahornvhd.7z"; yield return(Status($"Downloading {url} to {archive}", false, "download", false)); string tmp = archive + ".part"; if (File.Exists(tmp)) { File.Delete(tmp); } using (FileStream stream = File.Open(tmp, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) yield return(Download(url, 0, stream)); File.Move(tmp, archive); } string sevenzip = Path.Combine(Program.RootDirectory, "7zr.exe"); if (!File.Exists(sevenzip)) { const string url = "https://raw.githubusercontent.com/EverestAPI/Olympus/main/lib-windows/7zr.exe"; yield return(Status($"Couldn't find 7zr.exe, downloading from {url}", false, "download", false)); using (FileStream stream = File.Open(sevenzip, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) yield return(Download(url, 0, stream)); } yield return(Status("Extracting ahornvhd.7z", false, "download", false)); using (Process process = ProcessHelper.Wrap(sevenzip, $"x \"{archive}\" \"-o{Path.GetDirectoryName(vhd)}\" {Path.GetFileName(vhd)} -bb3")) { process.Start(); for (string line; (line = process.StandardOutput.ReadLine()) != null;) { yield return(Status(line, false, "download", false)); } process.WaitForExit(); if (process.ExitCode != 0) { throw new Exception("7zr encountered a fatal error:\n" + process.StandardError.ReadToEnd()); } if (!File.Exists(vhd)) { throw new Exception($"File not extracted: {vhd}"); } yield return(Status("ahornvhd.7z extracted", false, "download", false)); } } finally { if (!tmpPerm && File.Exists(archive)) { File.Delete(archive); } } yield return(Cmds.Get <CmdAhornMountAhornVHD>().Run()); yield return(Cmds.Get <CmdAhornInstallAhorn>().Run()); }