1import sys
2import typer
3from ..exception import FrictionlessException
4from ..transform import transform
5from .main import program
6from . import common
7
8
9@program.command(name="transform")
10def program_transform(
11    # Source
12    source: str = common.source,
13):
14    """Transform data using a provided pipeline.
15
16    Please read more about Transform pipelines to write a pipeline
17    that can be accepted by this funtion.
18    """
19
20    # Support stdin
21    is_stdin = False
22    if not source:
23        if not sys.stdin.isatty():
24            is_stdin = True
25            source = [sys.stdin.buffer.read()]
26
27    # Validate input
28    if not source:
29        message = 'Providing "source" is required'
30        typer.secho(message, err=True, fg=typer.colors.RED, bold=True)
31        raise typer.Exit(1)
32
33    # Transform source
34    try:
35        status = transform(source)
36        if not status.valid:
37            # NOTE: improve how we handle/present errors
38            groups = [status.errors] + list(map(lambda task: task.errors, status.tasks))
39            for group in groups:
40                for error in group:
41                    raise FrictionlessException(error)
42    except Exception as exception:
43        typer.secho(str(exception), err=True, fg=typer.colors.RED, bold=True)
44        raise typer.Exit(1)
45
46    # Return default
47    if is_stdin:
48        source = "stdin"
49    prefix = "success"
50    typer.secho(f"# {'-'*len(prefix)}", bold=True)
51    typer.secho(f"# {prefix}: {source}", bold=True)
52    typer.secho(f"# {'-'*len(prefix)}", bold=True)
53