##// END OF EJS Templates
packaging: stage installed files for Inno...
Gregory Szorc -
r43916:d053d3f1 default
parent child Browse files
Show More
@@ -14,7 +14,10 b' import subprocess'
14
14
15 import jinja2
15 import jinja2
16
16
17 from .py2exe import build_py2exe
17 from .py2exe import (
18 build_py2exe,
19 stage_install,
20 )
18 from .util import find_vc_runtime_files
21 from .util import find_vc_runtime_files
19
22
20 EXTRA_PACKAGES = {
23 EXTRA_PACKAGES = {
@@ -24,6 +27,11 b' EXTRA_PACKAGES = {'
24 'win32ctypes',
27 'win32ctypes',
25 }
28 }
26
29
30 PACKAGE_FILES_METADATA = {
31 'ReadMe.html': 'Flags: isreadme',
32 'hg.exe': "AfterInstall: Touch('{app}\\hg.exe.local')",
33 }
34
27
35
28 def build(
36 def build(
29 source_dir: pathlib.Path,
37 source_dir: pathlib.Path,
@@ -47,6 +55,7 b' def build('
47 arch = 'x64' if vc_x64 else 'x86'
55 arch = 'x64' if vc_x64 else 'x86'
48 inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
56 inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
49 inno_build_dir = build_dir / ('inno-%s' % arch)
57 inno_build_dir = build_dir / ('inno-%s' % arch)
58 staging_dir = inno_build_dir / 'stage'
50
59
51 requirements_txt = (
60 requirements_txt = (
52 source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
61 source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
@@ -63,6 +72,15 b' def build('
63 extra_packages=EXTRA_PACKAGES,
72 extra_packages=EXTRA_PACKAGES,
64 )
73 )
65
74
75 # Purge the staging directory for every build so packaging is
76 # pristine.
77 if staging_dir.exists():
78 print('purging %s' % staging_dir)
79 shutil.rmtree(staging_dir)
80
81 # Now assemble all the packaged files into the staging directory.
82 stage_install(source_dir, staging_dir)
83
66 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
84 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
67 for f in find_vc_runtime_files(vc_x64):
85 for f in find_vc_runtime_files(vc_x64):
68 if f.name.endswith('.manifest'):
86 if f.name.endswith('.manifest'):
@@ -70,11 +88,34 b' def build('
70 else:
88 else:
71 basename = f.name
89 basename = f.name
72
90
73 dest_path = source_dir / 'dist' / basename
91 dest_path = staging_dir / basename
74
92
75 print('copying %s to %s' % (f, dest_path))
93 print('copying %s to %s' % (f, dest_path))
76 shutil.copyfile(f, dest_path)
94 shutil.copyfile(f, dest_path)
77
95
96 # The final package layout is simply a mirror of the staging directory.
97 package_files = []
98 for root, dirs, files in os.walk(staging_dir):
99 dirs.sort()
100
101 root = pathlib.Path(root)
102
103 for f in sorted(files):
104 full = root / f
105 rel = full.relative_to(staging_dir)
106 if str(rel.parent) == '.':
107 dest_dir = '{app}'
108 else:
109 dest_dir = '{app}\\%s' % rel.parent
110
111 package_files.append(
112 {
113 'source': rel,
114 'dest_dir': dest_dir,
115 'metadata': PACKAGE_FILES_METADATA.get(str(rel), None),
116 }
117 )
118
78 print('creating installer')
119 print('creating installer')
79
120
80 # Install Inno files by rendering a template.
121 # Install Inno files by rendering a template.
@@ -93,11 +134,17 b' def build('
93 % (e.name, e.lineno, e.message,)
134 % (e.name, e.lineno, e.message,)
94 )
135 )
95
136
96 content = template.render()
137 content = template.render(package_files=package_files)
97
138
98 with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
139 with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
99 fh.write(content)
140 fh.write(content)
100
141
142 # Copy additional files used by Inno.
143 for p in ('mercurial.ico', 'postinstall.txt'):
144 shutil.copyfile(
145 source_dir / 'contrib' / 'win32' / p, inno_build_dir / p
146 )
147
101 args = [str(iscc_exe)]
148 args = [str(iscc_exe)]
102
149
103 if vc_x64:
150 if vc_x64:
@@ -15,10 +15,43 b' from .downloads import download_entry'
15 from .util import (
15 from .util import (
16 extract_tar_to_directory,
16 extract_tar_to_directory,
17 extract_zip_to_directory,
17 extract_zip_to_directory,
18 process_install_rules,
18 python_exe_info,
19 python_exe_info,
19 )
20 )
20
21
21
22
23 STAGING_RULES = [
24 ('contrib/bash_completion', 'Contrib/'),
25 ('contrib/hgk', 'Contrib/hgk.tcl'),
26 ('contrib/hgweb.fcgi', 'Contrib/'),
27 ('contrib/hgweb.wsgi', 'Contrib/'),
28 ('contrib/mercurial.el', 'Contrib/'),
29 ('contrib/mq.el', 'Contrib/'),
30 ('contrib/tcsh_completion', 'Contrib/'),
31 ('contrib/tcsh_completion_build.sh', 'Contrib/'),
32 ('contrib/vim/*', 'Contrib/Vim/'),
33 ('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'),
34 ('contrib/win32/ReadMe.html', 'ReadMe.html'),
35 ('contrib/xml.rnc', 'Contrib/'),
36 ('contrib/zsh_completion', 'Contrib/'),
37 ('dist/hg.exe', './'),
38 ('dist/lib/*.dll', 'lib/'),
39 ('dist/lib/*.pyd', 'lib/'),
40 ('dist/lib/library.zip', 'lib/'),
41 ('dist/Microsoft.VC*.CRT.manifest', './'),
42 ('dist/msvc*.dll', './'),
43 ('dist/python*.dll', './'),
44 ('doc/*.html', 'Docs/'),
45 ('doc/style.css', 'Docs/'),
46 ('mercurial/help/**/*.txt', 'help/'),
47 ('mercurial/default.d/*.rc', 'default.d/'),
48 ('mercurial/locale/**/*', 'locale/'),
49 ('mercurial/templates/**/*', 'Templates/'),
50 ('CONTRIBUTORS', 'Contributors.txt'),
51 ('COPYING', 'Copying.txt'),
52 ]
53
54
22 def build_py2exe(
55 def build_py2exe(
23 source_dir: pathlib.Path,
56 source_dir: pathlib.Path,
24 build_dir: pathlib.Path,
57 build_dir: pathlib.Path,
@@ -169,3 +202,12 b' def build_py2exe('
169 env=env,
202 env=env,
170 check=True,
203 check=True,
171 )
204 )
205
206
207 def stage_install(source_dir: pathlib.Path, staging_dir: pathlib.Path):
208 """Copy all files to be installed to a directory.
209
210 This allows packaging to simply walk a directory tree to find source
211 files.
212 """
213 process_install_rules(STAGING_RULES, source_dir, staging_dir)
@@ -9,8 +9,10 b''
9
9
10 import distutils.version
10 import distutils.version
11 import getpass
11 import getpass
12 import glob
12 import os
13 import os
13 import pathlib
14 import pathlib
15 import shutil
14 import subprocess
16 import subprocess
15 import tarfile
17 import tarfile
16 import zipfile
18 import zipfile
@@ -164,3 +166,47 b' def python_exe_info(python_exe: pathlib.'
164 'version': version,
166 'version': version,
165 'py3': version >= distutils.version.LooseVersion('3'),
167 'py3': version >= distutils.version.LooseVersion('3'),
166 }
168 }
169
170
171 def process_install_rules(
172 rules: list, source_dir: pathlib.Path, dest_dir: pathlib.Path
173 ):
174 for source, dest in rules:
175 if '*' in source:
176 if not dest.endswith('/'):
177 raise ValueError('destination must end in / when globbing')
178
179 # We strip off the source path component before the first glob
180 # character to construct the relative install path.
181 prefix_end_index = source[: source.index('*')].rindex('/')
182 relative_prefix = source_dir / source[0:prefix_end_index]
183
184 for res in glob.glob(str(source_dir / source), recursive=True):
185 source_path = pathlib.Path(res)
186
187 if source_path.is_dir():
188 continue
189
190 rel_path = source_path.relative_to(relative_prefix)
191
192 dest_path = dest_dir / dest[:-1] / rel_path
193
194 dest_path.parent.mkdir(parents=True, exist_ok=True)
195 print('copying %s to %s' % (source_path, dest_path))
196 shutil.copy(source_path, dest_path)
197
198 # Simple file case.
199 else:
200 source_path = pathlib.Path(source)
201
202 if dest.endswith('/'):
203 dest_path = pathlib.Path(dest) / source_path.name
204 else:
205 dest_path = pathlib.Path(dest)
206
207 full_source_path = source_dir / source_path
208 full_dest_path = dest_dir / dest_path
209
210 full_dest_path.parent.mkdir(parents=True, exist_ok=True)
211 shutil.copy(full_source_path, full_dest_path)
212 print('copying %s to %s' % (full_source_path, full_dest_path))
@@ -33,8 +33,8 b' ArchitecturesInstallIn64BitMode=x64'
33 AppVerName=Mercurial {#VERSION}
33 AppVerName=Mercurial {#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
35 #endif
35 #endif
36 InfoAfterFile=contrib/win32/postinstall.txt
36 InfoAfterFile=../postinstall.txt
37 LicenseFile=COPYING
37 LicenseFile=Copying.txt
38 ShowLanguageDialog=yes
38 ShowLanguageDialog=yes
39 AppPublisher=Matt Mackall and others
39 AppPublisher=Matt Mackall and others
40 AppPublisherURL=https://mercurial-scm.org/
40 AppPublisherURL=https://mercurial-scm.org/
@@ -43,49 +43,23 b' AppUpdatesURL=https://mercurial-scm.org/'
43 {{ 'AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}' }}
43 {{ 'AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}' }}
44 AppContact=mercurial@mercurial-scm.org
44 AppContact=mercurial@mercurial-scm.org
45 DefaultDirName={pf}\Mercurial
45 DefaultDirName={pf}\Mercurial
46 SourceDir=..\..
46 SourceDir=stage
47 VersionInfoDescription=Mercurial distributed SCM (version {#VERSION})
47 VersionInfoDescription=Mercurial distributed SCM (version {#VERSION})
48 VersionInfoCopyright=Copyright 2005-2019 Matt Mackall and others
48 VersionInfoCopyright=Copyright 2005-2019 Matt Mackall and others
49 VersionInfoCompany=Matt Mackall and others
49 VersionInfoCompany=Matt Mackall and others
50 InternalCompressLevel=max
50 InternalCompressLevel=max
51 SolidCompression=true
51 SolidCompression=true
52 SetupIconFile=contrib\win32\mercurial.ico
52 SetupIconFile=../mercurial.ico
53 AllowNoIcons=true
53 AllowNoIcons=true
54 DefaultGroupName=Mercurial
54 DefaultGroupName=Mercurial
55 PrivilegesRequired=none
55 PrivilegesRequired=none
56 ChangesEnvironment=true
56 ChangesEnvironment=true
57
57
58 [Files]
58 [Files]
59 Source: contrib\mercurial.el; DestDir: {app}/Contrib
59 {% for entry in package_files -%}
60 Source: contrib\vim\*.*; DestDir: {app}/Contrib/Vim
60 Source: {{ entry.source }}; DestDir: {{ entry.dest_dir }}
61 Source: contrib\zsh_completion; DestDir: {app}/Contrib
61 {%- if entry.metadata %}; {{ entry.metadata }}{% endif %}
62 Source: contrib\bash_completion; DestDir: {app}/Contrib
62 {% endfor %}
63 Source: contrib\tcsh_completion; DestDir: {app}/Contrib
64 Source: contrib\tcsh_completion_build.sh; DestDir: {app}/Contrib
65 Source: contrib\hgk; DestDir: {app}/Contrib; DestName: hgk.tcl
66 Source: contrib\xml.rnc; DestDir: {app}/Contrib
67 Source: contrib\mercurial.el; DestDir: {app}/Contrib
68 Source: contrib\mq.el; DestDir: {app}/Contrib
69 Source: contrib\hgweb.fcgi; DestDir: {app}/Contrib
70 Source: contrib\hgweb.wsgi; DestDir: {app}/Contrib
71 Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
72 Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
73 Source: dist\hg.exe; DestDir: {app}; AfterInstall: Touch('{app}\hg.exe.local')
74 Source: dist\lib\*.dll; Destdir: {app}\lib
75 Source: dist\lib\*.pyd; Destdir: {app}\lib
76 Source: dist\python*.dll; Destdir: {app}; Flags: skipifsourcedoesntexist
77 Source: dist\msvc*.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
78 Source: dist\Microsoft.VC*.CRT.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
79 Source: dist\lib\library.zip; DestDir: {app}\lib
80 Source: doc\*.html; DestDir: {app}\Docs
81 Source: doc\style.css; DestDir: {app}\Docs
82 Source: mercurial\help\*.txt; DestDir: {app}\help
83 Source: mercurial\help\internals\*.txt; DestDir: {app}\help\internals
84 Source: mercurial\default.d\*.rc; DestDir: {app}\default.d
85 Source: mercurial\locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs skipifsourcedoesntexist
86 Source: mercurial\templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
87 Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
88 Source: COPYING; DestDir: {app}; DestName: Copying.txt
89
63
90 [INI]
64 [INI]
91 Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: https://mercurial-scm.org/
65 Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: https://mercurial-scm.org/
General Comments 0
You need to be logged in to leave comments. Login now