public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Nate DeSimone" <nathaniel.l.desimone@intel.com>
To: devel@edk2.groups.io
Cc: Ashley DeSimone <ashley.e.desimone@intel.com>,
	Puja Pandya <puja.pandya@intel.com>,
	Erik Bjorge <erik.c.bjorge@intel.com>,
	Prince Agyeman <prince.agyeman@intel.com>,
	Bret Barkelew <Bret.Barkelew@microsoft.com>,
	Philippe Mathieu-Daude <philmd@redhat.com>
Subject: [edk2-staging/EdkRepo] [PATCH V1 3/3] EdkRepo: Add command completion setup to Windows installer
Date: Wed,  1 Apr 2020 15:34:52 -0700	[thread overview]
Message-ID: <20200401223452.4805-4-nathaniel.l.desimone@intel.com> (raw)
In-Reply-To: <20200401223452.4805-1-nathaniel.l.desimone@intel.com>

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 <ashley.e.desimone@intel.com>
Cc: Puja Pandya <puja.pandya@intel.com>
Cc: Erik Bjorge <erik.c.bjorge@intel.com>
Cc: Prince Agyeman <prince.agyeman@intel.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Philippe Mathieu-Daude <philmd@redhat.com>
Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
 .../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;
 
 namespace TianoCore.EdkRepoInstaller
@@ -611,7 +612,7 @@ namespace TianoCore.EdkRepoInstaller
             SilentProcess process = SilentProcess.StartConsoleProcessSilently(GitPath, "--version", dataCapture.DataReceivedHandler);
             process.WaitForExit();
             PythonVersion gitVersion = new PythonVersion(dataCapture.GetData().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 Git.", gitVersion));
                 ReportComplete(false, false);
@@ -624,7 +625,7 @@ namespace TianoCore.EdkRepoInstaller
             List<Tuple<string, PythonVersion>> ExclusivePackages = new List<Tuple<string, PythonVersion>>();
             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 => p.Item2).Contains(Obsolete))
+                if (ExistingEdkRepoPaths.Select(p => p.Item2).Contains(Obsolete))
                 {
                     foreach (string ExistingEdkrepoPythonPath in ExistingEdkRepoPaths.Where(p => p.Item2 == Obsolete).Select(p => p.Item1))
                     {
                         string UninstallerPath = Path.Combine(Path.GetDirectoryName(ExistingEdkrepoPythonPath), "Lib", "site-packages");
                         UninstallerPath = Path.Combine(UninstallerPath, Path.GetFileName(WindowsHelpers.GetApplicationPath()));
-                        if(File.Exists(UninstallerPath))
+                        if (File.Exists(UninstallerPath))
                         {
                             InstallLogger.Log(string.Format("Uninstalling {0}...", UninstallerPath));
                             string UninstallString = string.Format("\"{0}\" /Uninstall /Passive", UninstallerPath);
@@ -788,14 +789,15 @@ namespace TianoCore.EdkRepoInstaller
             //
             // Step 10 - Setup symlink to edkrepo and bash script to launch edkrepo from git bash
             //
+            string EdkrepoSymlinkPath = null;
             if (!string.IsNullOrEmpty(EdkrepoPythonPath))
             {
                 string EdkrepoScriptPath = Path.Combine(Path.GetDirectoryName(EdkrepoPythonPath), "Scripts", InstallerStrings.EdkrepoCliExecutable);
-                string EdkrepoSymlinkPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliExecutable);
+                EdkrepoSymlinkPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliExecutable);
                 if (File.Exists(EdkrepoScriptPath))
                 {
                     bool CreateSymlink = 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 edkrepo.exe...");
                         WindowsHelpers.CreateSymbolicLink(EdkrepoSymlinkPath, EdkrepoScriptPath, WindowsHelpers.SYMBOLIC_LINK_FLAG.File);
                     }
                     string GitBashBinPath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(GitPath)), "usr", "bin");
