def __init__(self, log: Log, filename: str, projectRootConfig: XmlProjectRootConfigFile) -> None: if projectRootConfig is None: raise Exception("projectRootConfig can not be None") if not os.path.isfile(filename): raise FileNotFoundException("Could not locate config file %s", filename) tree = ET.parse(filename) elem = tree.getroot() if elem.tag != 'FslBuildGenConfig': raise XmlInvalidRootElement("The file did not contain the expected root tag 'FslBuildGenConfig'") super().__init__(log, elem) currentVersion = '2' fileVersion = self._ReadAttrib(elem, 'Version') if fileVersion != currentVersion: raise XmlException("The file was not of the expected version {0}".format(currentVersion)) # In V2 we do not support local AddRootDirectory elements, we use the ones in ProjectRootConfig rootDirs = projectRootConfig.XmlRootDirectories if len(rootDirs) < 1: raise XmlException("The file did not contain at least one AddRootDirectory element") templateImportDirectory = self.__LoadAddTemplateImportDirectory(elem) self.__CheckForLegacyElements(elem, filename) # In V2 we do not support local PackageConfiguration elements, we use the ones in ProjectRootConfig xmlPackageConfigurations = projectRootConfig.XmlPackageConfiguration # type: List[XmlConfigPackageConfiguration] if len(xmlPackageConfigurations) < 1: if projectRootConfig.SourceFileName is None: raise XmlException("The file '{0}' did not contain at least one PackageConfiguration element".format(filename)) else: raise XmlException("The file '{0}' and {1} did not contain at least one PackageConfiguration element".format(filename, projectRootConfig.SourceFileName)) newProjectTemplatesRootDirectories = LoadUtil.LoadAddNewProjectTemplatesRootDirectory(log, elem, filename) newProjectTemplatesRootDirectories = self.__MergeNewProjectTemplatesRootDirectories(newProjectTemplatesRootDirectories, projectRootConfig.XmlNewProjectTemplatesRootDirectories) xmlContentBuilderConfiguration = self.__LoadContentBuilderConfiguration(elem) xmlConfigFileTemplateFolder = self.__LoadTemplateFolder(elem) self.Version = int(fileVersion) # type: int self.RootDirectories = rootDirs # type: List[XmlConfigFileAddRootDirectory] self.TemplateImportDirectories = templateImportDirectory # type: List[XmlConfigFileAddTemplateImportDirectory] self.PackageConfiguration = self.__ResolvePackageConfiguration(xmlPackageConfigurations) # type: Dict[str, XmlConfigPackageConfiguration] self.NewProjectTemplateRootDirectories = newProjectTemplatesRootDirectories # type: List[XmlConfigFileAddNewProjectTemplatesRootDirectory] self.TemplateFolder = xmlConfigFileTemplateFolder # type: XmlConfigFileTemplateFolder self.GenFileName = self.__LoadGenFileName(elem) # type: XmlConfigFileGenFile self.ContentBuilderConfiguration = xmlContentBuilderConfiguration # type: XmlConfigContentBuilderConfiguration self.BuildDocConfiguration = projectRootConfig.XmlBuildDocConfiguration # type: List[XmlBuildDocConfiguration] self.ClangFormatConfiguration = projectRootConfig.XmlClangFormatConfiguration # type: List[XmlClangFormatConfiguration] self.ClangTidyConfiguration = projectRootConfig.XmlClangTidyConfiguration # type: List[XmlClangTidyConfiguration] self.CMakeConfiguration = projectRootConfig.XmlCMakeConfiguration # type: List[XmlCMakeConfiguration] self.CompilerConfiguration = projectRootConfig.XmlCompilerConfiguration # type: List[XmlConfigCompilerConfiguration] self.Experimental = self.__ResolveExperimental(projectRootConfig.XmlExperimental) # type: Optional[XmlExperimental]
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super().__init__(log, xmlElement) self.Name = self._ReadAttrib(xmlElement, 'Name') self.DebugName = self._ReadAttrib(xmlElement, 'DebugName', self.Name) # type: str defaultTargetName = "{0}::{0}".format(self.Name) self.TargetName = self._ReadAttrib(xmlElement, 'TargetName', defaultTargetName) # type: str self.Include = self._TryReadAttrib(xmlElement, 'Include') # type: Optional['str'] self.Location = self._TryReadAttrib(xmlElement, 'Location') # type: Optional['str'] # New assembly keywords primarily used for C# assemblies self.HintPath = self._TryReadAttrib(xmlElement, 'HintPath') # type: Optional['str'] self.Version = self._TryReadAttribAsVersion(xmlElement, 'Version') # type: Optional[Version] self.PublicKeyToken = self._TryReadAttrib(xmlElement, 'PublicKeyToken') # type: Optional['str'] self.ProcessorArchitecture = self._TryReadAttrib(xmlElement, 'ProcessorArchitecture') # type: Optional['str'] self.Culture = self._TryReadAttrib(xmlElement, 'Culture') # type: Optional['str'] self.PackageManager = self.__TryGetPackageManager(log, xmlElement) self.IfCondition = self._TryReadAttrib(xmlElement, 'If') # type: Optional[str] # Can only be set from code, and it indicates that this dependency is managed by a recipe or similar self.IsManaged = False # type: bool strAccess = self._TryReadAttrib(xmlElement, 'Access') # type: Optional['str'] access = None if self.Include != None or strAccess != None: strAccess = self._ReadAttrib(xmlElement, 'Access') if access is None else access if strAccess == "Public": access = AccessType.Public elif strAccess == "Private": access = AccessType.Private else: raise XmlFormatException("Unknown access type '{0}' on external dependency: '{1}'".format(access, self.Name)) strElementType = self._ReadAttrib(xmlElement, 'Type') elementType = ExternalDependencyType.TryFromString(strElementType) if elementType is None: raise XmlException(xmlElement, "Unknown external dependency type: '{0}' expected: {1}".format(strElementType, ExternalDependencyType.AllStrings())) self.Type = elementType # type: ExternalDependencyType # The access type is only relevant for the include file location # the rest should always be included self.Access = AccessType.Public if access is None else access # type: int self.ConsumedBy = None if self.Type == ExternalDependencyType.DLL: if not self.Include is None: raise XmlException(xmlElement, "DLL dependency: '{0}' can not contain include paths".format(self.Name)) if self.Access != AccessType.Public: raise XmlException(xmlElement, "DLL dependency: '{0}' can only have a access type of Public".format(self.Name)) if not isinstance(self.Access, int): raise Exception("Internal error")
def __CheckForLegacyElement(self, xmlElement: ET.Element, filename: str, name: str) -> None: found = xmlElement.find(name) if found is not None: raise XmlException( "The file '{0}' contained a legacy {1} element which is not supported anymore. Use the 'Project.gen' file instead" .format(filename, name))
def __init__(self, log: Log, filename: str) -> None: if not os.path.isfile(filename): raise FileNotFoundException("Could not locate config file %s", filename) tree = ET.parse(filename) elem = tree.getroot() if elem.tag != 'FslBuildGeneratorVSProjectTemplateCustomization': raise XmlInvalidRootElement( "The file did not contain the expected root tag 'FslBuildGeneratorVSProjectTemplateCustomization'" ) super().__init__(log, elem) strVersion = self._ReadAttrib(elem, 'Version') if strVersion != "1": raise Exception("Unsupported version") xmlConfiguration = self.__LoadTemplateConfiguration(log, elem) if len(xmlConfiguration) != 1: raise XmlException( "The file did not contain exactly one BuildOutput element") self.Version = 1 self.BuildOutput = xmlConfiguration[0] self.Path = IOUtil.GetDirectoryName(filename)
def __init__(self, log: Log, filename: str) -> None: if not os.path.isfile(filename): raise FileNotFoundException("Could not locate config file %s", filename) tree = ET.parse(filename) elem = tree.getroot() if elem.tag == 'FslBuildGeneratorVSProjectTemplate': pass elif elem.tag == 'FslBuildNewVSProjectTemplate': log.LogPrintWarning("Template file '{0}' using legacy template FslBuildNewVSProjectTemplate update it to FslBuildGeneratorVSProjectTemplate".format(filename)) else: raise XmlInvalidRootElement("The file did not contain the expected root tag 'FslBuildGeneratorVSProjectTemplate'") super().__init__(log, elem) strVersion = self._ReadAttrib(elem, 'Version') if strVersion != "1": raise Exception("Unsupported version") xmlTemplate = self.__LoadTemplateConfiguration(log, elem) if len(xmlTemplate) != 1: raise XmlException("The file did not contain exactly one Template element") directoryName = IOUtil.GetDirectoryName(filename) self.Name = IOUtil.GetFileName(directoryName) self.Id = self.Name.lower() self.Version = 1 self.Template = xmlTemplate[0] self.Path = IOUtil.GetDirectoryName(filename) self.Prefix = ("%s_" % (self.Name)).upper() if self.Name != self.Template.Name: raise Exception("The parent template directory name '{0}' does not match the template name '{1}' {2}".format(self.Name, self.Template.Name, self.Path))
def __LoadContentBuilderConfiguration(self, xmlElement: ET.Element) -> XmlConfigContentBuilderConfiguration: foundElements = xmlElement.findall("ContentBuilderConfiguration") if len(foundElements) > 1: raise XmlException("The file contained more than one ContentBuilderConfiguration") elif len(foundElements) == 1: return XmlConfigContentBuilderConfiguration(self.Log, foundElements[0]) return FakeXmlConfigContentBuilderConfiguration(self.Log)
def __ExtractType(self, variantType: str) -> int: if variantType == 'Normal': return VariantType.Normal elif variantType == 'Virtual': return VariantType.Virtual else: raise XmlException( self.XMLElement, "Unknown variant type: '{0}' expected: Normal, Virtual".format( variantType))
def _LoadBuildDocConfiguration(log: Log, xmlElement: ET.Element, filename: str) -> List[XmlBuildDocConfiguration]: res = [] foundElements = xmlElement.findall("BuildDocConfiguration") for foundElement in foundElements: res.append(XmlBuildDocConfiguration(log, foundElement)) if len(res) > 1: raise XmlException("The file '{0}' contained more than one BuildDocConfiguration".format(filename)) return res
def _LoadAddRootDirectory(log: Log, xmlElement: ET.Element, filename: str) -> List[XmlConfigFileAddRootDirectory]: res = [] foundElements = xmlElement.findall("AddRootDirectory") for foundElement in foundElements: res.append(XmlConfigFileAddRootDirectory(log, foundElement)) if len(res) < 1: raise XmlException("The file '{0}' did not contain at least one AddRootDirectory element".format(filename)) return res
def __ValidateVariantName(self) -> None: if self.Type == VariantType.Normal: if not Util.IsValidName(self.Name): raise XmlUnsupportedVariantNameException( self.XMLElement, self.Name) elif self.Type == VariantType.Virtual: if not Util.IsValidVirtualVariantName(self.Name): raise XmlUnsupportedVirtualVariantNameException( self.XMLElement, self.Name) else: raise XmlException(self.XMLElement, "Unknown variant type")
def __ResolvePackageConfiguration(self, xmlPackageConfigurations: List[XmlConfigPackageConfiguration]) -> Dict[str, XmlConfigPackageConfiguration]: # prepare the package configurations packageConfigurationDict = {} # type: Dict[str, XmlConfigPackageConfiguration] for entry in xmlPackageConfigurations: if entry.Name in packageConfigurationDict: firstEntry = packageConfigurationDict[entry.Name] raise XmlException2(entry.XMLElement, "Duplicated package configuration name '{0}' found in '{1}' and '{2}'".format(entry.Name, entry.SourceFile, firstEntry.SourceFile)) packageConfigurationDict[entry.Name] = entry if 'default' not in packageConfigurationDict: raise XmlException("The file did not contain the 'default' PackageConfiguration element") return packageConfigurationDict
def __ValidateOptionNames(self) -> None: if self.Type == VariantType.Normal: for option in self.Options: if not Util.IsValidName(option.Name): raise XmlUnsupportedVariantOptionNameException( option.XMLElement, option.Name) elif self.Type == VariantType.Virtual: if len(self.Options) != 1: raise XmlInvalidVirtualVariantOptionException( self.XMLElement, self.Name) if not self.Options[0].Name == self.Name: raise XmlUnsupportedVirtualVariantOptionNameException( self.Options[0].XMLElement, self.Options[0].Name, self.Name) else: raise XmlException(self.XMLElement, "Unknown variant type")
def __init__(self, log: Log, filename: str) -> None: if not os.path.isfile(filename): raise FileNotFoundException("Could not locate config file %s", filename) tree = ET.parse(filename) elem = tree.getroot() if elem.tag != 'FslBuildNewTemplate': raise XmlInvalidRootElement("The file did not contain the expected root tag 'FslBuildGenConfig'") super().__init__(log, elem) fileVersion = self._ReadAttrib(elem, 'Version') if fileVersion != '1': raise Exception("The template file version was not correct") xmlTemplate = self.__LoadTemplateConfiguration(log, elem) if len(xmlTemplate) != 1: raise XmlException("The file did not contain exactly one Template element") self.Name = IOUtil.GetFileName(IOUtil.GetDirectoryName(filename)) self.Id = self.Name.lower() self.Version = int(fileVersion) # type: int self.Template = xmlTemplate[0] self.Path = IOUtil.GetDirectoryName(filename) self.Prefix = ("%s_" % (self.Name)).upper()
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super(XmlGenFileExternalDependency, self).__init__(log, xmlElement) self.Name = self._ReadAttrib(xmlElement, 'Name') self.DebugName = self._ReadAttrib(xmlElement, 'DebugName', self.Name) # type: str self.Include = self._TryReadAttrib(xmlElement, 'Include') # type: Optional['str'] self.Location = self._TryReadAttrib( xmlElement, 'Location') # type: Optional['str'] # New assembly keywords primarily used for C# assemblies self.HintPath = self._TryReadAttrib( xmlElement, 'HintPath') # type: Optional['str'] self.Version = self._TryReadAttrib(xmlElement, 'Version') # type: Optional['str'] self.PublicKeyToken = self._TryReadAttrib( xmlElement, 'PublicKeyToken') # type: Optional['str'] self.ProcessorArchitecture = self._TryReadAttrib( xmlElement, 'ProcessorArchitecture') # type: Optional['str'] self.Culture = self._TryReadAttrib(xmlElement, 'Culture') # type: Optional['str'] self.PackageManager = self.__TryGetPackageManager(log, xmlElement) strAccess = self._TryReadAttrib(xmlElement, 'Access') # type: Optional['str'] access = None if self.Include != None or strAccess != None: strAccess = self._ReadAttrib( xmlElement, 'Access') if access is None else access if strAccess == "Public": access = AccessType.Public elif strAccess == "Private": access = AccessType.Private else: raise XmlFormatException( "Unknown access type '{0}' on external dependency: '{1}'". format(access, self.Name)) strElementType = self._ReadAttrib(xmlElement, 'Type') elementType = ExternalDependencyType.TryFromString(strElementType) if elementType is None: raise XmlException( xmlElement, "Unknown external dependency type: '{0}' expected: StaticLib, DLL, Headers, Assembly, Find" .format(type)) self.Type = elementType # type: int # The access type is only relevant for the include file location # the rest should always be included self.Access = AccessType.Public if access is None else access # type: int self.ConsumedBy = None if self.Type == ExternalDependencyType.DLL: if not self.Include is None: raise XmlException( xmlElement, "DLL dependency: '{0}' can not contain include paths". format(self.Name)) if self.Access != AccessType.Public: raise XmlException( xmlElement, "DLL dependency: '{0}' can only have a access type of Public" .format(self.Name)) if not isinstance(self.Access, int): raise Exception("Internal error")