1#-----------------------------------------------------------------------------
2# Copyright (c) 2005-2019, PyInstaller Development Team.
3#
4# Distributed under the terms of the GNU General Public License with exception
5# for distributing bootloader.
6#
7# The full license is in the file COPYING.txt, distributed with this software.
8#-----------------------------------------------------------------------------
9
10
11"""
12Configure PyInstaller for the current Python installation.
13"""
14
15import os
16
17from . import compat
18from . import log as logging
19from .compat import is_win, is_darwin
20
21logger = logging.getLogger(__name__)
22
23
24def test_UPX(config, upx_dir):
25    logger.debug('Testing for UPX ...')
26    cmd = "upx"
27    if upx_dir:
28        cmd = os.path.normpath(os.path.join(upx_dir, cmd))
29
30    hasUPX = 0
31    try:
32        vers = compat.exec_command(
33            cmd, '-V', __raise_ENOENT__=True).strip().splitlines()
34        if vers:
35            v = vers[0].split()[1]
36            hasUPX = tuple(map(int, v.split(".")))
37            if is_win and hasUPX < (1, 92):
38                logger.error('UPX is too old! Python 2.4 under Windows requires UPX 1.92+')
39                hasUPX = 0
40    except Exception as e:
41        if isinstance(e, OSError) and e.errno == 2:
42            # No such file or directory
43            pass
44        else:
45            logger.info('An exception occured when testing for UPX:')
46            logger.info('  %r', e)
47    if hasUPX:
48        is_available = 'available'
49    else:
50        is_available = 'not available'
51    logger.info('UPX is %s.', is_available)
52    config['hasUPX'] = hasUPX
53    config['upx_dir'] = upx_dir
54
55
56def _get_pyinst_cache_dir():
57    old_cache_dir = None
58    if compat.getenv('PYINSTALLER_CONFIG_DIR'):
59        cache_dir = compat.getenv('PYINSTALLER_CONFIG_DIR')
60    elif is_win:
61        cache_dir = compat.getenv('APPDATA')
62        if not cache_dir:
63            cache_dir = os.path.expanduser('~\\Application Data')
64    elif is_darwin:
65        cache_dir = os.path.expanduser('~/Library/Application Support')
66    else:
67        # According to XDG specification
68        # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
69        old_cache_dir = compat.getenv('XDG_DATA_HOME')
70        if not old_cache_dir:
71            old_cache_dir = os.path.expanduser('~/.local/share')
72        cache_dir = compat.getenv('XDG_CACHE_HOME')
73        if not cache_dir:
74            cache_dir = os.path.expanduser('~/.cache')
75    cache_dir = os.path.join(cache_dir, 'pyinstaller')
76    # Move old cache-dir, if any, to now location
77    if old_cache_dir and not os.path.exists(cache_dir):
78        old_cache_dir = os.path.join(old_cache_dir, 'pyinstaller')
79        if os.path.exists(old_cache_dir):
80            parent_dir = os.path.dirname(cache_dir)
81            if not os.path.exists(parent_dir):
82                os.makedirs(parent_dir)
83            os.rename(old_cache_dir, cache_dir)
84    return cache_dir
85
86
87#FIXME: Rename to get_official_hooks_dir().
88#FIXME: Remove the "hook_type" parameter after unifying hook types.
89def get_importhooks_dir(hook_type=None):
90    from . import PACKAGEPATH
91    if not hook_type:
92        return os.path.join(PACKAGEPATH, 'hooks')
93    else:
94        return os.path.join(PACKAGEPATH, 'hooks', hook_type)
95
96
97def get_config(upx_dir, **kw):
98    config = {}
99    test_UPX(config, upx_dir)
100    config['cachedir'] = _get_pyinst_cache_dir()
101
102    return config
103