##// END OF EJS Templates
packaging: remove hg.exe.local file...
Gregory Szorc -
r43917:24633444 default
parent child Browse files
Show More
@@ -1,159 +1,158 b''
1 # inno.py - Inno Setup functionality.
1 # inno.py - Inno Setup functionality.
2 #
2 #
3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # no-check-code because Python 3 native.
8 # no-check-code because Python 3 native.
9
9
10 import os
10 import os
11 import pathlib
11 import pathlib
12 import shutil
12 import shutil
13 import subprocess
13 import subprocess
14
14
15 import jinja2
15 import jinja2
16
16
17 from .py2exe import (
17 from .py2exe import (
18 build_py2exe,
18 build_py2exe,
19 stage_install,
19 stage_install,
20 )
20 )
21 from .util import find_vc_runtime_files
21 from .util import find_vc_runtime_files
22
22
23 EXTRA_PACKAGES = {
23 EXTRA_PACKAGES = {
24 'dulwich',
24 'dulwich',
25 'keyring',
25 'keyring',
26 'pygments',
26 'pygments',
27 'win32ctypes',
27 'win32ctypes',
28 }
28 }
29
29
30 PACKAGE_FILES_METADATA = {
30 PACKAGE_FILES_METADATA = {
31 'ReadMe.html': 'Flags: isreadme',
31 'ReadMe.html': 'Flags: isreadme',
32 'hg.exe': "AfterInstall: Touch('{app}\\hg.exe.local')",
33 }
32 }
34
33
35
34
36 def build(
35 def build(
37 source_dir: pathlib.Path,
36 source_dir: pathlib.Path,
38 build_dir: pathlib.Path,
37 build_dir: pathlib.Path,
39 python_exe: pathlib.Path,
38 python_exe: pathlib.Path,
40 iscc_exe: pathlib.Path,
39 iscc_exe: pathlib.Path,
41 version=None,
40 version=None,
42 ):
41 ):
43 """Build the Inno installer.
42 """Build the Inno installer.
44
43
45 Build files will be placed in ``build_dir``.
44 Build files will be placed in ``build_dir``.
46
45
47 py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
46 py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
48 for finding the Python 2.7 toolchain. So, we require the environment
47 for finding the Python 2.7 toolchain. So, we require the environment
49 to already be configured with an active toolchain.
48 to already be configured with an active toolchain.
50 """
49 """
51 if not iscc_exe.exists():
50 if not iscc_exe.exists():
52 raise Exception('%s does not exist' % iscc_exe)
51 raise Exception('%s does not exist' % iscc_exe)
53
52
54 vc_x64 = r'\x64' in os.environ.get('LIB', '')
53 vc_x64 = r'\x64' in os.environ.get('LIB', '')
55 arch = 'x64' if vc_x64 else 'x86'
54 arch = 'x64' if vc_x64 else 'x86'
56 inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
55 inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
57 inno_build_dir = build_dir / ('inno-%s' % arch)
56 inno_build_dir = build_dir / ('inno-%s' % arch)
58 staging_dir = inno_build_dir / 'stage'
57 staging_dir = inno_build_dir / 'stage'
59
58
60 requirements_txt = (
59 requirements_txt = (
61 source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
60 source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
62 )
61 )
63
62
64 inno_build_dir.mkdir(parents=True, exist_ok=True)
63 inno_build_dir.mkdir(parents=True, exist_ok=True)
65
64
66 build_py2exe(
65 build_py2exe(
67 source_dir,
66 source_dir,
68 build_dir,
67 build_dir,
69 python_exe,
68 python_exe,
70 'inno',
69 'inno',
71 requirements_txt,
70 requirements_txt,
72 extra_packages=EXTRA_PACKAGES,
71 extra_packages=EXTRA_PACKAGES,
73 )
72 )
74
73
75 # Purge the staging directory for every build so packaging is
74 # Purge the staging directory for every build so packaging is
76 # pristine.
75 # pristine.
77 if staging_dir.exists():
76 if staging_dir.exists():
78 print('purging %s' % staging_dir)
77 print('purging %s' % staging_dir)
79 shutil.rmtree(staging_dir)
78 shutil.rmtree(staging_dir)
80
79
81 # Now assemble all the packaged files into the staging directory.
80 # Now assemble all the packaged files into the staging directory.
82 stage_install(source_dir, staging_dir)
81 stage_install(source_dir, staging_dir)
83
82
84 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
83 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
85 for f in find_vc_runtime_files(vc_x64):
84 for f in find_vc_runtime_files(vc_x64):
86 if f.name.endswith('.manifest'):
85 if f.name.endswith('.manifest'):
87 basename = 'Microsoft.VC90.CRT.manifest'
86 basename = 'Microsoft.VC90.CRT.manifest'
88 else:
87 else:
89 basename = f.name
88 basename = f.name
90
89
91 dest_path = staging_dir / basename
90 dest_path = staging_dir / basename
92
91
93 print('copying %s to %s' % (f, dest_path))
92 print('copying %s to %s' % (f, dest_path))
94 shutil.copyfile(f, dest_path)
93 shutil.copyfile(f, dest_path)
95
94
96 # The final package layout is simply a mirror of the staging directory.
95 # The final package layout is simply a mirror of the staging directory.
97 package_files = []
96 package_files = []
98 for root, dirs, files in os.walk(staging_dir):
97 for root, dirs, files in os.walk(staging_dir):
99 dirs.sort()
98 dirs.sort()
100
99
101 root = pathlib.Path(root)
100 root = pathlib.Path(root)
102
101
103 for f in sorted(files):
102 for f in sorted(files):
104 full = root / f
103 full = root / f
105 rel = full.relative_to(staging_dir)
104 rel = full.relative_to(staging_dir)
106 if str(rel.parent) == '.':
105 if str(rel.parent) == '.':
107 dest_dir = '{app}'
106 dest_dir = '{app}'
108 else:
107 else:
109 dest_dir = '{app}\\%s' % rel.parent
108 dest_dir = '{app}\\%s' % rel.parent
110
109
111 package_files.append(
110 package_files.append(
112 {
111 {
113 'source': rel,
112 'source': rel,
114 'dest_dir': dest_dir,
113 'dest_dir': dest_dir,
115 'metadata': PACKAGE_FILES_METADATA.get(str(rel), None),
114 'metadata': PACKAGE_FILES_METADATA.get(str(rel), None),
116 }
115 }
117 )
116 )
118
117
119 print('creating installer')
118 print('creating installer')
120
119
121 # Install Inno files by rendering a template.
120 # Install Inno files by rendering a template.
122 jinja_env = jinja2.Environment(
121 jinja_env = jinja2.Environment(
123 loader=jinja2.FileSystemLoader(str(inno_source_dir)),
122 loader=jinja2.FileSystemLoader(str(inno_source_dir)),
124 # Need to change these to prevent conflict with Inno Setup.
123 # Need to change these to prevent conflict with Inno Setup.
125 comment_start_string='{##',
124 comment_start_string='{##',
126 comment_end_string='##}',
125 comment_end_string='##}',
127 )
126 )
128
127
129 try:
128 try:
130 template = jinja_env.get_template('mercurial.iss')
129 template = jinja_env.get_template('mercurial.iss')
131 except jinja2.TemplateSyntaxError as e:
130 except jinja2.TemplateSyntaxError as e:
132 raise Exception(
131 raise Exception(
133 'template syntax error at %s:%d: %s'
132 'template syntax error at %s:%d: %s'
134 % (e.name, e.lineno, e.message,)
133 % (e.name, e.lineno, e.message,)
135 )
134 )
136
135
137 content = template.render(package_files=package_files)
136 content = template.render(package_files=package_files)
138
137
139 with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
138 with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
140 fh.write(content)
139 fh.write(content)
141
140
142 # Copy additional files used by Inno.
141 # Copy additional files used by Inno.
143 for p in ('mercurial.ico', 'postinstall.txt'):
142 for p in ('mercurial.ico', 'postinstall.txt'):
144 shutil.copyfile(
143 shutil.copyfile(
145 source_dir / 'contrib' / 'win32' / p, inno_build_dir / p
144 source_dir / 'contrib' / 'win32' / p, inno_build_dir / p
146 )
145 )
147
146
148 args = [str(iscc_exe)]
147 args = [str(iscc_exe)]
149
148
150 if vc_x64:
149 if vc_x64:
151 args.append('/dARCH=x64')
150 args.append('/dARCH=x64')
152
151
153 if version:
152 if version:
154 args.append('/dVERSION=%s' % version)
153 args.append('/dVERSION=%s' % version)
155
154
156 args.append('/Odist')
155 args.append('/Odist')
157 args.append(str(inno_build_dir / 'mercurial.iss'))
156 args.append(str(inno_build_dir / 'mercurial.iss'))
158
157
159 subprocess.run(args, cwd=str(source_dir), check=True)
158 subprocess.run(args, cwd=str(source_dir), check=True)
@@ -1,99 +1,98 b''
1 ; Script generated by the Inno Setup Script Wizard.
1 ; Script generated by the Inno Setup Script Wizard.
2 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
2 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3
3
4 #ifndef VERSION
4 #ifndef VERSION
5 #define FileHandle
5 #define FileHandle
6 #define FileLine
6 #define FileLine
7 #define VERSION = "unknown"
7 #define VERSION = "unknown"
8 #if FileHandle = FileOpen(SourcePath + "\..\..\mercurial\__version__.py")
8 #if FileHandle = FileOpen(SourcePath + "\..\..\mercurial\__version__.py")
9 #expr FileLine = FileRead(FileHandle)
9 #expr FileLine = FileRead(FileHandle)
10 #expr FileLine = FileRead(FileHandle)
10 #expr FileLine = FileRead(FileHandle)
11 #define VERSION = Copy(FileLine, Pos('"', FileLine)+1, Len(FileLine)-Pos('"', FileLine)-1)
11 #define VERSION = Copy(FileLine, Pos('"', FileLine)+1, Len(FileLine)-Pos('"', FileLine)-1)
12 #endif
12 #endif
13 #if FileHandle
13 #if FileHandle
14 #expr FileClose(FileHandle)
14 #expr FileClose(FileHandle)
15 #endif
15 #endif
16 #pragma message "Detected Version: " + VERSION
16 #pragma message "Detected Version: " + VERSION
17 #endif
17 #endif
18
18
19 #ifndef ARCH
19 #ifndef ARCH
20 #define ARCH = "x86"
20 #define ARCH = "x86"
21 #endif
21 #endif
22
22
23 [Setup]
23 [Setup]
24 AppCopyright=Copyright 2005-2019 Matt Mackall and others
24 AppCopyright=Copyright 2005-2019 Matt Mackall and others
25 AppName=Mercurial
25 AppName=Mercurial
26 AppVersion={#VERSION}
26 AppVersion={#VERSION}
27 #if ARCH == "x64"
27 #if ARCH == "x64"
28 AppVerName=Mercurial {#VERSION} (64-bit)
28 AppVerName=Mercurial {#VERSION} (64-bit)
29 OutputBaseFilename=Mercurial-{#VERSION}-x64
29 OutputBaseFilename=Mercurial-{#VERSION}-x64
30 ArchitecturesAllowed=x64
30 ArchitecturesAllowed=x64
31 ArchitecturesInstallIn64BitMode=x64
31 ArchitecturesInstallIn64BitMode=x64
32 #else
32 #else
33 AppVerName=Mercurial {#VERSION}
33 AppVerName=Mercurial {#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
35 #endif
35 #endif
36 InfoAfterFile=../postinstall.txt
36 InfoAfterFile=../postinstall.txt
37 LicenseFile=Copying.txt
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/
41 AppSupportURL=https://mercurial-scm.org/
41 AppSupportURL=https://mercurial-scm.org/
42 AppUpdatesURL=https://mercurial-scm.org/
42 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=stage
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=../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 {% for entry in package_files -%}
59 {% for entry in package_files -%}
60 Source: {{ entry.source }}; DestDir: {{ entry.dest_dir }}
60 Source: {{ entry.source }}; DestDir: {{ entry.dest_dir }}
61 {%- if entry.metadata %}; {{ entry.metadata }}{% endif %}
61 {%- if entry.metadata %}; {{ entry.metadata }}{% endif %}
62 {% endfor %}
62 {% endfor %}
63
63
64 [INI]
64 [INI]
65 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/
66 Filename: {app}\default.d\editor.rc; Section: ui; Key: editor; String: notepad
66 Filename: {app}\default.d\editor.rc; Section: ui; Key: editor; String: notepad
67
67
68 [UninstallDelete]
68 [UninstallDelete]
69 Type: files; Name: {app}\Mercurial.url
69 Type: files; Name: {app}\Mercurial.url
70 Type: filesandordirs; Name: {app}\default.d
70 Type: filesandordirs; Name: {app}\default.d
71 Type: files; Name: "{app}\hg.exe.local"
72
71
73 [Icons]
72 [Icons]
74 Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
73 Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
75 Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.html
74 Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.html
76 Name: {group}\Mercurial Configuration Files; Filename: {app}\Docs\hgrc.5.html
75 Name: {group}\Mercurial Configuration Files; Filename: {app}\Docs\hgrc.5.html
77 Name: {group}\Mercurial Ignore Files; Filename: {app}\Docs\hgignore.5.html
76 Name: {group}\Mercurial Ignore Files; Filename: {app}\Docs\hgignore.5.html
78 Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
77 Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
79
78
80 [Tasks]
79 [Tasks]
81 Name: modifypath; Description: Add the installation path to the search path; Flags: unchecked
80 Name: modifypath; Description: Add the installation path to the search path; Flags: unchecked
82
81
83 [Code]
82 [Code]
84 procedure Touch(fn: String);
83 procedure Touch(fn: String);
85 begin
84 begin
86 SaveStringToFile(ExpandConstant(fn), '', False);
85 SaveStringToFile(ExpandConstant(fn), '', False);
87 end;
86 end;
88
87
89 const
88 const
90 ModPathName = 'modifypath';
89 ModPathName = 'modifypath';
91 ModPathType = 'user';
90 ModPathType = 'user';
92
91
93 function ModPathDir(): TArrayOfString;
92 function ModPathDir(): TArrayOfString;
94 begin
93 begin
95 setArrayLength(Result, 1)
94 setArrayLength(Result, 1)
96 Result[0] := ExpandConstant('{app}');
95 Result[0] := ExpandConstant('{app}');
97 end;
96 end;
98
97
99 {% include 'modpath.iss' %}
98 {% include 'modpath.iss' %}
General Comments 0
You need to be logged in to leave comments. Login now