milieux.cli.config
1from dataclasses import dataclass, field 2from pathlib import Path 3from typing import Any, Union 4 5from fancy_dataclass import CLIDataclass 6from rich.prompt import Confirm, Prompt 7 8from milieux import PROG, logger 9from milieux.config import Config, PipConfig, get_config_path, user_default_base_dir 10from milieux.errors import ConfigNotFoundError 11 12 13@dataclass 14class ConfigNew(CLIDataclass, command_name='new'): 15 """Create a new config file.""" 16 stdout: bool = field( 17 default=False, 18 metadata={'help': 'output config file to stdout'} 19 ) 20 21 def run(self) -> None: 22 """Creates a new config file interactively.""" 23 path = get_config_path() 24 write = True 25 if (not self.stdout) and path.exists(): 26 prompt = f'Config file {path} already exists. Overwrite?' 27 write = Confirm.ask(prompt) 28 if not write: 29 return 30 default_base_dir = user_default_base_dir() 31 base_dir = Prompt.ask('Base directory for workspace', default=str(default_base_dir)).strip() 32 if not (p := Path(base_dir)).is_dir(): 33 prompt = f'Directory {p} does not exist. Create it?' 34 create = Confirm.ask(prompt) 35 if create: 36 p.mkdir(parents=True) 37 logger.info(f'Created directory {p}') 38 else: 39 return 40 kwargs: dict[str, Any] = {'base_dir': base_dir} 41 default_env_dir = Config.__dataclass_fields__['env_dir'].default 42 assert isinstance(default_env_dir, str) 43 kwargs['env_dir'] = Prompt.ask('Directory for env_dir', default=default_env_dir).strip() 44 # TODO: access ~/.pip/pip.conf to retrieve index_url if it exists 45 index_url = Prompt.ask('PyPI index URL \\[optional]').strip() or None 46 kwargs['pip'] = PipConfig(index_url=index_url) 47 cfg = Config(**kwargs) 48 if self.stdout: 49 print('\n' + cfg.to_toml_string()) 50 else: 51 cfg.save(path) 52 logger.info(f'Saved config file to {path}') 53 54 55@dataclass 56class ConfigPath(CLIDataclass, command_name='path'): 57 """Print out path to the configurations.""" 58 59 def run(self) -> None: 60 """Displays the path to the user's config file.""" 61 print(get_config_path()) 62 63 64@dataclass 65class ConfigShow(CLIDataclass, command_name='show'): 66 """Show the configurations.""" 67 68 def run(self) -> None: 69 """Displays the contents of the user's config file.""" 70 if (path := get_config_path()).exists(): 71 cfg = Config.load(path) 72 print(cfg.to_toml_string()) 73 else: 74 raise ConfigNotFoundError(f"No config file found. Run '{PROG} config new' to create a new one.") 75 76 77@dataclass 78class ConfigCmd(CLIDataclass, command_name='config'): 79 """Manage configurations.""" 80 81 subcommand: Union[ 82 ConfigNew, 83 ConfigPath, 84 ConfigShow, 85 ] = field(metadata={'subcommand': True})
@dataclass
class
ConfigNew14@dataclass 15class ConfigNew(CLIDataclass, command_name='new'): 16 """Create a new config file.""" 17 stdout: bool = field( 18 default=False, 19 metadata={'help': 'output config file to stdout'} 20 ) 21 22 def run(self) -> None: 23 """Creates a new config file interactively.""" 24 path = get_config_path() 25 write = True 26 if (not self.stdout) and path.exists(): 27 prompt = f'Config file {path} already exists. Overwrite?' 28 write = Confirm.ask(prompt) 29 if not write: 30 return 31 default_base_dir = user_default_base_dir() 32 base_dir = Prompt.ask('Base directory for workspace', default=str(default_base_dir)).strip() 33 if not (p := Path(base_dir)).is_dir(): 34 prompt = f'Directory {p} does not exist. Create it?' 35 create = Confirm.ask(prompt) 36 if create: 37 p.mkdir(parents=True) 38 logger.info(f'Created directory {p}') 39 else: 40 return 41 kwargs: dict[str, Any] = {'base_dir': base_dir} 42 default_env_dir = Config.__dataclass_fields__['env_dir'].default 43 assert isinstance(default_env_dir, str) 44 kwargs['env_dir'] = Prompt.ask('Directory for env_dir', default=default_env_dir).strip() 45 # TODO: access ~/.pip/pip.conf to retrieve index_url if it exists 46 index_url = Prompt.ask('PyPI index URL \\[optional]').strip() or None 47 kwargs['pip'] = PipConfig(index_url=index_url) 48 cfg = Config(**kwargs) 49 if self.stdout: 50 print('\n' + cfg.to_toml_string()) 51 else: 52 cfg.save(path) 53 logger.info(f'Saved config file to {path}')
Create a new config file.
def
run(self) -> None:
22 def run(self) -> None: 23 """Creates a new config file interactively.""" 24 path = get_config_path() 25 write = True 26 if (not self.stdout) and path.exists(): 27 prompt = f'Config file {path} already exists. Overwrite?' 28 write = Confirm.ask(prompt) 29 if not write: 30 return 31 default_base_dir = user_default_base_dir() 32 base_dir = Prompt.ask('Base directory for workspace', default=str(default_base_dir)).strip() 33 if not (p := Path(base_dir)).is_dir(): 34 prompt = f'Directory {p} does not exist. Create it?' 35 create = Confirm.ask(prompt) 36 if create: 37 p.mkdir(parents=True) 38 logger.info(f'Created directory {p}') 39 else: 40 return 41 kwargs: dict[str, Any] = {'base_dir': base_dir} 42 default_env_dir = Config.__dataclass_fields__['env_dir'].default 43 assert isinstance(default_env_dir, str) 44 kwargs['env_dir'] = Prompt.ask('Directory for env_dir', default=default_env_dir).strip() 45 # TODO: access ~/.pip/pip.conf to retrieve index_url if it exists 46 index_url = Prompt.ask('PyPI index URL \\[optional]').strip() or None 47 kwargs['pip'] = PipConfig(index_url=index_url) 48 cfg = Config(**kwargs) 49 if self.stdout: 50 print('\n' + cfg.to_toml_string()) 51 else: 52 cfg.save(path) 53 logger.info(f'Saved config file to {path}')
Creates a new config file interactively.
@dataclass
class
ConfigPath56@dataclass 57class ConfigPath(CLIDataclass, command_name='path'): 58 """Print out path to the configurations.""" 59 60 def run(self) -> None: 61 """Displays the path to the user's config file.""" 62 print(get_config_path())
Print out path to the configurations.
@dataclass
class
ConfigShow65@dataclass 66class ConfigShow(CLIDataclass, command_name='show'): 67 """Show the configurations.""" 68 69 def run(self) -> None: 70 """Displays the contents of the user's config file.""" 71 if (path := get_config_path()).exists(): 72 cfg = Config.load(path) 73 print(cfg.to_toml_string()) 74 else: 75 raise ConfigNotFoundError(f"No config file found. Run '{PROG} config new' to create a new one.")
Show the configurations.
def
run(self) -> None:
69 def run(self) -> None: 70 """Displays the contents of the user's config file.""" 71 if (path := get_config_path()).exists(): 72 cfg = Config.load(path) 73 print(cfg.to_toml_string()) 74 else: 75 raise ConfigNotFoundError(f"No config file found. Run '{PROG} config new' to create a new one.")
Displays the contents of the user's config file.
@dataclass
class
ConfigCmd78@dataclass 79class ConfigCmd(CLIDataclass, command_name='config'): 80 """Manage configurations.""" 81 82 subcommand: Union[ 83 ConfigNew, 84 ConfigPath, 85 ConfigShow, 86 ] = field(metadata={'subcommand': True})
Manage configurations.
ConfigCmd( subcommand: Union[ConfigNew, ConfigPath, ConfigShow])
subcommand: Union[ConfigNew, ConfigPath, ConfigShow]