Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition from schema to pydantic #13

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions devtools/conda-envs/docs_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies:
- gitpython
- toml
- typer[all]>=0.6
- schema
- pydantic~=2.0.0
- pyyaml

# Docs depends
Expand All @@ -19,4 +19,4 @@ dependencies:
- myst-parser~=1.0.0
- sphinx-notfound-page
- sphinx-click
- sphinx-jsonschema
- autodoc-pydantic
2 changes: 1 addition & 1 deletion devtools/conda-envs/test_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dependencies:
- gitpython
- toml
- typer[all]>=0.6
- schema
- pydantic~=2.0.0
- pyyaml

# Testing
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/user_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ dependencies:
- gitpython
- toml
- typer[all]>=0.6
- schema
- pydantic~=2.0.0
- pyyaml
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"sphinx.ext.doctest",
"myst_parser",
"sphinx_click",
"sphinx-jsonschema",
# "sphinxcontrib.autodoc_pydantic",
]


Expand Down
13 changes: 1 addition & 12 deletions docs/configuring.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
# Configuring SOAP


## Environments

:::{jsonschema} soap.config.ENV_SCHEMA_JSON
:::


## Aliases

:::{jsonschema} soap.config.ALIAS_SCHEMA_JSON
:::

SOAP is configured with the `soap.toml` file, which uses the fields described in [](soap.config).
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dependencies = [
"gitpython",
"toml",
"typer[all]>=0.6",
"schema",
"pydantic~=2.0.0",
"pyyaml",
]
dynamic = ["version"]
Expand All @@ -37,7 +37,7 @@ docs = [
"myst-parser~=1.0.0",
"sphinx-notfound-page",
"sphinx-click",
"sphinx-jsonschema",
"autodoc_pydantic",
]
all=["soap[test,docs]"]

Expand Down
8 changes: 4 additions & 4 deletions soap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Add imports here
from soap._soap import prepare_env, run_in_env
from soap.config import Config, Alias, Env
from soap.config import ConfigModel, AliasModel, EnvModel

# Import the version from setuptools_scm _version module
from soap._version import version as VERSION
Expand All @@ -11,9 +11,9 @@
__all__ = [
"prepare_env",
"run_in_env",
"Config",
"Alias",
"Env",
"ConfigModel",
"AliasModel",
"EnvModel",
"VERSION",
"VERSION_TUPLE",
]
28 changes: 14 additions & 14 deletions soap/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ def main():
"""Entry point for Snakes on a Plane.

Generates commands for aliases and catches and simplifies errors."""
cfg = soap.Config()
for alias in cfg.aliases:
cfg = soap.ConfigModel.from_file_tree()
for alias_name, alias in cfg.aliases.items():

@app.command(
alias.name,
alias_name,
help=alias.description,
context_settings={
"allow_extra_args": alias.passthrough_args,
Expand Down Expand Up @@ -109,14 +109,14 @@ def update(
"""
Update Conda environments.
"""
cfg = soap.Config()
envs = cfg.envs.values() if env is None else [cfg.envs[env]]
cfg = soap.ConfigModel.from_file_tree()
envs = cfg.envs.items() if env is None else [(env, cfg.envs[env])]
CONSOLE.print(
f"[cyan]Updating {len(envs)} environment{'s' if len(envs) != 1 else ''}"
)
for this_env in envs:
for env_name, this_env in envs:
CONSOLE.print(
f"[cyan]Preparing environment '{this_env.name}' "
f"[cyan]Preparing environment '{env_name}' "
+ f"from '{this_env.yml_path}' "
+ f"in '{this_env.env_path}'"
)
Expand All @@ -132,7 +132,7 @@ def run(
env: str = Option(DEFAULT_ENV, help="Environment in which to run the command"),
):
"""Run a command in an environment."""
cfg = soap.Config()
cfg = soap.ConfigModel.from_file_tree()
this_env = cfg.envs[env]
soap.prepare_env(this_env)
try:
Expand All @@ -152,7 +152,7 @@ def list(
)
):
"""List the available environments."""
cfg = soap.Config()
cfg = soap.ConfigModel.from_file_tree()

if verbosity < 3:
captions = [
Expand All @@ -177,8 +177,8 @@ def list(
table.add_column("🪧")
table.add_column("📥")

for env in cfg.envs.values():
row = [env.name, str(env.yml_path)]
for env_name, env in cfg.envs.items():
row = [env_name, str(env.yml_path)]
if verbosity > 0:
row.append("✓" if env.install_current else "")
if verbosity > 1:
Expand All @@ -191,8 +191,8 @@ def list(
else:
tree = rich.tree.Tree("[i]Snakes on a Plane environments", guide_style="dim")

for env in cfg.envs.values():
branch = tree.add(f"[cyan bold]{env.name}")
for env_name, env in cfg.envs.items():
branch = tree.add(f"[cyan bold]{env_name}")
yml_branch = branch.add(f"[b]YAML path:[/b] {env.yml_path}")
branch.add(f"[b]Environment path:[/b] {env.env_path}")
environment_exists = (
Expand All @@ -211,7 +211,7 @@ def list(
yml_branch.add(syntax)
if verbosity > 4:
branch.add(
f"[b]Command to update environment:[/b] [u]soap update --env {env.name}"
f"[b]Command to update environment:[/b] [u]soap update --env {env_name}"
)
branch.add(
f"[b]Command to recreate environment:[/b] [u]soap update --recreate --env {env.name}"
Expand Down
13 changes: 13 additions & 0 deletions soap/_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from pydantic import BaseModel as _BaseModel
from pydantic import ConfigDict

__all__ = [
"BaseModel",
]


class BaseModel(_BaseModel):
model_config = ConfigDict(
validate_assignment=True,
extra="forbid",
)
10 changes: 5 additions & 5 deletions soap/_soap.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import yaml

import soap.conda
from soap.config import Env
from soap.config import EnvModel
from soap.utils import yaml_file_to_dict, dict_to_yaml_str


Expand All @@ -33,7 +33,7 @@ def add_pip_package(
dependencies.append({"pip": [package]})


def prepare_env_file(env: Env) -> str:
def prepare_env_file(env: EnvModel) -> str:
"""
Prepare an environment YAML file and return its contents

Expand All @@ -56,15 +56,15 @@ def prepare_env_file(env: Env) -> str:
# Add the current package, in dev mode, if required
if env.install_current:
add_pip_package(
f"-e {env.package_root}[all]",
f"-e {env._package_root}[all]",
env_dict["dependencies"],
)

return dict_to_yaml_str(env_dict)


def prepare_env(
env: Env,
env: EnvModel,
ignore_cache: bool = False,
):
"""
Expand Down Expand Up @@ -122,7 +122,7 @@ def prepare_env(
working_yaml_path.unlink()


def run_in_env(args: Sequence[str], env: Env):
def run_in_env(args: Sequence[str], env: EnvModel):
"""
Run a command in the provided environment. Does not update the environment.

Expand Down
Loading