# Extending setuptools-scm

`setuptools-scm` uses [entry-point][entry-point] based hooks to extend its default capabilities.

[entry-point]: https://packaging.python.org/en/latest/specifications/entry-points/

## Adding a new SCM

`setuptools-scm` provides two entrypoints for adding new SCMs:

`setuptools_scm.parse_scm`
:   A function used to parse the metadata of the current workdir
    using the name of the control directory/file of your SCM as the
    entrypoint's name. E.g. for the built-in entrypoint for Git the
    entrypoint is named `.git` and references `setuptools_scm.git:parse`

    The return value MUST be a [`setuptools_scm.version.ScmVersion`][] instance
    created by the function [`setuptools_scm.version.meta`][].

`setuptools_scm.files_command`
:  Either a string containing a shell command that prints all SCM managed
   files in its current working directory or a callable, that given a
   pathname will return that list.

   Also uses then name of your SCM control directory as name of the entrypoint.


### api reference for scm version objects

::: setuptools_scm.version.ScmVersion
    options:
      show_root_heading: yes
      heading_level: 4

::: setuptools_scm.version.meta
    options:
      show_root_heading: yes
      heading_level: 4

## Version number construction





### `setuptools_scm.version_scheme`
Configures how the version number is constructed given a
[ScmVersion][setuptools_scm.version.ScmVersion] instance and should return a string
representing the version.

### Available implementations

`guess-next-dev (default)`
:   Automatically guesses the next development version (default).
    Guesses the upcoming release by incrementing the pre-release segment if present,
    otherwise by incrementing the micro segment. Then appends `.devN`.
    In case the tag ends with `.dev0` the version is not bumped
    and custom `.devN` versions will trigger an error.

    **Examples:**
    - Tag `v1.0.0` → version `1.0.1.dev0` (if dirty or distance > 0)
    - Tag `v1.0.0` → version `1.0.0` (if exact match)

`calver-by-date`
:   Calendar versioning scheme that generates versions based on dates.
    Uses the format `YY.MM.DD.patch` or `YYYY.MM.DD.patch` depending on the existing tag format.
    If the commit is on the same date as the latest tag, increments the patch number.
    Otherwise, uses the current date with patch 0. Supports branch-specific versioning
    for release branches.

    **Examples:**
    - Tag `v23.01.15.0` on same day → version `23.01.15.1.devN`
    - Tag `v23.01.15.0` on different day (e.g., 2023-01-16) → version `23.01.16.0.devN`
    - Tag `v2023.01.15.0` → uses 4-digit year format for new versions

`no-guess-dev`
:   Does no next version guessing, just adds `.post1.devN`.
    This is the recommended replacement for the deprecated `post-release` scheme.

    **Examples:**
    - Tag `v1.0.0` → version `1.0.0.post1.devN` (if distance > 0)
    - Tag `v1.0.0` → version `1.0.0` (if exact match)

`only-version`
:   Only use the version from the tag, as given.

    !!! warning "This means version is no longer pseudo unique per commit"

    **Examples:**
    - Tag `v1.0.0` → version `1.0.0` (always, regardless of distance or dirty state)

`post-release (deprecated)`
:   Generates post release versions (adds `.postN`)
    after review of the version number pep this is considered a bad idea
    as post releases are intended to be chosen not autogenerated.

    !!! warning "the recommended replacement is `no-guess-dev`"

    **Examples:**
    - Tag `1.0.0` → version `1.0.0.postN` (where N is the distance)

`python-simplified-semver`
:   Basic semantic versioning.

    Guesses the upcoming release by incrementing the minor segment
    and setting the micro segment to zero if the current branch contains the string `feature`,
    otherwise by incrementing the micro version. Then appending `.devN`.

    This scheme is not compatible with pre-releases.

    **Examples:**
    - Tag `1.0.0` on non-feature branch → version `1.0.1.devN`
    - Tag `1.0.0` on feature branch → version `1.1.0.devN`

`release-branch-semver`
:   Semantic versioning for projects with release branches.
    The same as `guess-next-dev` (incrementing the pre-release or micro segment)
    however when on a release branch: a branch whose name (ignoring namespace) parses as a version
    that matches the most recent tag up to the minor segment. Otherwise if on a
    non-release branch, increments the minor segment and sets the micro segment to
    zero, then appends `.devN`

    Namespaces are unix pathname separated parts of a branch/tag name.

    **Examples:**
    - Tag `1.0.0` on release branch `release-1.0` → version `1.0.1.devN`

    - Tag `1.0.0` on release branch `release/v1.0` → version `1.0.1.devN`
    - Tag `1.0.0` on development branch → version `1.1.0.devN`

### `setuptools_scm.local_scheme`
Configures how the local part of a version is rendered given a
[ScmVersion][setuptools_scm.version.ScmVersion] instance and should return a string
representing the local version.
Dates and times are in Coordinated Universal Time (UTC), because as part
of the version, they should be location independent.

#### Available implementations

`node-and-date (default)`
: adds the node on dev versions and the date on dirty workdir

`node-and-timestamp`
: like `node-and-date` but with a timestamp of the form `%Y%m%d%H%M%S` instead

`dirty-tag`
: adds `+dirty` if the current workdir has changes

`no-local-version`
: omits local version, useful e.g. because pypi does not support it
