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); }
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; } } } } }