Skip to content

Commit

Permalink
Merge pull request #488 from zapta/develop
Browse files Browse the repository at this point in the history
Updated the `apio raw` command
  • Loading branch information
Obijuan authored Dec 7, 2024
2 parents 4218fe3 + 1a381e2 commit 32829d0
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 36 deletions.
4 changes: 3 additions & 1 deletion apio/cmd_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ def check_at_most_one_param(
cmd_ctx, specified_param_ids
)
aliases_str = ", ".join(canonical_aliases)
fatal_usage_error(cmd_ctx, f"[{aliases_str}] are mutually exclusive.")
fatal_usage_error(
cmd_ctx, f"[{aliases_str}] cannot be combined together."
)


def check_exactly_one_param(
Expand Down
55 changes: 39 additions & 16 deletions apio/commands/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
"""Implementation of 'apio raw' command"""

import sys
import subprocess
from typing import Tuple, List
from varname import nameof
import click
from apio import util, pkg_util, cmd_util
from apio import pkg_util, cmd_util
from apio.apio_context import ApioContext


Expand All @@ -21,29 +24,27 @@
tools directly. This is an advanced command that requires familiarity
with the underlying tools. Before running the command, apio changes the
internal env settings to provide access to its packages. To view the
env changes, use the --env option.
env changes, run `apio raw --env'.
\b
Examples:
apio raw "yosys --version" # Yosys version
apio raw "nextpnr-ice40 --version" # Nextpnr version
apio raw "yosys -p 'read_verilog leds.v; show' -q" # Graph a module
apio raw "verilator --lint-only leds.v" # Lint a module
apio raw "icepll -i 12 -o 30" # ICE PLL parameters
apio raw --env # Show env changes
apio raw --env "yosys --version" # Show also env changes
apio raw yosys --version # Yosys version
apio raw -- nextpnr-ice40 --help # Nextpnr help
apio raw yosys -f verilog -p "show -format dot" main.v # Graph a module
apio raw icepll -i 12 -o 30 # Calc ICE PLL
apio raw --env # Show env
[Note] If you find a raw command that would benefit other apio users
consider suggesting it as an apio feature request.
The '--' token may be used to seperate between apio arguments and the
commands arguments (e.g. '-h' or '--help').
"""


verbose_option = click.option(
"env", # Var name.
"-e",
"--env",
is_flag=True,
help="Show env changes.",
help="Show the apio env changes.",
cls=cmd_util.ApioOption,
)

Expand All @@ -53,21 +54,28 @@
short_help="Execute commands directly from the Apio packages.",
help=HELP,
cls=cmd_util.ApioCommand,
context_settings={"ignore_unknown_options": True},
)
@click.pass_context
@click.argument("cmd", metavar="COMMAND", required=False)
@click.argument("cmd", metavar="COMMAND", nargs=-1, type=click.UNPROCESSED)
@verbose_option
def cli(
cmd_ctx: click.core.Context,
# Arguments
cmd: str,
cmd: Tuple[str],
# Options
env: bool,
):
"""Implements the apio raw command which executes user
specified commands from apio installed tools.
"""

# -- Prohibit cmd and --env together, for no specific reason.
cmd_util.check_at_most_one_param(cmd_ctx, nameof(env, cmd))

# -- Convert the tuple of strings to a list of strings.
cmd: List[str] = list(cmd)

if not cmd and not env:
cmd_util.fatal_usage_error(cmd_ctx, "Missing an option or a command")

Expand All @@ -82,8 +90,23 @@ def cli(
# -- Make sure that at least the oss-cad-suite is installed.
pkg_util.check_required_packages(apio_ctx, ["oss-cad-suite"])

# -- Echo the commands. The apio raw command is platform dependent
# -- so this may help us and the user diagnosing issues.
click.secho(f"cmd = {cmd}")

# -- Invoke the command.
exit_code = util.call(cmd)
try:
exit_code = subprocess.call(cmd, shell=False)
except FileNotFoundError as e:
click.secho(f"{e}", fg="red")
sys.exit(1)

if exit_code != 0:
click.secho(f"Exist status [{exit_code}] ERROR", fg="red")
else:
click.secho("Exit status [0] OK", fg="green")

# -- Return the command's status code.
sys.exit(exit_code)

sys.exit(0)
4 changes: 2 additions & 2 deletions apio/pkg_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ def _dump_env_mutations(
for p in reversed(mutations.paths):
styled_name = click.style("PATH", fg="magenta")
if windows:
click.secho(f"@set {styled_name}={p};%PATH%")
click.secho(f"set {styled_name}={p};%PATH%")
else:
click.secho(f'{styled_name}="{p}:$PATH"')

# -- Print vars mutations.
for name, val in mutations.vars:
styled_name = click.style(name, fg="magenta")
if windows:
click.secho(f"@set {styled_name}={val}")
click.secho(f"set {styled_name}={val}")
else:
click.secho(f'{styled_name}="{val}"')

Expand Down
14 changes: 0 additions & 14 deletions apio/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,6 @@ def get_path_in_apio_package(subpath: str) -> Path:
return path


def call(cmd):
"""Execute the given command."""

# -- Execute the command from the shell
result = subprocess.call(cmd, shell=True)

# -- Command not found
if result == 127:
message = f"ERROR. Comand not found!: {cmd}"
click.secho(message, fg="red")

return result


@dataclass(frozen=True)
class CommandResult:
"""Contains the results of a command (subprocess) execution."""
Expand Down
10 changes: 8 additions & 2 deletions test/integration/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ def test_utilities(apio_runner: ApioRunner):
sb.assert_ok(result)
assert "Apio version" in result.output

# -- Run 'apio raw --env "nextpnr-ice40 --help"
# -- Run 'apio raw "nextpnr-ice40 --help"'
result = sb.invoke_apio_cmd(
apio_raw, ["--env", "nextpnr-ice40 --help"], input="exit"
apio_raw, ["--", "nextpnr-ice40", "--help"]
)
sb.assert_ok(result)

# -- Run 'apio raw --env'
result = sb.invoke_apio_cmd(apio_raw, ["--env"])
sb.assert_ok(result)
assert "Envirnment settings:" in result.output
assert "YOSYS_LIB" in result.output
2 changes: 1 addition & 1 deletion test/test_cmd_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ def test_check_at_most_one_param(capsys):
check_at_most_one_param(cmd_ctx, ["_opt1", "_opt2", "_opt3"])
captured = capsys.readouterr()
assert e.value.code == 1
assert "[--opt1, --opt2] are mutually exclusive" in captured.out
assert "[--opt1, --opt2] cannot be combined together" in captured.out

0 comments on commit 32829d0

Please sign in to comment.