Source code for experimental_lowqa.edit
"""
A module implementing a target for preparing tags for editing.
"""
# built-in
import os
from pathlib import Path
# third-party
from vcorelib.paths import rel
from vcorelib.task import Inbox, Outbox
from vcorelib.task.subprocess.run import SubprocessLogMixin
# internal
from experimental_lowqa.env import real_sources
PREFIX = Path.home().joinpath(".local")
[docs]
def local_bin(program: str) -> Path:
"""Get the path to a local binary."""
return PREFIX.joinpath("bin", program)
[docs]
def is_local_bin(program: str) -> bool:
"""Determine if a binary or entry script is installed locally."""
return local_bin(program).is_file()
[docs]
def local_bin_if(program: str) -> str:
"""Prefer a local binary instead if it exists."""
return str(local_bin(program)) if is_local_bin(program) else program
[docs]
class GenerateTags(SubprocessLogMixin):
"""A class implementing a task for generating tags files."""
default_editor = "vim"
languages = "C,C++"
extra_source_candidates: list[tuple[str | Path, ...]] = [
("pico-sdk", "src", "boards"),
("pico-sdk", "src", "common"),
("pico-sdk", "src", "rp2_common"),
("pico-sdk", "src", "rp2040"),
("RP2040-HAT-C",),
("ioLibrary_Driver", "Ethernet"),
("ioLibrary_Driver", "Internet", "DHCP"),
("ioLibrary_Driver", "Internet", "DNS"),
# Create tags for this at some point?
# ("pico-sdk", "lib", "tinyusb", "src"),
]
extra_excludes: list[tuple[str, ...]] = []
[docs]
async def run(self, inbox: Inbox, outbox: Outbox, *args, **kwargs) -> bool:
"""Generate a tags files."""
root: Path = args[0]
# Remove existing tags.
tags = root.joinpath("tags")
tags.unlink(missing_ok=True)
common = [
local_bin_if("ctags"),
"-f",
str(rel(tags, base=root)),
f"--languages={self.languages}",
]
src = root.joinpath("src")
# Standard source paths.
sources = [src]
# Additional source paths.
sources += list(real_sources(root, self.extra_source_candidates))
# Tag third-party dependencies.
third_party = root.joinpath("third-party", "include")
if third_party.is_dir():
sources.append(third_party)
# Toolchains.
toolchain = kwargs.get("toolchain", "arm-picolibc-eabi")
toolchain_include = root.joinpath(
"toolchains", toolchain, toolchain, "include"
)
if toolchain_include.is_dir():
sources.append(toolchain_include)
result = True
if sources:
# Standard excludes.
excludes = [
x
for x in [
src.joinpath("third-party"),
src.joinpath("data"),
root.joinpath("tests", "data"),
]
if x.is_dir()
]
# Create initial tags file.
result = await self.shell_cmd_in_dir(
root,
common
+ list(
f"--exclude={rel(x, base=root)}"
for x in excludes
+ list(real_sources(root, self.extra_excludes))
)
+ ["-R"]
+ list(str(rel(x, base=root)) for x in sources),
)
# Run editor.
if result and kwargs.get("edit", True):
result = await self.shell_cmd_in_dir(
root, [os.environ.get("EDITOR", self.default_editor)]
)
return result