linux/tools/net/ynl/pyynl/lib/specdir.py
Jakub Kicinski 10c90f1bba tools: ynl: pyynl: pull the --family resolution logic into the lib
When packaging YNL as a system level utility we added a --family
argument which auto-resolves the full spec path from a well known
path in /usr/share. Spelling out full YAML spec files is at this
point only done in-tree, for example in the selftests which need
the very latest YAML. But the selftests have their own wrapping
classes for each family so test authors aren't really bothered
by having to spell the paths out.

Afford the same ease of use to the Python library users.
Move the path resolution from the CLI code to the library.
This simplifies the pyynl use by a lot:

  from pyynl import YnlFamily

  ynl = YnlFamily(family="netdev")

Unless I'm missing a trick, resolving the /usr/share path
is hard enough for most users to lean towards shelling out
to ynl CLI with --output-json, which is sad.

The ethtool script can now use family= instead of
resolving the path (the helpers are removed from cli.py
so this isn't just a cleanup).

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://patch.msgid.link/20260701021751.3234681-3-kuba@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-03 08:57:15 +02:00

52 lines
1.6 KiB
Python

# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
"""
Locating YNL spec and schema files on disk.
Resolves the directory holding the YAML specs (preferring an in-tree copy
over the installed system path) and maps family names to spec files.
"""
import os
SYS_SCHEMA_DIR='/usr/share/ynl'
RELATIVE_SCHEMA_DIR='../../../../../Documentation/netlink'
def schema_dir():
"""
Return the effective schema directory, preferring in-tree before
system schema directory.
"""
script_dir = os.path.dirname(os.path.abspath(__file__))
schema_dir_ = os.path.abspath(f"{script_dir}/{RELATIVE_SCHEMA_DIR}")
if not os.path.isdir(schema_dir_):
schema_dir_ = SYS_SCHEMA_DIR
if not os.path.isdir(schema_dir_):
raise FileNotFoundError(f"Schema directory {schema_dir_} does not exist")
return schema_dir_
def spec_dir():
"""
Return the effective spec directory, relative to the effective
schema directory.
"""
spec_dir_ = schema_dir() + '/specs'
if not os.path.isdir(spec_dir_):
raise FileNotFoundError(f"Spec directory {spec_dir_} does not exist")
return spec_dir_
def find_spec(family):
""" Return the path to the YAML spec file for a family by name. """
spec = f"{spec_dir()}/{family}.yaml"
if not os.path.isfile(spec):
raise FileNotFoundError(f"Spec for family '{family}' not found at {spec}")
return spec
def list_families():
""" Return the sorted names of all families with an installed spec. """
return sorted(f.removesuffix('.yaml')
for f in os.listdir(spec_dir()) if f.endswith('.yaml'))