-                    if(Directory.Exists(GitBashBinPath))
+                    if (Directory.Exists(GitBashBinPath))
                     {
                         InstallLogger.Log("Creating edkrepo launcher in Git Bash...");
                         string EdkrepoBashScriptPath = Path.Combine(GitBashBinPath, 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 data directory
             //
             string EdkrepoCfg = Path.Combine(Path.GetDirectoryName(WindowsHelpers.GetApplicationPath()), InstallerStrings.EdkrepoCfg);
-            if(File.Exists(EdkrepoCfg))
+            if (File.Exists(EdkrepoCfg))
             {
                 CreateEdkrepoGlobalDataDirectory();
                 string EdkrepoCfgDir = Path.Combine(WindowsHelpers.GetAllUsersAppDataPath(), InstallerStrings.EdkrepoGlobalDirectoryName);
@@ -853,7 +855,7 @@ namespace TianoCore.EdkRepoInstaller
                 {
                     string NewCfgHash = ComputeSha256(ReadFile(EdkrepoCfg));
                     string OldCfgHash = ComputeSha256(ReadFile(EdkrepoCfgTarget));
-                    if(NewCfgHash != OldCfgHash)
+                    if (NewCfgHash != OldCfgHash)
                     {
                         if (GetPreviousEdkrepoCfgFileHashes().Contains(OldCfgHash))
                         {
@@ -908,7 +910,119 @@ namespace TianoCore.EdkRepoInstaller
             }
 
             //
-            // Step 13 - Create Programs and Features uninstall links
+            // Step 13 - Copy win_edkrepo_prompt.sh and generate edkrepo_completions.sh
+            //
+            string edkrepoPromptSource = Path.Combine(Path.GetDirectoryName(WindowsHelpers.GetApplicationPath()), InstallerStrings.EdkrepoPrompt);
+
+            if (File.Exists(edkrepoPromptSource) && !string.IsNullOrEmpty(EdkrepoSymlinkPath))
+            {
+                string gitBashEtcPath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(GitPath)), "etc");
+                string gitBashEtcProfileDPath = Path.Combine(gitBashEtcPath, "profile.d");
+                if (Directory.Exists(gitBashEtcPath) && Directory.Exists(gitBashEtcProfileDPath))
+                {
+                    InstallLogger.Log("Installing EdkRepo command completion...");
+
+                    //Copy win_edkrepo_prompt.sh
+                    string edkrepoPromptDest = Path.Combine(gitBashEtcProfileDPath, InstallerStrings.EdkrepoPrompt);
+                    if (File.Exists(edkrepoPromptDest))
+                    {
+                        File.Delete(edkrepoPromptDest);
+                    }
+                    File.Copy(edkrepoPromptSource, edkrepoPromptDest);
+                    DirectoryInfo info = new DirectoryInfo(edkrepoPromptDest);
+                    DirectorySecurity security = info.GetAccessControl();
+                    security.AddAccessRule(new FileSystemAccessRule(
+                        new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
+                        FileSystemRights.FullControl,
+                        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
+                        PropagationFlags.NoPropagateInherit,
+                        AccessControlType.Allow
+                        ));
+                    info.SetAccessControl(security);
+                    InstallLogger.Log(string.Format("Copied {0}", InstallerStrings.EdkrepoPrompt));
+
+                    //Generate edkrepo_completions.sh
+                    string edkrepoCompletionDest = Path.Combine(gitBashEtcProfileDPath, InstallerStrings.EdkrepoCompletion);
+                    if (File.Exists(edkrepoCompletionDest))
+                    {
+                        File.Delete(edkrepoCompletionDest);
+                    }
+                    dataCapture = new SilentProcess.StdoutDataCapture();
+                    process = 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 != 0)
+                    {
+                        throw new InvalidOperationException(string.Format("generate-command-completion-script failed with status {0}", process.ExitCode));
+                    }
+                    if (!File.Exists(edkrepoCompletionDest))
+                    {
+                        throw new InvalidOperationException(string.Format("generate-command-completion-script did not create {0}", InstallerStrings.EdkrepoCompletion));
+                    }
+                    info = new DirectoryInfo(edkrepoCompletionDest);
+                    security = info.GetAccessControl();
+                    security.AddAccessRule(new FileSystemAccessRule(
+                        new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
+                        FileSystemRights.FullControl,
+                        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
+                        PropagationFlags.NoPropagateInherit,
+                        AccessControlType.Allow
+                        ));
+                    info.SetAccessControl(security);
+                    InstallLogger.Log(string.Format("Generated {0}", InstallerStrings.EdkrepoCompletion));
+
+                    //Call win_edkrepo_prompt.sh from bash.bashrc so edkrepo completions are available for "interactive non-login" bash shells
+                    string bashrcPath = Path.Combine(gitBashEtcPath, "bash.bashrc");
+                    if (File.Exists(bashrcPath))
+                    {
+                        string bashrc = Encoding.UTF8.GetString(ReadFile(bashrcPath));
+                        Match match = Regex.Match(bashrc, InstallerStrings.BashrcEdkrepoPromptCallPattern);
+                        if (match.Success)
+                        {
+                            InstallLogger.Log("EdkRepo prompt is already in bash.bashrc");
+                        }
+                        else
+                        {
+                            bashrc = string.Format("{0}{1}", bashrc, InstallerStrings.BashrcEdkRepoPromptCall);
+                            using (BinaryWriter writer = new BinaryWriter(File.Open(bashrcPath, FileMode.Truncate, FileAccess.Write)))
+                            {
+                                string sanitized = bashrc.Replace("\r\n", "\n");
+                                writer.Write(Encoding.UTF8.GetBytes(sanitized));
+                            }
+                            InstallLogger.Log("EdkRepo prompt added to bash.bashrc");
+                        }
+                    }
+                    else
+                    {
+                        InstallLogger.Log(string.Format("{0} not found", bashrcPath));
+                    }
+                }
+                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", InstallerStrings.EdkrepoPrompt));
+                }
+            }
+
+            //
+            // Step 14 - Create Programs and Features uninstall links
             //
             if (!string.IsNullOrEmpty(EdkrepoPythonPath))
             {
@@ -977,7 +1091,7 @@ namespace TianoCore.EdkRepoInstaller
             string GitPath = PythonOperations.GetFullPath("git.exe");
 
             //
-            // Step 2 - Delete symlink to edkrepo and bash script to launch it from git bash
+            // Step 2 - Delete symlink to edkrepo
             //
             string EdkrepoSymlinkPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), InstallerStrings.EdkrepoCliExecutable);
             if (File.Exists(EdkrepoSymlinkPath))
