Skip to content

Config

sereto.cli.config

add_dates_config(config, version=None, date_type=None, start_date=None, end_date=None)

Add date to the configuration.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
version ProjectVersion | None

The version of the project. If not provided, the last version is used.

None
date_type DateType | None

The type of the date event.

None
start_date str | None

The start date str in DD-Mmm-YYYY format.

None
end_date str | None

The end date str in DD-Mmm-YYYY format.

None
Source code in sereto/cli/config.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
@validate_call
def add_dates_config(
    config: Config,
    version: ProjectVersion | None = None,
    date_type: DateType | None = None,
    start_date: str | None = None,
    end_date: str | None = None,
) -> None:
    """Add date to the configuration.

    Args:
        config: Configuration of the project.
        version: The version of the project. If not provided, the last version is used.
        date_type: The type of the date event.
        start_date: The start date str in DD-Mmm-YYYY format.
        end_date: The end date str in DD-Mmm-YYYY format.
    """
    if version is None:
        version = config.last_version

    new_date = _build_date_from_options(date_type=date_type, start_date=start_date, end_date=end_date)

    # Add the date to the configuration
    config.at_version(version).add_date(new_date)

    # Write the configuration
    config.save()

add_people_config(config, version=None, person_type=None, person_name=None, business_unit=None, email=None, role=None)

Add person to the configuration.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
version ProjectVersion | None

The version of the project. If not provided, the last version is used.

None
person_type PersonType | None

The type of the person.

None
person_name str | None

The name of the person.

None
business_unit str | None

The business unit of the person.

None
email str | None

The email address of the person.

None
role str | None

The role of the person.

None
Source code in sereto/cli/config.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
@validate_call
def add_people_config(
    config: Config,
    version: ProjectVersion | None = None,
    person_type: PersonType | None = None,
    person_name: str | None = None,
    business_unit: str | None = None,
    email: str | None = None,
    role: str | None = None,
) -> None:
    """Add person to the configuration.

    Args:
        config: Configuration of the project.
        version: The version of the project. If not provided, the last version is used.
        person_type: The type of the person.
        person_name: The name of the person.
        business_unit: The business unit of the person.
        email: The email address of the person.
        role: The role of the person.
    """
    if version is None:
        version = config.last_version

    new_person = _build_person_from_options(
        person_type=person_type,
        person_name=person_name,
        business_unit=business_unit,
        email=email,
        role=role,
    )

    # Add the person to the configuration
    config.at_version(version).add_person(new_person)

    # Write the configuration
    config.save()

add_target(project_path, templates, config, categories, version=None, category=None, target_name=None, extra_json=None)

Add target to the configuration.

Parameters:

Name Type Description Default
project_path DirectoryPath

Path to the project directory.

required
templates DirectoryPath

Path to the templates directory.

required
config Config

Configuration of the project.

required
categories Iterable[str]

List of all categories.

required
version ProjectVersion | None

The version of the project. If not provided, the last version is used.

None
category str | None

Category of the target.

None
target_name str | None

Name of the target.

None
extra_json str | None

Extra target fields as a JSON string.

None
Source code in sereto/cli/config.py
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
@validate_call
def add_target(
    project_path: DirectoryPath,
    templates: DirectoryPath,
    config: Config,
    categories: Iterable[str],
    version: ProjectVersion | None = None,
    category: str | None = None,
    target_name: str | None = None,
    extra_json: str | None = None,
) -> None:
    """Add target to the configuration.

    Args:
        project_path: Path to the project directory.
        templates: Path to the templates directory.
        config: Configuration of the project.
        categories: List of all categories.
        version: The version of the project. If not provided, the last version is used.
        category: Category of the target.
        target_name: Name of the target.
        extra_json: Extra target fields as a JSON string.
    """
    if version is None:
        version = config.last_version

    new_target_model = _build_target_from_options(
        category=category, target_name=target_name, categories=categories, extra_json=extra_json
    )

    # Create the target instance, including on the filesystem
    new_target = Target.new(data=new_target_model, project_path=project_path, templates=templates, version=version)

    # Add the target to the configuration
    config.at_version(version).add_target(new_target)

    # Write the configuration
    config.save()

delete_target(config, index, version=None, interactive=False)

Delete target from the configuration by its index.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
index int

Index to item which should be deleted. First item is 1.

required
version ProjectVersion | None

The version of the project. If not provided, the last version is used.

None
interactive bool

Whether to ask for confirmations.

