Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes changes and lints (WIP) #6

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
61 changes: 61 additions & 0 deletions contrib/create_ruff_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3

"""
Create a ruff config file from tkldet_modules/ruff.py

Mostly to be used with ruff's formatter
"""

import subprocess
import json
import sys
from os.path import abspath, dirname, join

PROJECT_PATH = dirname(dirname(abspath(__file__)))
TKLDET_MODULE_PATH = join(PROJECT_PATH, "tkldet_modules")

sys.path.insert(0, PROJECT_PATH)
sys.path.insert(1, TKLDET_MODULE_PATH)

from ruff import RUFF_LINTS

known_ruff_lints = json.loads(subprocess.run(['ruff', 'rule', '--all', '--output-format', 'json'],
capture_output=True).stdout)
known_ruff_lints = { rule['code'] for rule in known_ruff_lints }

# these rules cause issues with the formatter
incompatible = ["ISC001", "D203"]

output = """

line-length = 79
indent-width = 4

target-version = "py311"

[lint]
"""

select = []
ignore = [*incompatible]

found = set()

for lints in RUFF_LINTS.values():
for lint, level in lints.items():
if lint in known_ruff_lints:
found.add(lint)

if level is not None and lint not in incompatible:
select.append(lint)
else:
ignore.append(lint)

output += "select = " + json.dumps(select, indent=4) + "\n"
output += "ignore = " + json.dumps(ignore, indent=4) + "\n"

print(output)

missing = known_ruff_lints-found
if missing:
sys.stderr.write(f'missing {missing}\n')
32 changes: 22 additions & 10 deletions libtkldet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,35 @@
# You should have received a copy of the GNU General Public License along with
# tkldev-detective. If not, see <https://www.gnu.org/licenses/>.

from typing import Generator
from os.path import relpath, abspath
from . import locator, common_data, classifier
from collections.abc import Iterator
from os.path import abspath, relpath

from . import classifier, common_data, locator
from .common_data import APPLIANCE_ROOT
from .error import ApplianceNotFoundError


def initialize(path: str, ignore_non_appliance: bool) -> None:
"""
Initialize everything

def initialize(path: str):
"""initialize everything, involves scraping makefiles, parsing plans, etc."""
root = locator.get_appliance_root(path)
common_data.initialize_common_data(root)
Involves scraping makefiles, parsing plans, etc.
"""
try:
root = locator.get_appliance_root(path)
except ApplianceNotFoundError:
if not ignore_non_appliance:
raise
root = path
else:
common_data.initialize_common_data(root)


def yield_appliance_items() -> Generator[classifier.Item, None, None]:
'''generator that yields everything "lintable"'''
def yield_appliance_items() -> Iterator[classifier.Item]:
"""Yield everything 'lintable'"""

yield from common_data.iter_packages()
for path in locator.locator(APPLIANCE_ROOT):
for path in locator.locator(APPLIANCE_ROOT, False):
yield classifier.FileItem(
value=path,
_tags={},
Expand Down
40 changes: 26 additions & 14 deletions libtkldet/apt_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,45 @@
# You should have received a copy of the GNU General Public License along with
# tkldev-detective. If not, see <https://www.gnu.org/licenses/>.

"""relates to finding packages based on files they provide, including those not
installed"""
"""
Utilities for finding packages

Finds packages based on files they provide, including those not
installed
"""

import subprocess


def is_in_path(name: str) -> bool:
"""check if a given name is in the path"""
in_path = subprocess.run(
["which", name],
capture_output=True
)
"""Check if a given name is in the path"""
in_path = subprocess.run(["/usr/bin/which", name], capture_output=True)
return in_path.returncode == 0


def is_installed(package_name: str) -> bool:
"""check if a given package is installed on the HOST system (tkldev)"""
"""Check if a given package is installed on the HOST system (tkldev)"""
pkg_installed = subprocess.run(
["dpkg-query", "-W", "--showformat='${Status}'", package_name]
)
[
"/usr/bin/dpkg-query",
"-W",
"--showformat='${Status}'",
package_name,
],
capture_output=True,
)
return pkg_installed.returncode != 0


HAS_APT_FILE: bool = is_installed("apt-file")


def find_package_by_file(path: str) -> list[str]:
"""return a list of packages that provide a file at a given path"""
"""Return a list of packages that provide a file at a given path"""

ret = subprocess.run(
[
"apt-file",
"/usr/bin/apt-file",
"search",
"--package-only",
"-x",
Expand All @@ -59,14 +68,17 @@ def find_package_by_file(path: str) -> list[str]:


def find_python_package(package_name: str) -> list[str]:
"""return a list of packages that provide a given python module"""
"""Return a list of packages that provide a given python module"""
return find_package_by_file(
f"/usr/lib/python3/dist-packages/{package_name}(\\.py)?"
)


def find_python_package_from_import(module_str: str) -> list[str]:
"""return a list of packages that provide a given python import module, may
"""
Find python package from import name

Return a list of packages that provide a given python import module, may
be several modules deep (e.g. `foo.bar.baz`), attempts to find most
specific python package provider
"""
Expand Down
Loading