This is an experimental project. It might become a part of the Sourcery CLI.
Sourcery Rules Generator creates architecture rules for your project.
The generated rules can be used by Sourcery to review your project's architecture.
Currently, the project can create dependency rules.
You can create Sourcery rules based on a template with the command:
sourcery-rules <TEMPLATE-NAME> create
Supported templates:
- dependencies
- naming / voldemort: avoid some names
- naming / name vs type mismatch (coming soon)
- performance / expensive loop
For example:
sourcery-rules dependencies create
With the dependencies template, you can create rules to check the dependencies:
- between the packages of your application
- to external packages.
Let's say your project has an architecture like this:
You can create rules to ensure:
- no other package imports
api
- only
api
importscore
- only
db
importSQLAlchemy
- etc.
Run the command:
sourcery-rules dependencies create
You'll be prompted to provide:
- a package name
- the packages that are allowed to import the package above
The 1st parameter is the fully qualified name of a package or module.
It can be a package within your project or an external dependency.
The 2nd parameter is optional.
You have the following possibilities:
- 0 allowed importer (e.g. for packages like
api
,cli
). Leave this parameter empty. - 1 allowed importer. Provide the importer package's fully qualified name.
- Multiple allowed importers. Provide multiple fully qualified package names separated by a comma
,
=>
2 rules will be generated:
- 1 for
import
statements - 1 for
from ... import
statements
Every generated rule allows imports:
- within the package itself
- in tests
- Law of Demeter: Packages should talk only to their "direct neighbors".
- A mature package shouldn't depend on a less mature package
- A core package shouldn't depend on a customer-specific package
Thanks to w_t_payne and hbrn for their input in this HackerNews discussion 😃
- Gateway pattern: Ensure that only a dedicated package of your software communicates with an external dependency.
- Ensure that a deprecated library isn't used
This blog post shows a 3-step method of defining dependency rules:
- Draw a diagram showing the optimal dependencies between your packages.
- Phrase some rules in a human language based on the diagram: Which package should depend on which?
- Translate the rules into code with Sourcery Rules Generator.
With a "voldemort" template, you can create rules that ensure that a specific name isn't used in your code.
For example:
- The word
annual
shouldn't be used, because the preferred term isyearly
. - The word
util
shouldn't be used, because it's overly general.
You can create a "voldemort" rule with the command:
sourcery-rules voldemort create
You'll be prompted to provide:
- the name that you want to avoid
=>
5 rules will be generated:
- function names
- function arguments
- class names
- variable declarations
- variable assignments
Loops often cause performance problems. Especially, if they execute expensive operations: talking to external systems, complex calculations.
sourcery-rules expensive-loop create
You'll be prompted to provide:
- the fully qualified name of the function that shouldn't be called in loops
=>
2 rules will be generated:
- for
for
loops - for
while
loops
The generated rules can be used by Sourcery to review your project.
If you copy the generated rules into your project's .sourcery.yaml
, Sourcery will use them automatically.
All the generated rules have the tag architecture
. Once you've copied them to your .sourcery.yaml
, you can run them with:
sourcery review --enable architecture .