Skip to content

Commit

Permalink
feat: ruff
Browse files Browse the repository at this point in the history
Introduces Ruff for formatting and linting and remove flake8, isort, and black.
Fixes the resulting linter errors.

Signed-off-by: Maxim Stykow <[email protected]>
  • Loading branch information
mstykow committed Jan 4, 2025
1 parent e0c8640 commit 6805999
Show file tree
Hide file tree
Showing 18 changed files with 163 additions and 274 deletions.
13 changes: 0 additions & 13 deletions .flake8

This file was deleted.

11 changes: 4 additions & 7 deletions .github/workflows/lint_and_run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,11 @@ jobs:
- name: Install the project
run: uv sync --locked

- name: Run isort
run: uv run isort src/ tests/ --check
- name: Run Ruff linter
run: uv run ruff check

- name: Run black
run: uv run black src/ tests/ --check

- name: Run flake8
run: uv run flake8 src/ tests/
- name: Run Ruff formatter
run: uv run ruff format --check

- name: Run mypy
run: uv run python -m mypy src/ tests/
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ __pycache__/
.vscode/*

.mypy_cache/
.ruff_cache

.venv/
dist/
16 changes: 4 additions & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@
#
# SPDX-License-Identifier: Apache-2.0
repos:
- repo: https://github.com/pycqa/isort
rev: 5.12.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.6
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
Expand Down
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,8 @@ Options:
To test your changes, run
```bash
uv run pytest
uv run ruff check
uv run ruff format --check
uv run python -m mypy src/ tests/
```
The package uses pre-commit hooks to check the code style of your changes.
It also provides a script `(./scripts/linter_and_formatting.sh)` to make your changes compliant with the expected
code style. To use this script under linux run
```bash
./scripts/linter_and_formatting.sh # in the root of the repo
uv run pytest
```
31 changes: 25 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ spdx2opossum = "opossum_lib.cli:spdx2opossum"
[dependency-groups]
test = ["pytest>=8.3.3,<9"]
dev = [
"black>=24.8.0,<25",
"isort>=5.13.2,<6",
"flake8>=7.1.1,<8",
"mypy>=1.14.1,<2",
"pre-commit>=3.8.0",
"ruff>=0.8.6",
]

[tool.uv]
Expand All @@ -37,9 +35,6 @@ default-groups = [
]
package = true

[tool.isort]
profile = "black"

[tool.mypy]
warn_return_any = true
warn_unused_configs = true
Expand All @@ -54,3 +49,27 @@ ignore_missing_imports = true

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
line-length = 88

[tool.ruff.lint]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
]
extend-select = ["E501"]

[tool.ruff.format]
quote-style = "double"
docstring-code-format = true
24 changes: 0 additions & 24 deletions scripts/linter_and_formatting.sh

This file was deleted.

3 changes: 1 addition & 2 deletions src/opossum_lib/attribution_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: Apache-2.0
from io import StringIO
from typing import Optional

from spdx_tools.spdx.model.document import CreationInfo
from spdx_tools.spdx.model.file import File
Expand All @@ -22,7 +21,7 @@
from opossum_lib.opossum_file import OpossumPackage, SourceInfo


def _get_purl(package: Package) -> Optional[str]:
def _get_purl(package: Package) -> str | None:
for external_reference in package.external_references:
if external_reference.reference_type == PURL:
return external_reference.locator
Expand Down
55 changes: 25 additions & 30 deletions src/opossum_lib/file_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import uuid
from dataclasses import fields
from pathlib import Path
from typing import Dict, List, Tuple, Union
from zipfile import ZIP_DEFLATED, ZipFile

from networkx import DiGraph, shortest_path
Expand Down Expand Up @@ -55,33 +54,29 @@ def write_dict_to_file(


def to_dict(
element: Union[
Resource,
Metadata,
OpossumPackage,
OpossumInformation,
SourceInfo,
ExternalAttributionSource,
str,
int,
bool,
Dict[str, OpossumPackage],
Dict[str, List[str]],
List[str],
None,
]
) -> Union[Dict, str, List[str], bool, int, None]:
element: Resource
| Metadata
| OpossumPackage
| OpossumInformation
| SourceInfo
| ExternalAttributionSource
| str
| int
| bool
| dict[str, OpossumPackage]
| dict[str, list[str]]
| list[str]
| None,
) -> dict | str | list[str] | bool | int | None:
if isinstance(element, Resource):
return element.to_dict()
if isinstance(
element,
(
Metadata,
OpossumPackage,
OpossumInformation,
SourceInfo,
ExternalAttributionSource,
),
Metadata
| OpossumPackage
| OpossumInformation
| SourceInfo
| ExternalAttributionSource,
):
result = []
for f in fields(element):
Expand All @@ -97,8 +92,8 @@ def to_dict(
def generate_json_file_from_tree(tree: DiGraph) -> OpossumInformation:
metadata = create_metadata(tree)
resources = Resource(type=ResourceType.TOP_LEVEL)
resources_to_attributions: Dict[str, List[str]] = dict()
external_attributions: Dict[str, OpossumPackage] = dict()
resources_to_attributions: dict[str, list[str]] = dict()
external_attributions: dict[str, OpossumPackage] = dict()
attribution_breakpoints = []
external_attribution_sources = {
SPDX_FILE_IDENTIFIER: ExternalAttributionSource(SPDX_FILE_IDENTIFIER, 500),
Expand All @@ -117,8 +112,8 @@ def generate_json_file_from_tree(tree: DiGraph) -> OpossumInformation:
"A tree should always have a node without incoming edge."
)
for node in connected_subgraph.nodes():
path: List[str] = shortest_path(connected_subgraph, source, node)
path_with_labels: List[Tuple[str, ResourceType]] = (
path: list[str] = shortest_path(connected_subgraph, source, node)
path_with_labels: list[tuple[str, ResourceType]] = (
_replace_node_ids_with_labels_and_add_resource_type(
path, connected_subgraph
)
Expand Down Expand Up @@ -149,8 +144,8 @@ def generate_json_file_from_tree(tree: DiGraph) -> OpossumInformation:


def create_attribution_and_link_with_resource(
external_attributions: Dict[OpossumPackageIdentifier, OpossumPackage],
resources_to_attributions: Dict[OpossumPackageIdentifier, List[str]],
external_attributions: dict[OpossumPackageIdentifier, OpossumPackage],
resources_to_attributions: dict[OpossumPackageIdentifier, list[str]],
file_path: str,
node: str,
tree: DiGraph,
Expand Down
7 changes: 3 additions & 4 deletions src/opossum_lib/graph_generation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# SPDX-FileCopyrightText: 2023 TNG Technology Consulting GmbH <https://www.tngtech.com>
#
# SPDX-License-Identifier: Apache-2.0
from typing import Optional, Union

from networkx import DiGraph, set_node_attributes
from spdx_tools.spdx.graph_generation import generate_relationship_graph_from_spdx
Expand All @@ -21,9 +20,9 @@ def generate_graph_from_spdx(document: Document) -> DiGraph:

def _create_label_for_node(graph: DiGraph, node: str) -> str:
if _node_represents_a_spdx_element(graph, node):
element_node: Optional[Union[CreationInfo, File, Package, Snippet]] = (
graph.nodes[node]["element"]
)
element_node: CreationInfo | File | Package | Snippet | None = graph.nodes[
node
]["element"]
if element_node:
return element_node.name or element_node.spdx_id
else:
Expand Down
20 changes: 10 additions & 10 deletions src/opossum_lib/helper_methods.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2023 TNG Technology Consulting GmbH <https://www.tngtech.com>
#
# SPDX-License-Identifier: Apache-2.0
from typing import Any, Dict, List, Optional, Tuple
from typing import Any

from networkx import DiGraph, weakly_connected_components
from spdx_tools.spdx.constants import DOCUMENT_SPDX_ID
Expand All @@ -10,15 +10,15 @@
from opossum_lib.opossum_file import ResourceType


def _get_source_for_graph_traversal(connected_subgraph: DiGraph) -> Optional[str]:
def _get_source_for_graph_traversal(connected_subgraph: DiGraph) -> str | None:
return (
DOCUMENT_SPDX_ID
if DOCUMENT_SPDX_ID in connected_subgraph.nodes
else _get_node_without_incoming_edge(connected_subgraph)
)


def _get_node_without_incoming_edge(graph: DiGraph) -> Optional[str]:
def _get_node_without_incoming_edge(graph: DiGraph) -> str | None:
for node, degree in graph.in_degree():
if degree == 0 and _node_represents_a_spdx_element(graph, node):
return str(node)
Expand All @@ -31,7 +31,7 @@ def _node_represents_a_spdx_element(graph: DiGraph, node: str) -> bool:
return "element" in graph.nodes[node]


def _weakly_connected_component_sub_graphs(graph: DiGraph) -> List[DiGraph]:
def _weakly_connected_component_sub_graphs(graph: DiGraph) -> list[DiGraph]:
connected_sub_graphs = []
for connected_set in weakly_connected_components(
graph
Expand All @@ -41,7 +41,7 @@ def _weakly_connected_component_sub_graphs(graph: DiGraph) -> List[DiGraph]:
return connected_sub_graphs


def _create_file_path_from_graph_path(path: List[str], graph: DiGraph) -> str:
def _create_file_path_from_graph_path(path: list[str], graph: DiGraph) -> str:
base_path = "/" + "/".join(
[_replace_prefix(graph.nodes[node]["label"]) for node in path]
)
Expand All @@ -51,8 +51,8 @@ def _create_file_path_from_graph_path(path: List[str], graph: DiGraph) -> str:


def _replace_node_ids_with_labels_and_add_resource_type(
path: List[str], graph: DiGraph
) -> List[Tuple[str, ResourceType]]:
path: list[str], graph: DiGraph
) -> list[tuple[str, ResourceType]]:
resulting_path = []
path_with_label_and_resource_type = [
(
Expand Down Expand Up @@ -85,11 +85,11 @@ def _replace_prefix(label: str) -> str:
return label


def _get_resource_type(node_attributes: Dict[str, Any]) -> ResourceType:
element = node_attributes.get("element", None)
def _get_resource_type(node_attributes: dict[str, Any]) -> ResourceType:
element = node_attributes.get("element")
if isinstance(element, Package):
return ResourceType.FOLDER
elif isinstance(element, (Snippet, File)):
elif isinstance(element, Snippet | File):
return ResourceType.FILE
else:
return ResourceType.OTHER
Loading

0 comments on commit 6805999

Please sign in to comment.