# Path: valohai_cli/api.py
# def request(self, method, url, **kwargs) -> Response:  # type: ignore
#     api_error_class = kwargs.pop('api_error_class', APIError)
#     handle_errors = bool(kwargs.pop('handle_errors', True))
#     try:
#         resp = super().request(method, url, **kwargs)
#     except requests.ConnectionError as ce:
#         host = urlparse(ce.request.url).netloc
#         if 'Connection refused' in str(ce):
#             raise CLIException(
#                 f'Unable to connect to {host} (connection refused); try again soon.'
#             ) from ce
#         raise
# 
#     if handle_errors and resp.status_code >= 400:
#         cls = (APINotFoundError if resp.status_code == 404 else api_error_class)
#         raise cls(resp)
#     return resp
# 
# Path: valohai_cli/commands/pipeline/run/utils.py
# def match_pipeline(config: Config, pipeline_name: str) -> str:
#     """
#     Take a pipeline name and try and match it to the configs pipelines.
#     Returns the match if there is only one option.
#     """
#     if pipeline_name in config.pipelines:
#         return pipeline_name
#     matching_pipelines = match_prefix(config.pipelines, pipeline_name, return_unique=False)
#     if not matching_pipelines:
#         raise click.BadParameter(
#             '"{pipeline}" is not a known pipeline (try one of {pipelines})'.format(
#                 pipeline=pipeline_name,
#                 pipelines=', '.join(click.style(t, bold=True) for t in sorted(config.pipelines))
#             ), param_hint='pipeline')
#     if len(matching_pipelines) > 1:
#         raise click.BadParameter(
#             '"{pipeline}" is ambiguous.\nIt matches {matches}.\nKnown pipelines are {pipelines}.'.format(
#                 pipeline=pipeline_name,
#                 matches=', '.join(click.style(t, bold=True) for t in sorted(matching_pipelines)),
#                 pipelines=', '.join(click.style(t, bold=True) for t in sorted(config.pipelines)),
#             ), param_hint='pipeline')
#     return str(matching_pipelines[0])
# 
# Path: valohai_cli/ctx.py
# @overload
# def get_project(dir: Optional[str] = None, require: Literal[True] = True) -> ProjectOrRemoteProject:
#     ...
# 
# Path: valohai_cli/messages.py
# def success(message: str, err: bool = True) -> None:
#     click.echo(_format_message(message, SUCCESS_EMOJI, 'Success!', 'green'), err=err)
# 
# Path: valohai_cli/utils/commits.py
# def create_or_resolve_commit(
#     project: Union[RemoteProject, Project],
#     *,
#     commit: Optional[str],
#     adhoc: bool,
#     validate_adhoc_commit: bool = True,
# ) -> str:
#     if adhoc:
#         if project.is_remote:
#             raise click.UsageError('--adhoc can not be used with remote projects.')
#         if commit:
#             raise click.UsageError('--commit and --adhoc are mutually exclusive.')
#         commit = str(package_adhoc_commit(project, validate=validate_adhoc_commit)['identifier'])
# 
#     commit = commit or get_git_commit(project)
#     return resolve_commit(commit, project)


import contextlib
import click
from typing import Any, Dict, Optional
from click import Context
from valohai_yaml.objs import Config, Pipeline
from valohai_yaml.pipelines.conversion import PipelineConverter
from valohai_cli.api import request
from valohai_cli.commands.pipeline.run.utils import match_pipeline
from valohai_cli.ctx import get_project
from valohai_cli.messages import success
from valohai_cli.utils.commits import create_or_resolve_commit
@click.argument('name', required=False, metavar='PIPELINE-NAME')
@click.option('--commit', '-c', default=None, metavar='SHA', help='The commit to use. Defaults to the current HEAD.')
@click.option('--title', '-c', default=None, help='The optional title of the pipeline run.')
@click.option('--adhoc', '-a', is_flag=True, help='Upload the current state of the working directory, then run it as an ad-hoc execution.')
@click.pass_context
def run(ctx: Context, name: Optional[str], commit: Optional[str], title: Optional[str], adhoc: bool) -> None:
    """
    Start a pipeline run.
    """
    # Having to explicitly compare to `--help` is slightly weird, but it's because of the nested command thing.
    if name == '--help' or not name:
        click.echo(ctx.get_help(), color=ctx.color)
        print_pipeline_list(ctx, commit)
        ctx.exit()
        return

    project = get_project(require=True)
    assert project

    commit = create_or_resolve_commit(project, commit=commit, adhoc=adhoc)
    config = project.get_config()

    matched_pipeline = match_pipeline(config, name)
    pipeline = config.pipelines[matched_pipeline]

    start_pipeline(config, pipeline, project.id, commit, title)


def print_pipeline_list(ctx: Context, commit: Optional[str]) -> None:
    with contextlib.suppress(Exception):  # If we fail to extract the pipeline list, it's not that big of a deal.

