All unit-tests now pass with Python 3
[zeroinstall/solver.git] / zeroinstall / cmd / digest.py
blob7d03b4a7ef323936990bec6b7a5b295732e38f4b
1 """
2 The B{0install digest} command-line interface.
3 """
5 # Copyright (C) 2011, Thomas Leonard
6 # See the README file for details, or visit http://0install.net.
8 from __future__ import print_function
10 import os, tempfile
12 from zeroinstall import SafeException, _
13 from zeroinstall.zerostore import manifest, unpack
14 from zeroinstall.cmd import UsageError
15 from zeroinstall import support
17 syntax = "DIRECTORY | ARCHIVE [EXTRACT]"
19 def add_options(parser):
20 parser.add_option("", "--algorithm", help=_("the hash function to use"), metavar="HASH")
22 def handle(config, options, args):
23 if len(args) == 1:
24 extract = None
25 elif len(args) == 2:
26 extract = args[1]
27 else:
28 raise UsageError()
30 source = args[0]
31 alg = manifest.algorithms.get(options.algorithm or 'sha1new', None)
32 if alg is None:
33 raise SafeException(_('Unknown algorithm "%s"') % alg)
35 def do_manifest(d):
36 if extract is not None:
37 d = os.path.join(d, extract)
38 digest = alg.new_digest()
39 for line in alg.generate_manifest(d):
40 digest.update((line + '\n').encode('utf-8'))
41 print(alg.getID(digest))
43 if os.path.isdir(source):
44 if extract is not None:
45 raise SafeException("Can't use extract with a directory")
46 do_manifest(source)
47 else:
48 data = None
49 tmpdir = tempfile.mkdtemp()
50 try:
51 data = open(args[0], 'rb')
52 unpack.unpack_archive(source, data, tmpdir, extract)
53 do_manifest(tmpdir)
54 finally:
55 support.ro_rmtree(tmpdir)
56 if data:
57 data.close()