22import importlib
33import importlib .util
44import os
5+ import pathlib
56import sys
67import textwrap
78import traceback
1920else :
2021 import tomli as tomllib
2122
23+
2224click .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
2544def 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