| #!python3
|
|
|
| """
|
| Compares the contents (disregarding files' sizes and timestamps) of Haiku packages (.hpkg).
|
|
|
| Useful to see, at first glance, if our newly built package looks more or less like the older ones.
|
|
|
| Usage:
|
| > compare_packages.py <package_name>
|
| > compare_packages.py <package1.hpkg> <package2.hpkg>
|
|
|
| First one compares the given <package_name> from:
|
|
|
| /system/packages/package_name-*.hpkg
|
|
|
| with the one from:
|
|
|
| {0}/package_name-*.hpkg
|
|
|
| The second one compares the two given <package1> <package2> files.
|
|
|
| Examples:
|
| > compare_packages.py ncurses6
|
| > compare_packages.py /foo/bar/some_package.hpkg ~/Downloads/some_package.hpkg
|
| """
|
|
|
| from pprint import pprint
|
|
|
| import os
|
| import re
|
| import subprocess
|
| import sys
|
|
|
|
|
| def usage():
|
| print(__doc__.format(hp_packages_dir()))
|
| exit()
|
|
|
|
|
| def call(what, check_rc=True, shell=True):
|
| """Returns the text output of calling the `what` in a subprocess.
|
|
|
| set check_rc=False if the subprocess may fail (and you can handle that).
|
| """
|
| if check_rc:
|
| return subprocess.check_output([what], shell=shell, text=True)
|
| return subprocess.run([what], stdout=subprocess.PIPE, shell=shell, text=True).stdout
|
|
|
|
|
| def get_package_filenames(package_name):
|
| """Returns a 2 items tuple of the first .hpkg filename that matches `package_name`.
|
|
|
| The first item from `/system/packages/`, the second from haikuporter's $TREE_PATH.
|
| """
|
| system = call('ls -1 /system/packages/%s-*.hpkg' % package_name, check_rc=False)
|
| local = call('ls -1 %s/%s-*.hpkg' % (hp_packages_dir(), package_name), check_rc=False)
|
|
|
| if system != '':
|
| system = system.splitlines()[0]
|
| if local != '':
|
| local = local.splitlines()[0]
|
|
|
| return system, local
|
|
|
|
|
| def hp_packages_dir():
|
| result = call('source ~/config/settings/haikuports.conf && echo $PACKAGES_PATH').splitlines()[0]
|
| if result != "":
|
| return result
|
|
|
| result = call('source ~/config/settings/haikuports.conf && echo $TREE_PATH').splitlines()[0]
|
| if result != "":
|
| return result + '/packages'
|
|
|
| raise Exception("Failed to detect HaikuPorts' packages dir location. Is your 'haikuports.conf' properly setup?")
|
|
|
|
|
| def diff(old, new):
|
| result = call('diff --color=always -u %s %s' % (old, new), check_rc=False)
|
| return result
|
|
|
|
|
| def get_package_info(filename):
|
| pkg_info = call('package list -i %s' % filename).splitlines()
|
| pkg_files = call('package list -p %s' % filename).splitlines()
|
|
|
| return '\n'.join(pkg_info) + '\n'.join(sorted(pkg_files))
|
|
|
|
|
| def main(package_name=None, package1=None, package2=None):
|
| if (package_name is not None) and (package1 is None and package2 is None):
|
| package1, package2 = get_package_filenames(package_name)
|
| errStr1 = 'Cannot locate a package named "%s" under /system/packages/' % package_name
|
| errStr2 = 'Cannot locate a package named "%s" under "%s"' % (package_name, hp_packages_dir())
|
| else:
|
| errStr1 = 'File "%s" doesn\'t exist/' % package1
|
| errStr2 = 'File "%s" doesn\'t exist/' % package2
|
|
|
| if not os.path.exists(package1):
|
| print(errStr1)
|
| exit()
|
| elif not os.path.exists(package2):
|
| print(errStr2)
|
| exit()
|
|
|
| print('\nComparing package files:\n\t%s\n\t%s\n' % (package1, package2))
|
|
|
| tmp_dir = '/boot/system/var/shared_memory'
|
| hpkginfo1 = tmp_dir + '/hpkginfo1.txt'
|
| hpkginfo2 = tmp_dir + '/hpkginfo2.txt'
|
|
|
| with open(hpkginfo1, 'w') as of:
|
| of.writelines(get_package_info(package1))
|
|
|
| with open(hpkginfo2, 'w') as nf:
|
| nf.writelines(get_package_info(package2))
|
|
|
| print(diff(hpkginfo1, hpkginfo2))
|
|
|
| os.unlink(hpkginfo1)
|
| os.unlink(hpkginfo2)
|
|
|
|
|
| if __name__ == '__main__':
|
| if len(sys.argv) == 2:
|
| main(package_name=sys.argv[1])
|
| elif len(sys.argv) == 3:
|
| main(package1=sys.argv[1], package2=sys.argv[2])
|
| else:
|
| usage()
|