# HG changeset patch # User Matt Harbison <matt_harbison@yahoo.com> # Date 1740414586 18000 # Mon Feb 24 11:29:46 2025 -0500 # Node ID 0e2be2abd963298c2b8521cd880642609f2f938c # Parent d655382584c573fc1021789ed703b24235580742 contrib: add modern `setuptools` and `setuptools_scm` to the packaging venv With `py -3.9 contrib/packaging/packaging.py wix --pyoxidizer-target x86_64-pc-windows-msvc`, there is an immediate failure after building the venv (3.9.13 has `setuptools` 58.1.0): ModuleNotFoundError: No module named 'setuptools.command.build' With that fixed, the same command then fails immediately with this error: Couldn't import setuptools_scm (direct call of setup.py?) Unfortunately, referencing `setuptools` in the requirements file needs `--allow-unsafe` to avoid a warning about not pinning `setuptools`. However, the same warning happens if `setuptools` is pinned to a specific revision, so I have no idea what it is complaining about. It's a separate venv that is only used for packaging, so we can fix it if it becomes a problem in the future. Interestingly, the Inno installer build doesn't fail immediately, and I can see it installing `setuptools` and `setuptools_scm` in the wall of text it emits. Eventually it does fail with the same errors without this change. diff --git a/contrib/packaging/requirements.txt b/contrib/packaging/requirements.txt --- a/contrib/packaging/requirements.txt +++ b/contrib/packaging/requirements.txt @@ -1,8 +1,8 @@ # -# This file is autogenerated by pip-compile with python 3.7 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: # -# pip-compile --generate-hashes --no-reuse-hashes --output-file=contrib/packaging/requirements.txt contrib/packaging/requirements.txt.in +# pip-compile --allow-unsafe --generate-hashes --no-reuse-hashes --output-file=contrib/packaging/requirements.txt contrib/packaging/requirements.txt.in # docutils==0.16 \ --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ @@ -66,3 +66,61 @@ --hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \ --hash=sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621 # via jinja2 +packaging==24.2 \ + --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ + --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f + # via setuptools-scm +setuptools-scm==8.2.0 \ + --hash=sha256:136e2b1d393d709d2bcf26f275b8dec06c48b811154167b0fd6bb002aad17d6d \ + --hash=sha256:a18396a1bc0219c974d1a74612b11f9dce0d5bd8b1dc55c65f6ac7fd609e8c28 + # via -r contrib/packaging/requirements.txt.in +tomli==2.2.1 \ + --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ + --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ + --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ + --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ + --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ + --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ + --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ + --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ + --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ + --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ + --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ + --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ + --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ + --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ + --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ + --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ + --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ + --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ + --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ + --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ + --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ + --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ + --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ + --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ + --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ + --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ + --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ + --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ + --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ + --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ + --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ + --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 + # via setuptools-scm +typing-extensions==4.12.2 \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 + # via setuptools-scm +wheel==0.45.1 \ + --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ + --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 + # via -r contrib/packaging/requirements.txt.in + +# The following packages are considered to be unsafe in a requirements file: +setuptools==75.8.0 \ + --hash=sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6 \ + --hash=sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3 + # via + # -r contrib/packaging/requirements.txt.in + # setuptools-scm diff --git a/contrib/packaging/requirements.txt.in b/contrib/packaging/requirements.txt.in --- a/contrib/packaging/requirements.txt.in +++ b/contrib/packaging/requirements.txt.in @@ -3,3 +3,8 @@ docutils jinja2 + +# Keep these in sync with pyproject.toml +setuptools >= 64 +setuptools-scm >= 8.1.0 +wheel # HG changeset patch # User Matt Harbison <matt_harbison@yahoo.com> # Date 1740417255 18000 # Mon Feb 24 12:14:15 2025 -0500 # Node ID d333e14477f1effcfe4c2e1b2b17f64c7fe6572b # Parent 0e2be2abd963298c2b8521cd880642609f2f938c packaging: adapt `__version__.py` parsing for `setuptools_scm` output The file is now generated by `setuptools_scm`, which stores values as strings with strong quotes. This avoids the following failure at the end of the Inno installer build: <snip> creating installer Traceback (most recent call last): File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\packaging.py", line 70, in <module> run() File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\packaging.py", line 62, in run cli.main() File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\cli.py", line 154, in main args.func(**kwargs) File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\cli.py", line 35, in build_inno inno.build_with_pyoxidizer( File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\inno.py", line 55, in build_with_pyoxidizer build_installer( File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\inno.py", line 146, in build_installer version = read_version_py(source_dir) File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\util.py", line 188, in read_version_py raise Exception('could not parse %s' % p) Exception: could not parse c:\Users\Matt\projects\mercurial\mercurial-devel\mercurial\__version__.py Note that non-tagged builds end up with complex version strings, and include characters that WiX rejects. That's probably fine- we don't do nightly or other non-tagged builds for installers. Also note that while the Inno installer is capable of using this version string as part of the installer, the WiX installer is not for some reason. That installer needs to be built with `--version VERSION` to inject the version into the installer metadata and the filename. diff --git a/contrib/packaging/hgpackaging/util.py b/contrib/packaging/hgpackaging/util.py --- a/contrib/packaging/hgpackaging/util.py +++ b/contrib/packaging/hgpackaging/util.py @@ -182,7 +182,7 @@ p = source_dir / 'mercurial' / '__version__.py' with p.open('r', encoding='utf-8') as fh: - m = re.search('version = b"([^"]+)"', fh.read(), re.MULTILINE) + m = re.search("version = '([^']+)'", fh.read(), re.MULTILINE) if not m: raise Exception('could not parse %s' % p) # HG changeset patch # User Matt Harbison <matt_harbison@yahoo.com> # Date 1740424432 18000 # Mon Feb 24 14:13:52 2025 -0500 # Node ID 80ec613fea4324591928004a369d80236e0bc06f # Parent d333e14477f1effcfe4c2e1b2b17f64c7fe6572b docs: update the IRC channel reference in the Windows readme I noticed this when trying the Inno installer. diff --git a/contrib/win32/ReadMe.html b/contrib/win32/ReadMe.html --- a/contrib/win32/ReadMe.html +++ b/contrib/win32/ReadMe.html @@ -124,7 +124,7 @@ <p> If you are IRC-savvy, that's usually the fastest way to get - help. Go to <tt>#mercurial</tt> on <tt>irc.freenode.net</tt>. + help. Go to <tt>#mercurial</tt> on <tt>libra.chat</tt>. </p> <h1>Author and copyright information</h1> # HG changeset patch # User Matt Harbison <matt_harbison@yahoo.com> # Date 1740266725 18000 # Sat Feb 22 18:25:25 2025 -0500 # Node ID e2c239dae5a27cae33f542fa2df9d52baf116ccd # Parent 80ec613fea4324591928004a369d80236e0bc06f setup: drop the inaccessible `py2exehacked` code around distutils The comment heavily implies, and experimenting confirms, that there's no `sys.real_prefix` in a venv on Python3. I have no idea how the problems described would manifest, but nobody has complained for the several years of py3 releases build from a venv. The experimenting was done with 6.9.2 and the TortoiseHg build script. diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -967,87 +967,6 @@ self.copy_file(os.path.join('contrib', src), dest) -# virtualenv installs custom distutils/__init__.py and -# distutils/distutils.cfg files which essentially proxy back to the -# "real" distutils in the main Python install. The presence of this -# directory causes py2exe to pick up the "hacked" distutils package -# from the virtualenv and "import distutils" will fail from the py2exe -# build because the "real" distutils files can't be located. -# -# We work around this by monkeypatching the py2exe code finding Python -# modules to replace the found virtualenv distutils modules with the -# original versions via filesystem scanning. This is a bit hacky. But -# it allows us to use virtualenvs for py2exe packaging, which is more -# deterministic and reproducible. -# -# It's worth noting that the common StackOverflow suggestions for this -# problem involve copying the original distutils files into the -# virtualenv or into the staging directory after setup() is invoked. -# The former is very brittle and can easily break setup(). Our hacking -# of the found modules routine has a similar result as copying the files -# manually. But it makes fewer assumptions about how py2exe works and -# is less brittle. - -# This only catches virtualenvs made with virtualenv (as opposed to -# venv, which is likely what Python 3 uses). -py2exehacked = py2exeloaded and getattr(sys, 'real_prefix', None) is not None - -if py2exehacked: - from distutils.command.py2exe import py2exe as buildpy2exe - from py2exe.mf import Module as py2exemodule - - class hgbuildpy2exe(buildpy2exe): - def find_needed_modules(self, mf, files, modules): - res = buildpy2exe.find_needed_modules(self, mf, files, modules) - - # Replace virtualenv's distutils modules with the real ones. - modules = {} - for k, v in res.modules.items(): - if k != 'distutils' and not k.startswith('distutils.'): - modules[k] = v - - res.modules = modules - - import opcode - - distutilsreal = os.path.join( - os.path.dirname(opcode.__file__), 'distutils' - ) - - for root, dirs, files in os.walk(distutilsreal): - for f in sorted(files): - if not f.endswith('.py'): - continue - - full = os.path.join(root, f) - - parents = ['distutils'] - - if root != distutilsreal: - rel = os.path.relpath(root, distutilsreal) - parents.extend(p for p in rel.split(os.sep)) - - modname = '%s.%s' % ('.'.join(parents), f[:-3]) - - if modname.startswith('distutils.tests.'): - continue - - if modname.endswith('.__init__'): - modname = modname[: -len('.__init__')] - path = os.path.dirname(full) - else: - path = None - - res.modules[modname] = py2exemodule( - modname, full, path=path - ) - - if 'distutils' not in res.modules: - raise SystemExit('could not find distutils modules') - - return res - - cmdclass = { 'build': hgbuild, 'build_doc': hgbuilddoc, @@ -1062,9 +981,6 @@ 'build_hgexe': buildhgexe, } -if py2exehacked: - cmdclass['py2exe'] = hgbuildpy2exe - packages = [ 'mercurial', 'mercurial.admin',