update parents to chlorine
[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             return False
39         found=False
40         pathToFind = XPath(valuePath)
41         pattern = re.compile('<([^>^\ ^?^!]+)')
42         curPath=XPath()
43         curParent=None
44         isComment=False
45         with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
46             with open(self.filename) as src_file:
47                 for line in src_file:
48                     if found == False or replaceMultiple:
49                         x=line.find('<!--')
50                         y=line.find('-->')
51                         if x>=0:
52                             isComment=True
53                         if y>=0 and y > x:
54                             isComment=False
55                         if not isComment:
56                             matches = pattern.finditer(line,y)
57                             for matchNum, match in enumerate(matches, 1):
58                                 f = match.group(1)
59                                 # end tag detected
60                                 if f.startswith("/"):
61                                     curPath.remove(f[1:])
62                                 # start tag detected (not autoclosing xml like <br />)
63                                 elif not f.endswith("/"):
64                                     x = curPath.add(f)
65                                     if curParent is None:
66                                         curParent = x
67                                     else:
68                                         curParent = curPath.last(1)
69                                 else:
70                                     continue
71                                 if pathToFind.equals(curPath, False):
72                                     pre=line[0:line.index('<')]
73                                     line=pre+'<{x}>{v}</{x}>\n'.format(x=f,v=value)
74                                     found=True
75                                     curPath.remove(f)
76                                     break
77                                 elif pathToFind.parentParamIsNeeded(curPath.subpath(1), f):
78                                     v = self.tryToGetValue(line, f)
79                                     if v is not None:
80                                         curParent.setFilter(f, v)
81
82                     tmp_file.write(line)
83             # Overwrite the original file with the munged temporary file in a
84             # manner preserving file attributes (e.g., permissions).
85             shutil.copystat(self.filename, tmp_file.name)
86             shutil.move(tmp_file.name, self.filename)
87         print("set {} to {} in {}: {}".format(valuePath, value, self.filename, str(found)))
88         return found
89
90     def tryToGetValue(self, line, xmlTag=None):
91         pattern = re.compile('<([^>^\ ^?^!]+)>([^<]+)<\/([^>^\ ^?^!]+)>' if xmlTag is None else '<('+xmlTag+')>([^<]+)<\/('+xmlTag+')>') 
92         matches = pattern.finditer(line)
93         match = next(matches)
94         if match is not None:
95             return match.group(2)
96         return None
97
98     @staticmethod
99     def findAll(folder, excludes=[]):
100         files= glob.glob(folder + "/**/pom.xml", recursive = True)
101         r=[]
102         for file in files:
103             doExclude=False
104             for exclude in excludes:
105                 if exclude in file:
106                     doExclude=True
107                     break
108             if not doExclude:
109                 r.append(file)
110         return r