Esempio n. 1
0
        private static EdkRepoConfig ParseXml(XmlDocument Xml)
        {
            EdkRepoConfig config = new EdkRepoConfig();
            List <SubstitutablePythons> Pythons = new List <SubstitutablePythons>();

            config.Pythons = Pythons;
            SubstitutablePythons SubPy;

            foreach (XmlNode node in Xml.DocumentElement)
            {
                switch (node.Name)
                {
                //
                // The use case for SubstitutablePythons is to allow a different set of
                // Python wheels to be installed on a IA32 vs. X64 version of the Python interperter.
                //
                // If all wheels work universally regardless of machine architecture Then just use a <Python> tag
                //
                case "SubstitutablePythons":
                    List <PythonInstance> InnerPyInstances = new List <PythonInstance>();
                    if (node.Attributes["MinVersion"] == null)
                    {
                        throw new ArgumentException("Required attribute \"MinVersion\" is missing from SubstitutablePythons element in configuration XML");
                    }
                    foreach (XmlNode innerNode in node)
                    {
                        if (innerNode.Name == "Python")
                        {
                            InnerPyInstances.Add(ParsePythonNode(innerNode));
                        }
                    }
                    SubPy = new SubstitutablePythons();
                    SubPy.PythonInstances = InnerPyInstances;
                    SubPy.MinVersion      = new PythonVersion(node.Attributes["MinVersion"].Value);
                    if (node.Attributes["MaxVersion"] != null)
                    {
                        SubPy.MaxVersion = new PythonVersion(node.Attributes["MaxVersion"].Value);
                    }
                    else
                    {
                        SubPy.MaxVersion = new PythonVersion(-1, -1, -1);
                    }
                    Pythons.Add(SubPy);
                    break;

                case "Python":
                    if (node.Attributes["MinVersion"] == null)
                    {
                        throw new ArgumentException("Required attribute \"MinVersion\" is missing from Python element in configuration XML");
                    }
                    PythonInstance PyInstaller = ParsePythonNode(node);
                    SubPy = new SubstitutablePythons();
                    SubPy.PythonInstances = new PythonInstance[] { PyInstaller };
                    SubPy.MinVersion      = new PythonVersion(node.Attributes["MinVersion"].Value);
                    if (node.Attributes["MaxVersion"] != null)
                    {
                        SubPy.MaxVersion = new PythonVersion(node.Attributes["MaxVersion"].Value);
                    }
                    else
                    {
                        SubPy.MaxVersion = new PythonVersion(-1, -1, -1);
                    }
                    Pythons.Add(SubPy);
                    break;
                }
            }
            ValidateConfig(config);
            return(config);
        }
Esempio n. 2
0
        private static void ValidateConfig(EdkRepoConfig Config)
        {
            //1. SubstitutablePythons should have a different machine architecture
            bool FoundFirstPython;
            List <CpuArchitecture> CpuArchitectureList = new List <CpuArchitecture>();

            foreach (SubstitutablePythons SubPyInstaller in Config.Pythons)
            {
                FoundFirstPython = false;
                CpuArchitectureList.Clear();
                foreach (PythonInstance PyInstance in SubPyInstaller.PythonInstances)
                {
                    if (!FoundFirstPython)
                    {
                        CpuArchitectureList.Add(PyInstance.Architecture);
                        FoundFirstPython = true;
                    }
                    else
                    {
                        if (CpuArchitectureList.Contains(PyInstance.Architecture))
                        {
                            throw new ArgumentException("Substitutable Python instances must all have different machine architectures for each instance");
                        }
                        CpuArchitectureList.Add(PyInstance.Architecture);
                    }
                }
            }

            //2. Only one entry for a min/max version of Python
            Tuple <PythonVersion, PythonVersion>         PyVersionPair;
            List <Tuple <PythonVersion, PythonVersion> > PyVersionList = new List <Tuple <PythonVersion, PythonVersion> >();

            foreach (SubstitutablePythons SubPython in Config.Pythons)
            {
                PyVersionPair = new Tuple <PythonVersion, PythonVersion>(SubPython.MinVersion, SubPython.MaxVersion);
                foreach (Tuple <PythonVersion, PythonVersion> Version in PyVersionList)
                {
                    if (Version.Item1 == PyVersionPair.Item1 && Version.Item2 == PyVersionPair.Item2)
                    {
                        throw new ArgumentException("There must be only one Python or SubstitutablePythons element for each min/max version of Python");
                    }
                }
                PyVersionList.Add(PyVersionPair);
            }
            //3. If a wheel has UninstallAllOtherCopies == true, then there should be no other copies of that wheel under different Python versions
            List <string> ExclusiveWheels          = new List <string>();
            List <string> CandidateExclusiveWheels = new List <string>();

            foreach (SubstitutablePythons SubPython in Config.Pythons)
            {
                CandidateExclusiveWheels.Clear();
                foreach (PythonInstance PyInstance in SubPython.PythonInstances)
                {
                    foreach (PythonWheel Wheel in PyInstance.Wheels)
                    {
                        if (Wheel.UninstallAllOtherCopies)
                        {
                            if (!CandidateExclusiveWheels.Contains(Wheel.Package.Name))
                            {
                                CandidateExclusiveWheels.Add(Wheel.Package.Name);
                            }
                        }
                    }
                }
                foreach (string WheelName in CandidateExclusiveWheels)
                {
                    if (!ExclusiveWheels.Contains(WheelName))
                    {
                        ExclusiveWheels.Add(WheelName);
                    }
                }
            }
            foreach (string WheelName in ExclusiveWheels)
            {
                bool FoundWheel = false;
                foreach (SubstitutablePythons SubPython in Config.Pythons)
                {
                    bool ContinueSearch = true;
                    foreach (PythonInstance PyInstance in SubPython.PythonInstances)
                    {
                        foreach (PythonWheel Wheel in PyInstance.Wheels)
                        {
                            if (Wheel.Package.Name == WheelName)
                            {
                                if (FoundWheel)
                                {
                                    throw new ArgumentException(string.Format("More than one version of Python contains the wheel {0} when only one copy of this wheel should be installed on the system", WheelName));
                                }
                                else
                                {
                                    FoundWheel = true;
                                }
                                ContinueSearch = false;
                                break;
                            }
                        }
                        if (!ContinueSearch)
                        {
                            break;
                        }
                    }
                }
            }
        }