Skip to content

Ports ​

Two Protocols define everything the core needs from the outside world. Adapters that satisfy them can be swapped freely.

TemplateRepository ​

python
class TemplateRepository(Protocol):
    def get(self, feature: Feature) -> tuple[Rule, ...]: ...
    def features(self) -> tuple[Feature, ...]: ...
    def version(self) -> str: ...

Built-in adapters ​

  • FileSystemTemplateRepository(root: Path, version: str): loads <feature>.gitignore files from a directory; caches per feature.
  • InMemoryTemplateRepository(data: dict[Feature, tuple[Rule, ...]], version: str = "test"): for tests and embedded use.

features() is sorted; the generator never relies on insertion order.

RulesTable ​

python
class RulesTable(Protocol):
    def extras_for(self, features: frozenset[Feature]) -> tuple[Rule, ...]: ...
    def version(self) -> str: ...

extras_for performs subset matching: a rule with feature set S is returned iff S ⊆ features. The result is sorted by (features, pattern).

Built-in adapters ​

  • JsonRulesTable.from_file(path: Path): loads a rules_table.json.
  • InMemoryRulesTable(...): for tests.

Custom adapters ​

Anything that satisfies the protocols works. Examples:

  • A TemplateRepository backed by a remote object store with a content hash as version().
  • A RulesTable that reads from a database, pinning version() to a schema-migration revision.

The core never serializes these objects; it only calls the methods above.

Released under the MIT License. · Privacy & legal