Skip to content

Commit

Permalink
Merge pull request #567 from zapta/develop
Browse files Browse the repository at this point in the history
Added the first iteration of 'apio api info' command
  • Loading branch information
cavearr authored Feb 5, 2025
2 parents 1b03a3a + f8499be commit cd6821a
Show file tree
Hide file tree
Showing 41 changed files with 526 additions and 146 deletions.
1 change: 1 addition & 0 deletions COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ Usage: apio preferences [OPTIONS]
Options:
-t, --theme [light|dark|no-colors]
Set colors theme name.
-c, --colors List themes colors.
-l, --list List the preferences.
-h, --help Show this message and exit.
Expand Down
2 changes: 1 addition & 1 deletion apio/apio_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pathlib import Path
from typing import Optional, Dict
from apio.common.apio_console import cout, cerror, cwarning
from apio.common.styles import INFO
from apio.common.apio_styles import INFO
from apio.profile import Profile
from apio.utils import jsonc, util, env_options
from apio.managers.project import (
Expand Down
2 changes: 2 additions & 0 deletions apio/commands/apio.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

# -- Import sub commands.
from apio.commands import (
apio_api,
apio_boards,
apio_build,
apio_clean,
Expand Down Expand Up @@ -74,6 +75,7 @@
apio_examples.cli,
apio_system.cli,
apio_raw.cli,
apio_api.cli,
apio_upgrade.cli,
],
),
Expand Down
221 changes: 221 additions & 0 deletions apio/commands/apio_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# -*- coding: utf-8 -*-
# -- This file is part of the Apio project
# -- (C) 2016-2024 FPGAwars
# -- Authors
# -- * Jesús Arroyo (2016-2019)
# -- * Juan Gonzalez (obijuan) (2019-2024)
# -- License GPLv2
"""Implementation of 'apio api' command"""

import sys
import json
from typing import List
from pathlib import Path
import click
from apio.commands import options
from apio.common.apio_console import cout, cerror
from apio.common.apio_styles import INFO, CMD_NAME
from apio.utils import cmd_util
from apio.apio_context import ApioContext, ApioContextScope
from apio.utils.cmd_util import ApioGroup, ApioSubgroup, ApioCommand


# ------ apio apio info

# -- Text in the markdown format of the python rich library.
APIO_API_INFO_HELP = f"""
The command 'apio api info' export information for apio in a JSON format \
that can can be easily parsed an used by other tools and scripts. The \
output JSON document is written to stdout or to a file and includes sections \
of information that are specified by the caller, with one or more \
'--section' options.
The optional flag --timestamp allows the caller to embed in the JSON \
document a known timestamp that allows to verify that the JSON file \
was indeed was generated by the same invocation.
Examples:[code]
apio api info -s boards -o apio.json # Output board info[/code]
Valid section names:
* [{CMD_NAME}]boards[/]
Currently, the 'apio api info' command does not load and report project \
specific information such as custom board definitions.
"""

sections_option = click.option(
"sections", # Var name.
"-s",
"--section",
type=str,
metavar="name",
multiple=True,
help="Enables a section [repeated].",
cls=cmd_util.ApioOption,
)


timestamp_option = click.option(
"timestamp", # Var name.
"-t",
"--timestamp",
type=str,
metavar="text",
help="Set a user provided timestamp.",
cls=cmd_util.ApioOption,
)

output_option = click.option(
"output", # Var name.
"-o",
"--output",
type=str,
metavar="file-name",
help="Set output file.",
cls=cmd_util.ApioOption,
)


# pylint: disable=too-many-locals
@click.command(
name="info",
cls=ApioCommand,
short_help="Retrieve apio information.",
help=APIO_API_INFO_HELP,
)
@sections_option
@timestamp_option
@output_option
@options.force_option_gen(help="Overwrite output file.")
def _info_cli(
# Options
sections: List[str],
timestamp: str,
output: str,
force: bool,
):
"""Implements the 'apio apio info' command."""

# -- Should have at list one section
if not sections:
cerror("Please list at least one section.")
sys.exit(1)

# -- For now, the information is not in a project context. That may
# -- change in the future.
apio_ctx = ApioContext(scope=ApioContextScope.NO_PROJECT)

# -- The top dict that we will emit as json.
top_dict = {}

# -- Append user timestamp if specified.
if timestamp:
top_dict["timestamp"] = timestamp

# -- A set to detect duplicate sections.
visited_sections = set()

# -- Iterate the sections and add them to the top dict.
for section in sections:
# -- Track duplicate sections.
if section in visited_sections:
cerror(f"Duplicate section [{section}]")
sys.exit(1)
visited_sections.add(section)

# -- Handle 'boards' section
if section == "boards":
# -- The output boards dict.
boards = {}
# -- Iterate and add the boards.
for board_id, board_info in apio_ctx.boards.items():
# -- The board output dict.
new_board = {}

# -- Add board description
new_board["description"] = board_info.get("description", None)

