From 0774c4fc344b0cf3f2ea5b5e9ab8aee5f8d86d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20R=C3=A4tzel?= Date: Wed, 16 Jun 2021 11:04:21 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20installation=20on=20Ubuntu=2020=20?= =?UTF-8?q?=F0=9F=90=9B=E2=98=A0=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the issue with installation on Ubuntu 20 discovered at https://github.com/elm-fullstack/elm-fullstack/issues/5 Use a new strategy of installing on Linux: Copy the executable file into the directory `/bin/`: Assume most systems will already have the `PATH` environment variable include this directory. --- implement/elm-fullstack/Program.cs | 86 ++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/implement/elm-fullstack/Program.cs b/implement/elm-fullstack/Program.cs index a7f86ff0..b462e33a 100644 --- a/implement/elm-fullstack/Program.cs +++ b/implement/elm-fullstack/Program.cs @@ -35,14 +35,14 @@ static int Main(string[] args) var installCmd = app.Command("install", installCmd => { - var (commandName, _, registerExecutableDirectoryOnPath) = CheckIfExecutableIsRegisteredOnPath(); + var (commandName, checkInstallation) = CheckIfExecutableIsRegisteredOnPath(); installCmd.Description = "Installs the '" + commandName + "' command for the current user account."; installCmd.UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.Throw; installCmd.OnExecute(() => { - registerExecutableDirectoryOnPath(); + checkInstallation().registerExecutableDirectoryOnPath(); }); }); @@ -93,8 +93,10 @@ static int Main(string[] args) allOption.ShortName = "a"; + var checkedInstallation = CheckIfExecutableIsRegisteredOnPath().checkInstallation(); + var setupGroupCommands = - CheckIfExecutableIsRegisteredOnPath().executableIsRegisteredOnPath + checkedInstallation.executableIsRegisteredOnPath ? new CommandLineApplication[0] : new[] @@ -1376,7 +1378,7 @@ static public void ReplicateProcessAndLogToConsole( httpResponse.Content.ReadAsStringAsync().Result); } - static (string commandName, bool executableIsRegisteredOnPath, Action registerExecutableDirectoryOnPath) + static (string commandName, Func<(bool executableIsRegisteredOnPath, Action registerExecutableDirectoryOnPath)> checkInstallation) CheckIfExecutableIsRegisteredOnPath() { var environmentVariableName = "PATH"; @@ -1390,29 +1392,71 @@ string getCurrentValueOfEnvironmentVariable() => var commandName = Regex.Match(executableFileName, @"(.+?)(?=\.exe$|$)").Groups[1].Value; - var registerExecutableForCurrentUser = new Action(() => + (bool executableIsRegisteredOnPath, Action registerExecutableDirectoryOnPath) checkInstallation() { - var newValueForPathEnv = - executableDirectoryPath + - System.IO.Path.PathSeparator + - getCurrentValueOfEnvironmentVariable(); + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) + { + var executableIsRegisteredOnPath = + (getCurrentValueOfEnvironmentVariable() ?? "") + .Split(Path.PathSeparator).Contains(executableDirectoryPath); + + var registerExecutableForCurrentUser = new Action(() => + { + var newValueForPathEnv = + executableDirectoryPath + + Path.PathSeparator + + getCurrentValueOfEnvironmentVariable(); - Environment.SetEnvironmentVariable(environmentVariableName, newValueForPathEnv, environmentVariableScope); + Environment.SetEnvironmentVariable(environmentVariableName, newValueForPathEnv, environmentVariableScope); - // https://stackoverflow.com/questions/32650063/get-environment-variable-out-of-new-process-in-c-sharp/32650213#32650213 - // https://devblogs.microsoft.com/oldnewthing/?p=91591 - // https://docs.microsoft.com/en-us/previous-versions//cc723564(v=technet.10)?redirectedfrom=MSDN#XSLTsection127121120120 + // https://stackoverflow.com/questions/32650063/get-environment-variable-out-of-new-process-in-c-sharp/32650213#32650213 + // https://devblogs.microsoft.com/oldnewthing/?p=91591 + // https://docs.microsoft.com/en-us/previous-versions//cc723564(v=technet.10)?redirectedfrom=MSDN#XSLTsection127121120120 - Console.WriteLine( - "I added the path '" + executableDirectoryPath + "' to the '" + environmentVariableName + - "' environment variable for the current user account. You will be able to use the '" + commandName + "' command in newer instances of the Command Prompt."); - }); + Console.WriteLine( + "I added the path '" + executableDirectoryPath + "' to the '" + environmentVariableName + + "' environment variable for the current user account. You will be able to use the '" + commandName + "' command in newer instances of the Command Prompt."); + }); + + return (executableIsRegisteredOnPath, registerExecutableForCurrentUser); + } + else + { + var destinationExecutableFilePath = "/bin/" + commandName; + + byte[] currentRegisteredFileContent = null; + + if (File.Exists(destinationExecutableFilePath)) + { + currentRegisteredFileContent = File.ReadAllBytes(destinationExecutableFilePath); + } + + var currentExecuableFileContent = File.ReadAllBytes(executableFilePath); + + var executableIsRegisteredOnPath = + currentRegisteredFileContent != null && + currentRegisteredFileContent.SequenceEqual(currentExecuableFileContent); + + var registerExecutableForCurrentUser = new Action(() => + { + File.WriteAllBytes(destinationExecutableFilePath, currentExecuableFileContent); - var executableIsRegisteredOnPath = - (getCurrentValueOfEnvironmentVariable() ?? "") - .Split(Path.PathSeparator).Contains(executableDirectoryPath); + var unixFileInfo = new Mono.Unix.UnixFileInfo(destinationExecutableFilePath); + + unixFileInfo.FileAccessPermissions |= + Mono.Unix.FileAccessPermissions.GroupExecute | Mono.Unix.FileAccessPermissions.UserExecute | Mono.Unix.FileAccessPermissions.OtherExecute | + Mono.Unix.FileAccessPermissions.GroupRead | Mono.Unix.FileAccessPermissions.UserRead | Mono.Unix.FileAccessPermissions.OtherRead; + + Console.WriteLine( + "I copied the executable file to '" + destinationExecutableFilePath + + "'. You will be able to use the '" + commandName + "' command in newer terminal instances."); + }); + + return (executableIsRegisteredOnPath, registerExecutableForCurrentUser); + } + }; - return (commandName, executableIsRegisteredOnPath, registerExecutableForCurrentUser); + return (commandName, checkInstallation); } static public void BuildConfiguration(