Skip to content

Commit

Permalink
Decouple peakrdl CLI installer from official plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
amykyta3 committed Dec 17, 2024
1 parent 289729f commit 0be5334
Show file tree
Hide file tree
Showing 31 changed files with 181 additions and 131 deletions.
133 changes: 72 additions & 61 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,44 @@ on:
types:
- published

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
name: Install Python
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install build
- name: Build
run: |
python -m build peakrdl-cli -o dist/
python -m build peakrdl -o dist/
- uses: actions/upload-artifact@v4
with:
name: dist
path: |
dist/*.tar.gz
dist/*.whl
#-------------------------------------------------------------------------------
test:
needs:
- build
strategy:
matrix:
python-version:
- 3.6
- 3.7
- 3.8
- 3.9
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
Expand All @@ -33,40 +59,35 @@ jobs:
- python-version: 3.6
os: ubuntu-20.04

- python-version: "3.7"
os: ubuntu-22.04

- python-version: "3.8"
os: ubuntu-22.04

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3

- name: Set up Python 3.7 to bootstrap py3.6
if: ${{ matrix.python-version == '3.6' }}
uses: actions/setup-python@v4
with:
python-version: 3.7

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install -U -r test/requirements.txt
- uses: actions/download-artifact@v4
with:
name: dist
path: dist

# Python 3.6 cannot install directly from a pyproject.toml
# Instead, build a wheel from py3.7 and then install it
- name: Install via wheel
if: ${{ matrix.python-version == '3.6' }}
- name: Install dependencies
run: |
python3.7 -m pip install build
python3.7 -m build
python --version
python -m pip install ./dist/*.whl
python -m pip install -r test/requirements.txt
- name: Install
if: ${{ matrix.python-version != '3.6' }}
run: |
python -m pip install .
python -m pip install dist/peakrdl_cli-*.whl
python -m pip install dist/peakrdl-*.whl
- name: Test
run: |
Expand Down Expand Up @@ -100,28 +121,37 @@ jobs:
#-------------------------------------------------------------------------------
lint:
needs:
- build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
python-version: "3.11"

- uses: actions/download-artifact@v4
with:
name: dist
path: dist

- name: Install dependencies
run: |
python -m pip install -U pylint
python -m pip install -r test/requirements.txt
- name: Install
run: |
python -m pip install .
python -m pip install dist/peakrdl_cli-*.whl
- name: Run Lint
run: |
pylint --rcfile test/pylint.rc peakrdl
pylint --rcfile test/pylint.rc peakrdl-cli/src/peakrdl
#-------------------------------------------------------------------------------
mypy:
needs:
- build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -130,48 +160,29 @@ jobs:
with:
python-version: "3.10"

- uses: actions/download-artifact@v4
with:
name: dist
path: dist

- name: Install dependencies
run: |
python -m pip install -U mypy
python -m pip install -r test/requirements.txt
- name: Install
run: |
python -m pip install dist/peakrdl_cli-*.whl
- name: Type Check
run: |
mypy --config-file test/mypy.ini src/peakrdl
mypy --config-file test/mypy.ini peakrdl-cli/src/peakrdl
#-------------------------------------------------------------------------------
build:
deploy:
needs:
- test
- lint
- mypy
name: Build distributions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
name: Install Python
with:
python-version: "3.10"

- name: Install dependencies
run: |
python -m pip install -U build
- name: Build
run: python -m build

- uses: actions/upload-artifact@v4
with:
name: dist
path: |
dist/*.tar.gz
dist/*.whl
#-------------------------------------------------------------------------------
deploy:
needs:
- build

runs-on: ubuntu-latest
environment: release
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ python:
install:
- requirements: docs/requirements.txt
- method: pip
path: .
path: peakrdl-cli/
1 change: 1 addition & 0 deletions peakrdl-cli/LICENSE
5 changes: 5 additions & 0 deletions peakrdl-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# PeakRDL command-line interface
This package implements the command-line interface for the PeakRDL toolchain.

## Documentation
See the [PeakRDL Documentation](http://peakrdl.readthedocs.io) for more details.
8 changes: 1 addition & 7 deletions pyproject.toml → peakrdl-cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[project]
name = "peakrdl"
name = "peakrdl-cli"
dynamic = ["version"]
requires-python = ">=3.6"
dependencies = [
"systemrdl-compiler >= 1.27.1, < 2",
"peakrdl-html >= 2.10.1, < 3",
"peakrdl-ipxact >= 3.4.1, < 4",
"peakrdl-regblock >= 0.19.0, < 2",
"peakrdl-systemrdl >= 0.3.0, < 2",
"peakrdl-uvm >= 2.3.0, < 3",
"peakrdl-cheader >= 1.0.0, < 2",
"tomli;python_version<'3.11'",
]

Expand Down
1 change: 1 addition & 0 deletions peakrdl-cli/src/peakrdl/__about__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.2.0"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def load_cfg(argv: List[str]) -> AppConfig:
if path is None:
# Nope. Still no config file. Provide empty data
raw_data = {}
path = ""
else:
if not os.path.isfile(path):
print(f"error: invalid config file path: {path}", file=sys.stderr)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys
from typing import List, Tuple, TYPE_CHECKING
from typing import List, Tuple, TYPE_CHECKING, Optional

if TYPE_CHECKING:
from importlib.metadata import EntryPoint, Distribution

if sys.version_info >= (3,10,0):
from importlib import metadata

def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', 'Distribution']]:
def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', Optional['Distribution']]]:
eps = []
for ep in metadata.entry_points().select(group=group_name):
eps.append((ep, ep.dist))
Expand All @@ -19,8 +19,8 @@ def _get_name_from_dist(dist: 'Distribution') -> str:
elif sys.version_info >= (3,8,0): # pragma: no cover
from importlib import metadata

def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', 'Distribution']]:
eps = []
def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', Optional['Distribution']]]:
eps = [] # type: List[Tuple[EntryPoint, Optional[Distribution]]]
dist_names = set()
for dist in metadata.distributions():
# Due to a bug in importlib.metadata's distributions iterator, in
Expand All @@ -42,7 +42,7 @@ def _get_name_from_dist(dist: 'Distribution') -> str:
else: # pragma: no cover
import pkg_resources # type: ignore

def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', 'Distribution']]:
def _get_entry_points(group_name: str) -> List[Tuple['EntryPoint', Optional['Distribution']]]:
eps = []
for ep in pkg_resources.iter_entry_points(group_name):
eps.append((ep, ep.dist))
Expand All @@ -52,7 +52,7 @@ def _get_name_from_dist(dist: 'Distribution') -> str:
return dist.project_name # type: ignore


def get_entry_points(group_name: str) -> List[Tuple['EntryPoint', 'Distribution']]:
def get_entry_points(group_name: str) -> List[Tuple['EntryPoint', Optional['Distribution']]]:
return _get_entry_points(group_name)

def get_name_from_dist(dist: 'Distribution') -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,17 @@ def get_exporter_plugins(cfg: 'AppConfig') -> List[ExporterSubcommandPlugin]:
# Get exporter plugins from entry-points
for ep, dist in get_entry_points("peakrdl.exporters"):
cls = ep.load()
dist_name = get_name_from_dist(dist)
if dist:
dist_name = get_name_from_dist(dist)
dist_version = dist.version
else:
dist_name = None
dist_version = None

if issubclass(cls, ExporterSubcommandPlugin):
# Override name - always use entry point's name
cls.name = ep.name
exporter = cls(dist_name=dist_name, dist_version=dist.version)
exporter = cls(dist_name=dist_name, dist_version=dist_version)
else:
raise RuntimeError(f"Exporter class {cls} is expected to be extended from peakrdl.plugins.exporter.ExporterSubcommandPlugin")
exporters.append(exporter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,17 @@ def get_importer_plugins(cfg: 'AppConfig') -> List[ImporterPlugin]:
# Get importer plugins from entry-points
for ep, dist in get_entry_points("peakrdl.importers"):
cls = ep.load()
dist_name = get_name_from_dist(dist)
if dist:
dist_name = get_name_from_dist(dist)
dist_version = dist.version
else:
dist_name = None
dist_version = None

if issubclass(cls, ImporterPlugin):
# Override name - always use entry point's name
cls.name = ep.name
importer = cls(dist_name=dist_name, dist_version=dist.version)
importer = cls(dist_name=dist_name, dist_version=dist_version)
else:
raise RuntimeError(f"Importer class {cls} is expected to be extended from peakrdl.plugins.importer.ImporterPlugin")
importers.append(importer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

if TYPE_CHECKING:
import argparse
from typing import Sequence
from typing import Sequence, Optional
from systemrdl import RDLCompiler, AddrmapNode
from .importer import Importer

Expand Down Expand Up @@ -73,6 +73,7 @@ def parse_parameters(rdlc: 'RDLCompiler', parameter_options: List[str]) -> Dict[
m = re.fullmatch(r"(\w+)=(.+)", raw_param)
if not m:
rdlc.msg.fatal(f"Invalid parameter argument: {raw_param}")
raise ValueError

p_name = m.group(1)
try:
Expand All @@ -89,6 +90,7 @@ def parse_defines(rdlc: 'RDLCompiler', define_options: List[str]) -> Dict[str, s
m = re.fullmatch(r"(\w+)(?:=(.+))?", raw_def)
if not m:
rdlc.msg.fatal(f"Invalid define argument: {raw_def}")
raise ValueError

k = m.group(1)
v = m.group(2) or ""
Expand Down Expand Up @@ -116,12 +118,11 @@ def process_input(rdlc: 'RDLCompiler', importers: 'Sequence[Importer]', input_fi

# Search which importer to use by extension first
importer_candidates = [] # type: List[Importer]
for importer in importers:
if ext in importer.file_extensions:
importer_candidates.append(importer)
for imp in importers:
if ext in imp.file_extensions:
importer_candidates.append(imp)

# Do 2nd pass if needed
importer = None
if len(importer_candidates) == 1:
importer = importer_candidates[0]
elif len(importer_candidates) > 1:
Expand All @@ -131,12 +132,17 @@ def process_input(rdlc: 'RDLCompiler', importers: 'Sequence[Importer]', input_fi
if importer_candidate.is_compatible(file):
importer = importer_candidate
break
else:
importer = None
else:
importer = None

if not importer:
rdlc.msg.fatal(
"Unknown file type. Could not find any importers capable of reading this file.",
FileSourceRef(file)
)
raise ValueError

importer.do_import(rdlc, options, file)

Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 0be5334

Please sign in to comment.