Skip to content

Ligare Development

Aaron Holmes edited this page Oct 25, 2024 · 2 revisions

Ligare is a mono-repo containing several independent libraries, which are noted under Available Libraries.

Follow this guide to learn how to contribute to Ligare's development.

Getting Started

Ligare ships with a Makefile that aims to make development easier to manage. The Makefile has been tested with GNU Make 3.x on MacOS, and GNU Make 4.x on Linux.

🚩 To get started, clone the repository and run make in the repository root.

Makefile Details

Makefile Targets / Goals

Target / Goal Purpose
dev The default goal. Installs all Ligare packages in the repository root as editable installs with pip install -e. Inter-referential packages, e.g., Ligare.web depends on Ligare.database point back to the local filesystem.
cicd Installs all Ligare packages in the repository root with pip install Inter-referential packages point back to the local filesystem.
test Executes all test- goals.
test-bandit Executes bandit. Stores reports under $(REPORTS_DIR)/$(BANDIT_REPORT).
test-isort Executes isort --check-only.
test-pyright Executes pyright.
test-pytest Executes pytest. Stores test and coverage reports under $(REPORTS_DIR)/$(PYTEST_REPORT)
test-ruff Executes ruff format --check.
format Executes all format- goals.
format-isort Executes isort.
format-ruff Executes ruff format.
clean Executes all clean-* goals.
clean-build Removes all artifacts created by the default goal (dev or cicd)
clean-test Removes all artifacts created by test-* goals.
remake Executes make clean followed by make.
reset Restore pyproject.toml files modified by $(REWRITE_DEPENDENCIES). Verifies with user first.
reset-check Verify with the user and exit if verification fails.
Ligare.AWS Build only Ligare.AWS.
Ligare.GitHub Build only Ligare.GitHub.
Ligare.all Build only Ligare.all.
Ligare.database Build only Ligare.database.
Ligare.development Build only Ligare.development.
Ligare.identity Build only Ligare.identity.
Ligare.platform Build only Ligare.platform.
Ligare.programming Build only Ligare.programming.
Ligare.testing Build only Ligare.testing.
Ligare.web Build only Ligare.web.
publish-all Build all packages without rewriting dependencies, and push to $(PYPI_REPO).

Modifiable Environment Variables

Variable Name Default Value Purpose
VENV .venv The directory in which a Python venv will be created.
DEFAULT_TARGET dev Can be dev or cicd. If dev, pip installs with -e.
PYTHON_VERSION 3.10 The version of Python used to create the venv.
REPORTS_DIR reports The directory in which to store the output of tests, coverage, and other quality assurance tools.
PYTEST_FLAGS Pass flags to pytest through the use of make and tox.
PYTEST_TARGET . The target directory in which tox should tell pytest to find tests.
PYRIGHT_MODE pip Can be pip or npm. If npm, the pyright executable in node_modules is executed directly.
REWRITE_DEPENDENCIES true Rewrites dependencies in the root pyproject.toml file to use local filesystem paths for all Ligare.* dependencies.
GITHUB_REF Empty GUID Used internally by the build system. If this is "" or refs/tags, REWRITE_DEPENDENCIES is ignored.
GITHUB_WORKSPACE $(CURDIR) Used internally by the build system. This is the working directory where make is executed.
PYPI_REPO testpypi The PyPI trusted env to publish builds to.

Monorepo Details

Local Configuration

When developing from within the mono-repo, the libraries can be individually installed via their path under src/. Both the mono-repo and each library have their own set of dependencies.

Because some Ligare libraries depend on other Ligare libraries, individual pyproject.toml files may need adjustment in your local development environment so that the libraries are not installed from PyPI, but are instead referenced through your development environment. For example, Ligare.all's pyproject.toml contains the following dependencies:

dependencies = [
    "Ligare.AWS",
    "Ligare.database",
    "Ligare.development",
    "Ligare.GitHub",
    "Ligare.platform",
    "Ligare.programming",
    "Ligare.testing",
    "Ligare.web"
]

If we were to install this library directly, pip would pull all of these dependencies from PyPI. Because we might be developing code across these libraries, we don't want this. The fix is to use pip's local project install functionality, and adjust dependencies as follows, replacing some/dir with the actual path:

dependencies = [
    "Ligare.AWS @ file:///some/dir/Ligare/src/AWS",
    "Ligare.database @ file:///some/dir/Ligare/src/database",
    "Ligare.development @ file:///some/dir/Ligare/src/development",
    "Ligare.GitHub @ file:///some/dir/Ligare/src/GitHub",
    "Ligare.platform @ file:///some/dir/Ligare/src/platform",
    "Ligare.programming @ file:///some/dir/Ligare/src/programming",
    "Ligare.testing @ file:///hsome/dir/Ligare/src/testing",
    "Ligare.web @ file:///some/dir/Ligare/src/web"
]

Utilize the Libraries

It is highly recommended to use editable installs during development. To do so, install the base dependencies with pip install -e . from the mono-repo root. Development dependencies can be installed with pip install -e .[dev-dependencies]. For convenience, you can run ./install_all.sh -e.

Things to be Aware of

Even when installing Ligare.all as an editable install, it turns out that the dependencies will be installed normally, rather than as editable installs. This means that, for example, if you make a change to Ligare.web under src/web/, that change will not be reflected unless the src/web/ package is reinstalled. To avoid this, install the library dependencies individually. For example, Ligare.web would be installed as an editable install with pip install -e src/web.

Occasionally it seems pip may still end up installing the Ligare packages normally. When this happens, it can be resolved by removing the library directory that the dependency was installed into, then installing that dependency with pip install -e src/...