gauge-sh / tach

A Python tool to enforce dependencies, using modular architecture 🌎 Open source 🐍 Installable via pip 🔧 Able to be adopted incrementally - ⚡ Implemented with no runtime impact ♾️ Interoperable with your existing systems 🦀 Written in rust
https://gauge.sh
MIT License
1.15k stars 36 forks source link

unify report-external and report interfaces #385

Open fraser-langton opened 4 weeks ago

fraser-langton commented 4 weeks ago

My use case

I have a common directory full of internal packages - these are being managed by uv So I have a pyproject in each package (ie common/packagename)

[project]
name = "api_models"
version = "0.0.1"
requires-python = "==3.8.*"
dependencies = [
    # external
    "pydantic==2.*",

    # common (internal)
    "blueprinter",
    "database",
    "mapbox",
    "respawned_models",
    "utils",
]

[tool.setuptools.packages.find]
exclude = ["*"]

Checking dependencies

Maybe I just made the package and want to just get all the dependencies

I can get there using tach report-external common/api_models --raw and tach report common/api_models and putting the output into chatgpt (this is awesome already btw thank you 🫶) however it's a little finnicky

Linting dependencies

I want to check that no one has inadvertently started using a package (internal or external) if it hasn't been declared in the packages dependencies

At the moment, not immediately possible, nor immediately obvious (which internal apis to use)

Improvements

emdoyle commented 3 weeks ago

Thanks for raising this, and I really appreciate the detailed report.

A few follow-up questions:

This use case seems very similar to check-external, except that in your case, certain internal modules are built and packaged separately. Therefore you want to validate their internal/workspace dependencies are declared in pyproject.toml (not just 3rd party dependencies).

It seems like the main piece of missing information in the current command is "which modules are workspace members", since check-external would otherwise exclude any internal module. The most straightforward solution might be to read this out of pyproject.toml, but I'll want to consider other options as well depending on your answers to the questions above.

fraser-langton commented 3 weeks ago

are you using uv workspaces?

yes

where have you added tach.toml?

root

have you marked common as the only source root or left it at the default?

source_roots = [
    "common",
]
root_module = "ignore"

are all of the top level packages under common marked as modules? have you marked any lower-level modules within packages?

all just top level

fraser-langton commented 3 weeks ago

This use case seems very similar to check-external, except that in your case, certain internal modules are built and packaged separately

In short, we have many internal modules where the actual dependencies are, the top level pyproj just pulls all them together for a dev env using workspaces (+ a few dev packages). I don't think check external was what I was after for auditing the workspaces, but report-external and report were

The most straightforward solution might be to read this out of pyproject.toml, but I'll want to consider other options as well depending on your answers to the questions above

I don't think tach needs to read the pyproject.toml necessarily that might complicate things, tach already has all it needs in report-external and report and existing tach.toml config it just needs to be unified a bit