<commit_before># semver-vcs

[![Travis](https://img.shields.io/travis/ajoberstar/semver-vcs.svg?style=flat-square)](https://travis-ci.org/ajoberstar/semver-vcs)
[![Maintainer Status](http://stillmaintained.com/ajoberstar/semver-vcs.svg)](http://stillmaintained.com/ajoberstar/semver-vcs)
[![Download](https://api.bintray.com/packages/ajoberstar/libraries/org.ajoberstar%3Asemver-vcs/images/download.svg)](https://bintray.com/ajoberstar/libraries/org.ajoberstar%3Asemver-vcs/_latestVersion)
[![GitHub license](https://img.shields.io/github/license/ajoberstar/semver-vcs.svg?style=flat-square)](https://github.com/ajoberstar/semver-vcs/blob/master/LICENSE)

## Introduction

semver-vcs provides an API for calculating a project's current version number based
on the state of the version control system (VCS) and (possibly) some user input. You
can think of it like a more flexible `git describe`.

###### Supported VCSs

* [Git](http://git-scm.com/) (through [grgit](https://github.com/ajoberstar/grgit)) (in progress)

###### Supported Tooling

* [Gradle](http://gradle.org/) (in progress)

### Rationale

- [Semantic versioning](http://semver.org) is a great specification and makes it
feasible to put meaningful tooling around versioning.
- Version control systems know your project's history and can provide most, and
in some cases all, of the information to determine your next version.
- Useful abstractions should live on their own, rather than hiding inside tooling-specific
plugins. This functionality originated in [gradle-git](https://github.com/ajoberstar/gradle-git),
but doesn't need to be specific to Gradle or Git.

## Usage

For full documentation see the [wiki](https://github.com/ajoberstar/semver-vcs/wiki).

### From Gradle w/ Git

Apply the plugin:

```groovy
buildscript {
	repositories { jcenter() }
	dependencies { classpath 'org.ajoberstar:semver-vcs-gradle-grgit:<version>' }
}

apply plugin: 'org.ajoberstar.semver-vcs-grgit'

semver {
	// optionally configure how the version will be calculated
}
```

When you run Gradle, pass in any of the following properties to influence the version being inferred:

* `semver.scope` - one of `major`, `minor`, or `patch` to specify which component of the previous release should be incremented
* `semver.stage` - (by default, one of `final`, `rc`, `milestone`, or `dev`) to specify what phase of development you are in
* `semver.base` - for your first version, if you don't want to start from `0.0.0`
* `semver.force` - if you're in a bind and just need a specific version to be used

For example if the previous release was `1.2.4`:

```
./gradlew build -Psemver.scope=minor -Psemver.stage=milestone
Inferred version 1.3.0-milestone.1
...
```

## Modules

**NOTE:** *All* modules require Java 8.

- [semver-vcs-api](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc) - Base API that tooling should use.
- [semver-vcs-grgit](http://ajoberstar.org/semver-vcs/docs/semver-vcs-grgit/groovydoc) - Implementation of a grgit backend.
- [semver-vcs-gradle-base](http://ajoberstar.org/semver-vcs/docs/semver-vcs-gradle-base/groovydoc) - Base Gradle plugin that
will calculate the project's version (given a VCS impl).
- [semver-vcs-gradle-grgit](http://ajoberstar.org/semver-vcs/docs/semver-vcs-gradle-grgit/groovydoc) - Extension of the base Gradle plugin to automatically configure a grgit VCS.

## Implementing

semver-vcs is intended to be extended to new VCSs and used in new contexts.

* VCS providers should implement [Vcs](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc/org/ajoberstar/semver/vcs/Vcs.html).
* Gradle plugin authors should provide a plugin that applies `org.ajoberstar.semver-base` and configures the `semver.vcs` property.

See the reference documentation linked in the *Modules* section for more information.

## Questions, Bugs, and Requests

Open an [issue](https://github.com/ajoberstar/semver-vcs/issues) describing your
situation.

For errors, please include logs and/or stack traces when available.

## Contributing

Contributions are very welcome and should be submitted as pull requests.
For larger or more complex changes, please open an issue first to discuss the
approach.

## Acknowledgements

Thanks to [everyone](https://github.com/ajoberstar/gradle-git/graphs/contributors)
who contributed to previous iterations of this library and to
[<NAME>](https://github.com/zafarkhaja) for the very helpful
[jsemver](https://github.com/zafarkhaja/jsemver) library.<commit_msg>Major rewrite of the readme. Still need the what.<commit_after># semver-vcs

[![Travis](https://img.shields.io/travis/ajoberstar/semver-vcs.svg?style=flat-square)](https://travis-ci.org/ajoberstar/semver-vcs)
[![Maintainer Status](http://stillmaintained.com/ajoberstar/semver-vcs.svg)](http://stillmaintained.com/ajoberstar/semver-vcs)
[![Download](https://api.bintray.com/packages/ajoberstar/libraries/org.ajoberstar%3Asemver-vcs/images/download.svg)](https://bintray.com/ajoberstar/libraries/org.ajoberstar%3Asemver-vcs/_latestVersion)
[![GitHub license](https://img.shields.io/github/license/ajoberstar/semver-vcs.svg?style=flat-square)](https://github.com/ajoberstar/semver-vcs/blob/master/LICENSE)

## Why do you care?

### Get your version number out of my build file!

Most build tools and release systems require you to hardcode a version number into
a file in your source repository. This results in commit messages like "Bumping
version number.". Even if you don't have to do this manually, your release plugin
probably modifies your build file and commits the new version.

However, your version control system (VCS) also contains tags with a version
number pointing to a specific commit. Git illustrates the power of this with
the `git describe` command which creates a version number based on the
amount of change since the previous tag.

Your VCS also likely contains branches that indicate specific stages of development
or indicate maintenance for a specific subset of versions.

With this much information available to the Vcs, there's very little the user
really should have to provide to get the next version number. And it certainly
doesn't need to be hardcoded anywhere.

### What does this version number mean?

[Semantic versioning](http://semver.org) is the best answer to this question so far.
It specifies a pretty stringent meaning for what a consumer of an API should expect
based on the difference between the version number they use now and the one they
want to move too.

Additionally it describes methods for encoding pre-release and build-metadata and
how those should be sorted by tools.

## What is it?

TBD

### Current Support

**VCSs**

* [Git](http://git-scm.com/) (through [grgit](https://github.com/ajoberstar/grgit)) (in progress)

**Tooling**

* [Gradle](http://gradle.org/) (in progress)

## Usage

**NOTE:** *All* semver-vcs modules require Java 8 (or higher).

Full documentation is in the [wiki](https://github.com/ajoberstar/semver-vcs/wiki).

### Gradle & Git

Apply the plugin:

```groovy
buildscript {
	repositories { jcenter() }
	dependencies { classpath 'org.ajoberstar:semver-vcs-gradle-grgit:<version>' }
}

apply plugin: 'org.ajoberstar.semver-vcs-grgit'

semver {
	// optionally configure how the version will be calculated
}
```

See [SemverVcsExtension](http://ajoberstar.org/semver-vcs/docs/semver-vcs-gradle-base/groovydoc/org/ajoberstar/semver/vcs/gradle/SemverExtension.html)
for details on the configuration options.

When you run Gradle, pass in any of the following properties to influence the version being inferred:

* `semver.scope` - one of `major`, `minor`, or `patch` to specify which component of the previous release should be incremented
* `semver.stage` - (by default, one of `final`, `rc`, `milestone`, or `dev`) to specify what phase of development you are in
* `semver.base` - for your first version, if you don't want to start from `0.0.0`
* `semver.force` - if you're in a bind and just need a specific version to be used

For example if the previous release was `1.2.4`:

```
./gradlew build -Psemver.scope=minor -Psemver.stage=milestone
Inferred version 1.3.0-milestone.1
...
```

### Direct API Usage

The four basic steps are:

1. Construct a [Version](https://github.com/zafarkhaja/jsemver/blob/master/src/main/java/com/github/zafarkhaja/semver/Version.java) to use as a base if one isn't found in the VCS.
1. Construct a [Vcs](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc/org/ajoberstar/semver/vcs/Vcs.html)
using one of the available providers.
1. Build a [Versioner](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc/org/ajoberstar/semver/vcs/Versioner.html)
which is a function of `(Version, Vcs) -> Version`. This does all of the work of inferring the version. The
[Versioners](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc/org/ajoberstar/semver/vcs/Versioners.html) class
provides some common `Versioner` implementations that can be composed as needed.
1. Call the `Versioner` with the base `Version` and the `Vcs`.

For example:

```java
import com.github.zafarkhaja.semver.Version;
import org.ajoberstar.semver.vcs.*;
import org.ajoberstar.semver.vcs.grgit.GrgitVcs;
import org.ajoberstar.grgit.Grgit;

Version base = Version.forIntegers(0, 0, 0);
Vcs vcs = new GrgitVcs(Grgit.open()));
Versioner versioner = Versioners.forScopeAndStage(Scope.MINOR, Stage.finalStage());
Version inferred = versioner.infer(base, vcs);
```

## Implementing

### Modules

- [semver-vcs-api](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc) - Base API that tooling should use.
- [semver-vcs-grgit](http://ajoberstar.org/semver-vcs/docs/semver-vcs-grgit/groovydoc) - Implementation of a grgit backend.
- [semver-vcs-gradle-base](http://ajoberstar.org/semver-vcs/docs/semver-vcs-gradle-base/groovydoc) - Base Gradle plugin that
will calculate the project's version (given a VCS impl).
- [semver-vcs-gradle-grgit](http://ajoberstar.org/semver-vcs/docs/semver-vcs-gradle-grgit/groovydoc) - Extension of the base Gradle plugin to automatically configure a grgit VCS.

### Implementing a Vcs

A `Vcs` implementation will literally just need to implement the
[Vcs](http://ajoberstar.org/semver-vcs/docs/semver-vcs-api/javadoc/org/ajoberstar/semver/vcs/Vcs.html) interface.

See the Grgit module in this repo for further guidance.

### Implementing a Tool

See the example in *Direct API Usage* above for a basic example and the implementation of the
Gradle modules in this repo as further guidance.

## Questions, Bugs, and Features

Please use the repo's [issue](https://github.com/ajoberstar/semver-vcs/issues)
for all questions, bug reports, and feature requests.

## Contributing

Contributions are both welcome and accepted through pull requests.

Smaller changes can come directly as a PR, but larger or more complex
ones should be discussed in an issue first to flesh out the approach.

If you're interested in implementing a feature on the
[issues backlog](https://github.com/ajoberstar/semver-vcs/issues), add a comment
to make sure it's not already in progress and for any needed discussion.

## Acknowledgements

Thanks to [everyone](https://github.com/ajoberstar/gradle-git/graphs/contributors)
who contributed to previous iterations of this library and to
[<NAME>](https://github.com/zafarkhaja) for the very helpful
[jsemver](https://github.com/zafarkhaja/jsemver) library.
{'fraction_non_alphanumeric': 0.11624846464291981, 'fraction_numerical': 0.002895244779785927, 'mean_word_length': 4.7570707070707074, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 27, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3760382', 'n_tokens_mistral': 3724, 'n_tokens_neox': 3588, 'n_words': 1130}