Source code for utms.cli.commands.anchor.create

"""Module for handling anchor creation commands within the `utms` command-line
interface.

This module provides the functionality to create new anchors, including parsing input,
resolving values, and saving anchor configurations.

Functions:
    set_anchor(args: argparse.Namespace, config: Config) -> None:
        Creates a new anchor based on the given command-line arguments and saves it.

    register_anchor_create_command(command_manager: CommandManager) -> None:
        Registers the "anchor create" command and its associated
        arguments with the command manager.
"""

import argparse
from datetime import datetime
from decimal import Decimal, InvalidOperation
from typing import List, Optional

from utms import AI, Config
from utms.anchors import AnchorConfig
from utms.cli.commands.anchor.helper import (
    add_breakdowns_argument,
    add_groups_argument,
    add_label_argument,
    add_name_argument,
    add_precision_argument,
    add_value_argument,
)
from utms.cli.commands.core import Command, CommandManager


[docs] def set_anchor(args: argparse.Namespace, config: Config) -> None: """Creates a new anchor based on the provided command-line arguments and saves it in the configuration. This function checks if an anchor with the given label already exists. If it does, it notifies the user. If the label is new, it parses and resolves the anchor's value, groups, precision, and breakdowns. If the value cannot be directly converted to a `Decimal`, it attempts to resolve it using AI or a date parser. Args: args (argparse.Namespace): The parsed command-line arguments containing anchor details. config (Config): The configuration object where the anchor will be saved. Raises: ValueError: If the value provided for the anchor cannot be resolved into a valid timestamp or decimal. """ if config.anchors.get(args.label): print(f"An anchor with label {args.label} already exists.") return groups: Optional[List[str]] = args.groups.split(",") if args.groups else None precision: Optional[Decimal] = Decimal(args.precision) if args.precision else None breakdowns: Optional[List[List[str]]] = ( [segment.split(",") for segment in args.breakdowns.split(";")] if args.breakdowns else None ) try: value = Decimal(args.value) except (InvalidOperation, ValueError) as exc: ai = AI(config) resolved_date = ai.resolve_date(args.value) if isinstance(resolved_date, Decimal): value = resolved_date elif isinstance(resolved_date, datetime): value = Decimal(resolved_date.timestamp()) else: raise ValueError(f"Could not resolve {args.value}") from exc anchor = AnchorConfig( args.label, args.name, value, groups=groups, precision=precision, breakdowns=breakdowns ) config.anchors.add_anchor(anchor) config.save_anchors()
[docs] def register_anchor_create_command(command_manager: CommandManager) -> None: """Registers the "anchor create" command with the provided command manager. This function defines the arguments for the "anchor create" command, including the anchor's label, name, value, groups, precision, and breakdowns. It associates the command with the `set_anchor` function that processes the input and creates a new anchor. Args: command_manager (CommandManager): The command manager used to register the new command. Returns: None """ command = Command("anchor", "create", lambda args: set_anchor(args, command_manager.config)) command.set_help("Create a new anchor") command.set_description("Create a new anchor and set its parameters.") # Add the arguments for this command add_label_argument(command) add_name_argument(command) add_value_argument(command) add_groups_argument(command) add_precision_argument(command) add_breakdowns_argument(command) command_manager.register_command(command)