diff options
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/pomfile.py | 109 | ||||
-rw-r--r-- | tools/lib/xpath.py | 84 |
2 files changed, 193 insertions, 0 deletions
diff --git a/tools/lib/pomfile.py b/tools/lib/pomfile.py new file mode 100644 index 00000000..35dfd5a3 --- /dev/null +++ b/tools/lib/pomfile.py @@ -0,0 +1,109 @@ +import re +import tempfile +import tempfile +import glob +import shutil +from .xpath import XPath + +class PomFile: + + def __init__(self, filename): + self.filename=filename + + def hasParent(self) -> bool: + pattern_compiled = re.compile('<project[>\ ]') + inProject=False + with open(self.filename,'r') as src_file: + for line in src_file: + m = pattern_compiled.search(line) + if m is not None: + if inProject == True: + return True + inProject=True + pattern_compiled = re.compile('<parent[>\ ]') + return False + + + def setDependencyVersion(self, groupId, artifactId, version) -> bool: + return self.setXmlValue('/project/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version) + def setDependencyManagementVersion(self, groupId, artifactId, version) -> bool: + return self.setXmlValue('/project/dependencyManagement/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version) + # set xmlElementValue (just simple values - no objects) + # valuePath: xpath + # e.g. /project/parent/version + # /project/dependencies/dependency[groupId=org.opendaylight.netconf]/version + # value: value to set + def setXmlValue(self, valuePath, value, replaceMultiple=False) -> bool: + + found=False + pathToFind = XPath(valuePath) + pattern = re.compile('<([^>^\ ^?^!]+)') + curPath=XPath() + curParent=None + isComment=False + with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file: + with open(self.filename) as src_file: + for line in src_file: + if found == False or replaceMultiple: + x=line.find('<!--') + y=line.find('-->') + if x>=0: + isComment=True + if y>=0 and y > x: + isComment=False + if not isComment: + matches = pattern.finditer(line,y) + for matchNum, match in enumerate(matches, 1): + f = match.group(1) + # end tag detected + if f.startswith("/"): + curPath.remove(f[1:]) + # start tag detected (not autoclosing xml like <br />) + elif not f.endswith("/"): + x = curPath.add(f) + if curParent is None: + curParent = x + else: + curParent = curPath.last(1) + else: + continue + if pathToFind.equals(curPath, False): + pre=line[0:line.index('<')] + line=pre+'<{x}>{v}</{x}>\n'.format(x=f,v=value) + found=True + curPath.remove(f) + break + elif pathToFind.parentParamIsNeeded(curPath.subpath(1), f): + v = self.tryToGetValue(line, f) + if v is not None: + curParent.setFilter(f, v) + + tmp_file.write(line) + # Overwrite the original file with the munged temporary file in a + # manner preserving file attributes (e.g., permissions). + shutil.copystat(self.filename, tmp_file.name) + shutil.move(tmp_file.name, self.filename) + print("set {} to {} in {}: {}".format(valuePath, value, self.filename, str(found))) + return found + + def tryToGetValue(self, line, xmlTag=None): + pattern = re.compile('<([^>^\ ^?^!]+)>([^<]+)<\/([^>^\ ^?^!]+)>' if xmlTag is None else '<('+xmlTag+')>([^<]+)<\/('+xmlTag+')>') + matches = pattern.finditer(line) + match = next(matches) + if match is not None: + return match.group(2) + return None + + @staticmethod + def findAll(folder, excludes=[]): + files= glob.glob(folder + "/**/pom.xml", recursive = True) + r=[] + for file in files: + doExclude=False + for exclude in excludes: + if exclude in file: + doExclude=True + break + if not doExclude: + r.append(file) + return r diff --git a/tools/lib/xpath.py b/tools/lib/xpath.py new file mode 100644 index 00000000..07f8e389 --- /dev/null +++ b/tools/lib/xpath.py @@ -0,0 +1,84 @@ + +import re + + +class XPathComponent: + regex = r"([^\/^\[]+)(\[([^\]]+)\])?" + def __init__(self, expr): + matches = re.finditer(XPathComponent.regex, expr, re.DOTALL | re.IGNORECASE) + match = next(matches) + self.name = match.group(1) + tmp = match.group(3) if len(match.groups())>2 else None + self.filter = tmp.split(',') if tmp is not None else [] + + def equals(self, comp, ignoreFilter=False) -> bool: + if ignoreFilter: + return self.name == comp.name + if self.name == comp.name: + return set(self.filter) == set(comp.filter) + return False + + def setFilter(self, f, v): + self.filter.append('{}={}'.format(f,v)) + + def hasFilter(self, propertyName): + search=propertyName+'=' + for filter in self.filter: + if filter.startswith(search): + return True + return False + + def __str__(self) -> str: + return "XPathComponent[name={}, filter={}]".format(self.name, self.filter) + +class XPath: + + def __init__(self, expr=None): + self.raw = expr + tmp = expr.split('/') if expr is not None else [] + self.components=[] + if len(tmp)>0 and len(tmp[0])==0: + tmp.pop(0) + for x in tmp: + self.components.append(XPathComponent(x)) + + def add(self, c: str) -> XPathComponent: + xc=XPathComponent(c) + self.components.append(xc) + return xc + + def remove(self, c: str) -> bool: + if self.components[len(self.components)-1].equals(XPathComponent(c), True): + self.components.pop() + return True + return False + + def parentParamIsNeeded(self, xp, paramName) -> bool: + for i in range(len(xp.components)): + if i>=len(self.components): + return False + if not self.components[i].equals(xp.components[i], True): + return False + return self.components[len(xp.components)-1].hasFilter(paramName) + + def equals(self, path, ignoreFilter=False) -> bool: + if len(self.components) != len(path.components): + return False + + for i in range(len(self.components)): + if not self.components[i].equals(path.components[i], ignoreFilter): + return False + return True + + def lastname(self) -> str: + tmp = self.last() + return tmp.name if tmp is not None else "" + + def last(self, off=0) -> XPathComponent: + return self.components[len(self.components)-1-off] if len(self.components)>off else None + + def subpath(self, off=0): + tmp =XPath() + for i in range(len(self.components)-off): + tmp.components.append(self.components[i]) + return tmp
\ No newline at end of file |