Skip to content

Commit

Permalink
Merge pull request #434 from zapta/develop
Browse files Browse the repository at this point in the history
Examples/Boards/FPGAs reports are now pipe friendly.
  • Loading branch information
Obijuan authored Oct 3, 2024
2 parents 1a93455 + 89dcec4 commit 7c4aa5d
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 126 deletions.
6 changes: 4 additions & 2 deletions apio/commands/boards.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
\b
Examples:
apio boards --list # List boards
apio boards --fpga # List FPGAs
apio boards --list # List boards
apio boards --fpga # List FPGAs
apio boards -l | grep ecp5 # Filter boards results
apio boards -f | grep gowin # Filter FPGA results.
[Advanced] Boards with wide availability can be added by contacting the
apio team. A custom one-of board can be added to your project by
Expand Down
9 changes: 5 additions & 4 deletions apio/commands/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@
\b
Examples:
apio examples --list # List all examples
apio examples -f icezum/leds # Fetch example files
apio examples -s icezum/leds # Fetch example directory
apio examples -d icezum # Fetch all board examples
apio examples --list # List all examples
apio examples -l | grep -i icezum # Filter examples.
apio examples -f icezum/leds # Fetch example files
apio examples -s icezum/leds # Fetch example directory
apio examples -d icezum # Fetch all board examples
"""


Expand Down
5 changes: 5 additions & 0 deletions apio/commands/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ def cli(
# -- Print apio package directory.
click.secho("Package: ", nl=False)
click.secho(util.get_path_in_apio_package(""), fg="yellow")

# -- Print apio home directory.
click.secho("Home: ", nl=False)
click.secho(util.get_home_dir(), fg="yellow")

ctx.exit(0)

# -- Invalid option. Just show the help
Expand Down
2 changes: 1 addition & 1 deletion apio/commands/uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _uninstall(packages: list, platform: str, resources: Resources):
"""Uninstall the given list of packages"""

# -- Ask the user for confirmation
if click.confirm("Do you want to continue?"):
if click.confirm("Do you want to uninstall?"):

# -- Uninstall packages, one by one
for package in packages:
Expand Down
142 changes: 83 additions & 59 deletions apio/managers/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
# -- Licence GPLv2

import shutil
from pathlib import Path
from pathlib import Path, PosixPath
from dataclasses import dataclass
from typing import Optional, Tuple, List
import click

from apio import util
from apio.profile import Profile
from apio.resources import Resources
Expand All @@ -30,6 +31,15 @@
"""


@dataclass
class ExampleInfo:
"""Information about a single example."""

name: str
path: PosixPath
description: str


class Examples:
"""Manage the apio examples"""

Expand All @@ -53,84 +63,98 @@ def __init__(self):
# -- Get the version restrictions
self.spec_version = util.get_package_spec_version(self.name, resources)

def list_examples(self):
"""Print all the examples available"""
def get_examples_infos(self) -> Optional[List[ExampleInfo]]:
"""Scans the examples and returns a list of ExampleInfos.
Returns null if an error."""

# -- Check if the example package is installed
installed = util.check_package(
self.name, self.version, self.spec_version, self.examples_dir
)

# -- No package installed: return
if not installed:
return 1

# -- Calculate the terminal width
terminal_width, _ = shutil.get_terminal_size()

# -- String with a horizontal line with the same width
# -- as the terminal
line = "─" * terminal_width
# -- A message was already printed.
return None

# -- Print the header
click.echo()
click.echo(line)
# -- Collect the examples home dir each board.
boards_dirs: List[PosixPath] = []

# -- Collect all the board (every folder in the examples packages
# -- correspond to a board)
boards = []
for board_dir in self.examples_dir.iterdir():
if board_dir.is_dir():
boards_dirs.append(board_dir)

for board in sorted(self.examples_dir.iterdir()):
if board.is_dir():
boards.append(board)
# -- Collect the examples of each boards.
examples: List[Tuple[str, PosixPath]] = []
for board_dir in boards_dirs:

# -- Collect the examples for each board
# -- Valid examples are folders...
examples = []
examples_names = []
# -- Iterate board's example subdirectories.
for example_dir in board_dir.iterdir():

# -- Every board...
for board in boards:
# -- Skip files. We care just about directories.
if not example_dir.is_dir():
continue

# -- Has one or more examples...
for example in board.iterdir():

# -- The examples are folders...
if example.is_dir():

# -- Store the example name
example_str = f"{board.name}/{example.name}"
examples_names.append(example_str)

# -- Store the example path
examples.append(example)
# -- Try to load description from the example info file.
info_file = example_dir / "info"
if info_file.exists():
with open(info_file, "r", encoding="utf-8") as f:
description = f.read().replace("\n", "")
else:
description = ""

# -- For each example, collect the information in the info file
# -- It contains the example description
for example, name in zip(examples, examples_names):
# -- Append this example to the list.
name = f"{board_dir.name}/{example_dir.name}"
example_info = ExampleInfo(name, example_dir, description)
examples.append(example_info)

# -- info file
info = example / "info"
# -- Sort in-place by ascceding example name, case insensitive.
examples.sort(key=lambda x: x.name.lower())

# -- Not all the folder has info...
if info.exists():
return examples

# -- Open info file
with open(info, "r", encoding="utf-8") as info_file:
def list_examples(self) -> None:
"""Print all the examples available. Return a process exit
code, 0 if ok, non zero otherwise."""

# -- Read info file and remove the new line characters
info_data = info_file.read().replace("\n", "")
# -- Get list of examples.
examples: List[ExampleInfo] = self.get_examples_infos()
if examples is None:
# -- Error message is aleady printed.
return 1

# -- Print the example name and description!
click.secho(f"{name}", fg="blue", bold=True)
click.secho(f"{info_data}")
click.secho(line)
# -- Get terminal configuration. We format the report differently for
# -- a terminal and for a pipe.
output_config = util.get_terminal_config()

# -- For terminal, print a header with an horizontal line across the
# -- terminal.
if output_config.terminal_mode():
terminal_seperator_line = "─" * output_config.terminal_width
click.echo()
click.echo(terminal_seperator_line)

# -- For a pipe, determine the max example name length.
max_example_name_len = max(len(x.name) for x in examples)

# -- Emit the examples
for example in examples:
if output_config.terminal_mode():
# -- For a terminal. Multi lines and colors.
click.secho(f"{example.name}", fg="blue", bold=True)
click.secho(f"{example.description}")
click.secho(terminal_seperator_line)
else:
# -- For a pipe, single line, no colors.
click.secho(
f"{example.name:<{max_example_name_len}} | "
f"{example.description}"
)

# -- Print the total examples
click.secho(f"Total: {len(examples)}")
# -- For a terminal, emit additional summary.
if output_config.terminal_mode():
click.secho(f"Total: {len(examples)}")
click.secho(USAGE_EXAMPLE, fg="green")

# -- Print more info about the examples
click.secho(USAGE_EXAMPLE, fg="green")
return 0

def copy_example_dir(self, example: str, project_dir: Path, sayno: bool):
Expand Down
Loading

0 comments on commit 7c4aa5d

Please sign in to comment.