<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:DengXian;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@DengXian";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1995185040;
        mso-list-type:hybrid;
        mso-list-template-ids:1335424336 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;
        mso-bidi-font-family:Symbol;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;
        mso-bidi-font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;
        mso-bidi-font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;
        mso-bidi-font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;
        mso-bidi-font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;
        mso-bidi-font-family:Wingdings;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Seems fair. Thanks for the head up. <span style="font-family:"Segoe UI Emoji",sans-serif">
😊</span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- Bret</p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Nate DeSimone via Groups.Io <nathaniel.l.desimone=intel.com@groups.io><br>
<b>Sent:</b> Saturday, March 21, 2020 2:56:20 PM<br>
<b>To:</b> Bret Barkelew <Bret.Barkelew@microsoft.com>; Desimone, Ashley E <ashley.e.desimone@intel.com>; devel@edk2.groups.io <devel@edk2.groups.io><br>
<b>Cc:</b> Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com><br>
<b>Subject:</b> [EXTERNAL] Re: [edk2-devel] [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</font>
<div> </div>
</div>
<style>
<!--
@font-face
        {font-family:Wingdings}
@font-face
        {font-family:"Cambria Math"}
@font-face
        {font-family:Calibri}
p.x_MsoNormal, li.x_MsoNormal, div.x_MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
a:link, span.x_MsoHyperlink
        {color:blue;
        text-decoration:underline}
a:visited, span.x_MsoHyperlinkFollowed
        {color:#954F72;
        text-decoration:underline}
p.x_MsoListParagraph, li.x_MsoListParagraph, div.x_MsoListParagraph
        {margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
p.x_msonormal0, li.x_msonormal0, div.x_msonormal0
        {margin-right:0in;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
span.x_EmailStyle20
        {font-family:"Calibri",sans-serif;
        color:windowtext}
span.x_EmailStyle21
        {font-family:"Calibri",sans-serif;
        color:windowtext}
.x_MsoChpDefault
        {font-size:10.0pt}
@page WordSection1
        {margin:1.0in 1.0in 1.0in 1.0in}
div.x_WordSection1
        {}
ol
        {margin-bottom:0in}
ul
        {margin-bottom:0in}
-->
</style>
<div lang="EN-US" link="blue" vlink="#954F72">
<div class="x_WordSection1">
<p class="x_MsoNormal">I’m reading between the lines a little bit… but it seems like your response amounts to:</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Acked-by: Bret Barkelew <Bret.Barkelew@microsoft.com></p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Which I added to the commit: <a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-staging%2Fcommit%2F79ba022e&data=02%7C01%7Cbret.barkelew%40microsoft.com%7C7844aa42c0d54d01cec208d7cde2b278%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637204245854647261&sdata=yteA9kEe%2FhNAWjDNYorj9sviOfcinyr%2BkZGgYHGWKwM%3D&reserved=0" originalsrc="https://github.com/tianocore/edk2-staging/commit/79ba022e" shash="OiV/rsRBCUiZSg0O59EfzNb6Wvk8Q9fSLbgHXzfgEwuShXnTEhurJ4UNAwRM6KTprJvIZOnJ+dLp0InwLqNM39auUOD7B9PHG8BtxfCALzi6FIN5viCN7eV3m92DjDvqFzvdRTJ+2WzOzFSowqV9uS2qCpPF13WQGMUBj04drO0=">
https://github.com/tianocore/edk2-staging/commit/79ba022e</a></p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Hope that’s cool <span style="font-family:"Segoe UI Emoji",sans-serif">
😊</span>.</p>
<p class="x_MsoNormal"> </p>
<div>
<div style="border:none; border-top:solid #E1E1E1 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><a name="x______replyseparator"></a><b>From:</b> Bret Barkelew <Bret.Barkelew@microsoft.com>
<br>
<b>Sent:</b> Friday, March 20, 2020 3:07 PM<br>
<b>To:</b> Desimone, Ashley E <ashley.e.desimone@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; devel@edk2.groups.io<br>
<b>Cc:</b> Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com><br>
<b>Subject:</b> RE: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</p>
</div>
</div>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Spiffy. Agreed; thanks for the background.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">My only other concern would be the function name and if some future developer thought that was permission to add other modules to it.</p>
<p class="x_MsoNormal">Then again, maybe I’m just bikeshedding. Feel free to ignore.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">- Bret</p>
<p class="x_MsoNormal"> </p>
<div style="border:none; border-top:solid #E1E1E1 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><b>From: </b><a href="mailto:ashley.e.desimone@intel.com">Desimone, Ashley E</a><br>
<b>Sent: </b>Friday, March 20, 2020 1:21 PM<br>
<b>To: </b><a href="mailto:nathaniel.l.desimone@intel.com">Desimone, Nathaniel L</a>;
<a href="mailto:Bret.Barkelew@microsoft.com">Bret Barkelew</a>; <a href="mailto:devel@edk2.groups.io">
devel@edk2.groups.io</a><br>
<b>Cc: </b><a href="mailto:puja.pandya@intel.com">Pandya, Puja</a>; <a href="mailto:erik.c.bjorge@intel.com">
Bjorge, Erik C</a><br>
<b>Subject: </b>[EXTERNAL] RE: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</p>
</div>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Thanks for the explanation.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Reviewed-by: Ashley DeSimone <<a href="mailto:ashley.e.deismone@intel.com">ashley.e.deismone@intel.com</a>></p>
<p class="x_MsoNormal"> </p>
<div>
<div style="border:none; border-top:solid #E1E1E1 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><b>From:</b> Desimone, Nathaniel L <<a href="mailto:nathaniel.l.desimone@intel.com">nathaniel.l.desimone@intel.com</a>>
<br>
<b>Sent:</b> Thursday, March 19, 2020 2:01 PM<br>
<b>To:</b> Bret Barkelew <<a href="mailto:Bret.Barkelew@microsoft.com">Bret.Barkelew@microsoft.com</a>>; Desimone, Ashley E <<a href="mailto:ashley.e.desimone@intel.com">ashley.e.desimone@intel.com</a>>;
<a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
<b>Cc:</b> Pandya, Puja <<a href="mailto:puja.pandya@intel.com">puja.pandya@intel.com</a>>; Bjorge, Erik C <<a href="mailto:erik.c.bjorge@intel.com">erik.c.bjorge@intel.com</a>><br>
<b>Subject:</b> Re: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</p>
</div>
</div>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Hi Bret,</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">I alluded to this a little bit in the cover letter, completely agreed a more detailed explanation is needed.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">There is an odd situation with the way GitPython’s dependencies are evolved over time. Initially, they had the following dependency graph:</p>
<p class="x_MsoNormal"> </p>
<ul type="disc" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">GitPython
<ul type="circle" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">gitdb
<ul type="square" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">smmap</li></ul>
</li></ul>
</li></ul>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">At some point in the past, they decided to make backwards incompatible API changes to gitdb and smmap, so the dependencies where updated as follows:</p>
<p class="x_MsoNormal"> </p>
<ul type="disc" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">GitPython
<ul type="circle" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">gitdb2
<ul type="square" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">smmap2</li></ul>
</li></ul>
</li></ul>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">However, now that Python 2.x is deprecated, any code that was using the old API will need updates anyway. So, the GitPython maintainers decided to go back to the original dependency tree. The issue is, gitdb2 and smmap2 wheels create
 packages in site-packages with the names gitdb and smmap, so installing gitdb2 and gitdb at the same time results in the gitdb folder in site-packages being overwritten. End result pretty crappy, whichever wheel was most recently installed is the one that
 will prevail in site-packages.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">The way the GitPython maintainers addressed this problem is by converting gitdb2 and smmap2 into wheels with no content other than a dependency on gitdb and smmap. So when one does a pip upgrade those packages remain and you get a dependency
 graph that looks like this:</p>
<p class="x_MsoNormal"> </p>
<ul type="disc" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">GitPython
<ul type="circle" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">gitdb2
<ul type="square" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">smmap2</li></ul>
</li></ul>
</li><li class="x_MsoListParagraph" style="margin-left:0in">gitdb2
<ul type="circle" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">gitdb
<ul type="square" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">smmap</li></ul>
</li></ul>
</li><li class="x_MsoListParagraph" style="margin-left:0in">smmap2
<ul type="circle" style="margin-top:0in">
<li class="x_MsoListParagraph" style="margin-left:0in">smmap</li></ul>
</li></ul>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">So, the net result for a regular pip upgrade leaves a fair amount of detritus sitting on the system which would not be present for a new user doing a clean install from pip. Obviously, we can do better than that which is why I’ve automated
 the uninstallation of smmap2 and gitdb2 before proceeding to upgrade GitPython. This also guarantees that the duplicate folder in site-packages situation does not happen at the same time.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">The fact that the GitPython maintainers created this situation in the first place is rather annoying.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Thanks,</p>
<p class="x_MsoNormal">Nate</p>
<p class="x_MsoNormal"> </p>
<div style="border:none; border-top:solid #B5C4DF 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><b><span style="font-size:12.0pt; color:black">From: </span>
</b><span style="font-size:12.0pt; color:black">Bret Barkelew <<a href="mailto:Bret.Barkelew@microsoft.com">Bret.Barkelew@microsoft.com</a>><br>
<b>Date: </b>Thursday, March 19, 2020 at 12:44 PM<br>
<b>To: </b>Ashley E Desimone <<a href="mailto:ashley.e.desimone@intel.com">ashley.e.desimone@intel.com</a>>, "Desimone, Nathaniel L" <<a href="mailto:nathaniel.l.desimone@intel.com">nathaniel.l.desimone@intel.com</a>>, "<a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a>"
 <<a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a>><br>
<b>Cc: </b>"Pandya, Puja" <<a href="mailto:puja.pandya@intel.com">puja.pandya@intel.com</a>>, "Bjorge, Erik C" <<a href="mailto:erik.c.bjorge@intel.com">erik.c.bjorge@intel.com</a>><br>
<b>Subject: </b>RE: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</span></p>
</div>
<div>
<p class="x_MsoNormal"> </p>
</div>
<p class="x_MsoNormal">Naïve question: why isn’t this upgrade handled when pip installs the new wheel? Are the dependencies not matched up correctly? I would think that pip would uninstall the old version on its own.</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">- Bret</p>
<p class="x_MsoNormal"> </p>
<div style="border:none; border-top:solid #E1E1E1 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><b>From: </b><a href="mailto:ashley.e.desimone@intel.com">Desimone, Ashley E</a><br>
<b>Sent: </b>Thursday, March 19, 2020 12:32 PM<br>
<b>To: </b><a href="mailto:nathaniel.l.desimone@intel.com">Desimone, Nathaniel L</a>;
<a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
<b>Cc: </b><a href="mailto:puja.pandya@intel.com">Pandya, Puja</a>; <a href="mailto:erik.c.bjorge@intel.com">
Bjorge, Erik C</a>; <a href="mailto:Bret.Barkelew@microsoft.com">Bret Barkelew</a><br>
<b>Subject: </b>[EXTERNAL] RE: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies</p>
</div>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal" style="margin-bottom:12.0pt">For the following section why are we singling out gitdb2 and smmap2 when deleting obsolete dependencies? Is there an alternative to hardcoding these values?<br>
<br>
+                if (DeleteObsoletePackages)<br>
+                {<br>
+                    //<br>
+                    // Delete obsolete dependencies<br>
+                    //<br>
+                    foreach (string PackageName in new string[] { "smmap2", "gitdb2" })<br>
+                    {<br>
+                        if (InstalledPackages.Where(p => p.Name == PackageName).FirstOrDefault() != null)<br>
+                        {<br>
+                            InstallLogger.Log(string.Format("Uninstalling {0}", PackageName));<br>
+                            PythonOperations.UninstallPythonPackage(PythonPath, PackageName);<br>
+                        }<br>
+                    }<br>
+                }<br>
<br>
Thanks,<br>
Ashley<br>
<br>
-----Original Message-----<br>
From: Desimone, Nathaniel L <<a href="mailto:nathaniel.l.desimone@intel.com">nathaniel.l.desimone@intel.com</a>>
<br>
Sent: Wednesday, March 18, 2020 8:17 PM<br>
To: <a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
Cc: Desimone, Ashley E <<a href="mailto:ashley.e.desimone@intel.com">ashley.e.desimone@intel.com</a>>; Pandya, Puja <<a href="mailto:puja.pandya@intel.com">puja.pandya@intel.com</a>>; Bjorge, Erik C <<a href="mailto:erik.c.bjorge@intel.com">erik.c.bjorge@intel.com</a>>;
 Bret Barkelew <<a href="mailto:Bret.Barkelew@microsoft.com">Bret.Barkelew@microsoft.com</a>><br>
Subject: [PATCH 1/4] EdkRepo: Installer should remove obsolete dependencies<br>
<br>
Cc: Ashley DeSimone <<a href="mailto:ashley.e.desimone@intel.com">ashley.e.desimone@intel.com</a>><br>
Cc: Puja Pandya <<a href="mailto:puja.pandya@intel.com">puja.pandya@intel.com</a>><br>
Cc: Erik Bjorge <<a href="mailto:erik.c.bjorge@intel.com">erik.c.bjorge@intel.com</a>><br>
Cc: Bret Barkelew <<a href="mailto:Bret.Barkelew@microsoft.com">Bret.Barkelew@microsoft.com</a>><br>
Signed-off-by: Nate DeSimone <<a href="mailto:nathaniel.l.desimone@intel.com">nathaniel.l.desimone@intel.com</a>><br>
---<br>
 .../EdkRepoInstaller/InstallWorker.cs         | 30 +++++++++-<br>
 edkrepo_installer/linux-scripts/install.py    | 58 ++++++++++++-------<br>
 2 files changed, 66 insertions(+), 22 deletions(-)<br>
<br>
diff --git a/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs b/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs<br>
index 8d824f2..b44e8fa 100644<br>
--- a/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs<br>
+++ b/edkrepo_installer/EdkRepoInstaller/InstallWorker.cs<br>
@@ -710,6 +710,7 @@ namespace TianoCore.EdkRepoInstaller<br>
                 string PythonPath;<br>
                 bool Has32Bit;<br>
                 bool Has64Bit;<br>
+                bool DeleteObsoletePackages = false;<br>
                 PythonOperations.GetPythonBitness(PyInstance.Version.Major, PyInstance.Version.Minor, out Has32Bit, out Has64Bit);<br>
                 if (Has32Bit && Has64Bit && PyInstance.Architecture == CpuArchitecture.IA32)<br>
                 {<br>
@@ -720,14 +721,39 @@ namespace TianoCore.EdkRepoInstaller<br>
                     PythonPath = PythonOperations.FindPython(PyInstance.Version.Major, PyInstance.Version.Minor, false);<br>
                 }<br>
                 List<PythonPackage> InstalledPackages = PythonOperations.GetInstalledPythonPackages(PythonPath);<br>
-                foreach(PythonWheel Wheel in PyInstance.Wheels)<br>
+                foreach (PythonWheel Wheel in PyInstance.Wheels)<br>
+                {<br>
+                    //If a package is already installed, check if we have a newer version bundled in the installer<br>
+                    //If yes, the package will be upgraded, make sure obsolete packages are uninstalled first<br>
+                    PythonPackage InstalledPackage = InstalledPackages.Where(p => p.Name == Wheel.Package.Name.Replace('_', '-')).FirstOrDefault();<br>
+                    if (InstalledPackage != null && InstalledPackage.Version < Wheel.Package.Version)<br>
+                    {<br>
+                        DeleteObsoletePackages = true;<br>
+                        break;<br>
+                    }<br>
+                }<br>
+                if (DeleteObsoletePackages)<br>
+                {<br>
+                    //<br>
+                    // Delete obsolete dependencies<br>
+                    //<br>
+                    foreach (string PackageName in new string[] { "smmap2", "gitdb2" })<br>
+                    {<br>
+                        if (InstalledPackages.Where(p => p.Name == PackageName).FirstOrDefault() != null)<br>
+                        {<br>
+                            InstallLogger.Log(string.Format("Uninstalling {0}", PackageName));<br>
+                            PythonOperations.UninstallPythonPackage(PythonPath, PackageName);<br>
+                        }<br>
+                    }<br>
+                }<br>
+                foreach (PythonWheel Wheel in PyInstance.Wheels)<br>
                 {<br>
                     //PythonPackage InstalledPackage = (from package in InstalledPackages<br>
                     //                                  where package.Name == Wheel.Package.Name<br>
                     //                                  select package).FirstOrDefault();<br>
                     //If the package is already installed, check if we have a newer version bundled in the installer<br>
                     //If so, upgrade the package<br>
-                    PythonPackage InstalledPackage = InstalledPackages.Where(p => p.Name == Wheel.Package.Name).FirstOrDefault();<br>
+                    PythonPackage InstalledPackage = <br>
+ InstalledPackages.Where(p => p.Name == Wheel.Package.Name.Replace('_', <br>
+ '-')).FirstOrDefault();<br>
                     if (InstalledPackage != null)<br>
                     {<br>
                         if (InstalledPackage.Version < Wheel.Package.Version) diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py<br>
index 0ea486d..b2cdfed 100755<br>
--- a/edkrepo_installer/linux-scripts/install.py<br>
+++ b/edkrepo_installer/linux-scripts/install.py<br>
@@ -3,7 +3,7 @@<br>
 ## @file<br>
 # install.py<br>
 #<br>
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR><br>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights <br>
+reserved.<BR><br>
 # SPDX-License-Identifier: BSD-2-Clause-Patent  #<br>
 <br>
@@ -53,6 +53,26 @@ def get_args():<br>
     parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output')<br>
     return parser.parse_args()<br>
 <br>
+def get_installed_packages(python_command):<br>
+    pip_cmd = [def_python, '-m', 'pip', 'list', '--legacy']<br>
+    try:<br>
+        res = default_run(pip_cmd)<br>
+    except:<br>
+        pip_cmd.pop(-1)<br>
+        try:<br>
+            res = default_run(pip_cmd)<br>
+        except:<br>
+            return ret_val<br>
+    installed_packages = {}<br>
+    for pip_mod in res.stdout.split('\n'):<br>
+        try:<br>
+            name, version = pip_mod.split()<br>
+            version = version.strip().strip('()')<br>
+        except:<br>
+            continue<br>
+        installed_packages[name] = version<br>
+    return installed_packages<br>
+<br>
 def get_required_wheels():<br>
     ret_val = collections.OrderedDict()<br>
     if platform.machine() == 'x86_64':<br>
@@ -79,27 +99,11 @@ def get_required_wheels():<br>
                                                  'version':wheel.attrib['Version'],<br>
                                                  'install':True}<br>
             break<br>
-    pip_cmd = [def_python, '-m', 'pip', 'list', '--legacy']<br>
-    try:<br>
-        res = default_run(pip_cmd)<br>
-    except:<br>
-        pip_cmd.pop(-1)<br>
-        try:<br>
-            res = default_run(pip_cmd)<br>
-        except:<br>
-            return ret_val<br>
-    installed_modules = {}<br>
-    for pip_mod in res.stdout.split('\n'):<br>
-        try:<br>
-            name, version = pip_mod.split()<br>
-            version = version.strip().strip('()')<br>
-        except:<br>
-            continue<br>
-        installed_modules[name] = version<br>
+    installed_packages = get_installed_packages(def_python)<br>
     for name in ret_val:<br>
         #pip doesn't understand the difference between '_' and '-'<br>
-        if name.replace('_','-') in installed_modules:<br>
-            version = installed_modules[name.replace('_','-')]<br>
+        if name.replace('_','-') in installed_packages:<br>
+            version = installed_packages[name.replace('_','-')]<br>
             if _check_version(version, ret_val[name]['version']) >= 0 and not ret_val[name]['uninstall']:<br>
                 ret_val[name]['install'] = False<br>
             else:<br>
@@ -328,16 +332,30 @@ def do_install():<br>
         if not os.path.isdir(whl_src_dir):<br>
             log.info('- Missing wheel file directory')<br>
             return 1<br>
+        updating_edkrepo = False<br>
         for whl_name in wheels_to_install:<br>
             uninstall_whl = wheels_to_install[whl_name]['uninstall']<br>
             whl_name = whl_name.replace('_','-')  #pip doesn't understand the difference between '_' and '-'<br>
             if uninstall_whl:<br>
+                updating_edkrepo = True<br>
                 try:<br>
                     res = default_run([def_python, '-m', 'pip', 'uninstall', '--yes', whl_name])<br>
                 except:<br>
                     log.info('- Failed to uninstall {}'.format(whl_name))<br>
                     return 1<br>
                 log.info('+ Uninstalled {}'.format(whl_name))<br>
+<br>
+        #Delete obsolete dependencies<br>
+        if updating_edkrepo:<br>
+            installed_packages = get_installed_packages(def_python)<br>
+            for whl_name in ['smmap2', 'gitdb2']:<br>
+                if whl_name in installed_packages:<br>
+                    try:<br>
+                        res = default_run([def_python, '-m', 'pip', 'uninstall', '--yes', whl_name])<br>
+                    except:<br>
+                        log.info('- Failed to uninstall {}'.format(whl_name))<br>
+                        return 1<br>
+                    log.info('+ Uninstalled {}'.format(whl_name))<br>
         for whl_name in wheels_to_install:<br>
             whl = wheels_to_install[whl_name]['wheel']<br>
             install_whl = wheels_to_install[whl_name]['install']<br>
--<br>
2.24.0.windows.2</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal"> </p>
</div>

</div>
</body>
</html>

<div width="1" style="color:white;clear:both">_._,_._,_</div>
<hr>
Groups.io Links:<p>


You receive all messages sent to this group.



<p>

<a target="_blank" href="https://edk2.groups.io/g/devel/message/56079">View/Reply Online (#56079)</a> |


  


|


  
    <a target="_blank" href="https://groups.io/mt/72067009/1813853">Mute This Topic</a>
  

| <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>



<br>

<a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> |
<a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |

<a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>

 [edk2-devel-archive@redhat.com]<br>
<div width="1" style="color:white;clear:both">_._,_._,_</div>