From nobody Mon Feb 9 01:16:24 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+56962+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+56962+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1585957782; cv=none; d=zohomail.com; s=zohoarc; b=J2xhnqVNs+F9qeqag2vCXqxfw8CSe5FMnUUKz+VwLqc04j1Hf9WpEROFCAgOlkGxrgt1iECrPBmCgDaJ7jGOZYsA3SrS6dDndv5dKCFhGdc1nke1GwfN/QMtNyOlKNNaxTS2h+TE9Zu+K3Kk0EoPaUQxPycmZsUmQ/G8aesc7Y8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1585957782; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=syl5QIDL2Srmfu/218rFCZVy/HIdLQwxBrgzM1giq7Y=; b=hUr2Spr3DR6yHxJa6m0dxgsnjjBkjcOVwsKOt0HgPqgYiEw9IffNAC3wkpbp8rDlPDANYNCGA8iRSMWH6A/pxN2DKJDel4ZtKRFRa74TV2bQqcVAfpzuUIV5UpIrkhj6EbiDPwAo+OmH4jJ4PF2V/GKPnpJMD3X/0NxGwpXBJqQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+56962+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 158595778260963.69439283503391; Fri, 3 Apr 2020 16:49:42 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id DJJEYY1788612x6oUMULO1Mk; Fri, 03 Apr 2020 16:49:42 -0700 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web10.117.1585957781089662050 for ; Fri, 03 Apr 2020 16:49:41 -0700 IronPort-SDR: i+IqAEiJ6pmaqNW5Q+0LGuufgzYr73YVr+DvtiaOTJfX8JbujZdl4lahOjduZqsJ/7892YktHh YimeDi55Ze8Q== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Apr 2020 16:49:41 -0700 IronPort-SDR: dCP29KBgVYzqV1qBgKTr9l8rLFPzQJvCHG9iPvkUkb0MLbr+zOapYoz8cfcbUrqVcwkmdmuDa4 obIwB+CInPew== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,341,1580803200"; d="scan'208";a="253528777" X-Received: from nldesimo-desk1.amr.corp.intel.com ([10.7.159.63]) by orsmga006.jf.intel.com with ESMTP; 03 Apr 2020 16:49:40 -0700 From: "Nate DeSimone" To: devel@edk2.groups.io Cc: Ashley DeSimone , Puja Pandya , Erik Bjorge , Prince Agyeman , Bret Barkelew , Philippe Mathieu-Daude Subject: [edk2-devel] [edk2-staging/EdkRepo] [PATCH V2 3/3] EdkRepo: Add command completion setup to Windows installer Date: Fri, 3 Apr 2020 16:49:32 -0700 Message-Id: <20200403234932.2497-4-nathaniel.l.desimone@intel.com> In-Reply-To: <20200403234932.2497-1-nathaniel.l.desimone@intel.com> References: <20200403234932.2497-1-nathaniel.l.desimone@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nathaniel.l.desimone@intel.com X-Gm-Message-State: aSKea2Ed4VLerHSR3zBqoF9Sx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1585957782; bh=SOlsibtcyIbv+acOhfPvWewPhN/koFLBq0qqXHHIpC4=; h=Cc:Date:From:Reply-To:Subject:To; b=MQjXPGyw3dtd0spk/JQSKtiCtCvTrtgoehfuo2ECryjsQ1fVzJyY1rMWCeZQ+dJOtob viFVrpsX15MQcvlBfGUwIagyZl0sD0djgaBMz7do/wRmsN91rIffNkeUL30+D066B54Ss fLZQq5hKexyNZkWsIF//hH+XaKmK+Jmr27Q= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" Add configuration of command completion scripts to the Windows installer. This enables edkrepo command completions to work "out of box" on Git for Windows by adding the edkrepo command completions scripts to the Git for Windows /etc/profile.d directory Cc: Ashley DeSimone Cc: Puja Pandya Cc: Erik Bjorge Cc: Prince Agyeman Cc: Bret Barkelew Cc: Philippe Mathieu-Daude Signed-off-by: Nate DeSimone --- .../EdkRepoInstaller/InstallWorker.cs | 212 ++++++++++++++++-- .../EdkRepoInstaller/InstallerStrings.cs | 44 +++- .../Vendor/win_edkrepo_prompt.sh | 60 +++++ 3 files changed, 296 insertions(+), 20 deletions(-) create mode 100644 edkrepo_installer/Vendor/win_edkrepo_prompt.sh diff --git a/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs b/edkrepo_= installer/EdkRepoInstaller/InstallWorker.cs index 472a6c8..679b4f4 100644 --- a/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs +++ b/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs @@ -19,6 +19,7 @@ using System.Security.AccessControl; using System.Security.Cryptography; using System.Security.Principal; using System.Text; +using System.Text.RegularExpressions; using System.Threading; =20 namespace TianoCore.EdkRepoInstaller @@ -611,7 +612,7 @@ namespace TianoCore.EdkRepoInstaller SilentProcess process =3D SilentProcess.StartConsoleProcessSil= ently(GitPath, "--version", dataCapture.DataReceivedHandler); process.WaitForExit(); PythonVersion gitVersion =3D new PythonVersion(dataCapture.Get= Data().Trim()); - if (gitVersion < new PythonVersion(2,13,0)) + if (gitVersion < new PythonVersion(2, 13, 0)) { InstallLogger.Log(string.Format("Git Version 2.13 or later= is required. You have version {0}, please upgrade to a newer version of Gi= t.", gitVersion)); ReportComplete(false, false); @@ -624,7 +625,7 @@ namespace TianoCore.EdkRepoInstaller List> ExclusivePackages =3D new L= ist>(); foreach (PythonInstance PyInstance in PythonWheelsToInstall) { - foreach(PythonWheel Wheel in PyInstance.Wheels) + foreach (PythonWheel Wheel in PyInstance.Wheels) { if (Wheel.UninstallAllOtherCopies) { @@ -668,13 +669,13 @@ namespace TianoCore.EdkRepoInstaller // foreach (PythonVersion Obsolete in ObsoletedPythonVersions) { - if(ExistingEdkRepoPaths.Select(p =3D> p.Item2).Contains(Ob= solete)) + if (ExistingEdkRepoPaths.Select(p =3D> p.Item2).Contains(O= bsolete)) { foreach (string ExistingEdkrepoPythonPath in ExistingE= dkRepoPaths.Where(p =3D> p.Item2 =3D=3D Obsolete).Select(p =3D> p.Item1)) { string UninstallerPath =3D Path.Combine(Path.GetDi= rectoryName(ExistingEdkrepoPythonPath), "Lib", "site-packages"); UninstallerPath =3D Path.Combine(UninstallerPath, = Path.GetFileName(WindowsHelpers.GetApplicationPath())); - if(File.Exists(UninstallerPath)) + if (File.Exists(UninstallerPath)) { InstallLogger.Log(string.Format("Uninstalling = {0}...", UninstallerPath)); string UninstallString =3D string.Format("\"{0= }\" /Uninstall /Passive", UninstallerPath); @@ -788,14 +789,15 @@ namespace TianoCore.EdkRepoInstaller // // Step 10 - Setup symlink to edkrepo and bash script to launc= h edkrepo from git bash // + string EdkrepoSymlinkPath =3D null; if (!string.IsNullOrEmpty(EdkrepoPythonPath)) { string EdkrepoScriptPath =3D Path.Combine(Path.GetDirector= yName(EdkrepoPythonPath), "Scripts", InstallerStrings.EdkrepoCliExecutable); - string EdkrepoSymlinkPath =3D Path.Combine(Environment.Get= FolderPath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliE= xecutable); + EdkrepoSymlinkPath =3D Path.Combine(Environment.GetFolderP= ath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliExecutab= le); if (File.Exists(EdkrepoScriptPath)) { bool CreateSymlink =3D true; - if(File.Exists(EdkrepoSymlinkPath)) + if (File.Exists(EdkrepoSymlinkPath)) { try { @@ -805,22 +807,22 @@ namespace TianoCore.EdkRepoInstaller } } catch (NotASymlinkException) { } - if(CreateSymlink) + if (CreateSymlink) { File.Delete(EdkrepoSymlinkPath); } } - if(CreateSymlink) + if (CreateSymlink) { InstallLogger.Log("Creating Symbolic Link for edkr= epo.exe..."); WindowsHelpers.CreateSymbolicLink(EdkrepoSymlinkPa= th, EdkrepoScriptPath, WindowsHelpers.SYMBOLIC_LINK_FLAG.File); } string GitBashBinPath =3D Path.Combine(Path.GetDirecto= ryName(Path.GetDirectoryName(GitPath)), "usr", "bin"); - if(Directory.Exists(GitBashBinPath)) + if (Directory.Exists(GitBashBinPath)) { InstallLogger.Log("Creating edkrepo launcher in Gi= t Bash..."); string EdkrepoBashScriptPath =3D Path.Combine(GitB= ashBinPath, InstallerStrings.EdkrepoBashLauncherScript); - if(File.Exists(EdkrepoBashScriptPath)) + if (File.Exists(EdkrepoBashScriptPath)) { File.Delete(EdkrepoBashScriptPath); } @@ -838,7 +840,7 @@ namespace TianoCore.EdkRepoInstaller // Step 11 - Copy edkrepo config file to the edkrepo global da= ta directory // string EdkrepoCfg =3D Path.Combine(Path.GetDirectoryName(Windo= wsHelpers.GetApplicationPath()), InstallerStrings.EdkrepoCfg); - if(File.Exists(EdkrepoCfg)) + if (File.Exists(EdkrepoCfg)) { CreateEdkrepoGlobalDataDirectory(); string EdkrepoCfgDir =3D Path.Combine(WindowsHelpers.GetAl= lUsersAppDataPath(), InstallerStrings.EdkrepoGlobalDirectoryName); @@ -853,7 +855,7 @@ namespace TianoCore.EdkRepoInstaller { string NewCfgHash =3D ComputeSha256(ReadFile(EdkrepoCf= g)); string OldCfgHash =3D ComputeSha256(ReadFile(EdkrepoCf= gTarget)); - if(NewCfgHash !=3D OldCfgHash) + if (NewCfgHash !=3D OldCfgHash) { if (GetPreviousEdkrepoCfgFileHashes().Contains(Old= CfgHash)) { @@ -908,7 +910,119 @@ namespace TianoCore.EdkRepoInstaller } =20 // - // Step 13 - Create Programs and Features uninstall links + // Step 13 - Copy win_edkrepo_prompt.sh and generate edkrepo_c= ompletions.sh + // + string edkrepoPromptSource =3D Path.Combine(Path.GetDirectoryN= ame(WindowsHelpers.GetApplicationPath()), InstallerStrings.EdkrepoPrompt); + + if (File.Exists(edkrepoPromptSource) && !string.IsNullOrEmpty(= EdkrepoSymlinkPath)) + { + string gitBashEtcPath =3D Path.Combine(Path.GetDirectoryNa= me(Path.GetDirectoryName(GitPath)), "etc"); + string gitBashEtcProfileDPath =3D Path.Combine(gitBashEtcP= ath, "profile.d"); + if (Directory.Exists(gitBashEtcPath) && Directory.Exists(g= itBashEtcProfileDPath)) + { + InstallLogger.Log("Installing EdkRepo command completi= on..."); + + //Copy win_edkrepo_prompt.sh + string edkrepoPromptDest =3D Path.Combine(gitBashEtcPr= ofileDPath, InstallerStrings.EdkrepoPrompt); + if (File.Exists(edkrepoPromptDest)) + { + File.Delete(edkrepoPromptDest); + } + File.Copy(edkrepoPromptSource, edkrepoPromptDest); + DirectoryInfo info =3D new DirectoryInfo(edkrepoPrompt= Dest); + DirectorySecurity security =3D info.GetAccessControl(); + security.AddAccessRule(new FileSystemAccessRule( + new SecurityIdentifier(WellKnownSidType.BuiltinUse= rsSid, null), + FileSystemRights.FullControl, + InheritanceFlags.ContainerInherit | InheritanceFla= gs.ObjectInherit, + PropagationFlags.NoPropagateInherit, + AccessControlType.Allow + )); + info.SetAccessControl(security); + InstallLogger.Log(string.Format("Copied {0}", Installe= rStrings.EdkrepoPrompt)); + + //Generate edkrepo_completions.sh + string edkrepoCompletionDest =3D Path.Combine(gitBashE= tcProfileDPath, InstallerStrings.EdkrepoCompletion); + if (File.Exists(edkrepoCompletionDest)) + { + File.Delete(edkrepoCompletionDest); + } + dataCapture =3D new SilentProcess.StdoutDataCapture(); + process =3D SilentProcess.StartConsoleProcessSilently( + EdkrepoSymlinkPath, + string.Format( + "generate-command-completion-script \"{0}\"", + edkrepoCompletionDest), + dataCapture.DataReceivedHandler); + process.WaitForExit(); + InstallLogger.Log(EdkrepoSymlinkPath); + InstallLogger.Log(edkrepoCompletionDest); + InstallLogger.Log(dataCapture.GetData().Trim()); + if (process.ExitCode !=3D 0) + { + throw new InvalidOperationException(string.Format(= "generate-command-completion-script failed with status {0}", process.ExitCo= de)); + } + if (!File.Exists(edkrepoCompletionDest)) + { + throw new InvalidOperationException(string.Format(= "generate-command-completion-script did not create {0}", InstallerStrings.E= dkrepoCompletion)); + } + info =3D new DirectoryInfo(edkrepoCompletionDest); + security =3D info.GetAccessControl(); + security.AddAccessRule(new FileSystemAccessRule( + new SecurityIdentifier(WellKnownSidType.BuiltinUse= rsSid, null), + FileSystemRights.FullControl, + InheritanceFlags.ContainerInherit | InheritanceFla= gs.ObjectInherit, + PropagationFlags.NoPropagateInherit, + AccessControlType.Allow + )); + info.SetAccessControl(security); + InstallLogger.Log(string.Format("Generated {0}", Insta= llerStrings.EdkrepoCompletion)); + + //Call win_edkrepo_prompt.sh from bash.bashrc so edkre= po completions are available for "interactive non-login" bash shells + string bashrcPath =3D Path.Combine(gitBashEtcPath, "ba= sh.bashrc"); + if (File.Exists(bashrcPath)) + { + string bashrc =3D Encoding.UTF8.GetString(ReadFile= (bashrcPath)); + Match match =3D Regex.Match(bashrc, InstallerStrin= gs.BashrcEdkrepoPromptCallPattern); + if (match.Success) + { + InstallLogger.Log("EdkRepo prompt is already i= n bash.bashrc"); + } + else + { + bashrc =3D string.Format("{0}{1}", bashrc, Ins= tallerStrings.BashrcEdkRepoPromptCall); + using (BinaryWriter writer =3D new BinaryWrite= r(File.Open(bashrcPath, FileMode.Truncate, FileAccess.Write))) + { + string sanitized =3D bashrc.Replace("\r\n"= , "\n"); + writer.Write(Encoding.UTF8.GetBytes(saniti= zed)); + } + InstallLogger.Log("EdkRepo prompt added to bas= h.bashrc"); + } + } + else + { + InstallLogger.Log(string.Format("{0} not found", b= ashrcPath)); + } + } + else + { + InstallLogger.Log("Git for Windows /etc/profile.d not = found"); + } + } + else + { + if (string.IsNullOrEmpty(EdkrepoSymlinkPath)) + { + InstallLogger.Log("EdkRepo symlink not found"); + } + if (!File.Exists(edkrepoPromptSource)) + { + InstallLogger.Log(string.Format("{0} not found", Insta= llerStrings.EdkrepoPrompt)); + } + } + + // + // Step 14 - Create Programs and Features uninstall links // if (!string.IsNullOrEmpty(EdkrepoPythonPath)) { @@ -977,7 +1091,7 @@ namespace TianoCore.EdkRepoInstaller string GitPath =3D PythonOperations.GetFullPath("git.exe"); =20 // - // Step 2 - Delete symlink to edkrepo and bash script to launc= h it from git bash + // Step 2 - Delete symlink to edkrepo // string EdkrepoSymlinkPath =3D Path.Combine(Environment.GetFold= erPath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliExecu= table); if (File.Exists(EdkrepoSymlinkPath)) @@ -1003,7 +1117,11 @@ namespace TianoCore.EdkRepoInstaller File.Delete(EdkrepoSymlinkPath); } } - if (GitPath !=3D null) + + // + // Step 3 - Delete scripts to launch edkrepo and Python from g= it bash, and edkrepo command completion scripts + // + if (!string.IsNullOrWhiteSpace(GitPath)) { string GitBashBinPath =3D Path.Combine(Path.GetDirectoryNa= me(Path.GetDirectoryName(GitPath)), "usr", "bin"); if (Directory.Exists(GitBashBinPath)) @@ -1057,10 +1175,68 @@ namespace TianoCore.EdkRepoInstaller File.Delete(EdkrepoPython2ScriptPath); } } + string gitBashEtcPath =3D Path.Combine(Path.GetDirectoryNa= me(Path.GetDirectoryName(GitPath)), "etc"); + string gitBashEtcProfileDPath =3D Path.Combine(gitBashEtcP= ath, "profile.d"); + if (Directory.Exists(gitBashEtcPath) && Directory.Exists(g= itBashEtcProfileDPath)) + { + string edkrepoPromptDest =3D Path.Combine(gitBashEtcPr= ofileDPath, InstallerStrings.EdkrepoPrompt); + if (File.Exists(edkrepoPromptDest)) + { + AllowCancel(false); + if (CancelPending()) + { + ReportComplete(true, true); + return; + } + InstallLogger.Log(string.Format("Deleting {0}...",= InstallerStrings.EdkrepoPrompt)); + File.Delete(edkrepoPromptDest); + } + + string edkrepoCompletionDest =3D Path.Combine(gitBashE= tcProfileDPath, InstallerStrings.EdkrepoCompletion); + if (File.Exists(edkrepoCompletionDest)) + { + AllowCancel(false); + if (CancelPending()) + { + ReportComplete(true, true); + return; + } + InstallLogger.Log(string.Format("Deleting {0}...",= InstallerStrings.EdkrepoCompletion)); + File.Delete(edkrepoCompletionDest); + } + + //Remove call win_edkrepo_prompt.sh from bash.bashrc + string bashrcPath =3D Path.Combine(gitBashEtcPath, "ba= sh.bashrc"); + if (File.Exists(bashrcPath)) + { + string original_bashrc =3D Encoding.UTF8.GetString= (ReadFile(bashrcPath)); + + string new_bashrc =3D Regex.Replace(original_bashr= c, InstallerStrings.BashrcEdkrepoPromptCommentPattern, ""); + new_bashrc =3D Regex.Replace(new_bashrc, Installer= Strings.BashrcEdkrepoPromptCallPattern, ""); + if (new_bashrc =3D=3D original_bashrc) + { + InstallLogger.Log("EdkRepo not found in bash.b= ashrc"); + } + else + { + new_bashrc =3D new_bashrc.TrimEnd(); + using (BinaryWriter writer =3D new BinaryWrite= r(File.Open(bashrcPath, FileMode.Truncate, FileAccess.Write))) + { + string sanitized =3D new_bashrc.Replace("\= r\n", "\n"); + writer.Write(Encoding.UTF8.GetBytes(saniti= zed)); + } + InstallLogger.Log("EdkRepo prompt removed from= bash.bashrc"); + } + } + else + { + InstallLogger.Log(string.Format("{0} not found", b= ashrcPath)); + } + } } =20 // - // Step 3 - Uninstall any instances of edkrepo + // Step 4 - Uninstall any instances of edkrepo // IEnumerable PackagesToUninstall =3D GetPythonWheelsToU= ninstall(); InstallLogger.Log("Determining currently installed Python pack= ages..."); @@ -1109,7 +1285,7 @@ namespace TianoCore.EdkRepoInstaller } =20 // - // Step 4 - Invoke the Finish Uninstall Event + // Step 5 - Invoke the Finish Uninstall Event // if (VendorCustomizer.Instance !=3D null) { @@ -1122,7 +1298,7 @@ namespace TianoCore.EdkRepoInstaller } =20 // - // Step 5 - Delete Programs and Feature uninstall link + // Step 6 - Delete Programs and Feature uninstall link // RegistryKey hklm =3D RegistryKey.OpenBaseKey(RegistryHive.Loca= lMachine, RegistryView.Registry64); RegistryKey winUninstallRegistryKey =3D hklm.OpenSubKey(@"SOFT= WARE\Microsoft\Windows\CurrentVersion\Uninstall", true); diff --git a/edkrepo_installer/EdkRepoInstaller/InstallerStrings.cs b/edkre= po_installer/EdkRepoInstaller/InstallerStrings.cs index 6aa90ee..1542641 100644 --- a/edkrepo_installer/EdkRepoInstaller/InstallerStrings.cs +++ b/edkrepo_installer/EdkRepoInstaller/InstallerStrings.cs @@ -2,7 +2,7 @@ InstallerStrings.cs =20 @copyright - Copyright 2016 - 2019 Intel Corporation. All rights reserved.
+ Copyright 2016 - 2020 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Specification Reference: @@ -43,7 +43,7 @@ namespace TianoCore.EdkRepoInstaller } =20 public static string EdkrepoPackageName - {=20 + { get { return "edkrepo"; @@ -113,6 +113,46 @@ namespace TianoCore.EdkRepoInstaller } } =20 + public static string EdkrepoPrompt + { + get + { + return "win_edkrepo_prompt.sh"; + } + } + + public static string EdkrepoCompletion + { + get + { + return "edkrepo_completions.sh"; + } + } + + public static string BashrcEdkrepoPromptCommentPattern + { + get + { + return @"#\s+Install\s+EdkRepo\s+command\s+completions"; + } + } + + public static string BashrcEdkrepoPromptCallPattern + { + get + { + return @"shopt\s+-q\s+login_shell\s+\|\|\s+\.\s+/etc/profi= le\.d/win_edkrepo_prompt\.sh"; + } + } + + public static string BashrcEdkRepoPromptCall + { + get + { + return "\n\n# Install EdkRepo command completions\nshopt -= q login_shell || . /etc/profile.d/win_edkrepo_prompt.sh"; + } + } + public static string InstallerName { get diff --git a/edkrepo_installer/Vendor/win_edkrepo_prompt.sh b/edkrepo_insta= ller/Vendor/win_edkrepo_prompt.sh new file mode 100644 index 0000000..5404175 --- /dev/null +++ b/edkrepo_installer/Vendor/win_edkrepo_prompt.sh @@ -0,0 +1,60 @@ +## @file win_edkrepo_prompt.sh +# Note: For use on Git for Windows/MSYS2 ONLY. +# UNIX version is in install.py +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +# Add EdkRepo command completions +[[ -r "/etc/profile.d/edkrepo_completions.sh" ]] && . "/etc/profile.d/edkr= epo_completions.sh" + +# Add EdkRepo to the prompt +ps1len=3D"${#PS1}" +let "pos38 =3D ps1len - 38" +let "pos3 =3D ps1len - 3" +let "pos2 =3D ps1len - 2" +if [ "${PS1:pos38}" =3D=3D '\[\033[36m\]`__git_ps1`\[\033[0m\]\n$ ' ]; then + newps1=3D"${PS1:0:pos38}" + prompt_suffix=3D'\[\033[36m\]`__git_ps1`\[\033[0m\]\n$ ' +elif [ "${PS1:pos3}" =3D=3D "\\$ " ]; then + newps1=3D"${PS1:0:pos3}" + prompt_suffix=3D"\\$ " +elif [ "${PS1:pos3}" =3D=3D " $ " ]; then + newps1=3D"${PS1:0:pos3}" + prompt_suffix=3D" $ " +elif [ "${PS1:pos2}" =3D=3D "$ " ]; then + newps1=3D"${PS1:0:pos2}" + prompt_suffix=3D"$ " +else + newps1=3D"$PS1" + prompt_suffix=3D"" +fi + +if [ -x "$(command -v edkrepo)" ] && [ -x "$(command -v $command_completio= n_edkrepo_file)" ]; then + newps1=3D"$newps1\[\033[32m\]\$current_edkrepo_combo\[\033[00m\]" + current_edkrepo_combo=3D$(command_completion_edkrepo current-combo) + + # Determining the current Edkrepo combo requires invoking Python and par= sing + # manifest XML, which is a relatively expensive operation to do every ti= me + # the user presses . + # As a performance optimization, only do this if the present working dir= ectory + # changed + if [[ ! -z ${PROMPT_COMMAND+x} ]] && [[ "$PROMPT_COMMAND" !=3D "edkrepo_= combo_chpwd" ]]; then + old_prompt_command=3D$PROMPT_COMMAND + fi + old_pwd=3D$(pwd) + edkrepo_combo_chpwd() { + if [[ "$(pwd)" !=3D "$old_pwd" ]]; then + old_pwd=3D$(pwd) + current_edkrepo_combo=3D$(command_completion_edkrepo current-combo) + fi + if [[ ! -z ${PROMPT_COMMAND+x} ]]; then + eval $old_prompt_command + fi + } + PROMPT_COMMAND=3Dedkrepo_combo_chpwd +fi + +PS1=3D"$newps1$prompt_suffix" +MSYS2_PS1=3D"$PS1" # for detection by MSYS2 SDK's bash.basrc --=20 2.26.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#56962): https://edk2.groups.io/g/devel/message/56962 Mute This Topic: https://groups.io/mt/72761909/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-