##// END OF EJS Templates
wix: remove enum and future packages...
Gregory Szorc -
r42090:9d4ae504 default
parent child Browse files
Show More
@@ -1,240 +1,239 b''
1 1 # wix.py - WiX installer functionality
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 re
13 13 import subprocess
14 14
15 15 from .downloads import (
16 16 download_entry,
17 17 )
18 18 from .py2exe import (
19 19 build_py2exe,
20 20 )
21 21 from .util import (
22 22 extract_zip_to_directory,
23 23 sign_with_signtool,
24 24 )
25 25
26 26
27 27 SUPPORT_WXS = [
28 28 ('contrib.wxs', r'contrib'),
29 29 ('dist.wxs', r'dist'),
30 30 ('doc.wxs', r'doc'),
31 31 ('help.wxs', r'mercurial\help'),
32 32 ('i18n.wxs', r'i18n'),
33 33 ('locale.wxs', r'mercurial\locale'),
34 34 ('templates.wxs', r'mercurial\templates'),
35 35 ]
36 36
37 37
38 38 EXTRA_PACKAGES = {
39 39 'distutils',
40 'enum',
41 40 'pygments',
42 41 }
43 42
44 43
45 44 def find_version(source_dir: pathlib.Path):
46 45 version_py = source_dir / 'mercurial' / '__version__.py'
47 46
48 47 with version_py.open('r', encoding='utf-8') as fh:
49 48 source = fh.read().strip()
50 49
51 50 m = re.search('version = b"(.*)"', source)
52 51 return m.group(1)
53 52
54 53
55 54 def normalize_version(version):
56 55 """Normalize Mercurial version string so WiX accepts it.
57 56
58 57 Version strings have to be numeric X.Y.Z.
59 58 """
60 59
61 60 if '+' in version:
62 61 version, extra = version.split('+', 1)
63 62 else:
64 63 extra = None
65 64
66 65 # 4.9rc0
67 66 if version[:-1].endswith('rc'):
68 67 version = version[:-3]
69 68
70 69 versions = [int(v) for v in version.split('.')]
71 70 while len(versions) < 3:
72 71 versions.append(0)
73 72
74 73 major, minor, build = versions[:3]
75 74
76 75 if extra:
77 76 # <commit count>-<hash>+<date>
78 77 build = int(extra.split('-')[0])
79 78
80 79 return '.'.join('%d' % x for x in (major, minor, build))
81 80
82 81
83 82 def ensure_vc90_merge_modules(build_dir):
84 83 x86 = (
85 84 download_entry('vc9-crt-x86-msm', build_dir,
86 85 local_name='microsoft.vcxx.crt.x86_msm.msm')[0],
87 86 download_entry('vc9-crt-x86-msm-policy', build_dir,
88 87 local_name='policy.x.xx.microsoft.vcxx.crt.x86_msm.msm')[0]
89 88 )
90 89
91 90 x64 = (
92 91 download_entry('vc9-crt-x64-msm', build_dir,
93 92 local_name='microsoft.vcxx.crt.x64_msm.msm')[0],
94 93 download_entry('vc9-crt-x64-msm-policy', build_dir,
95 94 local_name='policy.x.xx.microsoft.vcxx.crt.x64_msm.msm')[0]
96 95 )
97 96 return {
98 97 'x86': x86,
99 98 'x64': x64,
100 99 }
101 100
102 101
103 102 def run_candle(wix, cwd, wxs, source_dir, defines=None):
104 103 args = [
105 104 str(wix / 'candle.exe'),
106 105 '-nologo',
107 106 str(wxs),
108 107 '-dSourceDir=%s' % source_dir,
109 108 ]
110 109
111 110 if defines:
112 111 args.extend('-d%s=%s' % define for define in sorted(defines.items()))
113 112
114 113 subprocess.run(args, cwd=str(cwd), check=True)
115 114
116 115
117 116 def make_post_build_signing_fn(name, subject_name=None, cert_path=None,
118 117 cert_password=None, timestamp_url=None):
119 118 """Create a callable that will use signtool to sign hg.exe."""
120 119
121 120 def post_build_sign(source_dir, build_dir, dist_dir, version):
122 121 description = '%s %s' % (name, version)
123 122
124 123 sign_with_signtool(dist_dir / 'hg.exe', description,
125 124 subject_name=subject_name, cert_path=cert_path,
126 125 cert_password=cert_password,
127 126 timestamp_url=timestamp_url)
128 127
129 128 return post_build_sign
130 129
131 130
132 131 def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
133 132 msi_name='mercurial', version=None, post_build_fn=None):
134 133 """Build a WiX MSI installer.
135 134
136 135 ``source_dir`` is the path to the Mercurial source tree to use.
137 136 ``arch`` is the target architecture. either ``x86`` or ``x64``.
138 137 ``python_exe`` is the path to the Python executable to use/bundle.
139 138 ``version`` is the Mercurial version string. If not defined,
140 139 ``mercurial/__version__.py`` will be consulted.
141 140 ``post_build_fn`` is a callable that will be called after building
142 141 Mercurial but before invoking WiX. It can be used to e.g. facilitate
143 142 signing. It is passed the paths to the Mercurial source, build, and
144 143 dist directories and the resolved Mercurial version.
145 144 """
146 145 arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86'
147 146
148 147 hg_build_dir = source_dir / 'build'
149 148 dist_dir = source_dir / 'dist'
150 149
151 150 requirements_txt = (source_dir / 'contrib' / 'packaging' /
152 151 'wix' / 'requirements.txt')
153 152
154 153 build_py2exe(source_dir, hg_build_dir,
155 154 python_exe, 'wix', requirements_txt,
156 155 extra_packages=EXTRA_PACKAGES)
157 156
158 157 version = version or normalize_version(find_version(source_dir))
159 158 print('using version string: %s' % version)
160 159
161 160 if post_build_fn:
162 161 post_build_fn(source_dir, hg_build_dir, dist_dir, version)
163 162
164 163 build_dir = hg_build_dir / ('wix-%s' % arch)
165 164
166 165 build_dir.mkdir(exist_ok=True)
167 166
168 167 wix_pkg, wix_entry = download_entry('wix', hg_build_dir)
169 168 wix_path = hg_build_dir / ('wix-%s' % wix_entry['version'])
170 169
171 170 if not wix_path.exists():
172 171 extract_zip_to_directory(wix_pkg, wix_path)
173 172
174 173 ensure_vc90_merge_modules(hg_build_dir)
175 174
176 175 source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir))
177 176
178 177 defines = {'Platform': arch}
179 178
180 179 for wxs, rel_path in SUPPORT_WXS:
181 180 wxs = source_dir / 'contrib' / 'packaging' / 'wix' / wxs
182 181 wxs_source_dir = source_dir / rel_path
183 182 run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines)
184 183
185 184 source = source_dir / 'contrib' / 'packaging' / 'wix' / 'mercurial.wxs'
186 185 defines['Version'] = version
187 186 defines['Comments'] = 'Installs Mercurial version %s' % version
188 187 defines['VCRedistSrcDir'] = str(hg_build_dir)
189 188
190 189 run_candle(wix_path, build_dir, source, source_build_rel, defines=defines)
191 190
192 191 msi_path = source_dir / 'dist' / (
193 192 '%s-%s-%s.msi' % (msi_name, version, arch))
194 193
195 194 args = [
196 195 str(wix_path / 'light.exe'),
197 196 '-nologo',
198 197 '-ext', 'WixUIExtension',
199 198 '-sw1076',
200 199 '-spdb',
201 200 '-o', str(msi_path),
202 201 ]
203 202
204 203 for source, rel_path in SUPPORT_WXS:
205 204 assert source.endswith('.wxs')
206 205 args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
207 206
208 207 args.append(str(build_dir / 'mercurial.wixobj'))
209 208
210 209 subprocess.run(args, cwd=str(source_dir), check=True)
211 210
212 211 print('%s created' % msi_path)
213 212
214 213 return {
215 214 'msi_path': msi_path,
216 215 }
217 216
218 217
219 218 def build_signed_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
220 219 name: str, version=None, subject_name=None,
221 220 cert_path=None, cert_password=None,
222 221 timestamp_url=None):
223 222 """Build an installer with signed executables."""
224 223
225 224 post_build_fn = make_post_build_signing_fn(
226 225 name,
227 226 subject_name=subject_name,
228 227 cert_path=cert_path,
229 228 cert_password=cert_password,
230 229 timestamp_url=timestamp_url)
231 230
232 231 info = build_installer(source_dir, python_exe=python_exe,
233 232 msi_name=name.lower(), version=version,
234 233 post_build_fn=post_build_fn)
235 234
236 235 description = '%s %s' % (name, version)
237 236
238 237 sign_with_signtool(info['msi_path'], description,
239 238 subject_name=subject_name, cert_path=cert_path,
240 239 cert_password=cert_password, timestamp_url=timestamp_url)
@@ -1,17 +1,13 b''
1 1 #
2 2 # This file is autogenerated by pip-compile
3 3 # To update, run:
4 4 #
5 5 # pip-compile --generate-hashes contrib/packaging/wix/requirements.txt.in -o contrib/packaging/wix/requirements.txt
6 6 #
7 7 docutils==0.14 \
8 8 --hash=sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6 \
9 9 --hash=sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274 \
10 10 --hash=sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6
11 enum==0.4.7 \
12 --hash=sha256:8c7cf3587eda51008bcc1eed99ea2c331ccd265c231dbaa95ec5258d3dc03100
13 future==0.17.1 \
14 --hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8
15 11 pygments==2.3.1 \
16 12 --hash=sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a \
17 13 --hash=sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d
@@ -1,4 +1,2 b''
1 1 docutils
2 enum
3 future
4 2 pygments
General Comments 0
You need to be logged in to leave comments. Login now