False
Source code in sereto/cli/config.py
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
@validate_call
def delete_target(
    config: Config, index: int, version: ProjectVersion | None = None, interactive: bool = False
) -> None:
    """Delete target from the configuration by its index.

    Args:
        config: Configuration of the project.
        index: Index to item which should be deleted. First item is 1.
        version: The version of the project. If not provided, the last version is used.
        interactive: Whether to ask for confirmations.
    """
    if version is None:
        version = config.last_version

    # Extract the filesystem path before deleting the values
    version_config = config.at_version(version)
    target_path = version_config.targets[index - 1].path

    # Delete the date from the configuration
    version_config.delete_target(index=index)

    # Write the configuration
    config.save()

    # Delete target from the filesystem
    if (
        target_path.is_dir()
        and interactive
        and yes_no_dialog(title="Confirm", text=f"Delete '{target_path}' from the filesystem?").run()
    ):
        shutil.rmtree(target_path)

edit_config(project, non_interactive=False, extra_json=None)

Edit the configuration file in default CLI editor.

When non_interactive is True, the config is updated from extra_json without opening an editor. Otherwise, the config file is opened in the default editor.

Parameters:

Name Type Description Default
project Project

Project's representation.

required
non_interactive bool

If True, run non-interactively.

False
extra_json str | None

A JSON string with config fields to update.

None
Source code in sereto/cli/config.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@validate_call
def edit_config(
    project: Project,
    non_interactive: bool = False,
    extra_json: str | None = None,
) -> None:
    """Edit the configuration file in default CLI editor.

    When `non_interactive` is True, the config is updated from `extra_json` without opening an editor.
    Otherwise, the config file is opened in the default editor.

    Args:
        project: Project's representation.
        non_interactive: If True, run non-interactively.
        extra_json: A JSON string with config fields to update.
    """

    sereto_ver = importlib.metadata.version("sereto")
    config = project.config_path

    # If the config file does not exist, create it with default values
    if not project.config_path.is_file():
        Config(
            sereto_version=SeretoVersion.from_str(sereto_ver),
            version_configs={
                ProjectVersion.from_str("v1.0"): VersionConfig(
                    version=ProjectVersion.from_str("v1.0"),
                    id="",
                    name="",
                    version_description="Initial",
                    risk_due_dates=project.settings.risk_due_dates,
                ),
            },
            path=project.config_path,
            risk_due_dates=project.settings.risk_due_dates,
        ).save()

    if non_interactive:
        if extra_json is None:
            raise SeretoValueError("'--extra' is required in non-interactive mode.")
        try:
            extra = json.loads(extra_json)
        except json.JSONDecodeError as e:
            raise SeretoValueError(f"Invalid JSON in '--extra': {e}") from e

        if not isinstance(extra, dict):
            raise SeretoValueError("Value of '--extra' must be a JSON object")

        version_config = project.config.last_config
        skip_fields = {"version_configs", "targets", "dates", "people"}

        for key, value in extra.items():
            if key in skip_fields:
                continue
            elif key in VersionConfigModel.model_fields:
                setattr(version_config, key, value)
            elif key in ConfigModel.model_fields:
                setattr(project.config, key, value)
            else:
                raise SeretoValueError(f"Unknown config field: '{key}'")

        project.config.save()
    else:
        # Interactive: open the config file in the default editor
        click.edit(filename=str(config))

show_config(config, output_format, all=False, version=None)

Display the configuration for a project.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
output_format OutputFormat

Format of the output.

required
all bool

Whether to show values from all versions or just the last one.

False
version ProjectVersion | None

Show config at specific version, e.g. 'v1.0'.

None
Source code in sereto/cli/config.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
@validate_call
def show_config(
    config: Config, output_format: OutputFormat, all: bool = False, version: ProjectVersion | None = None
) -> None:
    """Display the configuration for a project.

    Args:
        config: Configuration of the project.
        output_format: Format of the output.
        all: Whether to show values from all versions or just the last one.
        version: Show config at specific version, e.g. 'v1.0'.
    """
    if version is None:
        version = config.last_version

    version_config = config.at_version(version)

    match output_format:
        case OutputFormat.table:
            Console().print(f"\n\n[blue]{version_config.id} - {version_config.name}\n", justify="center")
            show_targets_config(config=config, output_format=OutputFormat.table, all=all, version=version)
            show_dates_config(config=config, output_format=OutputFormat.table, all=all, version=version)
            show_people_config(config=config, output_format=OutputFormat.table, all=all, version=version)
        case OutputFormat.json:
            if all:
                Console().print_json(config.to_model().model_dump_json())
            else:
                Console().print_json(version_config.to_model().model_dump_json())

show_dates_config(config, output_format, all, version)

Display the configured dates.

By default, if neither of version and all arguments are used, dates from the latest version are displayed.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
output_format OutputFormat

Select format of the output.

required
all bool

Show dates from all versions.

required
version ProjectVersion | None

Show dates from specific version.

