@@ -162,80 +162,6 @@
"fsmonitor-watchman": "false",
"fsmonitor-watchman-error": "warning: Watchman unavailable: watchman exited with code 1",
-
-#if test-repo
- $ . "$TESTDIR/helpers-testrepo.sh"
-
- $ cat >> wixxml.py << EOF
- > import os
- > import subprocess
- > import sys
- > import xml.etree.ElementTree as ET
- > from mercurial import pycompat
- >
- > # MSYS mangles the path if it expands $TESTDIR
- > testdir = os.environ['TESTDIR']
- > ns = {'wix' : 'http://schemas.microsoft.com/wix/2006/wi'}
- >
- > def directory(node, relpath):
- > '''generator of files in the xml node, rooted at relpath'''
- > dirs = node.findall('./{%(wix)s}Directory' % ns)
- >
- > for d in dirs:
- > for subfile in directory(d, relpath + d.attrib['Name'] + '/'):
- > yield subfile
- >
- > files = node.findall('./{%(wix)s}Component/{%(wix)s}File' % ns)
- >
- > for f in files:
- > yield pycompat.sysbytes(relpath + f.attrib['Name'])
- >
- > def hgdirectory(relpath):
- > '''generator of tracked files, rooted at relpath'''
- > hgdir = "%s/../mercurial" % (testdir)
- > args = ['hg', '--cwd', hgdir, 'files', relpath]
- > proc = subprocess.Popen(args, stdout=subprocess.PIPE,
- > stderr=subprocess.PIPE)
- > output = proc.communicate()[0]
- >
- > for line in output.splitlines():
- > if os.name == 'nt':
- > yield line.replace(pycompat.sysbytes(os.sep), b'/')
- > else:
- > yield line
- >
- > tracked = [f for f in hgdirectory(sys.argv[1])]
- >
- > xml = ET.parse("%s/../contrib/packaging/wix/%s.wxs" % (testdir, sys.argv[1]))
- > root = xml.getroot()
- > dir = root.find('.//{%(wix)s}DirectoryRef' % ns)
- >
- > installed = [f for f in directory(dir, '')]
- >
- > print('Not installed:')
- > for f in sorted(set(tracked) - set(installed)):
- > print(' %s' % pycompat.sysstr(f))
- >
- > print('Not tracked:')
- > for f in sorted(set(installed) - set(tracked)):
- > print(' %s' % pycompat.sysstr(f))
- > EOF
-
- $ ( testrepohgenv; "$PYTHON" wixxml.py help )
- Not installed:
- help/common.txt
- help/hg-ssh.8.txt
- help/hg.1.txt
- help/hgignore.5.txt
- help/hgrc.5.txt
- Not tracked:
-
- $ ( testrepohgenv; "$PYTHON" wixxml.py templates )
- Not installed:
- Not tracked:
-
-#endif
-
#if py3
$ HGALLOWPYTHON3=1
$ export HGALLOWPYTHON3
@@ -16,7 +16,7 @@
[ui]
; editor used to enter commit logs, etc. Most text editors will work.
-editor = notepad
+; editor = notepad
; show changed files and be a bit more verbose if True
; verbose = True
; colorize commands output
deleted file mode 100644
@@ -1,251 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include guids.wxi ?>
- <?include defines.wxi ?>
-
- <Fragment>
- <ComponentGroup Id="templatesFolder">
-
- <ComponentRef Id="templates.root" />
-
- <ComponentRef Id="templates.atom" />
- <ComponentRef Id="templates.coal" />
- <ComponentRef Id="templates.gitweb" />
- <ComponentRef Id="templates.json" />
- <ComponentRef Id="templates.monoblue" />
- <ComponentRef Id="templates.paper" />
- <ComponentRef Id="templates.raw" />
- <ComponentRef Id="templates.rss" />
- <ComponentRef Id="templates.spartan" />
- <ComponentRef Id="templates.static" />
-
- </ComponentGroup>
- </Fragment>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR">
-
- <Directory Id="templatesdir" Name="templates" FileSource="$(var.SourceDir)">
-
- <Component Id="templates.root" Guid="$(var.templates.root.guid)" Win64='$(var.IsX64)'>
- <File Name="map-cmdline.changelog" KeyPath="yes" />
- <File Name="map-cmdline.compact" />
- <File Name="map-cmdline.default" />
- <File Name="map-cmdline.show" />
- <File Name="map-cmdline.bisect" />
- <File Name="map-cmdline.xml" />
- <File Name="map-cmdline.status" />
- <File Name="map-cmdline.phases" />
- </Component>
-
- <Directory Id="templates.jsondir" Name="json">
- <Component Id="templates.json" Guid="$(var.templates.json.guid)" Win64='$(var.IsX64)'>
- <File Id="json.changelist.tmpl" Name="changelist.tmpl" KeyPath="yes" />
- <File Id="json.graph.tmpl" Name="graph.tmpl" />
- <File Id="json.map" Name="map" />
- </Component>
- </Directory>
-
- <Directory Id="templates.atomdir" Name="atom">
- <Component Id="templates.atom" Guid="$(var.templates.atom.guid)" Win64='$(var.IsX64)'>
- <File Id="atom.changelog.tmpl" Name="changelog.tmpl" KeyPath="yes" />
- <File Id="atom.changelogentry.tmpl" Name="changelogentry.tmpl" />
- <File Id="atom.error.tmpl" Name="error.tmpl" />
- <File Id="atom.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="atom.header.tmpl" Name="header.tmpl" />
- <File Id="atom.map" Name="map" />
- <File Id="atom.tagentry.tmpl" Name="tagentry.tmpl" />
- <File Id="atom.tags.tmpl" Name="tags.tmpl" />
- <File Id="atom.branchentry.tmpl" Name="branchentry.tmpl" />
- <File Id="atom.branches.tmpl" Name="branches.tmpl" />
- <File Id="atom.bookmarks.tmpl" Name="bookmarks.tmpl" />
- <File Id="atom.bookmarkentry.tmpl" Name="bookmarkentry.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.coaldir" Name="coal">
- <Component Id="templates.coal" Guid="$(var.templates.coal.guid)" Win64='$(var.IsX64)'>
- <File Id="coal.header.tmpl" Name="header.tmpl" KeyPath="yes" />
- <File Id="coal.map" Name="map" />
- </Component>
- </Directory>
-
- <Directory Id="templates.gitwebdir" Name="gitweb">
- <Component Id="templates.gitweb" Guid="$(var.templates.gitweb.guid)" Win64='$(var.IsX64)'>
- <File Id="gitweb.branches.tmpl" Name="branches.tmpl" KeyPath="yes" />
- <File Id="gitweb.bookmarks.tmpl" Name="bookmarks.tmpl" />
- <File Id="gitweb.changelog.tmpl" Name="changelog.tmpl" />
- <File Id="gitweb.changelogentry.tmpl" Name="changelogentry.tmpl" />
- <File Id="gitweb.changeset.tmpl" Name="changeset.tmpl" />
- <File Id="gitweb.error.tmpl" Name="error.tmpl" />
- <File Id="gitweb.fileannotate.tmpl" Name="fileannotate.tmpl" />
- <File Id="gitweb.filecomparison.tmpl" Name="filecomparison.tmpl" />
- <File Id="gitweb.filediff.tmpl" Name="filediff.tmpl" />
- <File Id="gitweb.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="gitweb.filerevision.tmpl" Name="filerevision.tmpl" />
- <File Id="gitweb.footer.tmpl" Name="footer.tmpl" />
- <File Id="gitweb.graph.tmpl" Name="graph.tmpl" />
- <File Id="gitweb.graphentry.tmpl" Name="graphentry.tmpl" />
- <File Id="gitweb.header.tmpl" Name="header.tmpl" />
- <File Id="gitweb.index.tmpl" Name="index.tmpl" />
- <File Id="gitweb.manifest.tmpl" Name="manifest.tmpl" />
- <File Id="gitweb.map" Name="map" />
- <File Id="gitweb.notfound.tmpl" Name="notfound.tmpl" />
- <File Id="gitweb.search.tmpl" Name="search.tmpl" />
- <File Id="gitweb.shortlog.tmpl" Name="shortlog.tmpl" />
- <File Id="gitweb.summary.tmpl" Name="summary.tmpl" />
- <File Id="gitweb.tags.tmpl" Name="tags.tmpl" />
- <File Id="gitweb.help.tmpl" Name="help.tmpl" />
- <File Id="gitweb.helptopics.tmpl" Name="helptopics.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.monobluedir" Name="monoblue">
- <Component Id="templates.monoblue" Guid="$(var.templates.monoblue.guid)" Win64='$(var.IsX64)'>
- <File Id="monoblue.branches.tmpl" Name="branches.tmpl" KeyPath="yes" />
- <File Id="monoblue.bookmarks.tmpl" Name="bookmarks.tmpl" />
- <File Id="monoblue.changelog.tmpl" Name="changelog.tmpl" />
- <File Id="monoblue.changelogentry.tmpl" Name="changelogentry.tmpl" />
- <File Id="monoblue.changeset.tmpl" Name="changeset.tmpl" />
- <File Id="monoblue.error.tmpl" Name="error.tmpl" />
- <File Id="monoblue.fileannotate.tmpl" Name="fileannotate.tmpl" />
- <File Id="monoblue.filecomparison.tmpl" Name="filecomparison.tmpl" />
- <File Id="monoblue.filediff.tmpl" Name="filediff.tmpl" />
- <File Id="monoblue.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="monoblue.filerevision.tmpl" Name="filerevision.tmpl" />
- <File Id="monoblue.footer.tmpl" Name="footer.tmpl" />
- <File Id="monoblue.graph.tmpl" Name="graph.tmpl" />
- <File Id="monoblue.graphentry.tmpl" Name="graphentry.tmpl" />
- <File Id="monoblue.header.tmpl" Name="header.tmpl" />
- <File Id="monoblue.index.tmpl" Name="index.tmpl" />
- <File Id="monoblue.manifest.tmpl" Name="manifest.tmpl" />
- <File Id="monoblue.map" Name="map" />
- <File Id="monoblue.notfound.tmpl" Name="notfound.tmpl" />
- <File Id="monoblue.search.tmpl" Name="search.tmpl" />
- <File Id="monoblue.shortlog.tmpl" Name="shortlog.tmpl" />
- <File Id="monoblue.summary.tmpl" Name="summary.tmpl" />
- <File Id="monoblue.tags.tmpl" Name="tags.tmpl" />
- <File Id="monoblue.help.tmpl" Name="help.tmpl" />
- <File Id="monoblue.helptopics.tmpl" Name="helptopics.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.paperdir" Name="paper">
- <Component Id="templates.paper" Guid="$(var.templates.paper.guid)" Win64='$(var.IsX64)'>
- <File Id="paper.branches.tmpl" Name="branches.tmpl" KeyPath="yes" />
- <File Id="paper.bookmarks.tmpl" Name="bookmarks.tmpl" />
- <File Id="paper.changeset.tmpl" Name="changeset.tmpl" />
- <File Id="paper.diffstat.tmpl" Name="diffstat.tmpl" />
- <File Id="paper.error.tmpl" Name="error.tmpl" />
- <File Id="paper.fileannotate.tmpl" Name="fileannotate.tmpl" />
- <File Id="paper.filecomparison.tmpl" Name="filecomparison.tmpl" />
- <File Id="paper.filediff.tmpl" Name="filediff.tmpl" />
- <File Id="paper.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="paper.filelogentry.tmpl" Name="filelogentry.tmpl" />
- <File Id="paper.filerevision.tmpl" Name="filerevision.tmpl" />
- <File Id="paper.footer.tmpl" Name="footer.tmpl" />
- <File Id="paper.graph.tmpl" Name="graph.tmpl" />
- <File Id="paper.graphentry.tmpl" Name="graphentry.tmpl" />
- <File Id="paper.header.tmpl" Name="header.tmpl" />
- <File Id="paper.index.tmpl" Name="index.tmpl" />
- <File Id="paper.manifest.tmpl" Name="manifest.tmpl" />
- <File Id="paper.map" Name="map" />
- <File Id="paper.notfound.tmpl" Name="notfound.tmpl" />
- <File Id="paper.search.tmpl" Name="search.tmpl" />
- <File Id="paper.shortlog.tmpl" Name="shortlog.tmpl" />
- <File Id="paper.shortlogentry.tmpl" Name="shortlogentry.tmpl" />
- <File Id="paper.tags.tmpl" Name="tags.tmpl" />
- <File Id="paper.help.tmpl" Name="help.tmpl" />
- <File Id="paper.helptopics.tmpl" Name="helptopics.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.rawdir" Name="raw">
- <Component Id="templates.raw" Guid="$(var.templates.raw.guid)" Win64='$(var.IsX64)'>
- <File Id="raw.changeset.tmpl" Name="changeset.tmpl" KeyPath="yes" />
- <File Id="raw.error.tmpl" Name="error.tmpl" />
- <File Id="raw.fileannotate.tmpl" Name="fileannotate.tmpl" />
- <File Id="raw.filediff.tmpl" Name="filediff.tmpl" />
- <File Id="raw.graph.tmpl" Name="graph.tmpl" />
- <File Id="raw.graphedge.tmpl" Name="graphedge.tmpl" />
- <File Id="raw.graphnode.tmpl" Name="graphnode.tmpl" />
- <File Id="raw.index.tmpl" Name="index.tmpl" />
- <File Id="raw.manifest.tmpl" Name="manifest.tmpl" />
- <File Id="raw.map" Name="map" />
- <File Id="raw.notfound.tmpl" Name="notfound.tmpl" />
- <File Id="raw.search.tmpl" Name="search.tmpl" />
- <File Id="raw.logentry.tmpl" Name="logentry.tmpl" />
- <File Id="raw.changelog.tmpl" Name="changelog.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.rssdir" Name="rss">
- <Component Id="templates.rss" Guid="$(var.templates.rss.guid)" Win64='$(var.IsX64)'>
- <File Id="rss.changelog.tmpl" Name="changelog.tmpl" KeyPath="yes" />
- <File Id="rss.changelogentry.tmpl" Name="changelogentry.tmpl" />
- <File Id="rss.error.tmpl" Name="error.tmpl" />
- <File Id="rss.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="rss.filelogentry.tmpl" Name="filelogentry.tmpl" />
- <File Id="rss.header.tmpl" Name="header.tmpl" />
- <File Id="rss.map" Name="map" />
- <File Id="rss.tagentry.tmpl" Name="tagentry.tmpl" />
- <File Id="rss.tags.tmpl" Name="tags.tmpl" />
- <File Id="rss.bookmarks.tmpl" Name="bookmarks.tmpl" />
- <File Id="rss.bookmarkentry.tmpl" Name="bookmarkentry.tmpl" />
- <File Id="rss.branchentry.tmpl" Name="branchentry.tmpl" />
- <File Id="rss.branches.tmpl" Name="branches.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.spartandir" Name="spartan">
- <Component Id="templates.spartan" Guid="$(var.templates.spartan.guid)" Win64='$(var.IsX64)'>
- <File Id="spartan.branches.tmpl" Name="branches.tmpl" KeyPath="yes" />
- <File Id="spartan.changelog.tmpl" Name="changelog.tmpl" />
- <File Id="spartan.changelogentry.tmpl" Name="changelogentry.tmpl" />
- <File Id="spartan.changeset.tmpl" Name="changeset.tmpl" />
- <File Id="spartan.error.tmpl" Name="error.tmpl" />
- <File Id="spartan.fileannotate.tmpl" Name="fileannotate.tmpl" />
- <File Id="spartan.filediff.tmpl" Name="filediff.tmpl" />
- <File Id="spartan.filelog.tmpl" Name="filelog.tmpl" />
- <File Id="spartan.filelogentry.tmpl" Name="filelogentry.tmpl" />
- <File Id="spartan.filerevision.tmpl" Name="filerevision.tmpl" />
- <File Id="spartan.footer.tmpl" Name="footer.tmpl" />
- <File Id="spartan.graph.tmpl" Name="graph.tmpl" />
- <File Id="spartan.graphentry.tmpl" Name="graphentry.tmpl" />
- <File Id="spartan.header.tmpl" Name="header.tmpl" />
- <File Id="spartan.index.tmpl" Name="index.tmpl" />
- <File Id="spartan.manifest.tmpl" Name="manifest.tmpl" />
- <File Id="spartan.map" Name="map" />
- <File Id="spartan.notfound.tmpl" Name="notfound.tmpl" />
- <File Id="spartan.search.tmpl" Name="search.tmpl" />
- <File Id="spartan.shortlog.tmpl" Name="shortlog.tmpl" />
- <File Id="spartan.shortlogentry.tmpl" Name="shortlogentry.tmpl" />
- <File Id="spartan.tags.tmpl" Name="tags.tmpl" />
- </Component>
- </Directory>
-
- <Directory Id="templates.staticdir" Name="static">
- <Component Id="templates.static" Guid="$(var.templates.static.guid)" Win64='$(var.IsX64)'>
- <File Id="static.background.png" Name="background.png" KeyPath="yes" />
- <File Id="static.coal.file.png" Name="coal-file.png" />
- <File Id="static.coal.folder.png" Name="coal-folder.png" />
- <File Id="static.followlines.js" Name="followlines.js" />
- <File Id="static.mercurial.js" Name="mercurial.js" />
- <File Id="static.hgicon.png" Name="hgicon.png" />
- <File Id="static.hglogo.png" Name="hglogo.png" />
- <File Id="static.style.coal.css" Name="style-extra-coal.css" />
- <File Id="static.style.gitweb.css" Name="style-gitweb.css" />
- <File Id="static.style.monoblue.css" Name="style-monoblue.css" />
- <File Id="static.style.paper.css" Name="style-paper.css" />
- <File Id="static.style.css" Name="style.css" />
- <File Id="static.feed.icon" Name="feed-icon-14x14.png" />
- </Component>
- </Directory>
-
- </Directory>
-
- </DirectoryRef>
- </Fragment>
-
- </Wix>
@@ -60,30 +60,10 @@
<Directory Id='$(var.PFolder)' Name='PFiles'>
<Directory Id='INSTALLDIR' Name='Mercurial'>
<Component Id='MainExecutable' Guid='$(var.ComponentMainExecutableGUID)' Win64='$(var.IsX64)'>
- <File Id='hgEXE' Name='hg.exe' Source='dist\hg.exe' KeyPath='yes' />
+ <CreateFolder />
<Environment Id="Environment" Name="PATH" Part="last" System="yes"
Permanent="no" Value="[INSTALLDIR]" Action="set" />
</Component>
- <Component Id='ReadMe' Guid='$(var.ReadMe.guid)' Win64='$(var.IsX64)'>
- <File Id='ReadMe' Name='ReadMe.html' Source='contrib\win32\ReadMe.html'
- KeyPath='yes'/>
- </Component>
- <Component Id='COPYING' Guid='$(var.COPYING.guid)' Win64='$(var.IsX64)'>
- <File Id='COPYING' Name='COPYING.rtf' Source='contrib\packaging\wix\COPYING.rtf'
- KeyPath='yes'/>
- </Component>
-
- <Directory Id='HGRCD' Name='hgrc.d'>
- <Component Id='mercurial.rc' Guid='$(var.mercurial.rc.guid)' Win64='$(var.IsX64)'>
- <File Id='mercurial.rc' Name='mercurial.rc' Source='contrib\win32\mercurial.ini'
- ReadOnly='yes' KeyPath='yes'/>
- </Component>
- <Component Id='mergetools.rc' Guid='$(var.mergetools.rc.guid)' Win64='$(var.IsX64)'>
- <File Id='mergetools.rc' Name='mergetools.rc' Source='mercurial\default.d\mergetools.rc'
- ReadOnly='yes' KeyPath='yes'/>
- </Component>
- </Directory>
-
</Directory>
</Directory>
@@ -117,15 +97,12 @@
<Feature Id='MainProgram' Title='Program' Description='Mercurial command line app'
Level='1' Absent='disallow' >
<ComponentRef Id='MainExecutable' />
- <ComponentRef Id='distOutput' />
- <ComponentRef Id='libOutput' />
<ComponentRef Id='ProgramMenuDir' />
- <ComponentRef Id='ReadMe' />
- <ComponentRef Id='COPYING' />
- <ComponentRef Id='mercurial.rc' />
- <ComponentRef Id='mergetools.rc' />
- <ComponentGroupRef Id='helpFolder' />
- <ComponentGroupRef Id='templatesFolder' />
+ <ComponentGroupRef Id="hg.group.ROOT" />
+ <ComponentGroupRef Id="hg.group.hgrc.d" />
+ <ComponentGroupRef Id="hg.group.help" />
+ <ComponentGroupRef Id="hg.group.lib" />
+ <ComponentGroupRef Id="hg.group.templates" />
<MergeRef Id='VCRuntime' />
<MergeRef Id='VCRuntimePolicy' />
</Feature>
@@ -135,13 +112,13 @@
<?endforeach?>
<?endif?>
<Feature Id='Locales' Title='Translations' Description='Translations' Level='1'>
- <ComponentGroupRef Id='localeFolder' />
+ <ComponentGroupRef Id="hg.group.locale" />
</Feature>
<Feature Id='Documentation' Title='Documentation' Description='HTML man pages' Level='1'>
- <ComponentGroupRef Id='docFolder' />
+ <ComponentGroupRef Id="hg.group.doc" />
</Feature>
<Feature Id='Misc' Title='Miscellaneous' Description='Contributed scripts' Level='1'>
- <ComponentGroupRef Id='contribFolder' />
+ <ComponentGroupRef Id="hg.group.contrib" />
</Feature>
</Feature>
deleted file mode 100644
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include defines.wxi ?>
-
- <?define hglocales =
- da;de;el;fr;it;ja;pt_BR;ro;ru;sv;zh_CN;zh_TW
- ?>
-
- <Fragment>
- <ComponentGroup Id="localeFolder">
- <?foreach LOC in $(var.hglocales) ?>
- <ComponentRef Id="hg.locale.$(var.LOC)"/>
- <?endforeach?>
- </ComponentGroup>
- </Fragment>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR">
- <Directory Id="localedir" Name="locale" FileSource="$(var.SourceDir)">
- <?foreach LOC in $(var.hglocales) ?>
- <Directory Id="hg.locale.$(var.LOC)" Name="$(var.LOC)">
- <Directory Id="hg.locale.$(var.LOC).LC_MESSAGES" Name="LC_MESSAGES">
- <Component Id="hg.locale.$(var.LOC)" Guid="*" Win64='$(var.IsX64)'>
- <File Id="hg.mo.$(var.LOC)" Name="hg.mo" KeyPath="yes" />
- </Component>
- </Directory>
- </Directory>
- <?endforeach?>
- </Directory>
- </DirectoryRef>
- </Fragment>
-
-</Wix>
deleted file mode 100644
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include guids.wxi ?>
- <?include defines.wxi ?>
-
- <Fragment>
- <ComponentGroup Id='helpFolder'>
- <ComponentRef Id='help.root' />
- <ComponentRef Id='help.internals' />
- </ComponentGroup>
- </Fragment>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR">
- <Directory Id="helpdir" Name="help" FileSource="$(var.SourceDir)">
- <Component Id="help.root" Guid="$(var.help.root.guid)" Win64='$(var.IsX64)'>
- <File Name="bundlespec.txt" />
- <File Name="color.txt" />
- <File Name="common.txt" />
- <File Name="config.txt" KeyPath="yes" />
- <File Name="dates.txt" />
- <File Name="deprecated.txt" />
- <File Name="diffs.txt" />
- <File Name="environment.txt" />
- <File Name="extensions.txt" />
- <File Name="filesets.txt" />
- <File Name="flags.txt" />
- <File Name="glossary.txt" />
- <File Name="hg-ssh.8.txt" />
- <File Name="hg.1.txt" />
- <File Name="hgignore.5.txt" />
- <File Name="hgignore.txt" />
- <File Name="hgrc.5.txt" />
- <File Name="hgweb.txt" />
- <File Name="merge-tools.txt" />
- <File Name="pager.txt" />
- <File Name="patterns.txt" />
- <File Name="phases.txt" />
- <File Name="revisions.txt" />
- <File Name="scripting.txt" />
- <File Name="subrepos.txt" />
- <File Name="templates.txt" />
- <File Name="urls.txt" />
- </Component>
-
- <Directory Id="help.internaldir" Name="internals">
- <Component Id="help.internals" Guid="$(var.help.internals.guid)" Win64='$(var.IsX64)'>
- <File Id="internals.bundle2.txt" Name="bundle2.txt" />
- <File Id="internals.bundles.txt" Name="bundles.txt" KeyPath="yes" />
- <File Id="internals.cbor.txt" Name="cbor.txt" />
- <File Id="internals.censor.txt" Name="censor.txt" />
- <File Id="internals.changegroups.txt" Name="changegroups.txt" />
- <File Id="internals.config.txt" Name="config.txt" />
- <File Id="internals.extensions.txt" Name="extensions.txt" />
- <File Id="internals.linelog.txt" Name="linelog.txt" />
- <File Id="internals.mergestate.txt" Name="mergestate.txt" />
- <File Id="internals.requirements.txt" Name="requirements.txt" />
- <File Id="internals.revlogs.txt" Name="revlogs.txt" />
- <File Id="internals.wireprotocol.txt" Name="wireprotocol.txt" />
- <File Id="internals.wireprotocolrpc.txt" Name="wireprotocolrpc.txt" />
- <File Id="internals.wireprotocolv2.txt" Name="wireprotocolv2.txt" />
- </Component>
- </Directory>
-
- </Directory>
- </DirectoryRef>
- </Fragment>
-
-</Wix>
@@ -4,46 +4,9 @@
and replace 'Mercurial' in this notice with the name of
your project. Component GUIDs have global namespace! -->
- <!-- contrib.wxs -->
- <?define contrib.guid = {4E11FFC2-E2F7-482A-8460-9394B5489F02} ?>
- <?define contrib.vim.guid = {BB04903A-652D-4C4F-9590-2BD07A2304F2} ?>
-
- <!-- dist.wxs -->
- <?define dist.guid = {CE405FE6-CD1E-4873-9C9A-7683AE5A3D90} ?>
- <?define lib.guid = {877633b5-0b7e-4b46-8f1c-224a61733297} ?>
-
- <!-- doc.wxs -->
- <?define doc.hg.1.html.guid = {AAAA3FDA-EDC5-4220-B59D-D342722358A2} ?>
- <?define doc.hgignore.5.html.guid = {AA9118C4-F3A0-4429-A5F4-5A1906B2D67F} ?>
- <?define doc.hgrc.5.html = {E0CEA1EB-FA01-408c-844B-EE5965165BAE} ?>
- <?define doc.style.css = {172F8262-98E0-4711-BD39-4DAE0D77EF05} ?>
-
- <!-- help.wxs -->
- <?define help.root.guid = {9FA957DB-6DFE-44f2-AD03-293B2791CF17} ?>
- <?define help.internals.guid = {2DD7669D-0DB8-4C39-9806-78E6475E7ACC} ?>
-
- <!-- templates.wxs -->
- <?define templates.root.guid = {437FD55C-7756-4EA0-87E5-FDBE75DC8595} ?>
- <?define templates.atom.guid = {D30E14A5-8AF0-4268-8B00-00BEE9E09E39} ?>
- <?define templates.coal.guid = {B63CCAAB-4EAF-43b4-901E-4BD13F5B78FC} ?>
- <?define templates.gitweb.guid = {827334AF-1EFD-421B-962C-5660A068F612} ?>
- <?define templates.json.guid = {F535BE7A-EC34-46E0-B9BE-013F3DBAFB19} ?>
- <?define templates.monoblue.guid = {8060A1E4-BD4C-453E-92CB-9536DC44A9E3} ?>
- <?define templates.paper.guid = {61AB1DE9-645F-46ED-8AF8-0CF02267FFBB} ?>
- <?define templates.raw.guid = {834DF8D7-9784-43A6-851D-A96CE1B3575B} ?>
- <?define templates.rss.guid = {9338FA09-E128-4B1C-B723-1142DBD09E14} ?>
- <?define templates.spartan.guid = {80222625-FA8F-44b1-86CE-1781EF375D09} ?>
- <?define templates.static.guid = {6B3D7C24-98DA-4B67-9F18-35F77357B0B4} ?>
-
<!-- mercurial.wxs -->
<?define ProductUpgradeCode = {A1CC6134-E945-4399-BE36-EB0017FDF7CF} ?>
-
<?define ComponentMainExecutableGUID = {D102B8FA-059B-4ACC-9FA3-8C78C3B58EEF} ?>
-
- <?define ReadMe.guid = {56A8E372-991D-4DCA-B91D-93D775974CF5} ?>
- <?define COPYING.guid = {B7801DBA-1C49-4BF4-91AD-33C65F5C7895} ?>
- <?define mercurial.rc.guid = {52BBF223-58F6-47F5-9353-8FDEA88D9B8D} ?>
- <?define mergetools.rc.guid = {5AF0430B-2B76-4BC6-91EE-E771B74A0214} ?>
<?define ProgramMenuDir.guid = {D5A63320-1238-489B-B68B-CF053E9577CA} ?>
</Include>
deleted file mode 100644
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include guids.wxi ?>
- <?include defines.wxi ?>
-
- <Fragment>
- <ComponentGroup Id="docFolder">
- <ComponentRef Id="doc.hg.1.html" />
- <ComponentRef Id="doc.hgignore.5.html" />
- <ComponentRef Id="doc.hgrc.5.html" />
- <ComponentRef Id="doc.style.css" />
- </ComponentGroup>
- </Fragment>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR">
- <Directory Id="docdir" Name="doc" FileSource="$(var.SourceDir)">
- <Component Id="doc.hg.1.html" Guid="$(var.doc.hg.1.html.guid)" Win64='$(var.IsX64)'>
- <File Name="hg.1.html" KeyPath="yes">
- <Shortcut Id="hg1StartMenu" Directory="ProgramMenuDir"
- Name="Mercurial Command Reference"
- Icon="hgIcon.ico" IconIndex="0" Advertise="yes"
- />
- </File>
- </Component>
- <Component Id="doc.hgignore.5.html" Guid="$(var.doc.hgignore.5.html.guid)" Win64='$(var.IsX64)'>
- <File Name="hgignore.5.html" KeyPath="yes">
- <Shortcut Id="hgignore5StartMenu" Directory="ProgramMenuDir"
- Name="Mercurial Ignore Files"
- Icon="hgIcon.ico" IconIndex="0" Advertise="yes"
- />
- </File>
- </Component>
- <Component Id="doc.hgrc.5.html" Guid="$(var.doc.hgrc.5.html)" Win64='$(var.IsX64)'>
- <File Name="hgrc.5.html" KeyPath="yes">
- <Shortcut Id="hgrc5StartMenu" Directory="ProgramMenuDir"
- Name="Mercurial Configuration Files"
- Icon="hgIcon.ico" IconIndex="0" Advertise="yes"
- />
- </File>
- </Component>
- <Component Id="doc.style.css" Guid="$(var.doc.style.css)" Win64='$(var.IsX64)'>
- <File Name="style.css" KeyPath="yes" />
- </Component>
- </Directory>
- </DirectoryRef>
- </Fragment>
-
-</Wix>
deleted file mode 100644
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include guids.wxi ?>
- <?include defines.wxi ?>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR" FileSource="$(var.SourceDir)">
- <Component Id="distOutput" Guid="$(var.dist.guid)" Win64='$(var.IsX64)'>
- <File Name="python27.dll" KeyPath="yes" />
- </Component>
- </DirectoryRef>
- </Fragment>
-
-</Wix>
deleted file mode 100644
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include guids.wxi ?>
- <?include defines.wxi ?>
-
- <Fragment>
- <ComponentGroup Id="contribFolder">
- <ComponentRef Id="contrib" />
- <ComponentRef Id="contrib.vim" />
- </ComponentGroup>
- </Fragment>
-
- <Fragment>
- <DirectoryRef Id="INSTALLDIR">
- <Directory Id="contribdir" Name="contrib" FileSource="$(var.SourceDir)">
- <Component Id="contrib" Guid="$(var.contrib.guid)" Win64='$(var.IsX64)'>
- <File Name="bash_completion" KeyPath="yes" />
- <File Name="hgk.tcl" Source="$(var.SourceDir)/hgk" />
- <File Name="hgweb.fcgi" />
- <File Name="hgweb.wsgi" />
- <File Name="logo-droplets.svg" />
- <File Name="mercurial.el" />
- <File Name="mq.el" />
- <File Name="tcsh_completion" />
- <File Name="tcsh_completion_build.sh" />
- <File Name="xml.rnc" />
- <File Name="zsh_completion" />
- </Component>
- <Directory Id="vimdir" Name="vim">
- <Component Id="contrib.vim" Guid="$(var.contrib.vim.guid)" Win64='$(var.IsX64)'>
- <File Name="hg-menu.vim" KeyPath="yes" />
- <File Name="HGAnnotate.vim" />
- <File Name="hgcommand.vim" />
- <File Name="patchreview.txt" />
- <File Name="patchreview.vim" />
- <File Name="hgtest.vim" />
- </Component>
- </Directory>
- </Directory>
- </DirectoryRef>
- </Fragment>
-
-</Wix>
@@ -7,38 +7,60 @@
# no-check-code because Python 3 native.
+import collections
import os
import pathlib
import re
+import shutil
import subprocess
-import tempfile
import typing
+import uuid
import xml.dom.minidom
from .downloads import download_entry
-from .py2exe import build_py2exe
+from .py2exe import (
+ build_py2exe,
+ stage_install,
+)
from .util import (
extract_zip_to_directory,
+ process_install_rules,
sign_with_signtool,
)
-SUPPORT_WXS = [
- ('contrib.wxs', r'contrib'),
- ('dist.wxs', r'dist'),
- ('doc.wxs', r'doc'),
- ('help.wxs', r'mercurial\help'),
- ('locale.wxs', r'mercurial\locale'),
- ('templates.wxs', r'mercurial\templates'),
-]
-
-
EXTRA_PACKAGES = {
'distutils',
'pygments',
}
+EXTRA_INSTALL_RULES = [
+ ('contrib/packaging/wix/COPYING.rtf', 'COPYING.rtf'),
+ ('contrib/win32/mercurial.ini', 'hgrc.d/mercurial.rc'),
+]
+
+STAGING_REMOVE_FILES = [
+ # We use the RTF variant.
+ 'copying.txt',
+]
+
+SHORTCUTS = {
+ # hg.1.html'
+ 'hg.file.5d3e441c_28d9_5542_afd0_cdd4234f12d5': {
+ 'Name': 'Mercurial Command Reference',
+ },
+ # hgignore.5.html
+ 'hg.file.5757d8e0_f207_5e10_a2ec_3ba0a062f431': {
+ 'Name': 'Mercurial Ignore Files',
+ },
+ # hgrc.5.html
+ 'hg.file.92e605fd_1d1a_5dc6_9fc0_5d2998eb8f5e': {
+ 'Name': 'Mercurial Configuration Files',
+ },
+}
+
+
def find_version(source_dir: pathlib.Path):
version_py = source_dir / 'mercurial' / '__version__.py'
@@ -147,49 +169,165 @@
return post_build_sign
-LIBRARIES_XML = '''
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
- <?include {wix_dir}/guids.wxi ?>
- <?include {wix_dir}/defines.wxi ?>
+def make_files_xml(staging_dir: pathlib.Path, is_x64) -> str:
+ """Create XML string listing every file to be installed."""
- <Fragment>
- <DirectoryRef Id="INSTALLDIR" FileSource="$(var.SourceDir)">
- <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib">
- <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'>
- </Component>
- </Directory>
- </DirectoryRef>
- </Fragment>
-</Wix>
-'''.lstrip()
+ # We derive GUIDs from a deterministic file path identifier.
+ # We shoehorn the name into something that looks like a URL because
+ # the UUID namespaces are supposed to work that way (even though
+ # the input data probably is never validated).
-
-def make_libraries_xml(wix_dir: pathlib.Path, dist_dir: pathlib.Path):
- """Make XML data for library components WXS."""
- # We can't use ElementTree because it doesn't handle the
- # <?include ?> directives.
doc = xml.dom.minidom.parseString(
- LIBRARIES_XML.format(wix_dir=str(wix_dir))
+ '<?xml version="1.0" encoding="utf-8"?>'
+ '<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">'
+ '</Wix>'
)
- component = doc.getElementsByTagName('Component')[0]
+ # Assemble the install layout by directory. This makes it easier to
+ # emit XML, since each directory has separate entities.
+ manifest = collections.defaultdict(dict)
+
+ for root, dirs, files in os.walk(staging_dir):
+ dirs.sort()
+
+ root = pathlib.Path(root)
+ rel_dir = root.relative_to(staging_dir)
+
+ for i in range(len(rel_dir.parts)):
+ parent = '/'.join(rel_dir.parts[0 : i + 1])
+ manifest.setdefault(parent, {})
+
+ for f in sorted(files):
+ full = root / f
+ manifest[str(rel_dir).replace('\\', '/')][full.name] = full
+
+ component_groups = collections.defaultdict(list)
+
+ # Now emit a <Fragment> for each directory.
+ # Each directory is composed of a <DirectoryRef> pointing to its parent
+ # and defines child <Directory>'s and a <Component> with all the files.
+ for dir_name, entries in sorted(manifest.items()):
+ # The directory id is derived from the path. But the root directory
+ # is special.
+ if dir_name == '.':
+ parent_directory_id = 'INSTALLDIR'
+ else:
+ parent_directory_id = 'hg.dir.%s' % dir_name.replace('/', '.')
- f = doc.createElement('File')
- f.setAttribute('Name', 'library.zip')
- f.setAttribute('KeyPath', 'yes')
- component.appendChild(f)
+ fragment = doc.createElement('Fragment')
+ directory_ref = doc.createElement('DirectoryRef')
+ directory_ref.setAttribute('Id', parent_directory_id)
+
+ # Add <Directory> entries for immediate children directories.
+ for possible_child in sorted(manifest.keys()):
+ if (
+ dir_name == '.'
+ and '/' not in possible_child
+ and possible_child != '.'
+ ):
+ child_directory_id = 'hg.dir.%s' % possible_child
+ name = possible_child
+ else:
+ if not possible_child.startswith('%s/' % dir_name):
+ continue
+ name = possible_child[len(dir_name) + 1 :]
+ if '/' in name:
+ continue
+
+ child_directory_id = 'hg.dir.%s' % possible_child.replace(
+ '/', '.'
+ )
+
+ directory = doc.createElement('Directory')
+ directory.setAttribute('Id', child_directory_id)
+ directory.setAttribute('Name', name)
+ directory_ref.appendChild(directory)
+
+ # Add <Component>s for files in this directory.
+ for rel, source_path in sorted(entries.items()):
+ if dir_name == '.':
+ full_rel = rel
+ else:
+ full_rel = '%s/%s' % (dir_name, rel)
- lib_dir = dist_dir / 'lib'
+ component_unique_id = (
+ 'https://www.mercurial-scm.org/wix-installer/0/component/%s'
+ % full_rel
+ )
+ component_guid = uuid.uuid5(uuid.NAMESPACE_URL, component_unique_id)
+ component_id = 'hg.component.%s' % str(component_guid).replace(
+ '-', '_'
+ )
+
+ component = doc.createElement('Component')
+
+ component.setAttribute('Id', component_id)
+ component.setAttribute('Guid', str(component_guid).upper())
+ component.setAttribute('Win64', 'yes' if is_x64 else 'no')
+
+ # Assign this component to a top-level group.
+ if dir_name == '.':
+ component_groups['ROOT'].append(component_id)
+ elif '/' in dir_name:
+ component_groups[dir_name[0 : dir_name.index('/')]].append(
+ component_id
+ )
+ else:
+ component_groups[dir_name].append(component_id)
+
+ unique_id = (
+ 'https://www.mercurial-scm.org/wix-installer/0/%s' % full_rel
+ )
+ file_guid = uuid.uuid5(uuid.NAMESPACE_URL, unique_id)
+
+ # IDs have length limits. So use GUID to derive them.
+ file_guid_normalized = str(file_guid).replace('-', '_')
+ file_id = 'hg.file.%s' % file_guid_normalized
- for p in sorted(lib_dir.iterdir()):
- if not p.name.endswith(('.dll', '.pyd')):
- continue
+ file_element = doc.createElement('File')
+ file_element.setAttribute('Id', file_id)
+ file_element.setAttribute('Source', str(source_path))
+ file_element.setAttribute('KeyPath', 'yes')
+ file_element.setAttribute('ReadOnly', 'yes')
+
+ component.appendChild(file_element)
+ directory_ref.appendChild(component)
+
+ fragment.appendChild(directory_ref)
+ doc.documentElement.appendChild(fragment)
+
+ for group, component_ids in sorted(component_groups.items()):
+ fragment = doc.createElement('Fragment')
+ component_group = doc.createElement('ComponentGroup')
+ component_group.setAttribute('Id', 'hg.group.%s' % group)
+
+ for component_id in component_ids:
+ component_ref = doc.createElement('ComponentRef')
+ component_ref.setAttribute('Id', component_id)
+ component_group.appendChild(component_ref)
- f = doc.createElement('File')
- f.setAttribute('Name', p.name)
- component.appendChild(f)
+ fragment.appendChild(component_group)
+ doc.documentElement.appendChild(fragment)
+
+ # Add <Shortcut> to files that have it defined.
+ for file_id, metadata in sorted(SHORTCUTS.items()):
+ els = doc.getElementsByTagName('File')
+ els = [el for el in els if el.getAttribute('Id') == file_id]
+
+ if not els:
+ raise Exception('could not find File[Id=%s]' % file_id)
+
+ for el in els:
+ shortcut = doc.createElement('Shortcut')
+ shortcut.setAttribute('Id', 'hg.shortcut.%s' % file_id)
+ shortcut.setAttribute('Directory', 'ProgramMenuDir')
+ shortcut.setAttribute('Icon', 'hgIcon.ico')
+ shortcut.setAttribute('IconIndex', '0')
+ shortcut.setAttribute('Advertise', 'yes')
+ for k, v in sorted(metadata.items()):
+ shortcut.setAttribute(k, v)
+
+ el.appendChild(shortcut)
return doc.toprettyxml()
@@ -248,9 +386,27 @@
post_build_fn(source_dir, hg_build_dir, dist_dir, version)
build_dir = hg_build_dir / ('wix-%s' % arch)
+ staging_dir = build_dir / 'stage'
build_dir.mkdir(exist_ok=True)
+ # Purge the staging directory for every build so packaging is pristine.
+ if staging_dir.exists():
+ print('purging %s' % staging_dir)
+ shutil.rmtree(staging_dir)
+
+ stage_install(source_dir, staging_dir, lower_case=True)
+
+ # We also install some extra files.
+ process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
+
+ # And remove some files we don't want.
+ for f in STAGING_REMOVE_FILES:
+ p = staging_dir / f
+ if p.exists():
+ print('removing %s' % p)
+ p.unlink()
+
wix_pkg, wix_entry = download_entry('wix', hg_build_dir)
wix_path = hg_build_dir / ('wix-%s' % wix_entry['version'])
@@ -263,25 +419,16 @@
defines = {'Platform': arch}
- for wxs, rel_path in SUPPORT_WXS:
- wxs = wix_dir / wxs
- wxs_source_dir = source_dir / rel_path
- run_candle(wix_path, build_dir, wxs, wxs_source_dir, defines=defines)
+ # Derive a .wxs file with the staged files.
+ manifest_wxs = build_dir / 'stage.wxs'
+ with manifest_wxs.open('w', encoding='utf-8') as fh:
+ fh.write(make_files_xml(staging_dir, is_x64=arch == 'x64'))
+
+ run_candle(wix_path, build_dir, manifest_wxs, staging_dir, defines=defines)
for source, rel_path in sorted((extra_wxs or {}).items()):
run_candle(wix_path, build_dir, source, rel_path, defines=defines)
- # candle.exe doesn't like when we have an open handle on the file.
- # So use TemporaryDirectory() instead of NamedTemporaryFile().
- with tempfile.TemporaryDirectory() as td:
- td = pathlib.Path(td)
-
- tf = td / 'library.wxs'
- with tf.open('w') as fh:
- fh.write(make_libraries_xml(wix_dir, dist_dir))
-
- run_candle(wix_path, build_dir, tf, dist_dir, defines=defines)
-
source = wix_dir / 'mercurial.wxs'
defines['Version'] = version
defines['Comments'] = 'Installs Mercurial version %s' % version
@@ -307,20 +454,13 @@
str(msi_path),
]
- for source, rel_path in SUPPORT_WXS:
- assert source.endswith('.wxs')
- args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
-
for source, rel_path in sorted((extra_wxs or {}).items()):
assert source.endswith('.wxs')
source = os.path.basename(source)
args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
args.extend(
- [
- str(build_dir / 'library.wixobj'),
- str(build_dir / 'mercurial.wixobj'),
- ]
+ [str(build_dir / 'stage.wixobj'), str(build_dir / 'mercurial.wixobj'),]
)
subprocess.run(args, cwd=str(source_dir), check=True)
@@ -209,13 +209,26 @@
)
-def stage_install(source_dir: pathlib.Path, staging_dir: pathlib.Path):
+def stage_install(
+ source_dir: pathlib.Path, staging_dir: pathlib.Path, lower_case=False
+):
"""Copy all files to be installed to a directory.
This allows packaging to simply walk a directory tree to find source
files.
"""
- process_install_rules(STAGING_RULES, source_dir, staging_dir)
+ if lower_case:
+ rules = []
+ for source, dest in STAGING_RULES:
+ # Only lower directory names.
+ if '/' in dest:
+ parent, leaf = dest.rsplit('/', 1)
+ dest = '%s/%s' % (parent.lower(), leaf)
+ rules.append((source, dest))
+ else:
+ rules = STAGING_RULES
+
+ process_install_rules(rules, source_dir, staging_dir)
# An empty .exe.local file enables DLL Redirection and forces
# Windows to look for DLLs relative to the .exe.