code / tomo

Lines40.1K C23.5K Markdown9.5K YAML4.9K Tomo1.6K
7 others 735
Shell232 make207 Python205 INI48 Text21 SVG16 Lua6
(96 lines)

Versioning

The Tomo language and Tomo libraries both use a versioning system based on a changelog called CHANGES.md that includes a human-and-machine-readable markdown list of versions.

The version number is parsed from the first level 2 header (i.e. line beginning with ## ). An example CHANGES.md file might look like this:

# Version History

## v1.2

Version 1.2 adds some new features:

- Autofrobnication
- Reverse froodling

## v1.1

- Added a `--moop` compiler flag

## v1.0

Major version change including:

- Deprecated snobwozzling
- Added new syntax for sleazles

## v0.3

Bugfixes and new features...

The versions here use a vMAJOR.MINOR semantic versioning style, but this is not required. Versions can be any string literal, for example: edition-2025-11-29 or 1.2.3 or 6.1-EliteOcelot.

When you build the compiler or a library, if this file exists, it will be used to determine the current version (the top-most level 2 header).

Tomo Language Versions

The version for the Tomo language itself will come into play in a few ways:

  1. The compiler will be installed to tomo@TOMO_VERSION (where TOMO_VERSION is the verion of the Tomo compiler).
  2. A symbolic link will be installed from tomo to the largest version of Tomo that is installed on your machine (e.g. ~/.local/bin/tomo -> ~/.local/bin/tomo@v2025-11-29.1).
  3. Each version of Tomo will build and install its own shared library file (e.g. ~/.local/lib/libtomo@v2025-11-29.1.so) and headers (e.g. ~/.local/include/tomo@v2025-11-29.1/tomo.h).
  4. Tomo libraries will be installed to a separate subdirectory for each version of the compiler (e.g. ~/.local/lib/tomo@v2025-11-29.1/).

Tomo Program Versions

When you write a Tomo program (say, foo.tm) and run it, Tomo will automatically add support for parsing a version number out of an accompanying CHANGES.md file in the same directory. You can use the --version flag to print the version number and exit. For example, if I run tomo foo.tm -- --version, it will print v0 if no CHANGES.md file exists, otherwise it will compile the program with the most recent version number from that file and print it instead. Similarly, if you run tomo -e foo.tm to build foo as a standalone executable and then run ./foo --version, it will print the version number and exit without running the program.

Tomo Library Versions

Tomo libraries also have version numbers. When you install a library, its version number will be used to determine its installation location and how it's used in code. You must either explicitly import the library with its version number (e.g. use foo@v1.2) or include a modules.ini configuration file that maps a shorthand alias to a specific version of a library. For example, if the modules.ini file has a [foo] section with version=v1.2, you can put use foo to use v1.2 of the foo library (assuming you have it installed).

Rationale

I have opted to use a CHANGES.md file instead of git tags or a project configuration file for a few reasons. The first is that I think there is real value provided by maintaining a human-readable changelog. This approach encourages developers to maintain one. The second is to facilitate a development cycle where developers iterate on new features under the umbrella of a new version number, rather than the git tag-based approach where new features are developed in the no man's land between version tags. I also opted to use a human-readable markdown changelog rather than a build configuration file in order to ensure that there is no mismatch between the documentation and the configuration. My recommendation would be to develop code on a main or dev branch, bumping the version number pre-emptively (with an empty changelist). As new changes come in, add them to the changelog. Then, when it's appropriate, create a git tag to mark the current commit as the canonical one for that semantic version. Then, make a new commit after the tagged one bumping the version number and signaling the beginning of a new cycle of development.

1 # Versioning
3 The Tomo language and Tomo libraries both use a versioning system based on a
4 changelog called `CHANGES.md` that includes a human-and-machine-readable
5 markdown list of versions.
7 The version number is parsed from the first level 2 header (i.e. line beginning
8 with `## `). An example CHANGES.md file might look like this:
10 ```
11 # Version History
13 ## v1.2
15 Version 1.2 adds some new features:
17 - Autofrobnication
18 - Reverse froodling
20 ## v1.1
22 - Added a `--moop` compiler flag
24 ## v1.0
26 Major version change including:
28 - Deprecated snobwozzling
29 - Added new syntax for sleazles
31 ## v0.3
33 Bugfixes and new features...
34 ```
36 The versions here use a `vMAJOR.MINOR` semantic versioning style, but this is
37 not required. Versions can be any string literal, for example:
38 `edition-2025-11-29` or `1.2.3` or `6.1-EliteOcelot`.
40 When you build the compiler or a library, if this file exists, it will be used
41 to determine the current version (the top-most level 2 header).
43 ## Tomo Language Versions
45 The version for the Tomo language itself will come into play in a few ways:
47 1. The compiler will be installed to `tomo@TOMO_VERSION` (where `TOMO_VERSION`
48 is the verion of the Tomo compiler).
49 2. A symbolic link will be installed from `tomo` to the largest version of Tomo
50 that is installed on your machine (e.g. `~/.local/bin/tomo ->
51 ~/.local/bin/tomo@v2025-11-29.1`).
52 3. Each version of Tomo will build and install its own shared library file
53 (e.g. `~/.local/lib/libtomo@v2025-11-29.1.so`) and headers (e.g.
54 `~/.local/include/tomo@v2025-11-29.1/tomo.h`).
55 4. Tomo libraries will be installed to a separate subdirectory for each version
56 of the compiler (e.g. `~/.local/lib/tomo@v2025-11-29.1/`).
58 ## Tomo Program Versions
60 When you write a Tomo program (say, `foo.tm`) and run it, Tomo will
61 automatically add support for parsing a version number out of an accompanying
62 `CHANGES.md` file in the same directory. You can use the `--version` flag to
63 print the version number and exit. For example, if I run `tomo foo.tm --
64 --version`, it will print `v0` if no `CHANGES.md` file exists, otherwise it
65 will compile the program with the most recent version number from that file and
66 print it instead. Similarly, if you run `tomo -e foo.tm` to build `foo` as a
67 standalone executable and then run `./foo --version`, it will print the version
68 number and exit without running the program.
70 ## Tomo Library Versions
72 Tomo libraries also have version numbers. When you install a library, its
73 version number will be used to determine its installation location and how it's
74 used in code. You must either explicitly import the library with its version
75 number (e.g. `use foo@v1.2`) or include a `modules.ini` configuration file that
76 maps a shorthand alias to a specific version of a library. For example, if the
77 `modules.ini` file has a `[foo]` section with `version=v1.2`, you can put `use
78 foo` to use v1.2 of the `foo` library (assuming you have it installed).
80 # Rationale
82 I have opted to use a CHANGES.md file instead of git tags or a project
83 configuration file for a few reasons. The first is that I think there is real
84 value provided by maintaining a human-readable changelog. This approach
85 encourages developers to maintain one. The second is to facilitate a development
86 cycle where developers iterate on new features under the umbrella of a new
87 version number, rather than the git tag-based approach where new features are
88 developed in the no man's land between version tags. I also opted to use a
89 human-readable markdown changelog rather than a build configuration file in
90 order to ensure that there is no mismatch between the documentation and the
91 configuration. My recommendation would be to develop code on a `main` or `dev`
92 branch, bumping the version number pre-emptively (with an empty changelist). As
93 new changes come in, add them to the changelog. Then, when it's appropriate,
94 create a git tag to mark the current commit as the canonical one for that
95 semantic version. Then, make a new commit after the tagged one bumping the
96 version number and signaling the beginning of a new cycle of development.