# -- Add board's fpga information.
new_fpga = {}
fpga_id = board_info.get("fpga", None)
fpga_info = apio_ctx.fpgas.get(fpga_id, {})
new_fpga["id"] = fpga_id
new_fpga["part-num"] = fpga_info.get("part_num", None)
new_fpga["arch"] = fpga_info.get("arch", None)
new_board["fpga"] = new_fpga

# -- Add board's programmer information.
new_programmer = {}
programmer_id = board_info.get("programmer", {}).get(
"type", None
)
new_programmer["id"] = programmer_id
new_board["programmer"] = new_programmer

# -- Add the board to the boards dict.
boards[board_id] = new_board

# -- Add the boards dict to the top dict.
top_dict["boards"] = boards

# -- Handle unknown section
else:
cerror(f"Unknown section name [{section}].")
cout("Type 'apio api -h' for the list of available sections.")
sys.exc_info(1)

# -- Format the top dict as json text.
text = json.dumps(top_dict, indent=2)

if output:
# -- Output the json text to a user specified file.
output_path = Path(output)

if output_path.is_dir():
cerror(f"The output path {output_path} is a directory.")
sys.exit(1)

if output_path.exists() and not force:
cerror(f"The file already exists {output_path}.")
cout("Use the --force option to allow overwriting.", style=INFO)
sys.exit(1)

with open(output, "w", encoding="utf-8") as f:
f.write(text)
else:
# -- Output the json text to stdout.
print(text, file=sys.stdout)


# ------ apio apio

# -- Text in the markdown format of the python rich library.
APIO_API_HELP = """
The command group 'apio apio' contains subcommands that that are intended \
to be used by tools and programs such as icestudio, rather than being used \
directly by users.
"""

# -- We have only a single group with the title 'Subcommands'.
SUBGROUPS = [
ApioSubgroup(
"Subcommands",
[
_info_cli,
],
)
]


@click.command(
name="api",
cls=ApioGroup,
subgroups=SUBGROUPS,
short_help="Apio programmatic interface.",
help=APIO_API_HELP,
)
def cli():
"""Implements the 'apio apio' command group."""

# pass
4 changes: 2 additions & 2 deletions apio/commands/apio_boards.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from rich.table import Table
from rich import box
from apio.common.apio_console import cout, cprint
from apio.common.styles import INFO
from apio.common.apio_styles import INFO
from apio.common import apio_console
from apio.common.styles import BORDER, EMPH1
from apio.common.apio_styles import BORDER, EMPH1
from apio.apio_context import ApioContext, ApioContextScope
from apio.utils import util, cmd_util
from apio.commands import options
Expand Down
4 changes: 2 additions & 2 deletions apio/commands/apio_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from apio.utils.cmd_util import ApioGroup, ApioSubgroup, ApioCommand
from apio.utils import cmd_util
from apio.apio_context import ApioContext, ApioContextScope
from apio.common.styles import BORDER, EMPH1
from apio.common.apio_styles import BORDER, EMPH1
from apio.managers import project
from apio.common.styles import TITLE, INFO
from apio.common.apio_styles import TITLE, INFO
from apio.common.apio_console import (
PADDING,
docs_text,
Expand Down
2 changes: 1 addition & 1 deletion apio/commands/apio_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from rich import box
from apio.common import apio_console
from apio.common.apio_console import cout, cprint
from apio.common.styles import INFO, BORDER, EMPH1
from apio.common.apio_styles import INFO, BORDER, EMPH1
from apio.managers import installer
from apio.managers.examples import Examples, ExampleInfo
from apio.commands import options
Expand Down
2 changes: 1 addition & 1 deletion apio/commands/apio_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Tuple, List
import click
from apio.common.apio_console import cout, cerror, cstyle
from apio.common.styles import EMPH3, SUCCESS
from apio.common.apio_styles import EMPH3, SUCCESS
from apio.apio_context import ApioContext, ApioContextScope
from apio.commands import options
from apio.managers import installer
Expand Down
2 changes: 1 addition & 1 deletion apio/commands/apio_fpgas.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from rich import box
from apio.common import apio_console
from apio.common.apio_console import cout, cprint
from apio.common.styles import INFO, BORDER, EMPH1
from apio.common.apio_styles import INFO, BORDER, EMPH1
from apio.apio_context import ApioContext, ApioContextScope
from apio.utils import util, cmd_util
from apio.commands import options
Expand Down
2 changes: 1 addition & 1 deletion apio/commands/apio_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from rich.table import Table
from rich import box
from apio.common.apio_console import cout, cprint
from apio.common.styles import INFO, BORDER, ERROR, SUCCESS
from apio.common.apio_styles import INFO, BORDER, ERROR, SUCCESS
from apio.managers import installer
from apio.apio_context import ApioContext, ApioContextScope
from apio.utils import pkg_util
Expand Down
Loading

0 comments on commit cd6821a

Please sign in to comment.