22import importlib
33import importlib .util
44import os
5+ import pathlib
56import sys
67import textwrap
78import traceback
9+ from typing import Union
810
911import click
1012
1921else :
2022 import tomli as tomllib
2123
24+
2225click .Context .formatter_class = ColorHelpFormatter
2326
27+ config_filenames = (
28+ ".spin.toml" ,
29+ "spin.toml" ,
30+ "pyproject.toml" ,
31+ )
32+
33+
34+ def _detect_config_dir (path : pathlib .Path ) -> Union [pathlib .Path , None ]:
35+ path = path .resolve ()
36+ files = os .listdir (path )
37+ if any (f in files for f in config_filenames ):
38+ return path
39+ elif path .parent != path :
40+ return _detect_config_dir (path .parent )
41+ else :
42+ return None
43+
2444
2545def main ():
2646 # Alias `spin help` to `spin --help`
@@ -38,15 +58,25 @@ def load_toml(filename):
3858
3959 toml_config = collections .ChainMap ()
4060 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 ))
61+ DotDict (cfg ) for filename in config_filenames if (cfg := load_toml (filename ))
4862 )
4963
64+ if not toml_config :
65+ click .secho (
66+ f"Could not load configuration from one of: { ', ' .join (config_filenames )} " ,
67+ file = sys .stderr ,
68+ fg = "red" ,
69+ )
70+ config_dir = _detect_config_dir (pathlib .Path ("." ))
71+ if config_dir :
72+ print ()
73+ print (
74+ "Are you running `spin` from the correct directory? Perhaps you'd like to\n "
75+ )
76+ click .secho (f" $ cd { os .path .relpath (config_dir , '.' )} \n " )
77+ print ("and try again." )
78+ sys .exit (1 )
79+
5080 # Basic configuration validation
5181 version_query = len (sys .argv ) == 2 and (sys .argv [1 ] == "--version" )
5282
@@ -55,15 +85,18 @@ def load_toml(filename):
5585 if "tool.spin" in toml_config :
5686 spin_config = toml_config ["tool.spin" ]
5787 if "tool.spin.commands" not in toml_config :
58- print (
59- "Error: configuration is missing section [tool.spin.commands]\n " ,
88+ click .secho (
89+ "Error: configuration is missing section [tool.spin.commands]\n "
90+ "See https://github.com/scientific-python/spin/blob/main/README.md\n " ,
6091 file = sys .stderr ,
92+ fg = "red" ,
6193 )
6294 else :
63- print (
95+ click . secho (
6496 "Error: need valid configuration in [.spin.toml], [spin.toml], or [pyproject.toml]\n "
6597 "See https://github.com/scientific-python/spin/blob/main/README.md\n " ,
6698 file = sys .stderr ,
99+ fg = "red" ,
67100 )
68101
69102 proj_name = (
0 commit comments