comparison mercurial/utils/resourceutil.py @ 44148:aab70b540d3d stable

resourceutil: account for the non-resource-like file hierarchy under py2exe After 9e367157a990, config files for py2exe were expected to be in C:\Program Files\Mercurial\mercurial\defaultrc because of the implied resource structure of 'mercurial.defaultrc.*.rc', relative to the executable. Accomodating this would require changes to the WIX and Inno scripts (and perhaps the script that generates the WIX script), as well as 3rd party bundlers like TortoiseHg. But these files aren't read as resources anyway- they fall back to the filesystem APIs. (If we really wanted to carry on the charade, the installer would have to also sprinkle various empty __init__.py files around.) Instead, this simply prunes the 'mercurial.' portion of the resource name when run with py2exe. (PyOxidizer uses the resources API, not the filesystem fallback, so it is unaffected.) Since this hack only affects the py2 Windows installers and is less risky, I think it's reasonable. We haven't needed to load any 3rd party resource up to this point, and would have to make packaging changes anyway to handle that. Differential Revision: https://phab.mercurial-scm.org/D8058
author Matt Harbison <matt_harbison@yahoo.com>
date Fri, 31 Jan 2020 22:20:39 -0500
parents 9e367157a990
children 27787a43712f
comparison
equal deleted inserted replaced
44147:f010a80ec967 44148:aab70b540d3d
32 # the location of data files matching the source code 32 # the location of data files matching the source code
33 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app': 33 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app':
34 # executable version (py2exe) doesn't support __file__ 34 # executable version (py2exe) doesn't support __file__
35 datapath = os.path.dirname(pycompat.sysexecutable) 35 datapath = os.path.dirname(pycompat.sysexecutable)
36 _rootpath = datapath 36 _rootpath = datapath
37
38 # The installers store the files outside of library.zip, like
39 # C:\Program Files\Mercurial\defaultrc\*.rc. This strips the
40 # leading "mercurial." off of the package name, so that these
41 # pseudo resources are found in their directory next to the
42 # executable.
43 def _package_path(package):
44 dirs = package.split(b'.')
45 assert dirs[0] == b'mercurial'
46 return os.path.join(_rootpath, *dirs[1:])
47
37 else: 48 else:
38 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__))) 49 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__)))
39 _rootpath = os.path.dirname(datapath) 50 _rootpath = os.path.dirname(datapath)
51
52 def _package_path(package):
53 return os.path.join(_rootpath, *package.split(b'.'))
40 54
41 try: 55 try:
42 from importlib import resources 56 from importlib import resources
43 57
44 from .. import encoding 58 from .. import encoding
61 yield encoding.strtolocal(r) 75 yield encoding.strtolocal(r)
62 76
63 77
64 except (ImportError, AttributeError): 78 except (ImportError, AttributeError):
65 79
66 def _package_path(package):
67 return os.path.join(_rootpath, *package.split(b'.'))
68
69 def open_resource(package, name): 80 def open_resource(package, name):
70 path = os.path.join(_package_path(package), name) 81 path = os.path.join(_package_path(package), name)
71 return open(path, 'rb') 82 return open(path, 'rb')
72 83
73 def is_resource(package, name): 84 def is_resource(package, name):