Commands
tach mod
Tach comes bundled with a command to set up your initial boundaries - tach mod
.
Running tach mod
will open an editor in your terminal where you can mark your module boundaries.
You can navigate with the arrow keys, mark individual modules with Enter
, and mark all siblings
as modules with Ctrl + a
.
You can also mark your Python source roots by pressing s
.
This allows Tach to understand module paths and correctly identify first-party imports.
You can mark modules as utilities by pressing u
. This is appropriate for modules like utils/
, which can be freely used by the rest of the code.
To save your modules, use Ctrl + s
. Otherwise, to exit without saving, use Ctrl + c
.
Any time you make changes with tach mod
, run tach sync
to automatically configure dependency rules.
tach sync
Tach can automatically sync your project configuration (tach.toml
) with your project’s actual dependencies.
When this command runs, Tach will analyze the imports in your Python project.
Any undeclared dependencies will be automatically resolved by
adding the corresponding dependencies to your tach.toml
file.
With --add
,
any missing dependencies in your tach.toml
will be added, but does not remove unused dependencies.
When run without the --add
flag, tach sync
will remove modules from the tach.yml
file that do not exist in the project’s source roots.
tach check
Tach will flag any unwanted imports between modules. We recommend you run tach check
like a linter or test runner, e.g. in pre-commit hooks, on-save hooks, and in CI pipelines.
An error will indicate:
- the file path in which the error was detected
- the path associated with that file
- the path associated with the attempted import
If --exact
is provided, additional errors will be raised if a dependency exists in tach.toml
that does not exist in the code.
Example:
NOTE: If your terminal supports hyperlinks, you can click on the failing file path to go directly to the error.
tach report
Tach can generate a report showing all the dependencies and usages of a given module.
This will generate a textual report showing the file and line number of each relevant import.
By default, the report will include a section containing all external usages of a module,
as well as all dependencies of the module. These can be toggled off with --no-usages
and --no-deps
respectively.
To filter the output, the -d
and -u
options allow specifying which module paths to include in the dependency section and usage section respectively.
tach show
Tach will generate a visual representation of your dependency graph!
These are the results of tach show --web
on the Tach codebase itself:
tach test
Tach also functions as an intelligent test runner.
Using pytest
, running tach test
will perform impact analysis on the changes between your current filesystem and your main
branch to determine which test files need to be run.
This can dramatically speed up your test suite in CI, particularly when you make a small change to a large codebase.
This command also takes advantage of Tach’s computation cache.
tach check-external
Tach can validate that the external imports in your Python packages match your declared package dependencies in pyproject.toml
.
For each pyproject.toml
found from the project root, Tach will scan all imports in the associated Python source and compare them with the declared dependencies.
Tach will report an error for any external import which is not satisfied by the declared dependencies - preventing your users from errors due to missing imports.
This is typically useful if you are developing more than one Python package from a single virtual environment.
Although your local environment may contain the dependencies for all your packages, when an end-user installs each package they will only install the dependencies listed in the pyproject.toml
.
This means that, although tests may pass in your shared environment, an invalid import can still cause errors at runtime for your users.
In case you would like to explicitly allow a certain external module, this can be configured in your tach.toml
It is recommended to run Tach within a virtual environment containing all of your dependencies across all packages. This is because Tach uses the distribution metadata to map module names like ‘git’ to their distributions (‘GitPython’).
tach report-external
Tach can determine what external packages are used in a given path in your project.
This is typically useful for ‘tree-shaking’ during a build process. For example, if you are building a deployable image with only a subset of your code, you would run:
to generate a minimal set of external dependencies for that source code.
It is recommended to run Tach within a virtual environment containing all of your dependencies across all packages. This is because Tach uses the distribution metadata to map module names like ‘git’ to their distributions (‘GitPython’).
tach install
Tach can be installed into your development workflow automatically as a pre-commit hook.
With pre-commit framework
If you use the pre-commit framework, you can add the following to your .pre-commit-hooks.yaml
:
Note that you should specify the version you are using in the rev
key.
Standard install
If you don’t already have pre-commit hooks set up, you can run:
The command above will install tach check
as a pre-commit hook, directly into .git/hooks/pre-commit
.
If that file already exists, you will need to manually add tach check
to your existing .git/hooks/pre-commit
file.