WineBarrels-Wine/hash_modules.py

150 lines
5.3 KiB
Python

#!/usr/bin/env python3
import hashlib
import json
import os
import re
import subprocess
import yaml
def _load_stdout(args):
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
result = p.stdout.read()
if p.returncode != 0:
raise RuntimeError("Process crashed with " + repr(p.returncode)
+ ". Args: " + repr(args))
return result
_moduleFiles = {}
class ModuleLoader():
path = str
content = dict
__hash_find = re.compile(".*WB_HASH\\=\\'(?P<hash>[a-zA-Z0-9]*)\\'.*")
def __module(self, modules):
for iID in range(len(modules)):
i = modules[iID]
if isinstance(i, str):
i = self.relative(i)
if i in _moduleFiles:
tmp = _moduleFiles[i]
else:
tmp = ModuleLoader(i)
modules[iID] = tmp.content
else:
if "modules" in i:
self.__module(i["modules"])
def __init__(self, source):
if not isinstance(source, str):
raise ValueError("source have to be string. It was a "
+ repr(source) + ".")
self.path = os.path.abspath(source)
_moduleFiles[self.path] = self
self.content = yaml.load(open(self.path, "r").read(),
Loader=yaml.SafeLoader)
if "modules" in self.content:
self.__module(self.content["modules"])
def hash(self, function):
tmp = json.dumps(self.content, skipkeys=False, ensure_ascii=True,
check_circular=True, allow_nan=True, indent=None,
separators=("", ""), default=None, sort_keys=True)
tmp = tmp.encode("utf-8")
return function(tmp)
def gen_base_version(self, arch):
version = self.content["runtime-version"]
sdk = _load_stdout(["flatpak", "info", "-c", "--arch=" + arch,
"--user", self.content["sdk"], version])
platform = _load_stdout(["flatpak", "info", "-c", "--arch=" + arch,
"--user", self.content["runtime"], version])
sdk = sdk.splitlines()[0]
platform = platform.splitlines()[0]
return sdk, platform
def get_depends(self, arch):
version_src = "/" + arch + "/" + self.content["runtime-version"]
version_target = "/" + arch + "/" + self.content["branch"]
result = [self.content["sdk"] + version_src,
self.content["runtime"] + version_src,
self.content["id"] + version_target,
self.content["id-platform"] + version_target]
return result
def get_old_hash(self, arch):
vers = self.content["branch"]
try:
hash_sdk = _load_stdout(["flatpak", "info", "--arch=" + arch,
"--user", self.content["id"], vers])
hash_platform = _load_stdout(["flatpak", "info", "--arch=" + arch,
"--user",
self.content["id-platform"], vers])
if b"WB_HASH=" in hash_sdk:
hash_sdk = hash_sdk[hash_sdk.find(b"WB_HASH="):]
hash_sdk = self.__hash_find.match(hash_sdk.decode())
if hash_sdk is None:
hash_sdk = "--None--"
else:
hash_sdk = hash_sdk.groupdict()["hash"]
if b"WB_HASH=" in hash_platform:
hash_platform = hash_platform[hash_platform.find(b"WB_HASH="):]
hash_platform = self.__hash_find.match(hash_platform.decode())
if hash_platform is None:
hash_platform = "--None--"
else:
hash_platform = hash_platform.groupdict()["hash"]
return hash_sdk, hash_platform
except RuntimeError:
return "--None--", "--None--"
def relative(self, file):
return os.path.abspath(os.path.join(os.path.split(self.path)[0], file))
def get_hashes(source, arch):
mod = ModuleLoader(source)
parent_ids = b" ".join(mod.gen_base_version(arch)) + b" "
# Hash config
def hash_methode(hashclass):
def func(data):
tmp = hashclass()
tmp.update(parent_ids)
tmp.update(data)
return tmp.hexdigest()
return func
own = mod.hash(hash_methode(hashlib.sha3_512)).upper()
# Get old hash
old1, old2 = mod.get_old_hash(args.arch[0])
return own, old1, old2
def get_depends(source, arch):
mod = ModuleLoader(source)
return mod.get_depends(arch)
if __name__ == '__main__':
import argparse
# Parse config
parser = argparse.ArgumentParser(description="Generate hash of a module.")
parser.add_argument("file", metavar="file", type=str, nargs=1,
help="File configuration to generate hash.")
parser.add_argument("arch", metavar="arch", type=str, nargs=1,
help="The arch to build.")
parser.add_argument("--depends", dest="dependes", action="store_const",
const=True, default=False, help="List source runtime.")
args = parser.parse_args()
if args.dependes:
print("\n".join(get_depends(args.file[0], args.arch[0])))
else:
print("\n".join(get_hashes(args.file[0], args.arch[0])))