diff options
| author | ruki <[email protected]> | 2021-04-28 17:29:45 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-04-28 17:29:45 +0800 |
| commit | 6a65b90ba97c56bb551f97ffd7bc95725917bea6 (patch) | |
| tree | e4a5ba95c20b18277b09e24b5391c9ccb71e642d | |
| parent | e3986002e0b91d2a24227a487b88cbe3ef915563 (diff) | |
| parent | e98ca4f7d28c12fc1cfead20fd774e30eb7ff52a (diff) | |
Merge pull request #1368 from xq114/dev
improve environment management on powershell
| -rw-r--r-- | .github/workflows/windows.yml | 1 | ||||
| -rw-r--r-- | scripts/installer.nsi | 1 | ||||
| -rw-r--r-- | scripts/xrepo-hook.psm1 | 90 | ||||
| -rw-r--r-- | scripts/xrepo.ps1 | 34 | ||||
| -rw-r--r-- | xmake/modules/private/xrepo/action/env.lua | 43 |
5 files changed, 161 insertions, 8 deletions
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 661d74391..2ae4c1cb8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -57,6 +57,7 @@ jobs: run: | Copy-Item ./core/build/xmake.exe ./xmake Copy-Item ./scripts/xrepo.bat ./xmake + Copy-Item ./scripts/xrepo.ps1 ./xmake $Env:XMAKE_PROGRAM_DIR = $(Resolve-Path ./xmake) Set-Item -Path Env:Path -Value ($Env:XMAKE_PROGRAM_DIR + ";" + $Env:Path) xrepo --version diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 4f12aebea..a01b6feea 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -237,6 +237,7 @@ Section "XMake (required)" InstallExeutable File "..\*.md" File "..\core\build\xmake.exe" File "..\scripts\xrepo.bat" + File "..\scripts\xrepo.ps1" File /r /x ".DS_Store" "..\winenv" WriteUninstaller "uninstall.exe" diff --git a/scripts/xrepo-hook.psm1 b/scripts/xrepo-hook.psm1 new file mode 100644 index 000000000..ca63fb09b --- /dev/null +++ b/scripts/xrepo-hook.psm1 @@ -0,0 +1,90 @@ + +## ENVIRONMENT MANAGEMENT ###################################################### + +<# + .SYNOPSIS + Enter a xrepo environment based on your current project. + + .EXAMPLE + Enter-XrepoEnvironment +#> +function Enter-XrepoEnvironment { + [CmdletBinding()] + param(); + + begin { + $script:xrepoOldEnvs = (Get-ChildItem -Path Env:); + $xrepoPrompt = (& $Env:XMAKE_EXE lua private.xrepo.action.env.info prompt | Out-String); + $activateCommand = (& $Env:XMAKE_EXE lua private.xrepo.action.env.info script.powershell | Out-String); + + Write-Verbose "[xrepo env script.powershell]`n$activateCommand"; + Invoke-Expression -Command $activateCommand; + + $Env:XMAKE_PROMPT_MODIFIER = $xrepoPrompt.Trim() + " "; + } + process {} + end {} +} + + +<# + .SYNOPSIS + Exit the current xrepo environment, if any. + + .EXAMPLE + Exit-XrepoEnvironment +#> +function Exit-XrepoEnvironment { + [CmdletBinding()] + param(); + + begin { + # Write-Host $script:xrepoOldEnvs; + ForEach ($p in $script:xrepoOldEnvs) { + [Environment]::SetEnvironmentVariable($p.Name, $p.Value); + } + $Env:XMAKE_PROMPT_MODIFIER = ""; + } + process {} + end {} +} + + +if (Test-Path Function:\prompt) { + Rename-Item Function:\prompt XrepoPromptBackup +} else { + function XrepoPromptBackup() { + # Restore a basic prompt if the definition is missing. + "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "; + } +} + + +<# + .SYNOPSIS + Modifies the current prompt to show the current xmake project. + + .EXAMPLE + Add-XrepoEnvironmentToPrompt + + Causes the current session's prompt to display the current xmake project name. +#> +function Add-XrepoEnvironmentToPrompt() { + function global:prompt() { + if ($Env:XMAKE_PROMPT_MODIFIER) { + $Env:XMAKE_PROMPT_MODIFIER | Write-Host -NoNewline + } + XrepoPromptBackup; + } +} + + +## EXPORTS ################################################################### + +Export-ModuleMember ` + -Alias * ` + -Function ` + Add-XrepoEnvironmentToPrompt, ` + Enter-XrepoEnvironment, ` + Exit-XrepoEnvironment, ` + prompt diff --git a/scripts/xrepo.ps1 b/scripts/xrepo.ps1 new file mode 100644 index 000000000..84bb4f000 --- /dev/null +++ b/scripts/xrepo.ps1 @@ -0,0 +1,34 @@ +$script:SCRIPT_PATH = $myinvocation.mycommand.path +$script:BASE_DIR = Split-Path $SCRIPT_PATH -Parent +$Env:XMAKE_EXE = Join-Path $BASE_DIR xmake.exe + + +if ($Args.Count -eq 0) { + # No args, just call the underlying conda executable. + & $Env:XMAKE_EXE lua private.xrepo; +} else { + $Command = $Args[0]; + if (($Command -eq "env") -and ($Args.Count -ge 2)) { + switch ($Args[1]) { + "shell" { + if (-not (Test-Path 'Env:XMAKE_ROOTDIR')) { + $Env:XMAKE_ROOTDIR = $BASE_DIR; + Import-Module "$Env:XMAKE_ROOTDIR\scripts\xrepo-hook.psm1"; + Add-XrepoEnvironmentToPrompt; + } + if ((Test-Path 'Env:XMAKE_PROMPT_MODIFIER') -and ($Env:XMAKE_PROMPT_MODIFIER -ne "")) { + Exit-XrepoEnvironment; + } + Enter-XrepoEnvironment; + return; + } + "quit" { + Exit-XrepoEnvironment; + return; + } + } + } + + $OtherArgs = @(); + & $Env:XMAKE_EXE lua private.xrepo $Command @OtherArgs; +} diff --git a/xmake/modules/private/xrepo/action/env.lua b/xmake/modules/private/xrepo/action/env.lua index a1cf20506..da573ffca 100644 --- a/xmake/modules/private/xrepo/action/env.lua +++ b/xmake/modules/private/xrepo/action/env.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("core.base.task") +import("core.base.hashset") import("core.project.config") import("lib.detect.find_tool") import("private.action.require.impl.package") @@ -175,7 +176,7 @@ function _package_addenvs(envs, instance) return end - -- add run envs, e.g. PATH, LD_LIBRARY_PATH, .. + -- add run envs, e.g. PATH, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH local installdir = instance:installdir() for name, values in pairs(instance:envs()) do if name == "PATH" or name == "LD_LIBRARY_PATH" or name == "DYLD_LIBRARY_PATH" then @@ -191,7 +192,7 @@ function _package_addenvs(envs, instance) end end - -- add library envs, e.g. ACLOCAL_PATH, PKG_CONFIG_PATH .. + -- add library envs, e.g. ACLOCAL_PATH, PKG_CONFIG_PATH, CMAKE_PREFIX_PATH if instance:is_library() then local pkgconfig = path.join(installdir, "lib", "pkgconfig") if os.isdir(pkgconfig) then @@ -232,13 +233,42 @@ function _package_getenvs() return envs end +-- get environment setting script +function _get_env_script(envs, shell) + local prefix = "" + local connector = "=" + local suffix = "" + if shell == "powershell" or shell == "pwsh" then + prefix = "[Environment]::SetEnvironmentVariable('" + connector = "','" + suffix = "')" + end + local ret = "" + local modified = hashset.of("PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "ACLOCAL_PATH", "PKG_CONFIG_PATH", "CMAKE_PREFIX_PATH") + for name, value in pairs(envs) do + if modified:has(name) then + ret = ret .. prefix .. name .. connector .. value .. suffix .. "\n" + end + end + return ret +end + +-- get information of current virtual environment +function info(key) + if key == "prompt" then + print("[%s]", path.filename(os.projectdir())) + elseif key:startswith("script.") then + local shell = key:match("script%.(.+)") + print(_get_env_script(envs, shell)) + end +end + -- run shell function _run_shell(envs) local shell = os.shell() local projectname = path.filename(os.projectdir()) - if shell == "pwsh" then - local args = table.join({"-c", "'function prompt { \\\"[" .. projectname .. "] \\\" + $(Get-Location) + \\\"> \\\" }'"}, option.get("arguments")) - os.execv("pwsh", args, {envs = envs}) + if shell == "pwsh" or shell == "powershell" then + os.execv("pwsh", option.get("arguments"), {envs = envs}) elseif shell:endswith("sh") then local prompt = "[" .. projectname .. "] " local ps1 = os.getenv("PS1") @@ -250,9 +280,6 @@ function _run_shell(envs) prompt = prompt .. "> " end os.execv(shell, option.get("arguments"), {envs = table.join({PS1 = prompt}, envs)}) - elseif shell == "powershell" then - local args = table.join({"-c", "'function prompt { \\\"[" .. projectname .. "] \\\" + $(Get-Location) + \\\"> \\\" }'"}, option.get("arguments")) - os.execv("powershell", args, {envs = envs}) elseif shell == "cmd" or is_host("windows") then local prompt = "[" .. projectname .. "] $P$G" local args = table.join({"/k", "set PROMPT=[" .. projectname .. "] $P$G"}, option.get("arguments")) |
