Merge "Upgrade for Java 17 with Kotlin 1.7"
[ccsdk/parent.git] / tools / lib / pomfile.py
1 import re
2 import tempfile
3 import tempfile
4 import glob
5 import shutil
6 from .xpath import XPath
7
8 class PomFile:
9
10     def __init__(self, filename):
11         self.filename=filename
12
13     def hasParent(self) -> bool:
14         pattern_compiled = re.compile('<project[>\ ]')
15         inProject=False
16         with open(self.filename,'r') as src_file:
17                 for line in src_file:
18                     m = pattern_compiled.search(line)
19                     if m is not None:
20                         if inProject == True:
21                             return True
22                         inProject=True
23                         pattern_compiled = re.compile('<parent[>\ ]')
24         return False
25                     
26
27     def setDependencyVersion(self, groupId, artifactId, version) -> bool:
28         return self.setXmlValue('/project/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version)
29     def setDependencyManagementVersion(self, groupId, artifactId, version) -> bool:
30         return self.setXmlValue('/project/dependencyManagement/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version)
31     # set xmlElementValue (just simple values - no objects)
32     # valuePath: xpath
33     #    e.g. /project/parent/version
34     #         /project/dependencies/dependency[groupId=org.opendaylight.netconf]/version
35     # value: value to set
36     def setXmlValue(self, valuePath, value, replaceMultiple=False) -> bool:
37         if value is None:
38             print("unable to set {} to {} in {}: {}".format(valuePath, value, self.filename, str(False)))
39             return False
40         found=False
41         pathToFind = XPath(valuePath)
42         pattern = re.compile('<([^>^\ ^?^!]+(\ \/)?)')
43         curPath=XPath()
44         curParent=None
45         isComment=False
46         with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
47             with open(self.filename) as src_file:
48                 for line in src_file:
49                     if found == False or replaceMultiple:
50                         x=line.find('<!--')
51                         y=line.find('-->')
52                         if x>=0:
53                             isComment=True
54                         if y>=0 and y > x:
55                             isComment=False
56                         if not isComment:
57                             matches = pattern.finditer(line,y)
58                             for matchNum, match in enumerate(matches, 1):
59                                 f = match.group(1)
60                                 # end tag detected
61                                 if f.startswith("/"):
62                                     curPath.remove(f[1:])
63                                 # start tag detected (not autoclosing xml like <br />)
64                                 elif not f.endswith("/"):
65                                     x = curPath.add(f)
66                                     if curParent is None:
67                                         curParent = x
68                                     else:
69                                         curParent = curPath.last(1)
70                                 else:
71                                     continue
72                                 if pathToFind.equals(curPath, False):
73                                     pre=line[0:line.index('<')]
74                                     line=pre+'<{x}>{v}</{x}>\n'.format(x=f,v=value)
75                                     found=True
76                                     curPath.remove(f)
77                                     break
78                                 elif pathToFind.parentParamIsNeeded(curPath.subpath(1), f):
79                                     v = self.tryToGetValue(line, f)
80                                     if v is not None:
81                                         curParent.setFilter(f, v)
82
83                     tmp_file.write(line)
84             # Overwrite the original file with the munged temporary file in a
85             # manner preserving file attributes (e.g., permissions).
86             shutil.copystat(self.filename, tmp_file.name)
87             shutil.move(tmp_file.name, self.filename)
88         print("set {} to {} in {}: {}".format(valuePath, value, self.filename, str(found)))
89         return found
90
91     def tryToGetValue(self, line, xmlTag=None):
92         pattern = re.compile('<([^>^\ ^?^!]+)>([^<]+)<\/([^>^\ ^?^!]+)>' if xmlTag is None else '<('+xmlTag+')>([^<]+)<\/('+xmlTag+')>') 
93         matches = pattern.finditer(line)
94         match = next(matches)
95         if match is not None:
96             return match.group(2)
97         return None
98
99     @staticmethod
100     def findAll(folder, excludes=[]):
101         files= glob.glob(folder + "/**/pom.xml", recursive = True)
102         r=[]
103         for file in files:
104             doExclude=False
105             for exclude in excludes:
106                 if exclude in file:
107                     doExclude=True
108                     break
109             if not doExclude:
110                 r.append(file)
111         return r