180 lines
5.5 KiB
Python
180 lines
5.5 KiB
Python
from __future__ import print_function
|
|
|
|
import os
|
|
import hashlib
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
PY2 = (2,) <= sys.version_info < (3,)
|
|
|
|
MANIFEST_ROOT = 'manifest'
|
|
MANIFEST_FILE = 'file'
|
|
MANIFEST_NAME = 'name'
|
|
MANIFEST_MD5 = 'md5'
|
|
|
|
MANIFEST_FILE_NAME = 'manifest.xml'
|
|
MANIFEST_MD5_EXT = '.md5'
|
|
|
|
manifest_files = ['CHANGELOG', 'smdx.xsd']
|
|
|
|
""" Simple XML pretty print support function
|
|
|
|
"""
|
|
def xml_indent(elem, level=0):
|
|
i = "\n" + level*" "
|
|
if len(elem):
|
|
if not elem.text or not elem.text.strip():
|
|
elem.text = i + " "
|
|
if not elem.tail or not elem.tail.strip():
|
|
elem.tail = i
|
|
for elem in elem:
|
|
xml_indent(elem, level+1)
|
|
if not elem.tail or not elem.tail.strip():
|
|
elem.tail = i
|
|
else:
|
|
if level and (not elem.tail or not elem.tail.strip()):
|
|
elem.tail = i
|
|
|
|
class ManifestError(Exception):
|
|
pass
|
|
|
|
class File(object):
|
|
def __init__(self, name=None, md5=None):
|
|
self.name = name
|
|
self.md5 = md5
|
|
|
|
class Manifest(object):
|
|
def __init__(self, path='.', filename=None):
|
|
self.path = path
|
|
self.files = {}
|
|
self.filename = filename
|
|
|
|
if filename:
|
|
self.from_xml(filename=filename)
|
|
|
|
def create(self):
|
|
self.scan()
|
|
filename = os.path.join(self.path, MANIFEST_FILE_NAME)
|
|
self.to_xml_file(filename=filename)
|
|
md5 = hashlib.md5(open(filename, 'rb').read()).hexdigest()
|
|
f = open(filename + MANIFEST_MD5_EXT, 'w')
|
|
f.write(md5)
|
|
f.close()
|
|
|
|
def md5(self):
|
|
return hashlib.md5(self.to_xml_bytes()).hexdigest()
|
|
|
|
def diff(self, m):
|
|
diff_str = ''
|
|
for f, md5 in self.files.items():
|
|
m_md5 = m.files.get(f)
|
|
if md5 != m_md5:
|
|
diff_str += '%s: %s %s\n' % (f, md5, m_md5)
|
|
|
|
if len(self.files) != len(m.files):
|
|
for f, md5 in m.files.items():
|
|
if self.files.get(f) is None:
|
|
diff_str += '%s: "None" %s\n' % (f, md5)
|
|
return diff_str
|
|
|
|
def scan(self):
|
|
try:
|
|
files = os.listdir(self.path)
|
|
for f in files:
|
|
name, ext = os.path.splitext(f)
|
|
if f in manifest_files or (ext == '.xml' and f.startswith('smdx_')):
|
|
filename = os.path.join(self.path, f)
|
|
content = open(filename, 'rb').read()
|
|
# if content.find(b'\r\n') >= 0:
|
|
# print('windows file ', self.path)
|
|
content = content.replace(b'\r\n', b'\n')
|
|
md5 = hashlib.md5(content).hexdigest()
|
|
self.files[f] = md5
|
|
except Exception as e:
|
|
raise ManifestError('Error scanning directory %s: %s' % (self.path, str(e)))
|
|
|
|
def scan_strip(self):
|
|
try:
|
|
files = os.listdir(self.path)
|
|
for f in files:
|
|
name, ext = os.path.splitext(f)
|
|
if f in manifest_files or (ext == '.xml' and f.startswith('smdx_')):
|
|
filename = os.path.join(self.path, f)
|
|
content = open(filename, 'rb').read()
|
|
if content.find(b'\r\n') >= 0:
|
|
content = content.replace(b'\r\n', b'\n')
|
|
fc = open(filename, 'w')
|
|
fc.write(content)
|
|
fc.close()
|
|
md5 = hashlib.md5(content).hexdigest()
|
|
self.files[f] = md5
|
|
except Exception as e:
|
|
raise ManifestError('Error scanning directory %s: %s' % (self.path, str(e)))
|
|
|
|
def to_xml(self, parent=None, filename=None):
|
|
if parent is not None:
|
|
e = ET.SubElement(parent, MANIFEST_ROOT)
|
|
else:
|
|
e = ET.Element(MANIFEST_ROOT)
|
|
|
|
for f in sorted(self.files.keys()):
|
|
attr = {MANIFEST_NAME: f, MANIFEST_MD5: self.files.get(f)}
|
|
ET.SubElement(e, MANIFEST_FILE, attrib=attr)
|
|
|
|
return e
|
|
|
|
def to_xml_bytes(self, pretty_print=True):
|
|
e = self.to_xml()
|
|
|
|
if pretty_print:
|
|
xml_indent(e)
|
|
|
|
return ET.tostring(e)
|
|
|
|
def to_xml_file(self, filename=None, pretty_print=True, replace_existing=True):
|
|
xml = self.to_xml_bytes(pretty_print)
|
|
|
|
if filename is not None:
|
|
if replace_existing is False and os.path.exists(filename):
|
|
raise ManifestError('File %s already exists' % (filename))
|
|
f = open(filename, 'wb')
|
|
f.write(xml)
|
|
f.close()
|
|
else:
|
|
if PY2:
|
|
print(xml)
|
|
else:
|
|
print(xml.decode())
|
|
|
|
def from_xml(self, element=None, filename=None):
|
|
if element is None and filename is not None:
|
|
element = ET.ElementTree(file=filename).getroot()
|
|
|
|
if element is None:
|
|
raise ManifestError('No xml document element')
|
|
|
|
if element.tag != MANIFEST_ROOT:
|
|
raise ManifestError('Unexpected test suite root element %s' % (element.tag))
|
|
|
|
for e in element.findall('*'):
|
|
if e.tag == MANIFEST_FILE:
|
|
name = e.attrib.get(MANIFEST_NAME)
|
|
md5 = e.attrib.get(MANIFEST_MD5)
|
|
if name and md5:
|
|
self.files[name] = md5
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
path = os.path.dirname(os.path.realpath(__file__))
|
|
a = Manifest(path)
|
|
a.scan()
|
|
a.create()
|
|
|
|
# b = Manifest(filename=os.path.join(path, 'manifest.xml'))
|
|
|
|
# print a.diff(b)
|
|
# print '----------------------------------------------------'
|
|
# print a.to_xml_str()
|
|
# print a.md5()
|