# Don't do this and do the simple thing?
E.g., https://github.com/NotAShelf/ZenVer ? An monotonically increasing number is very simple. You can tack on `.dev` right after a release and guarantee you will be accurate going forward. You _could_ still calculate a local build number if you wanted to (or not). It still accomplishes what CalVer does by not having something that tries to convey meaning, but still lets people set version requirements appropriately.
# Idea
[How setuptools_scm calculates things](https://setuptools-scm.readthedocs.io/en/latest/usage/#default-versioning-scheme); [overrides](https://setuptools-scm.readthedocs.io/en/latest/overrides/).
- Derive from Git tags when possible
- `git tag --color=never --no-column --list "[0-9][0-9][0-9][0-9].[0-9]*"`
- Fallback to querying PyPI if Git isn't available, or is that overkill?
- Allow overriding calculation as an escape hatch; `*_VERSION`
- Calculate [developmental release](https://packaging.python.org/en/latest/specifications/version-specifiers/#developmental-releases) based on Git commit datetime (UTC)
- `<commit UTC timestamp>+git.<commit ID>(.dirty.<now UTC - commit UTC timestamp)?`
- [`git log -1 --pretty=%ct` for commit timestamp](https://reproducible-builds.org/docs/source-date-epoch/)
- Trying to be fancy to shrink the number of digits w/o risking odd edge cases like the release year being in the future only saves 2 digits compared to just using the epoch and keeping it simple
- `git status --porcelain` to [detect dirty/untracked state](https://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git)
- Ignoring the current branch so as to not need to normalize it
- Current branch: `git rev-parse --abbrev-ref HEAD` via https://stackoverflow.com/questions/6245570/how-do-i-get-the-current-branch-name-in-git
- When outside of a Git repo or Git isn't available, have some sensible default, e.g. `.dev<UTC datetime>+source`
- Can be overridden by `SOURCE_DATE_EPOCH`?
- Specify release level: development, alpha, beta, candidate, final, post; `*_RELEASE_LEVEL`
- "development" is the default
- It's the only release level that has local version details as all other states are intended for public release
- This makes "[final](https://packaging.python.org/en/latest/specifications/version-specifiers/#final-releases)" opt-in (on purpose so folks don't accidentally end up w/ a wheel that they think is actually a released binary)
- If the previous release was a [pre-release](https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases) (i.e. alpha/beta/candidate), keep that version for the bump
- This is only an issue if you did the pre-release last year and now you're ready for a final release this year, so as to not confuse users as to where the final release of that e.g. beta went
- If doing a [post release](https://packaging.python.org/en/latest/specifications/version-specifiers/#post-releases) after another post release, keep the version number
- Doing a post release after a pre-release is an error
# Flow
```mermaid
flowchart TD
Start([Start])
End([End])
Start --> Override{Override\nversion?}
Override -- Yes --> OverrideVersion[version = override] --> End
Override -- No --> Year["major = str(datetime.datetime.now(datetime.timezone.utc).year)"]
Year --> IsPrevRelease{Previous release\nthis year?}
IsPrevRelease -- No --> Minor0["minor = '0'"]
IsPrevRelease -- Yes --> PrevMinor["minor = str(prev_release[1] + 1)"]
Stable{Stable\nrelease?}
Minor0 --> Stable
PrevMinor --> Stable
Stable -- Yes --> Version["version = f'{major}.{minor}'"] --> End
Stable -- No --> GitInstalled{Is Git installed\nand in a checkout?}
GitInstalled -- Yes --> GitSuffix["dev_suffix = subprocess('git log -1 --pretty=%ct') + '+' + subprocess('git rev-parse HEAD')"]
GitInstalled -- No --> JulianSuffix["dev_suffix = str((datetime.datetime.now(datetime.timzeon.utc) - datetime.datetime(year, 1, 1)).total_seconds())"]
DevVersion["version = f'{year}.{minor}.dev{dev_suffix}'"]
GitSuffix --> DevVersion
JulianSuffix --> DevVersion
DevVersion --> End
```