# Path: valohai_cli/api.py
# def request(self, method, url, **kwargs) -> Response:  # type: ignore
#     api_error_class = kwargs.pop('api_error_class', APIError)
#     handle_errors = bool(kwargs.pop('handle_errors', True))
#     try:
#         resp = super().request(method, url, **kwargs)
#     except requests.ConnectionError as ce:
#         host = urlparse(ce.request.url).netloc
#         if 'Connection refused' in str(ce):
#             raise CLIException(
#                 f'Unable to connect to {host} (connection refused); try again soon.'
#             ) from ce
#         raise
# 
#     if handle_errors and resp.status_code >= 400:
#         cls = (APINotFoundError if resp.status_code == 404 else api_error_class)
#         raise cls(resp)
#     return resp
# 
# Path: valohai_cli/commands/pipeline/run/utils.py
# def match_pipeline(config: Config, pipeline_name: str) -> str:
#     """
#     Take a pipeline name and try and match it to the configs pipelines.
#     Returns the match if there is only one option.
#     """
#     if pipeline_name in config.pipelines:
#         return pipeline_name
#     matching_pipelines = match_prefix(config.pipelines, pipeline_name, return_unique=False)
#     if not matching_pipelines:
#         raise click.BadParameter(
#             '"{pipeline}" is not a known pipeline (try one of {pipelines})'.format(
#                 pipeline=pipeline_name,
#                 pipelines=', '.join(click.style(t, bold=True) for t in sorted(config.pipelines))
#             ), param_hint='pipeline')
#     if len(matching_pipelines) > 1:
#         raise click.BadParameter(
#             '"{pipeline}" is ambiguous.\nIt matches {matches}.\nKnown pipelines are {pipelines}.'.format(
#                 pipeline=pipeline_name,
#                 matches=', '.join(click.style(t, bold=True) for t in sorted(matching_pipelines)),
#                 pipelines=', '.join(click.style(t, bold=True) for t in sorted(config.pipelines)),
#             ), param_hint='pipeline')
#     return str(matching_pipelines[0])
# 
# Path: valohai_cli/ctx.py
# @overload
# def get_project(dir: Optional[str] = None, require: Literal[True] = True) -> ProjectOrRemoteProject:
#     ...
# 
# Path: valohai_cli/messages.py
# def success(message: str, err: bool = True) -> None:
#     click.echo(_format_message(message, SUCCESS_EMOJI, 'Success!', 'green'), err=err)
# 
# Path: valohai_cli/utils/commits.py
# def create_or_resolve_commit(
#     project: Union[RemoteProject, Project],
#     *,
#     commit: Optional[str],
#     adhoc: bool,
#     validate_adhoc_commit: bool = True,
# ) -> str:
#     if adhoc:
#         if project.is_remote:
#             raise click.UsageError('--adhoc can not be used with remote projects.')
#         if commit:
#             raise click.UsageError('--commit and --adhoc are mutually exclusive.')
#         commit = str(package_adhoc_commit(project, validate=validate_adhoc_commit)['identifier'])
# 
#     commit = commit or get_git_commit(project)
#     return resolve_commit(commit, project)


# Path: valohai_cli/commands/pipeline/run/run.py
import contextlib
import click
from typing import Any, Dict, Optional
from click import Context
from valohai_yaml.objs import Config, Pipeline
from valohai_yaml.pipelines.conversion import PipelineConverter
from valohai_cli.api import request
from valohai_cli.commands.pipeline.run.utils import match_pipeline
from valohai_cli.ctx import get_project
from valohai_cli.messages import success
from valohai_cli.utils.commits import create_or_resolve_commit

@click.argument('name', required=False, metavar='PIPELINE-NAME')
@click.option('--commit', '-c', default=None, metavar='SHA', help='The commit to use. Defaults to the current HEAD.')
@click.option('--title', '-c', default=None, help='The optional title of the pipeline run.')
@click.option('--adhoc', '-a', is_flag=True, help='Upload the current state of the working directory, then run it as an ad-hoc execution.')
@click.pass_context
def run(ctx: Context, name: Optional[str], commit: Optional[str], title: Optional[str], adhoc: bool) -> None:
    """
    Start a pipeline run.
    """
    # Having to explicitly compare to `--help` is slightly weird, but it's because of the nested command thing.
    if name == '--help' or not name:
        click.echo(ctx.get_help(), color=ctx.color)
        print_pipeline_list(ctx, commit)
        ctx.exit()
        return

    project = get_project(require=True)
    assert project

    commit = create_or_resolve_commit(project, commit=commit, adhoc=adhoc)
    config = project.get_config()

    matched_pipeline = match_pipeline(config, name)
    pipeline = config.pipelines[matched_pipeline]

    start_pipeline(config, pipeline, project.id, commit, title)


def print_pipeline_list(ctx: Context, commit: Optional[str]) -> None:
    with contextlib.suppress(Exception):  # If we fail to extract the pipeline list, it's not that big of a deal.

        project = get_project(require=True)