Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions spin/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
import importlib
import importlib.util
import os
import pathlib
import sys
import textwrap
import traceback
from typing import Union

import click

Expand All @@ -19,8 +21,26 @@
else:
import tomli as tomllib


click.Context.formatter_class = ColorHelpFormatter

config_filenames = (
".spin.toml",
"spin.toml",
"pyproject.toml",
)


def _detect_config_dir(path: pathlib.Path) -> Union[pathlib.Path, None]:
path = path.resolve()
files = os.listdir(path)
if any(f in files for f in config_filenames):
return path
elif path.parent != path:
return _detect_config_dir(path.parent)
else:
return None


def main():
# Alias `spin help` to `spin --help`
Expand All @@ -38,15 +58,25 @@ def load_toml(filename):

toml_config = collections.ChainMap()
toml_config.maps.extend(
DotDict(cfg)
for filename in (
".spin.toml",
"spin.toml",
"pyproject.toml",
)
if (cfg := load_toml(filename))
DotDict(cfg) for filename in config_filenames if (cfg := load_toml(filename))
)

if not toml_config:
click.secho(
f"Could not load configuration from one of: {', '.join(config_filenames)}",
file=sys.stderr,
fg="red",
)
config_dir = _detect_config_dir(pathlib.Path("."))
if config_dir:
print()
print(
"Are you running `spin` from the correct directory? Perhaps you'd like to\n"
)
click.secho(f" $ cd {os.path.relpath(config_dir, '.')}\n")
print("and try again.")
sys.exit(1)

# Basic configuration validation
version_query = len(sys.argv) == 2 and (sys.argv[1] == "--version")

Expand All @@ -55,15 +85,18 @@ def load_toml(filename):
if "tool.spin" in toml_config:
spin_config = toml_config["tool.spin"]
if "tool.spin.commands" not in toml_config:
print(
"Error: configuration is missing section [tool.spin.commands]\n",
click.secho(
"Error: configuration is missing section [tool.spin.commands]\n"
"See https://github.com/scientific-python/spin/blob/main/README.md\n",
file=sys.stderr,
fg="red",
)
else:
print(
click.secho(
"Error: need valid configuration in [.spin.toml], [spin.toml], or [pyproject.toml]\n"
"See https://github.com/scientific-python/spin/blob/main/README.md\n",
file=sys.stderr,
fg="red",
)

proj_name = (
Expand Down