Open jbms opened 1 year ago
I made some progress on this. Working with the info from the linked docs, I was able to get editable installs to use a setuptools SubCommand
. Although, I'm still trying to figure out how to pass a SubCommand
option (ie dirty
in the following snippet) from CLI.
from pathlib import Path
import subprocess
from setuptools import setup, Command
from setuptools.command.build_py import build_py
from setuptools.command.sdist import sdist
from setuptools.command.build import SubCommand
pkg_root = Path(__file__).parent / "src"
class SrcDistCommand(sdist):
"""Custom build command."""
def run(self):
self.run_command("bundle-icons")
super().run()
class BuildPyCommand(build_py):
"""Custom build command."""
def run(self):
self.run_command("bundle-icons")
super().run()
class BundleCommand(Command, SubCommand):
"""A custom command to run svgo (via nox) on all bundled SVG icons."""
description = "Copy and optimize SVG files from npm modules."
user_options = [
# The format is (long option, short option, description).
("dirty", None, "skip bundling icons if they already exist in pkg src"),
]
def initialize_options(self):
"""Set default values for options."""
# Each user option must be listed here with their default value.
self.dirty = False
def finalize_options(self):
"""Post-process options."""
if (
self.dirty
and not Path(pkg_root, "my_pkg", ".icons", "tabler").exists()
):
raise OSError("Building package 'dirty', but no generated SVG files exist!")
def run(self):
"""Run command."""
if not self.dirty:
self.announce("Running nox session: bundle_icons", level=2)
subprocess.run(["nox", "-s", "bundle_icons"], check=True, shell=True)
# all install info is located in pyproject.toml
setup(
cmdclass={
"bundle-icons": BundleCommand,
"build_py": BuildPyCommand,
"sdist": SrcDistCommand,
},
)
The inheriting from both Command
and SubCommand
seems redundant, but it seems like they were designed to work together.
I think you can't pass options when using pip install
.
This is how I fixed this issue for a different project:
pip install
does have a --install-options
arg, but I've been focusing on how to pass the option from pip wheel
. Turns out this
pip wheel --config-settings='--build-option=--dirty' -w dist --no-deps .
will pass the --dirty
option to the build commands, but since my pkg deps don't support a --dirty
build option, I get errors during the "Installing build dependencies" stage; I also tried dirty
without the prefixed --
but same error popped up.
TBH, I don't fully follow all the changes in that diff's setup.py file. But I haven't really explored the setuptools internals enough.
I do like this tactic:
# If building from an sdist, `package.json` won't be present but the
# bundled files will.
Seems useful if using pypa/build to make dists.
I just found out that setuptools v64.0.2+ will ignore any exceptions raised by custom commands during editable installs: https://github.com/pypa/setuptools/commit/048633afd7d6e4f852766d06c975ad602a035193 👎🏼
Looks like the issue is that
pip install -e .
no longer runs thedevelop
command, which is what we were relying on in setup.py to do the nodejs build. It looks like there is a new mechanism that can be used to handle editable builds, but it is not clear to me exactly how to use it:https://setuptools.pypa.io/en/latest/userguide/extension.html#supporting-sdists-and-editable-installs-in-build-sub-commands
_Originally posted by @jbms in https://github.com/jbms/sphinx-immaterial/pull/247#discussion_r1179906766_