@@ -1003,7 +1117,11 @@ namespace TianoCore.EdkRepoInstaller
                     File.Delete(EdkrepoSymlinkPath);
                 }
             }
-            if (GitPath != null)
+
+            //
+            // Step 3 - Delete scripts to launch edkrepo and Python from git bash, and edkrepo command completion scripts
+            //
+            if (!string.IsNullOrWhiteSpace(GitPath))
             {
                 string GitBashBinPath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(GitPath)), "usr", "bin");
                 if (Directory.Exists(GitBashBinPath))
@@ -1057,10 +1175,68 @@ namespace TianoCore.EdkRepoInstaller
                         File.Delete(EdkrepoPython2ScriptPath);
                     }
                 }
+                string gitBashEtcPath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(GitPath)), "etc");
+                string gitBashEtcProfileDPath = Path.Combine(gitBashEtcPath, "profile.d");
+                if (Directory.Exists(gitBashEtcPath) && Directory.Exists(gitBashEtcProfileDPath))
+                {
+                    string edkrepoPromptDest = Path.Combine(gitBashEtcProfileDPath, 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 = Path.Combine(gitBashEtcProfileDPath, 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 = Path.Combine(gitBashEtcPath, "bash.bashrc");
+                    if (File.Exists(bashrcPath))
+                    {
+                        string original_bashrc = Encoding.UTF8.GetString(ReadFile(bashrcPath));
+
+                        string new_bashrc = Regex.Replace(original_bashrc, InstallerStrings.BashrcEdkrepoPromptCommentPattern, "");
+                        new_bashrc = Regex.Replace(new_bashrc, InstallerStrings.BashrcEdkrepoPromptCallPattern, "");
+                        if (new_bashrc == original_bashrc)
+                        {
+                            InstallLogger.Log("EdkRepo not found in bash.bashrc");
+                        }
+                        else
+                        {
+                            new_bashrc = new_bashrc.TrimEnd();
+                            using (BinaryWriter writer = new BinaryWriter(File.Open(bashrcPath, FileMode.Truncate, FileAccess.Write)))
+                            {
+                                string sanitized = new_bashrc.Replace("\r\n", "\n");
+                                writer.Write(Encoding.UTF8.GetBytes(sanitized));
+                            }
+                            InstallLogger.Log("EdkRepo prompt removed from bash.bashrc");
+                        }
+                    }
+                    else
+                    {
+                        InstallLogger.Log(string.Format("{0} not found", bashrcPath));
+                    }
+                }
             }
 
             //
-            // Step 3 - Uninstall any instances of edkrepo
+            // Step 4 - Uninstall any instances of edkrepo
             //
             IEnumerable<string> PackagesToUninstall = GetPythonWheelsToUninstall();
             InstallLogger.Log("Determining currently installed Python packages...");
@@ -1109,7 +1285,7 @@ namespace TianoCore.EdkRepoInstaller
             }
 
             //
-            // Step 4 - Invoke the Finish Uninstall Event
+            // Step 5 - Invoke the Finish Uninstall Event
             //
             if (VendorCustomizer.Instance != null)
             {
@@ -1122,7 +1298,7 @@ namespace TianoCore.EdkRepoInstaller
             }
 
             //
