Show More
@@ -11,6 +11,8 b' import os' | |||
|
11 | 11 | import pathlib |
|
12 | 12 | import re |
|
13 | 13 | import subprocess |
|
14 | import tempfile | |
|
15 | import xml.dom.minidom | |
|
14 | 16 | |
|
15 | 17 | from .downloads import ( |
|
16 | 18 | download_entry, |
@@ -128,6 +130,52 b' def make_post_build_signing_fn(name, sub' | |||
|
128 | 130 | return post_build_sign |
|
129 | 131 | |
|
130 | 132 | |
|
133 | LIBRARIES_XML = ''' | |
|
134 | <?xml version="1.0" encoding="utf-8"?> | |
|
135 | <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> | |
|
136 | ||
|
137 | <?include {wix_dir}/guids.wxi ?> | |
|
138 | <?include {wix_dir}/defines.wxi ?> | |
|
139 | ||
|
140 | <Fragment> | |
|
141 | <DirectoryRef Id="INSTALLDIR" FileSource="$(var.SourceDir)"> | |
|
142 | <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib"> | |
|
143 | <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'> | |
|
144 | </Component> | |
|
145 | </Directory> | |
|
146 | </DirectoryRef> | |
|
147 | </Fragment> | |
|
148 | </Wix> | |
|
149 | '''.lstrip() | |
|
150 | ||
|
151 | ||
|
152 | def make_libraries_xml(wix_dir: pathlib.Path, dist_dir: pathlib.Path): | |
|
153 | """Make XML data for library components WXS.""" | |
|
154 | # We can't use ElementTree because it doesn't handle the | |
|
155 | # <?include ?> directives. | |
|
156 | doc = xml.dom.minidom.parseString( | |
|
157 | LIBRARIES_XML.format(wix_dir=str(wix_dir))) | |
|
158 | ||
|
159 | component = doc.getElementsByTagName('Component')[0] | |
|
160 | ||
|
161 | f = doc.createElement('File') | |
|
162 | f.setAttribute('Name', 'library.zip') | |
|
163 | f.setAttribute('KeyPath', 'yes') | |
|
164 | component.appendChild(f) | |
|
165 | ||
|
166 | lib_dir = dist_dir / 'lib' | |
|
167 | ||
|
168 | for p in sorted(lib_dir.iterdir()): | |
|
169 | if not p.name.endswith(('.dll', '.pyd')): | |
|
170 | continue | |
|
171 | ||
|
172 | f = doc.createElement('File') | |
|
173 | f.setAttribute('Name', p.name) | |
|
174 | component.appendChild(f) | |
|
175 | ||
|
176 | return doc.toprettyxml() | |
|
177 | ||
|
178 | ||
|
131 | 179 | def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path, |
|
132 | 180 | msi_name='mercurial', version=None, post_build_fn=None): |
|
133 | 181 | """Build a WiX MSI installer. |
@@ -181,6 +229,17 b' def build_installer(source_dir: pathlib.' | |||
|
181 | 229 | wxs_source_dir = source_dir / rel_path |
|
182 | 230 | run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines) |
|
183 | 231 | |
|
232 | # candle.exe doesn't like when we have an open handle on the file. | |
|
233 | # So use TemporaryDirectory() instead of NamedTemporaryFile(). | |
|
234 | with tempfile.TemporaryDirectory() as td: | |
|
235 | td = pathlib.Path(td) | |
|
236 | ||
|
237 | tf = td / 'library.wxs' | |
|
238 | with tf.open('w') as fh: | |
|
239 | fh.write(make_libraries_xml(wix_dir, dist_dir)) | |
|
240 | ||
|
241 | run_candle(wix_path, build_dir, tf, dist_dir, defines=defines) | |
|
242 | ||
|
184 | 243 | source = wix_dir / 'mercurial.wxs' |
|
185 | 244 | defines['Version'] = version |
|
186 | 245 | defines['Comments'] = 'Installs Mercurial version %s' % version |
@@ -204,7 +263,10 b' def build_installer(source_dir: pathlib.' | |||
|
204 | 263 | assert source.endswith('.wxs') |
|
205 | 264 | args.append(str(build_dir / ('%s.wixobj' % source[:-4]))) |
|
206 | 265 | |
|
207 | args.append(str(build_dir / 'mercurial.wixobj')) | |
|
266 | args.extend([ | |
|
267 | str(build_dir / 'library.wixobj'), | |
|
268 | str(build_dir / 'mercurial.wixobj'), | |
|
269 | ]) | |
|
208 | 270 | |
|
209 | 271 | subprocess.run(args, cwd=str(source_dir), check=True) |
|
210 | 272 |
@@ -9,35 +9,6 b'' | |||
|
9 | 9 | <Component Id="distOutput" Guid="$(var.dist.guid)" Win64='$(var.IsX64)'> |
|
10 | 10 | <File Name="python27.dll" KeyPath="yes" /> |
|
11 | 11 | </Component> |
|
12 | <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib"> | |
|
13 | <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'> | |
|
14 | <File Name="library.zip" KeyPath="yes" /> | |
|
15 | <File Name="mercurial.cext.base85.pyd" /> | |
|
16 | <File Name="mercurial.cext.bdiff.pyd" /> | |
|
17 | <File Name="mercurial.cext.mpatch.pyd" /> | |
|
18 | <File Name="mercurial.cext.osutil.pyd" /> | |
|
19 | <File Name="mercurial.cext.parsers.pyd" /> | |
|
20 | <File Name="mercurial.thirdparty.zope.interface._zope_interface_coptimizations.pyd" /> | |
|
21 | <File Name="mercurial.zstd.pyd" /> | |
|
22 | <File Name="hgext.fsmonitor.pywatchman.bser.pyd" /> | |
|
23 | <File Name="pyexpat.pyd" /> | |
|
24 | <File Name="bz2.pyd" /> | |
|
25 | <File Name="select.pyd" /> | |
|
26 | <File Name="sqlite3.dll" /> | |
|
27 | <File Name="tcl85.dll" /> | |
|
28 | <File Name="tk85.dll" /> | |
|
29 | <File Name="unicodedata.pyd" /> | |
|
30 | <File Name="_ctypes.pyd" /> | |
|
31 | <File Name="_elementtree.pyd" /> | |
|
32 | <File Name="_testcapi.pyd" /> | |
|
33 | <File Name="_hashlib.pyd" /> | |
|
34 | <File Name="_multiprocessing.pyd" /> | |
|
35 | <File Name="_socket.pyd" /> | |
|
36 | <File Name="_sqlite3.pyd" /> | |
|
37 | <File Name="_ssl.pyd" /> | |
|
38 | <File Name="_tkinter.pyd" /> | |
|
39 | </Component> | |
|
40 | </Directory> | |
|
41 | 12 | </DirectoryRef> |
|
42 | 13 | </Fragment> |
|
43 | 14 |
General Comments 0
You need to be logged in to leave comments.
Login now