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