Skip to content

Commit

Permalink
Group meson commands in preparation for other build systems (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanv authored Mar 2, 2023
1 parent 30ae90e commit 1ef2112
Show file tree
Hide file tree
Showing 15 changed files with 381 additions and 328 deletions.
76 changes: 49 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,44 @@ As an example, see the `[tool.devpy]` section of [an example `pyproject.toml`](h
The `[tool.devpy]` section should contain:

```
package = 'pkg_importname' # used by pytest
commands = ['devpy.build', 'devpy.test']
package = "pkg_importname" # name of your package
commands = [
"devpy.cmds.meson.build",
"devpy.cmds.meson.test"
]
```

See [the command selection](#built-in-commands) below.

### Command sections

Once you have several commands, it may be useful to organize them into sections.
In `pyproject.toml`, instead of specifying the commands as a list, use the following structure:

```toml
[tool.devpy.commands]
"Build" = [
"devpy.cmds.meson.build",
"devpy.cmds.meson.test"
]
"Environments" = [
"devpy.cmds.meson.shell",
"devpy.cmds.meson.ipython",
"devpy.cmds.meson.python"
]
```

These commands will then be rendered as:

```
Build:
build 🔧 Build package with Meson/ninja and install
test 🔧 Run tests
Environments:
shell 💻 Launch shell with PYTHONPATH set
ipython 💻 Launch IPython shell with PYTHONPATH set
python 🐍 Launch Python shell with PYTHONPATH set
```

## Running
Expand All @@ -45,12 +81,22 @@ On Unix-like systems, you can also copy the [`dev.py` script](https://github.com

## Built-in commands

### [Meson](https://meson-python.readthedocs.io)

```
build 🔧 Build package with Meson/ninja and install to `build-install`
ipython 💻 Launch IPython shell with PYTHONPATH set
python 🐍 Launch Python shell with PYTHONPATH set
shell 💻 Launch shell with PYTHONPATH set
test 🔧 Run tests
test 🔧 Run pytest
```

### [Build](https://pypa-build.readthedocs.io/en/stable/) (PEP 517 builder)

`devpy` was started with Meson in mind, but we're working on expanding commands for PEP 517 `build`.

```
sdist 📦 Build a source distribution in `dist/`.
```

## 🧪 Custom commands
Expand Down Expand Up @@ -82,30 +128,6 @@ def example():
print(config["tool.devpy"])
```

### Command sections

Once you have several commands, it may be useful to organize them into sections.
In `pyproject.toml`, instead of specifying the commands as a list, use the following structure:

```toml
[tool.devpy.commands]
"Build" = ["devpy.build_meson", "devpy.test"]
"Environments" = ["devpy.shell", "devpy.ipython", "devpy.python"]
```

These commands will then be rendered as:

```
Build:
build 🔧 Build package with Meson/ninja and install
test 🔧 Run tests
Environments:
shell 💻 Launch shell with PYTHONPATH set
ipython 💻 Launch IPython shell with PYTHONPATH set
python 🐍 Launch Python shell with PYTHONPATH set
```

## History

The `dev.py` tool was [proposed for SciPy](https://github.com/scipy/scipy/issues/15489) by Ralf Gommers and [implemented](https://github.com/scipy/scipy/pull/15959) by Sayantika Banik, Eduardo Naufel Schettino, and Ralf Gommers (also see [Sayantika's blog post](https://labs.quansight.org/blog/the-evolution-of-the-scipy-developer-cli)).
Expand Down
63 changes: 40 additions & 23 deletions devpy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@ def __getitem__(self, key):
print("No configuration found in [pyproject.toml] for [tool.devpy]")
sys.exit(1)

commands = {
f"devpy.{name}": getattr(cmds, name)
for name in dir(cmds)
if not name.startswith("_")
}

proj_name = project_config.get("name", config["package"])

@click.group(help=f"Developer tool for {proj_name}", cls=SectionedHelpGroup)
Expand All @@ -69,31 +63,54 @@ def group(ctx):
if isinstance(config_cmds, list):
config_cmds = {"Commands": config_cmds}

# Backward compatibility workaround
# Originally, you could specify any of these commands as `devpy.cmd`
# and we'd fetch it from util
commands = {
"devpy.build": cmds.meson.build,
"devpy.test": cmds.meson.test,
"devpy.ipython": cmds.meson.ipython,
"devpy.python": cmds.meson.python,
"devpy.shell": cmds.meson.shell,
}

for section, cmds in config_cmds.items():
for cmd in cmds:
if cmd not in commands:
try:
path, func = cmd.split(":")
spec = importlib.util.spec_from_file_location("custom_mod", path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
# First, see if we can directly import the command
if not ":" in cmd:
path, func = cmd.rsplit(".", maxsplit=1)
try:
mod = importlib.import_module(path)
except ImportError:
print(
f"!! Could not import module `{path}` to load command `{cmd}`"
)
continue
else:
try:
cmd_func = getattr(mod, func)
except AttributeError:
path, func = cmd.split(":")
spec = importlib.util.spec_from_file_location(
"custom_mod", path
)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
except FileNotFoundError:
print(
f"!! Could not load command `{func}` from file `{path}`.\n"
f"!! Could not find file `{path}` to load custom command `{cmd}`.\n"
)
continue
except FileNotFoundError:
print(
f"!! Could not find file `{path}` to load custom command `{cmd}`.\n"
)
except Exception as e:
print(
f"!! Could not import file `{path}` to load custom command `{cmd}`.\n"
)
raise e

try:
cmd_func = getattr(mod, func)
except AttributeError:
print(f"!! Could not load command `{func}` from file `{path}`.\n")
continue
except Exception as e:
print(
f"!! Could not import file `{path}` to load custom command `{cmd}`.\n"
)
raise e

commands[cmd] = cmd_func

Expand Down
11 changes: 8 additions & 3 deletions devpy/cmds/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from ._build import build
from ._test import test
from ._shell import ipython, python, shell
from . import meson

# Backward compatibility with older versions
build = meson.build
test = meson.test
ipython = meson.ipython
python = meson.python
shell = meson.shell
69 changes: 0 additions & 69 deletions devpy/cmds/_build.py

This file was deleted.

77 changes: 0 additions & 77 deletions devpy/cmds/_shell.py

This file was deleted.

48 changes: 0 additions & 48 deletions devpy/cmds/_test.py

This file was deleted.

Loading

0 comments on commit 1ef2112

Please sign in to comment.