From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web11.7887.1585950950086846618 for ; Fri, 03 Apr 2020 14:55:50 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=eRN6PQm4; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: ashley.e.desimone@intel.com) IronPort-SDR: EAA8tXDrCOJNvUJiPcL0PTh4fPFhg8T1/y+E85KLJ3OPT7DbdJ4ZBx911Mz5WDcIyYjFCIG46u oqafMMMmgsAA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Apr 2020 14:55:49 -0700 IronPort-SDR: it2yKQJEqUNW0w1XDeRrCxqIua8iVRjm9VyQeuc5eYZkv2Ku4F9drzvmrU+TEAJIeGKfnui1Db 3L3P+cRGyl/g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,341,1580803200"; d="scan'208";a="250294707" Received: from orsmsx105.amr.corp.intel.com ([10.22.225.132]) by orsmga003.jf.intel.com with ESMTP; 03 Apr 2020 14:55:49 -0700 Received: from orsmsx153.amr.corp.intel.com (10.22.226.247) by ORSMSX105.amr.corp.intel.com (10.22.225.132) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 3 Apr 2020 14:55:48 -0700 Received: from ORSEDG001.ED.cps.intel.com (10.7.248.4) by ORSMSX153.amr.corp.intel.com (10.22.226.247) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 3 Apr 2020 14:55:48 -0700 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.103) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 3 Apr 2020 14:55:48 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ihFD4RERbDiReFPj3h2QYqBEgY1T8oMMp8oqZNp1eLEwr/x6mIv+/NuqNWg9SxTOlFwKuXehCt4DQJXle8rfBRn5lrLvzGWuqN3bITpdA5ba037D7lVkauseeXvT5sA1jsPJus2uplfHIR+EU6VBW2nU5+17nK/B+YHDMp0nEZu2hfORiSYCi7p4aRkgDB7hU4lpUycaypuUXpfQ+GcRsInetejsiHJxbr/edsKIXhbqaJ6MOX/K8gX6iihCfTCt8vGG7QNnQln5OsCyVbPHAbh/fGwCbuiVbZmox9wmzqlUyfcuIRfeXW23vY68gRMGO3M5fnYfWadJyvlZZKM7Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=S9GHgfU5SLWr9e7cKQfjYjFsa4KNdu0wvDlcW4LTVHk=; b=gzwyb0DIupZKb1xREJ17KL6SQuXLfH8UL5gvlqXJoUD9jqveEal7dQqHLxFS+xJSxCnGfcfqjYTy33nSWZooCPYxd8LOos5x0NSejX3mueWdGJeO/XEKITUx4/XIGCk221Bmxk3e0b+gU1+Kfs/h+6+w0zxHegCaBD/UYxNLcRLu1wwsZFY4ZDGuvdkRLLMSzSdkLeeLqCBz+rsbaZH2YWE6Y/f5woR0lor5QA349a0WiUeuYQxvQUX4gUyN5Ky+Dox9ntiwDy5F//zfMeOzK2ZPC/TgCoMDGICvdrShosJAJCT93CTv7ec0x48k3PJjNejvDbE5JWZhPFS8oGC8vg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=S9GHgfU5SLWr9e7cKQfjYjFsa4KNdu0wvDlcW4LTVHk=; b=eRN6PQm4mUSm3+7V7P+aWnVple18pMpAlVQsLM+gY6SUvbHh3yFhywumuglOcaSX/5iGW5Pnw1H/esR8HqGW7LU9YCgvujVwimYSsiEYswd/Q+7hrcI7GbGXF9Ko51xGsft5AWmPr65T16t8wtKe0b/pdY4EbTB59vUL15bUEnI= Received: from DM6PR11MB3628.namprd11.prod.outlook.com (2603:10b6:5:144::25) by DM6PR11MB3578.namprd11.prod.outlook.com (2603:10b6:5:143::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2878.16; Fri, 3 Apr 2020 21:55:46 +0000 Received: from DM6PR11MB3628.namprd11.prod.outlook.com ([fe80::5904:e7d9:f64d:9a7e]) by DM6PR11MB3628.namprd11.prod.outlook.com ([fe80::5904:e7d9:f64d:9a7e%3]) with mapi id 15.20.2878.014; Fri, 3 Apr 2020 21:55:46 +0000 From: "Ashley E Desimone" To: "Desimone, Nathaniel L" , "devel@edk2.groups.io" CC: "Pandya, Puja" , "Bjorge, Erik C" , "Agyeman, Prince" , "Bret Barkelew" , Philippe Mathieu-Daude Subject: Re: [edk2-staging/EdkRepo] [PATCH V1 3/3] EdkRepo: Add command completion setup to Windows installer Thread-Topic: [edk2-staging/EdkRepo] [PATCH V1 3/3] EdkRepo: Add command completion setup to Windows installer Thread-Index: AQHWCHXfr/1fxxaKhUmem1S1nykpl6hn9Dsw Date: Fri, 3 Apr 2020 21:55:46 +0000 Message-ID: References: <20200401223452.4805-1-nathaniel.l.desimone@intel.com> <20200401223452.4805-4-nathaniel.l.desimone@intel.com> In-Reply-To: <20200401223452.4805-4-nathaniel.l.desimone@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.2.0.6 dlp-reaction: no-action dlp-product: dlpe-windows authentication-results: spf=none (sender IP is ) smtp.mailfrom=ashley.e.desimone@intel.com; x-originating-ip: [134.134.136.213] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c6944daf-df90-478c-5bde-08d7d819c3c7 x-ms-traffictypediagnostic: DM6PR11MB3578: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2089; x-forefront-prvs: 0362BF9FDB x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM6PR11MB3628.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(10019020)(366004)(39860400002)(136003)(376002)(346002)(396003)(54906003)(478600001)(45080400002)(2906002)(30864003)(26005)(8936002)(86362001)(186003)(8676002)(81156014)(81166006)(71200400001)(76116006)(66946007)(6506007)(110136005)(53546011)(316002)(4326008)(66446008)(33656002)(64756008)(66556008)(66476007)(7696005)(5660300002)(9686003)(55016002)(52536014)(579004)(414714003)(473944003)(460985005);DIR:OUT;SFP:1102; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: tZdAp1oK8R9f09MPUj6Ke/ZL4itnAGQuE3+XO4KUFAq1ed7rEg7TQ1tMgNOriAkGtfNeO0bi8GmD+mxAeIiz+kwHYxAB5e3rynhqBdotJXOJLStdq0S/GPlk3ZFlgghP6cPhIYt5Pv94ut6BLBj1HiS7Ji+4G71iBtCnN24QvWQUEE4EyImbbujQEGWTuhqBXFZB4p604HZanLzKORbH9jDGUCjOhYKFvXKuwvGR4VIyCx6rvjrFwizg/P+PSRfKrk7wBzs7woZhD6EMBsV/2Vwt191QISE4LTCZFENsfKWfSD4QGChG51MfPWTD+/GXvvGjGhTj3ypnmwRGZphRtgAwZtY2xgMS91PXsIhkjswzEWCxpEYcMA34Yff1XPS38BsiWULJAxisojwRoLiwpcaeSvMgd6GImDCik5wCPAoCgkDxN6F7DkWzhAIPz++eBy6T7aZNzHpY1+WgLxswFIB/yIcyAMZWqzhSw8CCnDtVul1b/soKgF1lu0UqKbiWerXRrUaSVQWTallaFBsx9rXzX4lBqvbHii/Vg/SU+iM= x-ms-exchange-antispam-messagedata: VepoIGgOJlxWuTfkjMeS/to3m0k1e+W28NYGbkfk8mGdF112oa6zZ16YMiXhsIRJATRCSWswmMgrLjvqmK7xEXwFJKzP1tWojeJy5c3TTBBsor7aCr/8dYxvvrduQWApcLXDW/KETp3zElQCf86n5w== MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: c6944daf-df90-478c-5bde-08d7d819c3c7 X-MS-Exchange-CrossTenant-originalarrivaltime: 03 Apr 2020 21:55:46.5209 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: oMf7qd1jae4B8+wTqNQnIQHdKlugk5qDX0axcRPNql7bdBGjFI/iwZRcSwYQGploSYBMGinPM3N7AaJmAULipACg3w6iStW7TD2K1lWvKIo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR11MB3578 Return-Path: ashley.e.desimone@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Ashley DeSimone -----Original Message----- From: Desimone, Nathaniel L =20 Sent: Wednesday, April 1, 2020 3:35 PM To: devel@edk2.groups.io Cc: Desimone, Ashley E ; Pandya, Puja ; Bjorge, Erik C ; Agyeman, Prince = ; Bret Barkelew ; Ph= ilippe Mathieu-Daude Subject: [edk2-staging/EdkRepo] [PATCH V1 3/3] EdkRepo: Add command complet= ion setup to Windows installer Add configuration of command completion scripts to the Windows installer. T= his enables edkrepo command completions to work "out of box" on Git for Win= dows by adding the edkrepo command completions scripts to the Git for Windo= ws /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 ed= krepo_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.Securi= ty.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 @@ namespac= e 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>=20 + p.Item2).Contains(Obsolete)) { 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=20 + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windo + ws), InstallerStrings.EdkrepoCliExecutable); 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=20 + Path.Combine(Path.GetDirectoryName(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=20 + completion..."); + + //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}",=20 + InstallerStrings.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}",=20 + InstallerStrings.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 @@ na= mespace 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=20 + 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/edkre= po_installer/EdkRepoInstaller/InstallerStrings.cs b/edkrepo_installer/EdkRe= poInstaller/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.
#=20 +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$ ' ]; the= n + 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=20 +$command_completion_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=20 +parsing + # manifest XML, which is a relatively expensive operation to do every=20 +time + # the user presses . + # As a performance optimization, only do this if the present working=20 +directory + # 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 -- 2.24.0.windows.2