SSOT: Single Source Of Truth command line utility
SSOT stores a single source of truth for constant values in an ./ssot.yaml file that contains a list of constants and a list of files to processes.
SSOT directives are comments in the native language and replacements are done "inline."
Directives are end-of-line comments that contain a named constant to replace, and a regexp to allow direct matching of content within the line. Matching identifies the content in the line that ssot will replace with the constant's value from the Constants map in ./ssot/yaml.
The regex can — but is not required to — have begin (^) and end ($) of line anchors but only one capture group ((...)) which should identify the value to replace.
Why use ssot? Here are the benefits I was after when I chose to develop and start using it:
- Use directives to identify locations in source where constants are shared across language files.
- Enable error checking for all directives to ensure correct syntax.
- Change values in one place when there is a need to change values.
- Or, Easily rename constants accurately via editor search.
Store a ssot.yaml file in whatever directory you want to maintain your constants with:
- A
commentsmap with file extensions and their related comment start characters, - An
filesarray with filenames to scan for constants, and - A
constantsmap with constant keys and values
For example:
---
comments:
.go: //
.sql: --
files:
- ./shared/link_group.go
- ./query.sql
constants:
from_group_missing: "from_group_missing"
link_missing: "link_missing"
to_group_found: "to_group_found"Then in your source files use an end-of-line comment in the form of:
ssot[<constant>]: <regex>
Finally, run ssot in the directory where your ssot.yaml file exists.
package shared
const (
FromGroupMissing = "from_group_missing" //ssot[from_group_missing]: "([^"]+)"
LinkMissing = "link_missing" //ssot[link_missing]: "([^"]+)"
ToGroupFound = "to_group_found" //ssot[to_group_found]: "([^"]+)"
)SELECT
'link_missing' AS exception, --ssot[link_missing]: '([^']+)'
from_group_id,
from_group_name,
link_id,
link_url,
to_group_id,
to_group_name
FROM
link_group_move_from_to
WHERE
link_found = 0
UNION
SELECT
'from_group_missing' AS exception, --ssot[from_group_missing]: '([^']+)'
from_group_id,
from_group_name,
link_id,
link_url,
to_group_id,
to_group_name
FROM
link_group_move_from_to
WHERE
from_group_found = 0
UNION
SELECT
'to_group_found' AS exception, --ssot[to_group_found]: '([^']+)'
from_group_id,
from_group_name,
link_id,
link_url,
to_group_id,
to_group_name
FROM
link_group_move_from_to
WHERE
to_group_found = 0;The current goals for ssot are:
- In-place updates — no
/src(e.g..ts) vs./dst(e.g..js) files. - Performance first — Don't scan all files, require developer to provide a list to scan.
- Keep it simple — only adding complexity when really required.
- YAGNI — Do not implement more than I (or maybe someone else) currently need(s).
Written to scratch my own itch. I wanted to have a single-source of truth across different source files from different programming languages, but I did not want to have a source -> dist build step given the nature of the truth being small compared to the size of the code the truth is typically embedded in.
- Currently only one named constant can be replaced per line, but a constant can be referenced multiple times in the same line, if needed (this is assumed but untested.)
- Wildcards for files are not (yet?) supported.
- No command line options so no execution options (yet?).
- No versioning (yet?); use latest and caveat emptor.
- No tests (yet?) as I did not need for the simple use-case that inspired me to write
ssot.
...are Welcome!
If you find this and it is useful for you but you discover bugs or have improvements to add, please feel free to create a bug report and/or a pull request.
Copyright 2024 Mike Schinkel
MIT
