From cc8d16f4a9240e9c16a95d092902c559cb0b89ee Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 05:11:13 +0200 Subject: [PATCH 1/3] Export with Linux variables for #152 --- GBM/Managers/mgrPath.vb | 140 +++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 262769a..88fa2ab 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -12,7 +12,6 @@ Public Class mgrPath Private Shared sLogFile As String = sSettingsRoot & Path.DirectorySeparatorChar & "gbm_log_" & Date.Now.ToString("dd-MM-yyyy-HH-mm-ss") & ".txt" Private Shared sRemoteDatabaseLocation As String Private Shared hshCustomVariables As Hashtable - Private Shared hshUnixEnv As Hashtable Private Shared oReleaseType As ProcessorArchitecture = AssemblyName.GetAssemblyName(Application.ExecutablePath()).ProcessorArchitecture Shared Sub New() @@ -331,61 +330,54 @@ Public Class mgrPath If Not mgrCommon.IsUnix Then Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) Environment.SetEnvironmentVariable("COMMONDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)) - Else - GetUnixEnv() - Environment.SetEnvironmentVariable("USERDOCUMENTS", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) - Environment.SetEnvironmentVariable("APPDATA", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) - Environment.SetEnvironmentVariable("LOCALAPPDATA", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) End If End Sub - Private Shared Sub GetUnixEnv() - Dim prEnv As Process - Dim sEnv As String() - - Try - hshUnixEnv = New Hashtable - prEnv = New Process - prEnv.StartInfo.FileName = "/usr/bin/env" - prEnv.StartInfo.UseShellExecute = False - prEnv.StartInfo.RedirectStandardOutput = True - prEnv.StartInfo.CreateNoWindow = True - prEnv.Start() - - Using swEnv As StreamReader = prEnv.StandardOutput - While Not swEnv.EndOfStream - sEnv = swEnv.ReadLine().Split("=") - If Not hshUnixEnv.Contains(sEnv(0)) Then - hshUnixEnv.Add(sEnv(0), sEnv(1)) - End If - End While - End Using - Catch ex As Exception - mgrCommon.ShowMessage(mgrPath_ErrorUnixEnv, ex.Message, MsgBoxStyle.Exclamation) - End Try - End Sub - Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String - Dim sUnixShortHome As String = "~" - Dim sEnvUnixHome As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) - Dim sCurrentUnixVar As String + Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Dim sCurrentUserLinux As String = "${HOME}" + Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then - 'Replace ~ for HOME - If sValue.Contains(sUnixShortHome) Then - Return sValue.Replace(sUnixShortHome, sEnvUnixHome) + Dim oParse As new Regex("\$([a-zA-Z0-9_]+?)") + Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + End If + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) End If - 'Replace any other environemnt variable - For Each de As DictionaryEntry In hshUnixEnv - sCurrentUnixVar = "$" & de.Key - If sValue.Contains(sCurrentUnixVar) Then - sValue = sValue.Replace(sCurrentUnixVar, de.Value) - End If - Next - Else - sValue = Environment.ExpandEnvironmentVariables(sValue) + '$HOME to ${HOME} + sValue = oParse.Replace(sValue, "${$1}") + 'Special notations for home directory + sValue = sValue.Replace("~", "${HOME}") + 'XDG Base Directory Specification has default values + sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") + sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") + + 'Replace with paths + sValue = sValue.Replace(sAppDataLocalLinux, sEnvAppDataLocal) + sValue = sValue.Replace(sAppDataRoamingLinux, sEnvAppDataRoaming) + sValue = sValue.Replace(sCurrentUserLinux, sEnvCurrentUser) + + 'Transform Linux variables to Windows variables + 'More complex syntax couldn't be converted back + sValue = oParseBracketed.Replace(sValue, "%$1%") + End If + 'On Linux real Linux environmental variables are used + sValue = Environment.ExpandEnvironmentVariables(sValue) + + If mgrCommon.IsUnix Then + 'TODO: breaks support of Windows variables on Linux + Dim oParse As new Regex("%([a-zA-Z0-9_]+?)%") + sValue = oParse.Replace(sValue, "${$1}") End If Return sValue @@ -397,36 +389,40 @@ Public Class mgrPath Dim sPublicDocs As String = "%COMMONDOCUMENTS%" Dim sEnvPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) Dim sAppDataLocal As String = "%LOCALAPPDATA%" + Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) Dim sAppDataRoaming As String = "%APPDATA%" + Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Dim sCurrentUser As String = "%USERPROFILE%" + Dim sCurrentUserLinux As String = "~" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable sValue = ProcessEnvironmentVariables(sValue) + For Each oCustomVariable In hshCustomVariables.Values If sValue.Contains(oCustomVariable.Path) Then Return sValue.Replace(oCustomVariable.Path, oCustomVariable.FormattedName) End If Next - If sValue.Contains(sEnvAppDataRoaming) Then - Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoaming) - End If - - If sValue.Contains(sEnvAppDataLocal) Then - Return sValue.Replace(sEnvAppDataLocal, sAppDataLocal) - End If - - 'This needs to be tested last for Unix compatability - If sValue.Contains(sEnvMyDocs) Then - Return sValue.Replace(sEnvMyDocs, sMyDocs) - End If - - 'Mono doesn't set a path for these folders If Not mgrCommon.IsUnix Then + If sValue.Contains(sEnvAppDataRoaming) Then + Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoaming) + End If + + If sValue.Contains(sEnvAppDataLocal) Then + Return sValue.Replace(sEnvAppDataLocal, sAppDataLocal) + End If + + 'This needs to be tested last for Unix compatability + If sValue.Contains(sEnvMyDocs) Then + Return sValue.Replace(sEnvMyDocs, sMyDocs) + End If + + 'Mono doesn't set a path for these folders If sValue.Contains(sEnvPublicDocs) Then Return sValue.Replace(sEnvPublicDocs, sPublicDocs) End If @@ -434,6 +430,28 @@ Public Class mgrPath If sValue.Contains(sEnvCurrentUser) Then Return sValue.Replace(sEnvCurrentUser, sCurrentUser) End If + Else + 'Use different paths on Linux + If sValue.Contains(sEnvAppDataRoaming) Then + Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoamingLinux) + End If + + If sValue.Contains(sEnvAppDataLocal) Then + Return sValue.Replace(sEnvAppDataLocal, sAppDataLocalLinux) + End If + + 'Must be last + If sValue.Contains(sEnvCurrentUser) Then + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + End If + If sEnvCurrentUser = String.Empty Then + 'Fall back + sEnvCurrentUser = sMyDocs + End If + Return sValue.Replace(sEnvCurrentUser, sCurrentUserLinux) + End If End If Return sValue From 874dfd4c86c459d0df75d94c69ac0bcb9f1e8567 Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 06:11:50 +0200 Subject: [PATCH 2/3] Replace ~ only outside of variables --- GBM/Managers/mgrPath.vb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 88fa2ab..4fd8ce3 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -343,8 +343,9 @@ Public Class mgrPath Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then - Dim oParse As new Regex("\$([a-zA-Z0-9_]+?)") + Dim oParse As new Regex("\$([a-zA-Z0-9_]+)") Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + Dim oParseTilde As new Regex("~(?![^\$\{]*\})") If sEnvCurrentUser = String.Empty Then 'Fall back sEnvCurrentUser = Environment.GetFolderPath(Environment.SpecialFolder.Personal) @@ -357,7 +358,8 @@ Public Class mgrPath '$HOME to ${HOME} sValue = oParse.Replace(sValue, "${$1}") 'Special notations for home directory - sValue = sValue.Replace("~", "${HOME}") + 'Don't replace inside variables + sValue = oParseTilde.Replace(sValue,"${HOME}") 'XDG Base Directory Specification has default values sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") From 9b89af931f48548c53c6648baf68623ff7d3fdba Mon Sep 17 00:00:00 2001 From: Sebastian Riedel Date: Sat, 8 Sep 2018 06:31:46 +0200 Subject: [PATCH 3/3] Keep Windows variables untouched on Linux --- GBM/Managers/mgrPath.vb | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb index 4fd8ce3..b2c9e88 100644 --- a/GBM/Managers/mgrPath.vb +++ b/GBM/Managers/mgrPath.vb @@ -335,16 +335,19 @@ Public Class mgrPath End Sub Private Shared Function ProcessEnvironmentVariables(ByVal sValue As String) As String - Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sXdgData As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) - Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sXdgConfig As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) - Dim sCurrentUserLinux As String = "${HOME}" + Dim sHomeDir As String = "${HOME}" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) If mgrCommon.IsUnix Then + '$VAR_iable Dim oParse As new Regex("\$([a-zA-Z0-9_]+)") + '${VAR_iable} but not advanced syntax like ${VAR:-iable} Dim oParseBracketed As new Regex("\$\{([a-zA-Z0-9_]+?)\}") + '~ not inside ${...} Dim oParseTilde As new Regex("~(?![^\$\{]*\})") If sEnvCurrentUser = String.Empty Then 'Fall back @@ -358,28 +361,31 @@ Public Class mgrPath '$HOME to ${HOME} sValue = oParse.Replace(sValue, "${$1}") 'Special notations for home directory - 'Don't replace inside variables sValue = oParseTilde.Replace(sValue,"${HOME}") 'XDG Base Directory Specification has default values - sValue = sValue.Replace("${XDG_DATA_HOME}", "${XDG_DATA_HOME:-~/.local/share}") - sValue = sValue.Replace("${XDG_CONFIG_HOME}", "${XDG_CONFIG_HOME:-~/.config}") + sValue = sValue.Replace("${XDG_DATA_HOME}", sXdgData) + sValue = sValue.Replace("${XDG_CONFIG_HOME}", sXdgConfig) 'Replace with paths - sValue = sValue.Replace(sAppDataLocalLinux, sEnvAppDataLocal) - sValue = sValue.Replace(sAppDataRoamingLinux, sEnvAppDataRoaming) - sValue = sValue.Replace(sCurrentUserLinux, sEnvCurrentUser) + sValue = sValue.Replace(sXdgData, sEnvAppDataLocal) + sValue = sValue.Replace(sXdgConfig, sEnvAppDataRoaming) + sValue = sValue.Replace(sHomeDir, sEnvCurrentUser) + 'Escape real Windows variables + sValue = sValue.Replace("%", "\%") 'Transform Linux variables to Windows variables - 'More complex syntax couldn't be converted back sValue = oParseBracketed.Replace(sValue, "%$1%") End If + 'On Linux real Linux environmental variables are used sValue = Environment.ExpandEnvironmentVariables(sValue) If mgrCommon.IsUnix Then - 'TODO: breaks support of Windows variables on Linux + 'Transform missing variables back Dim oParse As new Regex("%([a-zA-Z0-9_]+?)%") sValue = oParse.Replace(sValue, "${$1}") + 'Unscape real Windows variables + sValue = sValue.Replace("\%", "%") End If Return sValue @@ -391,13 +397,13 @@ Public Class mgrPath Dim sPublicDocs As String = "%COMMONDOCUMENTS%" Dim sEnvPublicDocs As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) Dim sAppDataLocal As String = "%LOCALAPPDATA%" - Dim sAppDataLocalLinux As String = "${XDG_DATA_HOME:-~/.local/share}" + Dim sXdgData As String = "${XDG_DATA_HOME:-~/.local/share}" Dim sEnvAppDataLocal As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) Dim sAppDataRoaming As String = "%APPDATA%" - Dim sAppDataRoamingLinux As String = "${XDG_CONFIG_HOME:-~/.config}" + Dim sXdgConfig As String = "${XDG_CONFIG_HOME:-~/.config}" Dim sEnvAppDataRoaming As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Dim sCurrentUser As String = "%USERPROFILE%" - Dim sCurrentUserLinux As String = "~" + Dim sHomeDir As String = "~" Dim sEnvCurrentUser As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) Dim oCustomVariable As clsPathVariable @@ -435,11 +441,11 @@ Public Class mgrPath Else 'Use different paths on Linux If sValue.Contains(sEnvAppDataRoaming) Then - Return sValue.Replace(sEnvAppDataRoaming, sAppDataRoamingLinux) + Return sValue.Replace(sEnvAppDataRoaming, sXdgConfig) End If If sValue.Contains(sEnvAppDataLocal) Then - Return sValue.Replace(sEnvAppDataLocal, sAppDataLocalLinux) + Return sValue.Replace(sEnvAppDataLocal, sXdgData) End If 'Must be last @@ -452,7 +458,7 @@ Public Class mgrPath 'Fall back sEnvCurrentUser = sMyDocs End If - Return sValue.Replace(sEnvCurrentUser, sCurrentUserLinux) + Return sValue.Replace(sEnvCurrentUser, sHomeDir) End If End If