##// END OF EJS Templates
packaging: add logo-droplets.svg...
Gregory Szorc -
r43826:29083459 default draft
parent child Browse files
Show More
@@ -1,213 +1,214 b''
1 1 # py2exe.py - Functionality for performing py2exe builds.
2 2 #
3 3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 # no-check-code because Python 3 native.
9 9
10 10 import os
11 11 import pathlib
12 12 import subprocess
13 13
14 14 from .downloads import download_entry
15 15 from .util import (
16 16 extract_tar_to_directory,
17 17 extract_zip_to_directory,
18 18 process_install_rules,
19 19 python_exe_info,
20 20 )
21 21
22 22
23 23 STAGING_RULES = [
24 24 ('contrib/bash_completion', 'Contrib/'),
25 25 ('contrib/hgk', 'Contrib/hgk.tcl'),
26 26 ('contrib/hgweb.fcgi', 'Contrib/'),
27 27 ('contrib/hgweb.wsgi', 'Contrib/'),
28 ('contrib/logo-droplets.svg', 'Contrib/'),
28 29 ('contrib/mercurial.el', 'Contrib/'),
29 30 ('contrib/mq.el', 'Contrib/'),
30 31 ('contrib/tcsh_completion', 'Contrib/'),
31 32 ('contrib/tcsh_completion_build.sh', 'Contrib/'),
32 33 ('contrib/vim/*', 'Contrib/Vim/'),
33 34 ('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'),
34 35 ('contrib/win32/ReadMe.html', 'ReadMe.html'),
35 36 ('contrib/xml.rnc', 'Contrib/'),
36 37 ('contrib/zsh_completion', 'Contrib/'),
37 38 ('dist/hg.exe', './'),
38 39 ('dist/lib/*.dll', 'lib/'),
39 40 ('dist/lib/*.pyd', 'lib/'),
40 41 ('dist/lib/library.zip', 'lib/'),
41 42 ('dist/Microsoft.VC*.CRT.manifest', './'),
42 43 ('dist/msvc*.dll', './'),
43 44 ('dist/python*.dll', './'),
44 45 ('doc/*.html', 'doc/'),
45 46 ('doc/style.css', 'doc/'),
46 47 ('mercurial/help/**/*.txt', 'help/'),
47 48 ('mercurial/default.d/*.rc', 'default.d/'),
48 49 ('mercurial/locale/**/*', 'locale/'),
49 50 ('mercurial/templates/**/*', 'Templates/'),
50 51 ('CONTRIBUTORS', 'Contributors.txt'),
51 52 ('COPYING', 'Copying.txt'),
52 53 ]
53 54
54 55
55 56 def build_py2exe(
56 57 source_dir: pathlib.Path,
57 58 build_dir: pathlib.Path,
58 59 python_exe: pathlib.Path,
59 60 build_name: str,
60 61 venv_requirements_txt: pathlib.Path,
61 62 extra_packages=None,
62 63 extra_excludes=None,
63 64 extra_dll_excludes=None,
64 65 extra_packages_script=None,
65 66 ):
66 67 """Build Mercurial with py2exe.
67 68
68 69 Build files will be placed in ``build_dir``.
69 70
70 71 py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
71 72 for finding the Python 2.7 toolchain. So, we require the environment
72 73 to already be configured with an active toolchain.
73 74 """
74 75 if 'VCINSTALLDIR' not in os.environ:
75 76 raise Exception(
76 77 'not running from a Visual C++ build environment; '
77 78 'execute the "Visual C++ <version> Command Prompt" '
78 79 'application shortcut or a vcsvarsall.bat file'
79 80 )
80 81
81 82 # Identity x86/x64 and validate the environment matches the Python
82 83 # architecture.
83 84 vc_x64 = r'\x64' in os.environ['LIB']
84 85
85 86 py_info = python_exe_info(python_exe)
86 87
87 88 if vc_x64:
88 89 if py_info['arch'] != '64bit':
89 90 raise Exception(
90 91 'architecture mismatch: Visual C++ environment '
91 92 'is configured for 64-bit but Python is 32-bit'
92 93 )
93 94 else:
94 95 if py_info['arch'] != '32bit':
95 96 raise Exception(
96 97 'architecture mismatch: Visual C++ environment '
97 98 'is configured for 32-bit but Python is 64-bit'
98 99 )
99 100
100 101 if py_info['py3']:
101 102 raise Exception('Only Python 2 is currently supported')
102 103
103 104 build_dir.mkdir(exist_ok=True)
104 105
105 106 gettext_pkg, gettext_entry = download_entry('gettext', build_dir)
106 107 gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0]
107 108 virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir)
108 109 py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir)
109 110
110 111 venv_path = build_dir / (
111 112 'venv-%s-%s' % (build_name, 'x64' if vc_x64 else 'x86')
112 113 )
113 114
114 115 gettext_root = build_dir / ('gettext-win-%s' % gettext_entry['version'])
115 116
116 117 if not gettext_root.exists():
117 118 extract_zip_to_directory(gettext_pkg, gettext_root)
118 119 extract_zip_to_directory(gettext_dep_pkg, gettext_root)
119 120
120 121 # This assumes Python 2. We don't need virtualenv on Python 3.
121 122 virtualenv_src_path = build_dir / (
122 123 'virtualenv-%s' % virtualenv_entry['version']
123 124 )
124 125 virtualenv_py = virtualenv_src_path / 'virtualenv.py'
125 126
126 127 if not virtualenv_src_path.exists():
127 128 extract_tar_to_directory(virtualenv_pkg, build_dir)
128 129
129 130 py2exe_source_path = build_dir / ('py2exe-%s' % py2exe_entry['version'])
130 131
131 132 if not py2exe_source_path.exists():
132 133 extract_zip_to_directory(py2exe_pkg, build_dir)
133 134
134 135 if not venv_path.exists():
135 136 print('creating virtualenv with dependencies')
136 137 subprocess.run(
137 138 [str(python_exe), str(virtualenv_py), str(venv_path)], check=True
138 139 )
139 140
140 141 venv_python = venv_path / 'Scripts' / 'python.exe'
141 142 venv_pip = venv_path / 'Scripts' / 'pip.exe'
142 143
143 144 subprocess.run(
144 145 [str(venv_pip), 'install', '-r', str(venv_requirements_txt)], check=True
145 146 )
146 147
147 148 # Force distutils to use VC++ settings from environment, which was
148 149 # validated above.
149 150 env = dict(os.environ)
150 151 env['DISTUTILS_USE_SDK'] = '1'
151 152 env['MSSdk'] = '1'
152 153
153 154 if extra_packages_script:
154 155 more_packages = set(
155 156 subprocess.check_output(extra_packages_script, cwd=build_dir)
156 157 .split(b'\0')[-1]
157 158 .strip()
158 159 .decode('utf-8')
159 160 .splitlines()
160 161 )
161 162 if more_packages:
162 163 if not extra_packages:
163 164 extra_packages = more_packages
164 165 else:
165 166 extra_packages |= more_packages
166 167
167 168 if extra_packages:
168 169 env['HG_PY2EXE_EXTRA_PACKAGES'] = ' '.join(sorted(extra_packages))
169 170 hgext3rd_extras = sorted(
170 171 e for e in extra_packages if e.startswith('hgext3rd.')
171 172 )
172 173 if hgext3rd_extras:
173 174 env['HG_PY2EXE_EXTRA_INSTALL_PACKAGES'] = ' '.join(hgext3rd_extras)
174 175 if extra_excludes:
175 176 env['HG_PY2EXE_EXTRA_EXCLUDES'] = ' '.join(sorted(extra_excludes))
176 177 if extra_dll_excludes:
177 178 env['HG_PY2EXE_EXTRA_DLL_EXCLUDES'] = ' '.join(
178 179 sorted(extra_dll_excludes)
179 180 )
180 181
181 182 py2exe_py_path = venv_path / 'Lib' / 'site-packages' / 'py2exe'
182 183 if not py2exe_py_path.exists():
183 184 print('building py2exe')
184 185 subprocess.run(
185 186 [str(venv_python), 'setup.py', 'install'],
186 187 cwd=py2exe_source_path,
187 188 env=env,
188 189 check=True,
189 190 )
190 191
191 192 # Register location of msgfmt and other binaries.
192 193 env['PATH'] = '%s%s%s' % (
193 194 env['PATH'],
194 195 os.pathsep,
195 196 str(gettext_root / 'bin'),
196 197 )
197 198
198 199 print('building Mercurial')
199 200 subprocess.run(
200 201 [str(venv_python), 'setup.py', 'py2exe', 'build_doc', '--html'],
201 202 cwd=str(source_dir),
202 203 env=env,
203 204 check=True,
204 205 )
205 206
206 207
207 208 def stage_install(source_dir: pathlib.Path, staging_dir: pathlib.Path):
208 209 """Copy all files to be installed to a directory.
209 210
210 211 This allows packaging to simply walk a directory tree to find source
211 212 files.
212 213 """
213 214 process_install_rules(STAGING_RULES, source_dir, staging_dir)
General Comments 0
You need to be logged in to leave comments. Login now