CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
spec_diff.py
Go to the documentation of this file.
1 #
2 # This file is part of the CernVM File System.
3 #
4 
5 import argparse
6 
7 class TreeNode:
8  def __init__(self, mode):
9  self.children = {}
10  self.mode = mode
11  def getString(self, prefix, wildcard):
12  stringRes = ''
13  if self.mode == '!':
14  stringRes = '!' + prefix + '\n'
15  if not wildcard:
16  if self.mode == '^':
17  stringRes = '^'+prefix+'*\n'
18  elif self.mode == '*':
19  stringRes = prefix + '/*\n'
20  elif self.mode == '/':
21  if len(prefix) == 0:
22  stringRes = "^/\n"
23  stringRes = '^' + prefix + '\n'
24  for key, val in self.children.items():
25  stringRes+=val.getString(prefix+'/'+key, self.mode == '*')
26  return stringRes
27  def __str__(self):
28  return self.getString("", False)
29 
31  def __init__(self, args):
32  self.infiles = args.infiles
33  self.outfile = args.outfile
34  self.depth = args.depth
35  self.root = TreeNode('/')
36 
37  def build_diff(self):
38  with open(self.infiles[0], 'r') as specFile0:
39  for curLine in specFile0:
40  (curLine, mode) = self.get_info(curLine)
41  path_parts = curLine.split('/')
42  curNode = self.add_node(path_parts, mode)
43  curNode.mode = self.calc_new_mode(curNode.mode, mode)
44  for curfile in self.infiles[1:]:
45  with open(curfile, 'r') as curSpecFile:
46  for curLine in curSpecFile:
47  (curLine, mode) = self.get_info(curLine)
48  path_parts = curLine.split('/')
49  if (mode == '!'):
50  curNode = self.add_node(path_parts, mode)
51  curNode.mode = self.calc_new_mode(curNode.mode, mode)
52  else:
53  curNode = self.root
54  passthrough = '-' if mode=='!' else '_'
55  curDepth = 0
56  mergeable = True
57  for part in path_parts:
58  curDepth+=1
59  if not part in curNode.children\
60  and curDepth > self.depth\
61  and mergeable:
62  print("Found mergeable")
63  curNode.mode = self.calc_new_mode(curNode.mode, '*')
64  break
65  elif not part in curNode.children:
66  mergeable = False
67  curNode.children[part] = TreeNode(passthrough)
68  curNode = curNode.children[part]
69  curNode.mode = self.calc_new_mode(curNode.mode, passthrough)
70  curNode.mode = self.calc_new_mode(curNode.mode, mode)
71  with open(self.outfile, "w") as specFile:
72  specFile.write(str(self.root))
73 
74  def add_node(self, path_parts, mode):
75  curNode = self.root
76  passthrough = '-' if mode=='!' else '_'
77  for part in path_parts:
78  if not part in curNode.children:
79  curNode.children[part] = TreeNode(passthrough)
80  curNode = curNode.children[part]
81  curNode.mode = self.calc_new_mode(curNode.mode, passthrough)
82  return curNode
83 
84  def calc_new_mode(self, old, update):
85  if update == '!':
86  return update
87  if old == '-':
88  return update
89  if update == '-':
90  return old
91  if old == '_':
92  return update
93  if old == '/' and update in ['^', '*']:
94  return update
95  if old == '^' and update == '*':
96  return update
97  return old
98 
99  def get_info(self, curLine):
100  curLine = curLine.strip()
101  mode = curLine[0]
102  wildcard = False
103  if (curLine[-1] == '*'):
104  wildcard = True
105  curLine = curLine[:-1]
106  if (mode == '/'):
107  if (wildcard):
108  mode = '*'
109  curLine = curLine[1:]
110  else:
111  if not wildcard and mode=='^':
112  mode = '/'
113  curLine = curLine[2:]
114  return (curLine, mode)
115 
116 
117 
118 
119 
120 
122  argparser = argparse.ArgumentParser()
123 
124  argparser.add_argument("depth",
125  type=int,
126  help="The trace log file")
127 
128  argparser.add_argument("infiles",
129  type=str,
130  nargs="+",
131  help="The trace log file")
132 
133  argparser.add_argument("outfile",
134  type=str,
135  help="The output file")
136 
137  return argparser.parse_args()
138 
139 def main():
140  args = parse_args()
141  diffBuilder = DiffBuilder(args)
142  diffBuilder.build_diff()
143 
144 if __name__ == "__main__":
145  main()
def main
Definition: spec_diff.py:139
def parse_args
Definition: spec_diff.py:121