source-code.md 4.5 KB


title: Source code eleventyNavigation: key: 🐍 Source code parent: Reference guides

order: 3

If you're interested in developing on borgmatic, here's an abridged primer on how its Python source code is organized to help you get started. Starting at the top level, we have:

  • borgmatic: The main borgmatic source module. Most of the code is here. Within that:
    • actions: borgmatic-specific logic for running each action (create, list, check, etc.).
    • borg: Lower-level code that's responsible for interacting with Borg to run each action.
    • commands: Looking to add a new flag or action? Start here. This contains borgmatic's entry point, argument parsing, and shell completion.
    • config: Code responsible for loading, normalizing, and validating borgmatic's configuration. Interested in adding a new configuration option? Check out schema.yaml here.
    • hooks: Looking to add a new database, filesystem, or monitoring integration? Start here.
      • credential: Credential hooks—for loading passphrases and secrets from external providers.
      • data_source: Database and filesystem hooks—anything that produces data or files to go into a backup archive.
      • monitoring: Monitoring hooks—integrations with third-party or self-hosted monitoring services.
  • docs: How-to and reference documentation, including the document you're reading now.
  • sample: Example configurations for cron and systemd.
  • scripts: Dev-facing scripts for things like building documentation and running end-to-end tests.
  • tests: Automated tests organized by: end-to-end, integration, and unit.

So, broadly speaking, the control flow goes: commandsconfig followed by commandsactionsborg and hooks.

Code style

When writing code for borgmatic, start with PEP 8. But then, apply the following deviations from it:

  • For strings, prefer single quotes over double quotes.
  • Limit all lines to a maximum of 100 characters.
  • Use trailing commas within multiline values or argument lists.
  • For multiline constructs, put opening and closing delimiters on lines separate from their contents.
  • Within multiline constructs, use standard four-space indentation. Don't align indentation with an opening delimiter.
  • In general, spell out words in variable names instead of shortening them. So, think index instead of idx. There are some notable exceptions to this though (like config).
  • Favor blank lines around logical code groupings, if statements, returns, etc. Readability is more important than packing code tightly.
  • Import fully qualified Python modules instead of importing individual functions, classes, or constants. E.g., do import os.path instead of from os import path. (Some exceptions to this are made in tests.)
  • Only use classes and OOP as a last resort, such as when integrating with Python libraries that require it.
  • Prefer functional code where it makes sense, e.g. when constructing a command (to subsequently execute imperatively).

Since borgmatic uses Ruff for code lining and formatting, many other code style requirements are also enforced when running automated tests.