diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9456f3e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "basedpyright.analysis.diagnosticMode": "workspace", + "python.analysis.diagnosticsSource": "Pyright" +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d94a770 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +# This file is at the root level, as it applies to all Python code, +# not only to docs or to tools. +[tool.pyright] +extends = "python_basics/pyproject.toml" + +exclude = [ + "**/__pycache__", + "**/.*", + "**/bazel-*", +] + +[tool.ruff] +extend = "python_basics/pyproject.toml" + +extend-exclude = [ + "**/__pycache__", + "/.*", + "bazel-*", +] diff --git a/python_basics/.bazelignore b/python_basics/.bazelignore new file mode 100644 index 0000000..d2963de --- /dev/null +++ b/python_basics/.bazelignore @@ -0,0 +1,3 @@ +# integration tests have their own MODULE file and cannot be included from the root +integration_tests/ +python_basics/python_lib/test/external_module diff --git a/python_basics/BUILD b/python_basics/BUILD index b5891ac..bf07520 100644 --- a/python_basics/BUILD +++ b/python_basics/BUILD @@ -17,3 +17,9 @@ exports_files([ "pyproject.toml", "dummy_venv.py", ]) + +alias( + name = "python_basics_lib", + actual = "//lib/src:python_basics_lib", + visibility = ["//visibility:public"], +) diff --git a/python_basics/README.md b/python_basics/README.md index 775d19d..63053ac 100644 --- a/python_basics/README.md +++ b/python_basics/README.md @@ -128,7 +128,12 @@ bazel run //private:requirements.update -- --upgrade ``` ### Running tests -To run the tests of the pytest module use: +To run the tests you need to run separate test commands: ``` +# Run the tests for the python_basics module $ bazel test //... + +# Run the integration tests +$ cd integration_tests && bazel test //... +$ cd python_basics/python_lib/test/external_module && bazel test //... ``` diff --git a/python_basics/integration_tests/MODULE.bazel b/python_basics/integration_tests/MODULE.bazel index 5206f4c..65a496a 100644 --- a/python_basics/integration_tests/MODULE.bazel +++ b/python_basics/integration_tests/MODULE.bazel @@ -46,14 +46,14 @@ use_repo(pip, "pip_score_venv_test") # Generic linting and formatting rules # ############################################################################### -bazel_dep(name = "aspect_rules_py", version = "1.0.0") +bazel_dep(name = "aspect_rules_py", version = "1.4.0") bazel_dep(name = "bazel_skylib", version = "1.7.1", dev_dependency=True) bazel_dep( name = "score_python_basics", - version = "0.3.0" + version = "0.0.0" ) local_path_override( diff --git a/python_basics/python_lib/src/BUILD b/python_basics/python_lib/src/BUILD new file mode 100644 index 0000000..89d554f --- /dev/null +++ b/python_basics/python_lib/src/BUILD @@ -0,0 +1,19 @@ +# ******************************************************************************* +# Copyright (c) 2025 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +# load("@score_python_basics//:defs.bzl", "score_py_pytest") + +py_library( + name = "python_basics_lib", + srcs = glob(["**/*.py"]), + visibility = ["//visibility:public"], +) diff --git a/python_basics/python_lib/src/__init__.py b/python_basics/python_lib/src/__init__.py new file mode 100644 index 0000000..459727a --- /dev/null +++ b/python_basics/python_lib/src/__init__.py @@ -0,0 +1 @@ +from . import path_utils as path_utils diff --git a/python_basics/python_lib/src/path_utils.py b/python_basics/python_lib/src/path_utils.py new file mode 100644 index 0000000..4c41a1d --- /dev/null +++ b/python_basics/python_lib/src/path_utils.py @@ -0,0 +1,43 @@ +"""Path helpers for running python code within Bazel.""" + +import os +from pathlib import Path + + +def runfiles_dir() -> Path: + """Returns the runfiles directory for the current Bazel build.""" + ... + +def bazel_root() -> Path: + """ + Returns the location of MODULE.bazel file. + TODO: which one? + Only works when called from bazel. + """ + + env_root = os.getenv("BUILD_WORKSPACE_DIRECTORY") + if env_root: + return Path(env_root).resolve() + else: + return None + + +def git_root() -> Path: + """Returns a path to the git repository.""" + return _find_upwards(Path(__file__).resolve(), marker=".git") + + +def cwd() -> Path: + """Returns the current working directory = invocation directory.""" + return Path(os.getenv("BUILD_WORKING_DIRECTORY") or os.getcwd()).resolve() + + +def _find_upwards(start: Path, marker: str) -> Path: + """ + Walks up from `start` to find a directory containing `marker`. + Raises FileNotFoundError if not found. + """ + for parent in [start] + list(start.parents): + if (parent / marker).exists(): + return parent + raise FileNotFoundError(f"Could not find '{marker}' in any parent directory of {start}") diff --git a/python_basics/python_lib/test/README.md b/python_basics/python_lib/test/README.md new file mode 100644 index 0000000..0486857 --- /dev/null +++ b/python_basics/python_lib/test/README.md @@ -0,0 +1,52 @@ +# Tests + +## path_utils.py + +path_utils behaves differently depending on how it is executed. +Therefore unit tests are not important, it's all about integration tests. + + + +```mermaid +flowchart TD + User(["๐Ÿ‘จโ€๐Ÿ’ป User"]) + + subgraph python_lib + subgraph src + path_utils["๐Ÿ“ฆ path_utils.py"] + end + + subgraph test + subgraph same_module + run_path_utils["๐Ÿ”ง python_basics_as_a_binary + (simulates py_binary usage)"] + test_path_utils["๐Ÿ”ง python_basics_as_a_test + (simulates py_test usage)"] + actual_test["๐Ÿง  TODO + (sh_test?)"] + end + subgraph different_module + run_path_utils2["๐Ÿ”ง python_basics_as_an_external_binary + (simulates py_binary usage)"] + test_path_utils2["๐Ÿ”ง python_basics_as_an_external_test + (simulates py_test usage)"] + actual_test2["๐Ÿง  TODO + (sh_test?)"] + end + end + end + run_path_utils -->|imports| path_utils + test_path_utils -->|imports| path_utils + actual_test -->|โ–ถ๏ธ bazel run| run_path_utils + actual_test -->|๐Ÿ“‚ bazel-bin/run_path_utils | run_path_utils + actual_test -->|๐Ÿงช bazel test| test_path_utils + + run_path_utils2 -->|imports| path_utils + test_path_utils2 -->|imports| path_utils + actual_test2 -->|โ–ถ๏ธ bazel run| run_path_utils2 + actual_test2 -->|๐Ÿ“‚ bazel-bin/run_path_utils | run_path_utils2 + actual_test2 -->|๐Ÿงช bazel test| test_path_utils2 + + User -->|๐Ÿงช bazel test| actual_test + User -->|๐Ÿงช cd different_module && bazel test| actual_test2 +``` diff --git a/python_basics/python_lib/test/external_module/MODULE.bazel b/python_basics/python_lib/test/external_module/MODULE.bazel new file mode 100644 index 0000000..6025eff --- /dev/null +++ b/python_basics/python_lib/test/external_module/MODULE.bazel @@ -0,0 +1,63 @@ +# ******************************************************************************* +# Copyright (c) 2025 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +############################################################################## +# +# Python version & Pip +# +############################################################################### +bazel_dep(name = "rules_python", version = "1.0.0") + +PYTHON_VERSION = "3.12" + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + is_default = True, + python_version = PYTHON_VERSION, +) +use_repo(python) + +############################################################################### +# +# For venv-with-extra-requirements test +# +############################################################################### +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "pip_score_venv_test", + python_version = PYTHON_VERSION, + requirements_lock = "//venv-with-extra-requirements:requirements.txt", +) +use_repo(pip, "pip_score_venv_test") + + +############################################################################### +# +# Generic linting and formatting rules +# +############################################################################### +bazel_dep(name = "aspect_rules_py", version = "1.4.0") + +bazel_dep(name = "bazel_skylib", version = "1.7.1", dev_dependency=True) + + +bazel_dep( + name = "score_python_basics", + version = "0.0.0" +) + +local_path_override( + module_name = "score_python_basics", + path = "../python_basics" +) + diff --git a/python_basics/python_lib/test/run_python_basics_path_utils.py b/python_basics/python_lib/test/run_python_basics_path_utils.py new file mode 100644 index 0000000..4d6aefe --- /dev/null +++ b/python_basics/python_lib/test/run_python_basics_path_utils.py @@ -0,0 +1,4 @@ +import python_basics_lib +import python_basics_lib.path_utils + +bazel_root = python_basics_lib.path_utils.bazel_root() diff --git a/python_basics/python_lib/test/same_module/BUILD b/python_basics/python_lib/test/same_module/BUILD new file mode 100644 index 0000000..c9087a6 --- /dev/null +++ b/python_basics/python_lib/test/same_module/BUILD @@ -0,0 +1,22 @@ +# ******************************************************************************* +# Copyright (c) 2025 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Simulates user +py_binary( + name = "run_python_basics_path_utils", + srcs = ["run_python_basics_path_utils.py"], + deps = ["//lib/src:python_basics_lib"], +) + +# Tests user behavior +# TODO