Mercurial > public > mercurial-scm > hg-stable
annotate 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 |
rev | line source |
---|---|
43712
664e24207728
procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
43701
diff
changeset
|
1 # resourceutil.py - utility for looking up resources |
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
2 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
6 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
7 # This software may be used and distributed according to the terms of the |
10263 | 8 # GNU General Public License version 2 or any later version. |
1082 | 9 |
37121
5be286db5fb5
procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37120
diff
changeset
|
10 from __future__ import absolute_import |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
11 |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
12 import imp |
43713
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
13 import os |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
14 import sys |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43021
diff
changeset
|
15 |
43712
664e24207728
procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
43701
diff
changeset
|
16 from .. import pycompat |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
17 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43021
diff
changeset
|
18 |
14228
116de1da2154
rename util.main_is_frozen to mainfrozen
Adrian Buehlmann <adrian@cadifra.com>
parents:
14167
diff
changeset
|
19 def mainfrozen(): |
6499
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
20 """return True if we are a frozen executable. |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
21 |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
22 The code supports py2exe (most common, Windows only) and tools/freeze |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
23 (portable, not much used). |
479847ccabe0
Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents:
5659
diff
changeset
|
24 """ |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43021
diff
changeset
|
25 return ( |
43115
4aa72cdf616f
py3: delete b'' prefix from safehasattr arguments
Martin von Zweigbergk <martinvonz@google.com>
parents:
43106
diff
changeset
|
26 pycompat.safehasattr(sys, "frozen") |
4aa72cdf616f
py3: delete b'' prefix from safehasattr arguments
Martin von Zweigbergk <martinvonz@google.com>
parents:
43106
diff
changeset
|
27 or pycompat.safehasattr(sys, "importers") # new py2exe |
43551
313e3a279828
cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents:
43526
diff
changeset
|
28 or imp.is_frozen("__main__") # old py2exe |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43021
diff
changeset
|
29 ) # tools/freeze |
43713
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
30 |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
31 |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
32 # the location of data files matching the source code |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
33 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app': |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
34 # executable version (py2exe) doesn't support __file__ |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
35 datapath = os.path.dirname(pycompat.sysexecutable) |
44146
9e367157a990
resourceutil: correct the root path for file based lookup under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44136
diff
changeset
|
36 _rootpath = datapath |
44148
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
37 |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
38 # The installers store the files outside of library.zip, like |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
39 # C:\Program Files\Mercurial\defaultrc\*.rc. This strips the |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
40 # leading "mercurial." off of the package name, so that these |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
41 # pseudo resources are found in their directory next to the |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
42 # executable. |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
43 def _package_path(package): |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
44 dirs = package.split(b'.') |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
45 assert dirs[0] == b'mercurial' |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
46 return os.path.join(_rootpath, *dirs[1:]) |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
47 |
43713
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
48 else: |
9fb85668ee15
util: move definition of datapath to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
43712
diff
changeset
|
49 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__))) |
44029
52f0140c2604
resourceutil: don't limit resources to the `mercurial` package
Matt Harbison <matt_harbison@yahoo.com>
parents:
43960
diff
changeset
|
50 _rootpath = os.path.dirname(datapath) |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
51 |
44148
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
52 def _package_path(package): |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
53 return os.path.join(_rootpath, *package.split(b'.')) |
aab70b540d3d
resourceutil: account for the non-resource-like file hierarchy under py2exe
Matt Harbison <matt_harbison@yahoo.com>
parents:
44146
diff
changeset
|
54 |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
55 try: |
43960
75ec46c63657
resourceutil: use `from importlib import resources`
Martin von Zweigbergk <martinvonz@google.com>
parents:
43911
diff
changeset
|
56 from importlib import resources |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
57 |
44030
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
58 from .. import encoding |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
59 |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
60 # Force loading of the resources module |
43960
75ec46c63657
resourceutil: use `from importlib import resources`
Martin von Zweigbergk <martinvonz@google.com>
parents:
43911
diff
changeset
|
61 resources.open_binary # pytype: disable=module-attr |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
62 |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
63 def open_resource(package, name): |
43960
75ec46c63657
resourceutil: use `from importlib import resources`
Martin von Zweigbergk <martinvonz@google.com>
parents:
43911
diff
changeset
|
64 return resources.open_binary( # pytype: disable=module-attr |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
65 pycompat.sysstr(package), pycompat.sysstr(name) |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
66 ) |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
67 |
44030
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
68 def is_resource(package, name): |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
69 return resources.is_resource( |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
70 pycompat.sysstr(package), encoding.strfromlocal(name) |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
71 ) |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
72 |
44031
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
73 def contents(package): |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
74 for r in resources.contents(pycompat.sysstr(package)): |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
75 yield encoding.strtolocal(r) |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
76 |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
77 |
43960
75ec46c63657
resourceutil: use `from importlib import resources`
Martin von Zweigbergk <martinvonz@google.com>
parents:
43911
diff
changeset
|
78 except (ImportError, AttributeError): |
43877
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
79 |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
80 def open_resource(package, name): |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
81 path = os.path.join(_package_path(package), name) |
1390bb81163e
help: get helptext/ data from `resources` module if available
Martin von Zweigbergk <martinvonz@google.com>
parents:
43873
diff
changeset
|
82 return open(path, 'rb') |
44030
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
83 |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
84 def is_resource(package, name): |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
85 path = os.path.join(_package_path(package), name) |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
86 |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
87 try: |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
88 return os.path.isfile(pycompat.fsdecode(path)) |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
89 except (IOError, OSError): |
42a897bf678c
resourceutil: implement `is_resource()`
Matt Harbison <matt_harbison@yahoo.com>
parents:
44029
diff
changeset
|
90 return False |
44031
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
91 |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
92 def contents(package): |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
93 path = pycompat.fsdecode(_package_path(package)) |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
94 |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
95 for p in os.listdir(path): |
bba9149adc14
resourceutil: implement `contents()` to iterate over resources in a package
Matt Harbison <matt_harbison@yahoo.com>
parents:
44030
diff
changeset
|
96 yield pycompat.fsencode(p) |