Coverage for apio/commands/apio_raw.py: 72%
35 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-06 10:20 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-06 10:20 +0000
1# -*- coding: utf-8 -*-
2# -- This file is part of the Apio project
3# -- (C) 2016-2024 FPGAwars
4# -- Authors
5# -- * Jesús Arroyo (2016-2019)
6# -- * Juan Gonzalez (obijuan) (2019-2024)
7# -- License GPLv2
8"""Implementation of 'apio raw' command"""
10import sys
11import subprocess
12from typing import Tuple, List
13import click
14from apio.common.apio_console import cout
15from apio.common.apio_styles import SUCCESS, ERROR
16from apio.apio_context import (
17 ApioContext,
18 PackagesPolicy,
19 ProjectPolicy,
20 RemoteConfigPolicy,
21)
22from apio.commands import options
23from apio.utils import cmd_util
24from apio.utils.cmd_util import ApioCommand
26# ----------- apio raw
28# -- Text in the rich-text format of the python rich library.
29APIO_RAW_HELP = """
30The command 'apio raw' allows you to bypass Apio and run underlying tools \
31directly. This is an advanced command that requires familiarity with the \
32underlying tools.
34Before running the command, Apio temporarily modifies system environment \
35variables such as '$PATH' to provide access to its packages. To view these \
36environment changes, run the command with the '-v' option.
38Examples:[code]
39 apio raw -- yosys --version # Yosys version
40 apio raw -v -- yosys --version # Verbose apio info.
41 apio raw -- yosys # Yosys interactive mode.
42 apio raw -- icepll -i 12 -o 30 # Calc ICE PLL.
43 apio raw -- which yosys # Lookup a command.
44 apio raw -v # Show apio env setting.
45 apio raw -h # Show this help info.[/code]
47The marker '--' is used to separate between the arguments of the apio \
48command itself and those of the executed command.
49"""
52@click.command(
53 name="raw",
54 cls=ApioCommand,
55 short_help="Execute commands directly from the Apio packages.",
56 help=APIO_RAW_HELP,
57 context_settings={"ignore_unknown_options": True},
58)
59@click.pass_context
60@click.argument("cmd", metavar="COMMAND", nargs=-1, type=click.UNPROCESSED)
61@options.verbose_option
62def cli(
63 cmd_ctx: click.Context,
64 # Arguments
65 cmd: Tuple[str],
66 # Options
67 verbose: bool,
68):
69 """Implements the apio raw command which executes user
70 specified commands from apio installed tools.
71 """
72 # -- At lease one of -v and cmd should be specified.
73 cmd_util.check_at_least_one_param(cmd_ctx, ["verbose", "cmd"])
75 # -- Create an apio context. We don't care about an apio project.
76 # -- Using config and packages because we want the binaries in the apio
77 # -- packages to be available for the 'apio raw' command.
78 apio_ctx = ApioContext(
79 project_policy=ProjectPolicy.NO_PROJECT,
80 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
81 packages_policy=PackagesPolicy.ENSURE_PACKAGES,
82 )
84 # -- Set the env for packages. If verbose, also dumping the env changes
85 # -- in a user friendly way.
86 apio_ctx.set_env_for_packages(quiet=not verbose, verbose=verbose)
88 # -- If no command, we are done.
89 if not cmd:
90 sys.exit(0)
92 # -- Convert the tuple of strings to a list of strings.
93 cmd: List[str] = list(cmd)
95 # -- Echo the commands. The apio raw command is platform dependent
96 # -- so this may help us and the user diagnosing issues.
97 if verbose: 97 ↛ 98line 97 didn't jump to line 98 because the condition on line 97 was never true
98 cout(f"\n---- Executing {cmd}:")
100 # -- Invoke the command.
101 try:
102 exit_code = subprocess.call(cmd, shell=False)
103 except FileNotFoundError as e:
104 cout(f"{e}", style=ERROR)
105 sys.exit(1)
107 if verbose: 107 ↛ 108line 107 didn't jump to line 108 because the condition on line 107 was never true
108 cout("----\n")
109 if exit_code == 0:
110 cout("Exit status [0] OK", style=SUCCESS)
112 else:
113 cout(f"Exist status [{exit_code}] ERROR", style=ERROR)
115 # -- Return the command's status code.
116 sys.exit(exit_code)