-            // Step 5 - Delete Programs and Feature uninstall link
+            // Step 6 - Delete Programs and Feature uninstall link
             //
             RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
             RegistryKey winUninstallRegistryKey = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", true);
diff --git a/edkrepo_installer/EdkRepoInstaller/InstallerStrings.cs b/edkrepo_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
 
 @copyright
-  Copyright 2016 - 2019 Intel Corporation. All rights reserved.<BR>
+  Copyright 2016 - 2020 Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 @par Specification Reference:
@@ -43,7 +43,7 @@ namespace TianoCore.EdkRepoInstaller
         }
 
         public static string EdkrepoPackageName
-        { 
+        {
             get
             {
                 return "edkrepo";
@@ -113,6 +113,46 @@ namespace TianoCore.EdkRepoInstaller
             }
         }
 
+        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/profile\.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_installer/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.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+# Add EdkRepo command completions
+[[ -r "/etc/profile.d/edkrepo_completions.sh" ]] && . "/etc/profile.d/edkrepo_completions.sh"
+
+# Add EdkRepo to the prompt
+ps1len="${#PS1}"
+let "pos38 = ps1len - 38"
+let "pos3 = ps1len - 3"
+let "pos2 = ps1len - 2"
+if [ "${PS1:pos38}" == '\[\033[36m\]`__git_ps1`\[\033[0m\]\n$ ' ]; then
+  newps1="${PS1:0:pos38}"
+  prompt_suffix='\[\033[36m\]`__git_ps1`\[\033[0m\]\n$ '
+elif [ "${PS1:pos3}" == "\\$ " ]; then
+  newps1="${PS1:0:pos3}"
+  prompt_suffix="\\$ "
+elif [ "${PS1:pos3}" == " $ " ]; then
+  newps1="${PS1:0:pos3}"
+  prompt_suffix=" $ "
+elif [ "${PS1:pos2}" == "$ " ]; then
+  newps1="${PS1:0:pos2}"
+  prompt_suffix="$ "
+else
+  newps1="$PS1"
+  prompt_suffix=""
+fi
+
+if [ -x "$(command -v edkrepo)" ] && [ -x "$(command -v $command_completion_edkrepo_file)" ]; then
+  newps1="$newps1\[\033[32m\]\$current_edkrepo_combo\[\033[00m\]"
+  current_edkrepo_combo=$(command_completion_edkrepo current-combo)
+
+  # Determining the current Edkrepo combo requires invoking Python and parsing
+  # manifest XML, which is a relatively expensive operation to do every time
+  # the user presses <Enter>.
+  # As a performance optimization, only do this if the present working directory
+  # changed
+  if [[ ! -z ${PROMPT_COMMAND+x} ]] && [[ "$PROMPT_COMMAND" != "edkrepo_combo_chpwd" ]]; then
+    old_prompt_command=$PROMPT_COMMAND
+  fi
+  old_pwd=$(pwd)
+  edkrepo_combo_chpwd() {
+      if [[ "$(pwd)" != "$old_pwd" ]]; then
+        old_pwd=$(pwd)
+        current_edkrepo_combo=$(command_completion_edkrepo current-combo)
+      fi
+      if [[ ! -z ${PROMPT_COMMAND+x} ]]; then
+        eval $old_prompt_command
+      fi
+  }
+  PROMPT_COMMAND=edkrepo_combo_chpwd
+fi
+
+PS1="$newps1$prompt_suffix"
+MSYS2_PS1="$PS1"  # for detection by MSYS2 SDK's bash.basrc
-- 
2.24.0.windows.2


  parent reply	other threads:[~2020-04-01 22:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-01 22:34 [edk2-staging/EdkRepo] [PATCH V1 0/3] EdkRepo: Command completion in bash/zsh Nate DeSimone
2020-04-01 22:34 ` [edk2-staging/EdkRepo] [PATCH V1 1/3] EdkRepo: Generate command completion scripts Nate DeSimone
2020-04-03 21:33   ` Ashley E Desimone
2020-04-01 22:34 ` [edk2-staging/EdkRepo] [PATCH V1 2/3] EdkRepo: Add command completion setup to install.py Nate DeSimone
2020-04-03 21:51   ` Ashley E Desimone
2020-04-01 22:34 ` Nate DeSimone [this message]
2020-04-03 21:55   ` [edk2-staging/EdkRepo] [PATCH V1 3/3] EdkRepo: Add command completion setup to Windows installer Ashley E Desimone

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200401223452.4805-4-nathaniel.l.desimone@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox