summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-04-28 17:29:45 +0800
committerGitHub <[email protected]>2021-04-28 17:29:45 +0800
commit6a65b90ba97c56bb551f97ffd7bc95725917bea6 (patch)
treee4a5ba95c20b18277b09e24b5391c9ccb71e642d
parente3986002e0b91d2a24227a487b88cbe3ef915563 (diff)
parente98ca4f7d28c12fc1cfead20fd774e30eb7ff52a (diff)
Merge pull request #1368 from xq114/dev
improve environment management on powershell
-rw-r--r--.github/workflows/windows.yml1
-rw-r--r--scripts/installer.nsi1
-rw-r--r--scripts/xrepo-hook.psm190
-rw-r--r--scripts/xrepo.ps134
-rw-r--r--xmake/modules/private/xrepo/action/env.lua43
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"))