spec/unit/build_version_spec.rb (167 lines of code) (raw):
require "spec_helper"
module Omnibus
describe BuildVersion do
let(:git_describe) { "11.0.0-alpha1-207-g694b062" }
let(:valid_semver_regex) { /^\d+\.\d+\.\d+(\-[\dA-Za-z\-\.]+)?(\+[\dA-Za-z\-\.]+)?$/ }
let(:valid_git_describe_regex) { /^\d+\.\d+\.\d+(\-[A-Za-z0-9\-\.]+)?(\-\d+\-g[0-9a-f]+)?$/ }
subject(:build_version) { described_class.new }
before do
Config.append_timestamp(true)
allow_any_instance_of(described_class).to receive(:shellout)
.and_return(double("ouput", stdout: git_describe, exitstatus: 0))
end
describe "git describe parsing" do
# we prefer our git tags to be SemVer compliant
# release version
context "11.0.1" do
let(:git_describe) { "11.0.1" }
its(:version_tag) { should == "11.0.1" }
its(:prerelease_tag) { should be_nil }
its(:git_sha_tag) { should be_nil }
its(:commits_since_tag) { should == 0 }
its(:prerelease_version?) { should be(false) }
end
# SemVer compliant prerelease version
context "11.0.0-alpha.2" do
let(:git_describe) { "11.0.0-alpha.2" }
its(:version_tag) { should == "11.0.0" }
its(:prerelease_tag) { should == "alpha.2" }
its(:git_sha_tag) { should be_nil }
its(:commits_since_tag) { should == 0 }
its(:prerelease_version?) { should be_truthy }
end
# full git describe string
context "11.0.0-alpha.3-59-gf55b180" do
let(:git_describe) { "11.0.0-alpha.3-59-gf55b180" }
its(:version_tag) { should == "11.0.0" }
its(:prerelease_tag) { should == "alpha.3" }
its(:git_sha_tag) { should == "f55b180" }
its(:commits_since_tag) { should == 59 }
its(:prerelease_version?) { should be_truthy }
end
# Degenerate git tag formats
# RubyGems compliant git tag
context "10.16.0.rc.0" do
let(:git_describe) { "10.16.0.rc.0" }
its(:version_tag) { should == "10.16.0" }
its(:prerelease_tag) { should == "rc.0" }
its(:git_sha_tag) { should be_nil }
its(:commits_since_tag) { should == 0 }
its(:prerelease_version?) { should be_truthy }
end
# dash seperated prerelease
context "11.0.0-alpha-2" do
let(:git_describe) { "11.0.0-alpha-2" }
its(:version_tag) { should == "11.0.0" }
its(:prerelease_tag) { should == "alpha-2" }
its(:git_sha_tag) { should be_nil }
its(:commits_since_tag) { should == 0 }
its(:prerelease_version?) { should be_truthy }
end
# dash seperated prerelease full git describe string
context "11.0.0-alpha-2-59-gf55b180" do
let(:git_describe) { "11.0.0-alpha-2-59-gf55b180" }
its(:version_tag) { should == "11.0.0" }
its(:prerelease_tag) { should == "alpha-2" }
its(:git_sha_tag) { should == "f55b180" }
its(:commits_since_tag) { should == 59 }
its(:prerelease_version?) { should be_truthy }
end
# WTF git tag
context "11.0.0-alpha2" do
let(:git_describe) { "11.0.0-alpha2" }
its(:version_tag) { should == "11.0.0" }
its(:prerelease_tag) { should == "alpha2" }
its(:git_sha_tag) { should be_nil }
its(:commits_since_tag) { should == 0 }
its(:prerelease_version?) { should be_truthy }
end
# v-prefixed tag
context "v1.2.3-beta2" do
let(:git_describe) { "v1.2.3-beta2" }
its(:version_tag) { should == "1.2.3" }
its(:prerelease_tag) { should == "beta2" }
its(:git_sha_tag) { should be(nil) }
its(:commits_since_tag) { should eq(0) }
its(:prerelease_version?) { should be(true) }
end
end
describe "semver output" do
let(:today_string) { Time.now.utc.strftime("%Y%m%d") }
it "generates a valid semver version" do
expect(build_version.semver).to match(valid_semver_regex)
end
it "generates a version matching format 'MAJOR.MINOR.PATCH-PRERELEASE+TIMESTAMP.git.COMMITS_SINCE.GIT_SHA'" do
expect(build_version.semver).to match(/11.0.0-alpha1\+#{today_string}[0-9]+.git.207.694b062/)
end
it "uses ENV['BUILD_TIMESTAMP'] to generate timestamp if set" do
stub_env("BUILD_TIMESTAMP", "2012-12-25_16-41-40")
expect(build_version.semver).to eq("11.0.0-alpha1+20121225164140.git.207.694b062")
end
it "fails on invalid ENV['BUILD_TIMESTAMP'] values" do
stub_env("BUILD_TIMESTAMP", "AAAA")
expect { build_version.semver }.to raise_error(ArgumentError)
end
it "uses ENV['BUILD_ID'] to generate timestamp if set and BUILD_TIMESTAMP is not set" do
stub_env("BUILD_ID", "2012-12-25_16-41-40")
expect(build_version.semver).to eq("11.0.0-alpha1+20121225164140.git.207.694b062")
end
it "fails on invalid ENV['BUILD_ID'] values" do
stub_env("BUILD_ID", "AAAA")
expect { build_version.semver }.to raise_error(ArgumentError)
end
context "prerelease version with dashes" do
let(:git_describe) { "11.0.0-alpha-3-207-g694b062" }
it "converts all dashes to dots" do
expect(build_version.semver).to match(/11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/)
end
end
context "exact version" do
let(:git_describe) { "11.0.0-alpha2" }
it "appends a timestamp with no git info" do
expect(build_version.semver).to match(/11.0.0-alpha2\+#{today_string}[0-9]+/)
end
end
describe "appending a timestamp" do
let(:git_describe) { "11.0.0-alpha-3-207-g694b062" }
context "by default" do
it "appends a timestamp" do
expect(build_version.semver).to match(/11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/)
end
end
context "when Config.append_timestamp is true" do
it "appends a timestamp" do
expect(build_version.semver).to match(/11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/)
end
end
context "when Config.append_timestamp is false" do
before { Config.append_timestamp(false) }
it "does not append a timestamp" do
expect(build_version.semver).to match(/11.0.0-alpha.3\+git.207.694b062/)
end
end
end
end
describe "git describe output" do
it "generates a valid git describe version" do
expect(build_version.git_describe).to match(valid_git_describe_regex)
end
it "generates a version matching format 'MAJOR.MINOR.PATCH-PRELEASE.COMMITS_SINCE-gGIT_SHA'" do
expect(build_version.git_describe).to eq(git_describe)
end
end
describe "`git describe` command failure" do
before do
stderr = <<-STDERR
fatal: No tags can describe '809ea1afcce67e1148c1bf0822d40a7ef12c380e'.
Try --always, or create some tags.
STDERR
allow(build_version).to receive(:shellout)
.and_return(double("ouput", stderr: stderr, exitstatus: 128))
end
it "sets the version to 0.0.0" do
expect(build_version.git_describe).to eq("0.0.0")
end
end
describe "#initialize `path` parameter" do
let(:path) { "/some/fake/path" }
subject(:build_version) { BuildVersion.new(path) }
it "runs `git describe` at an alternate path" do
expect(build_version).to receive(:shellout)
.with("git describe --tags", cwd: path)
.and_return(double("ouput", stdout: git_describe, exitstatus: 0))
build_version.git_describe
end
end
end
end