Skip to content

Commands

sereto.cli.commands

WorkingDir

Helper class for REPL implementing the cd command.

Attributes:

Name Type Description
old_cwd Path

The previous working directory.

Source code in sereto/cli/commands.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class WorkingDir(metaclass=Singleton):
    """Helper class for REPL implementing the `cd` command.

    Attributes:
        old_cwd: The previous working directory.
    """

    old_cwd: Path = Field(default_factory=Path.cwd)

    def change(self, dst: Path, /) -> None:
        """Change the current working directory to the new location.

        Also saves the previous location for future reference.

        Args:
            dst: The new working directory

        Raises:
            SeretoPathError: If the provided path is not an existing directory.
        """
        if not dst.is_dir():
            raise SeretoPathError(f"Directory '{dst}' does not exist.")

        cwd = Path.cwd()
        os.chdir(dst)
        self.old_cwd = cwd

    def go_back(self) -> None:
        """Change the current working directory to the previous location."""
        self.change(self.old_cwd)

change(dst)

Change the current working directory to the new location.

Also saves the previous location for future reference.

Parameters:

Name Type Description Default
dst Path

The new working directory

required

Raises:

Type Description
SeretoPathError

If the provided path is not an existing directory.

Source code in sereto/cli/commands.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def change(self, dst: Path, /) -> None:
    """Change the current working directory to the new location.

    Also saves the previous location for future reference.

    Args:
        dst: The new working directory

    Raises:
        SeretoPathError: If the provided path is not an existing directory.
    """
    if not dst.is_dir():
        raise SeretoPathError(f"Directory '{dst}' does not exist.")

    cwd = Path.cwd()
    os.chdir(dst)
    self.old_cwd = cwd

go_back()

Change the current working directory to the previous location.

Source code in sereto/cli/commands.py
76
77
78
def go_back(self) -> None:
    """Change the current working directory to the previous location."""
    self.change(self.old_cwd)

repl_cd(settings, project_id)

Switch the active project in the REPL.

Parameters:

Name Type Description Default
settings Settings

The Settings object.

required
project_id TypeProjectId | Literal['-']

The ID of the project to switch to. Use '-' to go back to the previous working directory.

required

Raises:

Type Description
SeretoValueError

If the project ID is invalid.

SeretoPathError

If the project's path does not exist.

Source code in sereto/cli/commands.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@click.command(name="cd")
@click.argument("project_id", type=str)
@load_settings
@validate_call
def repl_cd(settings: Settings, project_id: TypeProjectId | Literal["-"]) -> None:
    """Switch the active project in the REPL.

    Args:
        settings: The Settings object.
        project_id: The ID of the project to switch to. Use '-' to go back to the previous working directory.

    Raises:
        SeretoValueError: If the project ID is invalid.
        SeretoPathError: If the project's path does not exist.
    """
    wd = WorkingDir()

    # `cd -` ... Go back to the previous working directory
    if project_id == "-":
        wd.go_back()
        return

    # Check if the project's location exists
    # TODO: Should we iterate over all projects and read the config to get the correct path?
    project_path = settings.projects_path / project_id
    if not Project.is_project_dir(project_path):
        raise SeretoPathError(f"project '{project_id}' does not exist. Use 'ls' to list all projects")

    # Change the current working directory to the new location
    wd.change(project_path)

repl_exit()

Exit from the Read-Eval-Print Loop (REPL).

Source code in sereto/cli/commands.py
145
146
147
148
@click.command(name="exit")
def repl_exit() -> None:
    """Exit from the Read-Eval-Print Loop (REPL)."""
    click_repl_exit()

repl_toggle_debug()

Toggle the debug mode.

Source code in sereto/cli/commands.py
151
152
153
154
155
156
157
@click.command(name="debug")
def repl_toggle_debug() -> None:
    """Toggle the debug mode."""
    if os.environ.get("DEBUG", "0") == "1":
        del os.environ["DEBUG"]
    else:
        os.environ["DEBUG"] = "1"

sereto_ls(settings)

List all projects in the user's projects directory.

Print a table with the details to the console.

Parameters:

Name Type Description Default
settings Settings

The Settings object.

required
Source code in sereto/cli/commands.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@validate_call
def sereto_ls(settings: Settings) -> None:
    """List all projects in the user's projects directory.

    Print a table with the details to the console.

    Args:
        settings: The Settings object.
    """
    project_paths: list[Path] = [d for d in settings.projects_path.iterdir() if Project.is_project_dir(d)]
    table = Table("ID", "Name", "Location", title="Projects", box=box.MINIMAL)

    for dir in project_paths:
        try:
            project_name = Project.load_from(dir).config.last_config().name
        except (RuntimeError, SeretoValueError):
            project_name = "n/a"

        table.add_row(dir.name, project_name, f"[link {dir.as_uri()}]{dir}")

    Console().print(table, justify="center")

sereto_repl(cli)

Start an interactive Read-Eval-Print Loop (REPL) session.

Parameters:

Name Type Description Default
cli Group

The main CLI group.

required
Source code in sereto/cli/commands.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def sereto_repl(cli: Group) -> None:
    """Start an interactive Read-Eval-Print Loop (REPL) session.

    Args:
        cli: The main CLI group.
    """
    Console().log(r"""
  ____       ____     _____
 / ___|  ___|  _ \ __|_   _|__
 \___ \ / _ \ |_) / _ \| |/ _ \
  ___) |  __/  _ <  __/| | (_) |
 |____/ \___|_| \_\___||_|\___/

Welcome to [blue]SeReTo Interactive Mode[/blue]!
-------------------------------------------
Type 'exit' or press 'Ctrl+D' to quit.
Use 'cd <ID>' to change the active project.
Type '-h'/'--help' to see available commands.
    """)

    # Add REPL specific commands
    cli.add_command(repl_cd)
    cli.add_command(repl_exit)
    cli.add_command(repl_toggle_debug)

    # Define the prompt style
    prompt_style = Style.from_dict(
        {
            "debug": "red",
            "sereto": "#02a0f0 bold",
            "bracket": "#8a8a8a",
            "project_id": "#00ff00",
            "gt": "#8a8a8a bold",
        }
    )

    prompt_kwargs = {
        "message": _get_repl_prompt,
        "history": FileHistory(Path(get_app_dir(app_name="sereto")) / ".sereto_history"),
        "style": prompt_style,
    }
    repl(click.get_current_context(), prompt_kwargs=prompt_kwargs)