-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mtree.py
94 lines (65 loc) · 2.44 KB
/
Mtree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import gzip
import re
import logging
from Thing import Thing
##mtree
#/set type=file uid=0 gid=0 mode=644
#./.BUILDINFO time=1581622860.0 size=4891 md5digest=85c4a154d55cc9a3856d4e368b293259 sha256digest=9dfdeb2e1b67043e31d7855a37dfd00b8839dc9ca300b9273ce75429f04867bc
#./somefile time=1581622860.0 size=584 md5digest=bf536e1ff9a04547133103de718d680f sha256digest=d09be33c9b92f8d9561f29db0b6d903040b6a5f53ea065dfd828ed035606adc4
def parse_mtree(mtree_file):
gz = gzip.open(mtree_file, mode="rt", encoding='utf-8')
defaults = {}
objects = []
for line in gz:
# strip comments, etc
#logging.debug(line.strip())
line = re.sub(r'\s*#.*', '', line.strip())
if line == '':
logging.debug('Empty line')
continue
# the /set lines update the default attributes
m = re.match(r'^/set\s+(.*)', line)
if m:
for a in re.split(r'\s+', m.group(1)):
k, v = a.split('=')
defaults[k] = v
logging.debug('new defaults: %s', str(defaults))
continue
# handle /unset
m = re.match(r'^/unset\s+(.*)', line)
if m:
for a in re.split(r'\s+', m.group(1)):
defaults.pop(a)
print(defaults)
continue
# A "data" line has a path, followed by k=v pairs
path, attrstr = line.split(' ', maxsplit=1)
# skip these
if path in ('./.BUILDINFO', './.PKGINFO', './.INSTALL', './.CHANGELOG'):
continue
# Set the current defaults, all of which can be overriden
# on a per-line basis. Set the default type to be "file",
# as that is usually omitted, unless the entry isn't a file.
attribs = dict(defaults)
attribs['type'] = 'file'
# Add metadata
for a in attrstr.split(' '):
k, v = a.split('=')
attribs[k] = v
objects.append(Thing(path, attrs=attribs, ignore_dir_mtime=True))
return objects
class Mtree():
def __init__(self, mtree_file):
self.mtree_file = mtree_file
self.index = 0
self.objects = parse_mtree(self.mtree_file)
self.length = len(self.objects)
def __iter__(self):
self.index = 0
yield self
def __next__(self):
if self.index > self.length:
yield StopIteration
result = self.objects[self.index]
self.index += 1
yield result