Skip to content

CLI

The devpi-gitea-sync command is implemented using Click. It is the main entry point for both one-off syncs and server mode.

devpi_gitea_sync.cli

main(config_path, organizations, mapping_names, dry_run, force, server, host, port, verbose)

Synchronize Python distribution release assets from Gitea into Devpi.

Parameters:

Name Type Description Default
config_path Path | None

Path to the configuration file.

required
organizations tuple[str, ...]

A tuple of organizations to synchronize.

required
mapping_names tuple[str, ...]

A tuple of mapping names to synchronize.

required
dry_run bool

If True, discover assets without downloading or uploading them.

required
force bool

If True, re-upload package versions even if they already exist in Devpi.

required
server bool

If True, start the web dashboard and sync continuously.

required
host str | None

Override the server host from the config file.

required
port int | None

Override the server port from the config file.

required
verbose int

The verbosity level.

required
Source code in devpi_gitea_sync/cli.py
@click.command(context_settings={"help_option_names": ["-h", "--help"]})
@click.option(
    "-c",
    "--config",
    "config_path",
    type=click.Path(path_type=Path),
    help="Path to the configuration file (defaults to ./devpi-gitea-sync.conf).",
)
@click.option(
    "-o",
    "--org",
    "organizations",
    multiple=True,
    help="Limit synchronization to specific Gitea organizations. Repeat to include more.",
)
@click.option(
    "-m",
    "--mapping",
    "mapping_names",
    multiple=True,
    help="Limit synchronization to specific mapping names. Repeat to include more.",
)
@click.option(
    "--dry-run",
    is_flag=True,
    help="Discover assets without downloading or uploading them.",
)
@click.option(
    "--force",
    is_flag=True,
    help="Re-upload package versions even if they already exist in Devpi.",
)
@click.option(
    "--server",
    is_flag=True,
    help="Start the web dashboard and continuously sync in the background.",
)
@click.option(
    "--host",
    default=None,
    show_default=False,
    help="Host address for the web server (overrides [runtime] server_host, default 0.0.0.0).",
)
@click.option(
    "--port",
    default=None,
    type=int,
    show_default=False,
    help="Port for the web server (overrides [runtime] server_port, default 8080).",
)
@click.option(
    "-v",
    "--verbose",
    count=True,
    help="Increase logging verbosity. Repeat for more detail.",
)
def main(
    config_path: Path | None,
    organizations: tuple[str, ...],
    mapping_names: tuple[str, ...],
    dry_run: bool,
    force: bool,
    server: bool,
    host: str | None,
    port: int | None,
    verbose: int,
) -> None:
    """Synchronize Python distribution release assets from Gitea into Devpi.

    :param config_path: Path to the configuration file.
    :param organizations: A tuple of organizations to synchronize.
    :param mapping_names: A tuple of mapping names to synchronize.
    :param dry_run: If True, discover assets without downloading or uploading them.
    :param force: If True, re-upload package versions even if they already exist in Devpi.
    :param server: If True, start the web dashboard and sync continuously.
    :param host: Override the server host from the config file.
    :param port: Override the server port from the config file.
    :param verbose: The verbosity level.
    """
    _configure_logging(verbose)
    config = _load_config(config_path)

    orgs = list(organizations) if organizations else None
    mappings = list(mapping_names) if mapping_names else None

    if server:
        from .server import SyncServer

        effective_host = host if host is not None else config.server_host
        effective_port = port if port is not None else config.server_port
        SyncServer(
            config,
            host=effective_host,
            port=effective_port,
            dry_run=dry_run,
            force=force,
            organizations=orgs,
            mapping_names=mappings,
        ).run()
    else:
        _run_sync_once(config, orgs, mappings, dry_run, force)