Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit of base rebar_vsn_plugin functionality

  • Loading branch information...
commit b3f62632e7a22e8d5c94cc54203504bce97b52a4 1 parent 2c49211
Eric Merritt authored
View
95 Makefile
@@ -0,0 +1,95 @@
+# Copyright 2012 Erlware, LLC. All Rights Reserved.
+#
+# This file is provided to you under the Apache License,
+# Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+ERLFLAGS= -pa $(CURDIR)/.eunit -pa $(CURDIR)/ebin -pa $(CURDIR)/deps/*/ebin
+
+DEPS_PLT=$(CURDIR)/.deps_plt
+
+# =============================================================================
+# Verify that the programs we need to run are installed on this system
+# =============================================================================
+ERL = $(shell which erl)
+
+ifeq ($(ERL),)
+$(error "Erlang not available on this system")
+endif
+
+REBAR=$(shell which rebar)
+
+ifeq ($(REBAR),)
+$(error "Rebar not available on this system")
+endif
+
+.PHONY: all compile doc clean test dialyzer typer shell distclean pdf \
+ get-deps
+
+all: compile dialyzer test
+
+# =============================================================================
+# Rules to build the system
+# =============================================================================
+
+get-deps:
+ $(REBAR) get-deps
+ $(REBAR) compile
+
+compile:
+ $(REBAR) skip_deps=true compile
+
+doc:
+ $(REBAR) skip_deps=true doc
+
+eunit: compile
+ $(REBAR) skip_deps=true eunit
+
+ct: compile
+ $(REBAR) skip_deps=true ct
+
+test: compile eunit
+
+$(DEPS_PLT):
+ @echo Building local plt at $(DEPS_PLT)
+ @echo
+ dialyzer --output_plt $(DEPS_PLT) --build_plt \
+ --apps erts kernel stdlib -r deps
+
+dialyzer: $(DEPS_PLT)
+ dialyzer --plt $(DEPS_PLT) --fullpath -Wrace_conditions \
+ -pa $(CURDIR)/ebin --src src
+
+typer:
+ typer --plt $(DEPS_PLT) -r ./src
+
+shell: get-deps compile
+# You often want *rebuilt* rebar tests to be available to the
+# shell you have to call eunit (to get the tests
+# rebuilt). However, eunit runs the tests, which probably
+# fails (thats probably why You want them in the shell). This
+# runs eunit but tells make to ignore the result.
+ - @$(REBAR) skip_deps=true eunit
+ @$(ERL) $(ERLFLAGS)
+
+pdf:
+ pandoc README.md -o README.pdf
+
+clean:
+ - rm -rf $(CURDIR)/test/*.beam
+ - rm -rf $(CURDIR)/logs
+ $(REBAR) skip_deps=true clean
+
+distclean: clean
+ - rm -rf $(DEPS_PLT)
+ - rm -rvf $(CURDIR)/deps/*
View
41 README.md
@@ -1,4 +1,43 @@
rebar_vsn_plugin
================
-Provides a more reasonable versioning scheme then the rebar standard 'git' vsn extension
+TLDR
+----
+
+This plugin will make accurate [semver](http://semver.org) compatible
+version strings for your Erlang OTP Apps as long as you are doing
+semver style versioning with tags 'v<version>'.
+
+Use
+---
+
+Add the following dep specification to the deps tuple of your
+`rebar.config`:
+
+ {rebar_vsn_plugin, "",
+ {git, "https://github.com/ericbmerritt/rebar_vsn_plugin.git",
+ {tag, "master"}}},
+
+Then inform rebar that you want this to be used as a plugin like so:
+
+ {plugins, [rebar_vsn_plugin]}.
+
+
+Explanation
+-------------
+
+This plugin is designed to take the latest semver
+compatible tag and turn it into a semver compatible version for the
+OTP Application. One of the key things it does (aside from making sure
+that semver is respected) is insure that there is a unique
+monotonically increasing version for each commit built. It does this
+by creating a version from both the latest tag, the epoch timestamp and
+the ref. The ref is actually only there to make the version human
+readable.
+
+So lets say you have a repository with the tag `v0.0.1` and the epoch
+`1348518514` on the latest commit identified by `26ff3c6` then you
+would end up with the version `0.0.1+build.1348518514.26ff3c6`. While
+that version string is long, it is perfectly accurate, semver
+compatible, and works well with OTP. This solves many of the current
+versioning problems with rebar and erlang OTP Apps.
View
9 rebar.config
@@ -0,0 +1,9 @@
+%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
+
+%% configure testing
+{cover_enabled, true}.
+{cover_print_enabled, true}.
+
+{erl_opts, [debug_info, warnings_as_errors, inline]}.
+
+{deps, [{rebar, ".*", {git, "https://github.com/basho/rebar.git", "master"}}]}.
View
26 src/rebar_vsn_plugin.app.src
@@ -0,0 +1,26 @@
+%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
+%%
+%% @author Eric Merritt <ericbmerritt@gmail.com>
+%% @copyright Erlware, Inc.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+
+{application, rebar_vsn_plugin,
+ [{description, "Correct version manipulation for rebar"},
+ {vsn, git},
+ {modules, []},
+ {registered, []},
+ {applications, [kernel, stdlib]}]}.
View
67 src/rebar_vsn_plugin.erl
@@ -0,0 +1,67 @@
+%%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
+%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
+%%%
+%%% This file is provided to you under the Apache License,
+%%% Version 2.0 (the "License"); you may not use this file
+%%% except in compliance with the License. You may obtain
+%%% a copy of the License at
+%%%
+%%% http://www.apache.org/licenses/LICENSE-2.0
+%%%
+%%% Unless required by applicable law or agreed to in writing,
+%%% software distributed under the License is distributed on an
+%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%%% KIND, either express or implied. See the License for the
+%%% specific language governing permissions and limitations
+%%% under the License.
+%%%---------------------------------------------------------------------------
+%%% @author Eric Merrit <ericbmerritt@gmail.com>
+%%% @copyright (C) 2012, Eric Merrit
+%%% @doc
+%%% This module provides a reasonable way to get decent semver compatible vsn
+%%% from the system. This uses the rebar post_compile hook to rewrite the app
+%%% file metadata with the correct version.
+-module(rebar_vsn_plugin).
+
+-export([post_compile/2]).
+
+%%============================================================================
+%% API
+%%============================================================================
+
+post_compile(Config, AppFile) ->
+ {ok, [{application, AppName, _}]} = file:consult(AppFile),
+
+ EbinAppFile= filename:join("ebin", erlang:atom_to_list(AppName) ++ ".app"),
+
+ {AppName, Details0} =
+ rebar_config:get_xconf(Config, {appfile, {app_file, AppFile}}, []),
+
+ %% Get the tag timestamp and minimal ref from the system. The
+ %% timestamp is really important from an ordering perspective.
+ {ok, RawRef} = rebar_utils:sh("git log -n 1 --pretty=format:'%ct.%h\n' .", []),
+ {ok, RawTag} = rebar_utils:sh("git describe --always --abbrev=0 --tags "
+ "`git log -n 1 --pretty=format:%h .`", []),
+
+ %% Cleanup the tag and the Ref information. Basically leading 'v's and
+ %% whitespace needs to go away.
+ Tag = re:replace(RawTag, "(^v)|\\s", "", [global]),
+ Ref = re:replace(RawRef, "\\s", "", [global]),
+
+ %% Create the valid [semver](http://semver.org) version from the tag
+ Vsn = erlang:binary_to_list(erlang:iolist_to_binary([Tag, "+build.", Ref])),
+
+ %% Replace the old version with the new one
+ Details1 = lists:keyreplace(vsn, 1, Details0, {vsn, Vsn}),
+
+ write_app_file(EbinAppFile, {application, AppName, Details1}),
+ {ok, rebar_config:set_xconf(Config, {appfile, {app_file, AppFile}},
+ {AppName, Details1})}.
+
+%%============================================================================
+%% Internal Functions
+%%============================================================================
+
+write_app_file(AppFile, AppTerms) ->
+ AppHeader = "%%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-\n\n",
+ file:write_file(AppFile, [AppHeader, io_lib:fwrite("~p. ", [AppTerms])]).
Please sign in to comment.
Something went wrong with that request. Please try again.