Skip to content

Commit f5aa254

Browse files
committed
Guess project root and warn user
Partially closes #230
1 parent a2becb3 commit f5aa254

1 file changed

Lines changed: 42 additions & 10 deletions

File tree

spin/__main__.py

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import importlib
33
import importlib.util
44
import os
5+
import pathlib
56
import sys
67
import textwrap
78
import traceback
@@ -19,8 +20,26 @@
1920
else:
2021
import tomli as tomllib
2122

23+
2224
click.Context.formatter_class = ColorHelpFormatter
2325

26+
config_filenames = (
27+
".spin.toml",
28+
"spin.toml",
29+
"pyproject.toml",
30+
)
31+
32+
33+
def _detect_config_dir(path: pathlib.Path) -> pathlib.Path | None:
34+
path = path.resolve()
35+
files = os.listdir(path)
36+
if any(f in files for f in config_filenames):
37+
return path
38+
elif path.parent != path:
39+
return _detect_config_dir(path.parent)
40+
else:
41+
return None
42+
2443

2544
def main():
2645
# Alias `spin help` to `spin --help`
@@ -38,15 +57,25 @@ def load_toml(filename):
3857

3958
toml_config = collections.ChainMap()
4059
toml_config.maps.extend(
41-
DotDict(cfg)
42-
for filename in (
43-
".spin.toml",
44-
"spin.toml",
45-
"pyproject.toml",
46-
)
47-
if (cfg := load_toml(filename))
60+
DotDict(cfg) for filename in config_filenames if (cfg := load_toml(filename))
4861
)
4962

63+
if not toml_config:
64+
click.secho(
65+
f"Could not load configuration from one of: {", ".join(config_filenames)}",
66+
file=sys.stderr,
67+
fg="red",
68+
)
69+
config_dir = _detect_config_dir(pathlib.Path("."))
70+
if config_dir:
71+
print()
72+
print(
73+
"Are you running `spin` from the correct directory? Perhaps you'd like to\n"
74+
)
75+
click.secho(f" $ cd {os.path.relpath(config_dir, '.')}\n")
76+
print("and try again.")
77+
sys.exit(1)
78+
5079
# Basic configuration validation
5180
version_query = len(sys.argv) == 2 and (sys.argv[1] == "--version")
5281

@@ -55,15 +84,18 @@ def load_toml(filename):
5584
if "tool.spin" in toml_config:
5685
spin_config = toml_config["tool.spin"]
5786
if "tool.spin.commands" not in toml_config:
58-
print(
59-
"Error: configuration is missing section [tool.spin.commands]\n",
87+
click.secho(
88+
"Error: configuration is missing section [tool.spin.commands]\n"
89+
"See https://github.com/scientific-python/spin/blob/main/README.md\n",
6090
file=sys.stderr,
91+
fg="red",
6192
)
6293
else:
63-
print(
94+
click.secho(
6495
"Error: need valid configuration in [.spin.toml], [spin.toml], or [pyproject.toml]\n"
6596
"See https://github.com/scientific-python/spin/blob/main/README.md\n",
6697
file=sys.stderr,
98+
fg="red",
6799
)
68100

69101
proj_name = (

0 commit comments

Comments
 (0)