required
Source code in sereto/cli/config.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
@validate_call
def show_dates_config(
    config: Config,
    output_format: OutputFormat,
    all: bool,
    version: ProjectVersion | None,
) -> None:
    """Display the configured dates.

    By default, if neither of `version` and `all` arguments are used, dates from the latest version are displayed.

    Args:
        config: Configuration of the project.
        output_format: Select format of the output.
        all: Show dates from all versions.
        version: Show dates from specific version.
    """
    if version is None:
        version = config.last_version

    match output_format:
        case OutputFormat.table:
            for ver in config.versions if all else [version]:
                Console().line()
                table = _get_dates_table(version_config=config.at_version(version=ver).to_model(), version=ver)
                Console().print(table, justify="center")
        case OutputFormat.json:
            DateList: TypeAdapter[list[Date]] = TypeAdapter(list[Date])
            DateAll: TypeAdapter[dict[str, list[Date]]] = TypeAdapter(dict[str, list[Date]])

            if all:
                all_dates = DateAll.validate_python(
                    {str(ver): config.at_version(version=ver).dates for ver in config.versions}
                )
                Console().print_json(DateAll.dump_json(all_dates).decode("utf-8"))
            else:
                dates = DateList.validate_python(config.at_version(version).dates)
                Console().print_json(DateList.dump_json(dates).decode("utf-8"))

show_people_config(config, output_format, all, version)

Display the configured people.

By default, if neither of version and all arguments are used, people from the latest version are displayed.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
output_format OutputFormat

Select format of the output.

required
all bool

Show people from all versions.

required
version ProjectVersion | None

Show people from specific version.

required
Source code in sereto/cli/config.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
@validate_call
def show_people_config(config: Config, output_format: OutputFormat, all: bool, version: ProjectVersion | None) -> None:
    """Display the configured people.

    By default, if neither of `version` and `all` arguments are used, people from the latest version are displayed.

    Args:
        config: Configuration of the project.
        output_format: Select format of the output.
        all: Show people from all versions.
        version: Show people from specific version.
    """
    if version is None:
        version = config.last_version

    match output_format:
        case OutputFormat.table:
            for ver in config.versions if all else [version]:
                Console().line()
                table = _get_person_table(version_config=config.at_version(version=ver).to_model(), version=ver)
                Console().print(table, justify="center")
        case OutputFormat.json:
            PersonList: TypeAdapter[list[Person]] = TypeAdapter(list[Person])
            PersonAll: TypeAdapter[dict[str, list[Person]]] = TypeAdapter(dict[str, list[Person]])

            if all:
                all_people = PersonAll.validate_python(
                    {str(ver): config.at_version(version=ver).people for ver in config.versions}
                )
                Console().print_json(PersonAll.dump_json(all_people).decode("utf-8"))
            else:
                people = PersonList.validate_python(config.at_version(version).people)
                Console().print_json(PersonList.dump_json(people).decode("utf-8"))

show_targets_config(config, output_format, all, version)

Display the configured targets.

By default, if neither of version and all arguments are used, targets from the latest version are displayed.

Parameters:

Name Type Description Default
config Config

Configuration of the project.

required
output_format OutputFormat

Select format of the output.

required
all bool

Show targets from all versions.

required
version ProjectVersion | None

Show targets from the specified project's version.

required
Source code in sereto/cli/config.py
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
@validate_call
def show_targets_config(
    config: Config, output_format: OutputFormat, all: bool, version: ProjectVersion | None
) -> None:
    """Display the configured targets.

    By default, if neither of `version` and `all` arguments are used, targets from the latest version are displayed.

    Args:
        config: Configuration of the project.
        output_format: Select format of the output.
        all: Show targets from all versions.
        version: Show targets from the specified project's version.
    """
    if version is None:
        version = config.last_version

    match output_format:
        case OutputFormat.table:
            for ver in config.versions if all else [version]:
                Console().line()
                table = _get_target_table(version_config=config.at_version(version=ver).to_model(), version=ver)
                Console().print(table, justify="center")
        case OutputFormat.json:
            TargetList: TypeAdapter[list[AnyTargetModel]] = TypeAdapter(list[AnyTargetModel])
            TargetAll: TypeAdapter[dict[str, list[AnyTargetModel]]] = TypeAdapter(dict[str, list[AnyTargetModel]])

            if all:
                all_targets = TargetAll.validate_python(
                    {
                        str(ver): [t.to_model() for t in config.at_version(version=ver).targets]
                        for ver in config.versions
                    }
                )
                Console().print_json(TargetAll.dump_json(all_targets).decode("utf-8"))
            else:
                target_models = [t.to_model() for t in config.at_version(version).targets]
                targets = TargetList.validate_python(target_models)
                Console().print_json(TargetList.dump_json(targets).decode("utf-8"))