blob: 35dfd5a37b36f9b0cc7e52d0654059e552f2739e [file] [log] [blame]
Michael DÜrre7bb133e2022-01-18 10:06:31 +01001import re
2import tempfile
3import tempfile
4import glob
5import shutil
6from .xpath import XPath
7
8class 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