# # Copyright:: Copyright (c) 2012 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed 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. # require 'omnibus/build_version' require 'spec_helper' describe Omnibus::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){ Omnibus::BuildVersion.new } before :each do ENV['BUILD_ID'] = nil ENV['OMNIBUS_APPEND_TIMESTAMP'] = nil Omnibus::BuildVersion.any_instance.stub(:shellout) .and_return(mock("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(:development_version?){ should be_true } 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(:development_version?){ should be_false } its(:prerelease_version?){ should be_true } 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(:development_version?){ should be_false } its(:prerelease_version?){ should be_true } 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(:development_version?){ should be_false } its(:prerelease_version?){ should be_true } 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(:development_version?){ should be_false } its(:prerelease_version?){ should be_true } 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(:development_version?){ should be_false } its(:prerelease_version?){ should be_true } 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(:development_version?){ should be_false } 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 build_version.semver.should =~ valid_semver_regex end it "generates a version matching format 'MAJOR.MINOR.PATCH-PRERELEASE+TIMESTAMP.git.COMMITS_SINCE.GIT_SHA'" do build_version.semver.should =~ /11.0.0-alpha1\+#{today_string}[0-9]+.git.207.694b062/ end it "uses ENV['BUILD_ID'] to generate timestamp if set" do ENV['BUILD_ID'] = "2012-12-25_16-41-40" build_version.semver.should == "11.0.0-alpha1+20121225164140.git.207.694b062" end it "fails on invalid ENV['BUILD_ID'] values" do 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 build_version.semver.should =~ /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 build_version.semver.should =~ /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" } it "appends a timestamp by default" do build_version.semver.should =~ /11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/ end describe "ENV['OMNIBUS_APPEND_TIMESTAMP'] is set" do ["true","t","yes","y",1].each do |truthy| context "to #{truthy}" do before { ENV['OMNIBUS_APPEND_TIMESTAMP'] = truthy.to_s } it "appends a timestamp" do build_version.semver.should =~ /11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/ end end end ["false","f","no","n",0].each do |falsey| context "to #{falsey}" do before { ENV['OMNIBUS_APPEND_TIMESTAMP'] = falsey.to_s } it "does not append a timestamp" do build_version.semver.should =~ /11.0.0-alpha.3\+git.207.694b062/ end end end end describe "Omnibus::Config.append_timestamp is set" do context "is true" do before { Omnibus::Config.append_timestamp(true) } it "appends a timestamp" do build_version.semver.should =~ /11.0.0-alpha.3\+#{today_string}[0-9]+.git.207.694b062/ end end context "is false" do before { Omnibus::Config.append_timestamp(false) } it "does not append a timestamp" do build_version.semver.should =~ /11.0.0-alpha.3\+git.207.694b062/ end end end describe "both are set" do before do ENV['OMNIBUS_APPEND_TIMESTAMP'] = "false" Omnibus::Config.append_timestamp(true) end it "prefers the value from ENV['OMNIBUS_APPEND_TIMESTAMP']" do build_version.semver.should =~ /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 build_version.git_describe.should =~ valid_git_describe_regex end it "generates a version matching format 'MAJOR.MINOR.PATCH-PRELEASE.COMMITS_SINCE-gGIT_SHA'" do build_version.git_describe.should == git_describe end end describe "deprecated full output" do it "generates a valid git describe version" do Omnibus::BuildVersion.full.should =~ valid_git_describe_regex end it "outputs a deprecation message" do Omnibus::BuildVersion.should_receive(:puts).with(/is deprecated/) Omnibus::BuildVersion.full 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 build_version.stub(:shellout) .and_return(mock("ouput", :stderr => stderr, :exitstatus => 128)) end it "sets the version to 0.0.0" do build_version.git_describe.should eq("0.0.0") end end describe "#initialize `path` parameter" do let(:path) { "/some/fake/path" } subject(:build_version){ Omnibus::BuildVersion.new(path) } it "runs `git describe` at an alternate path" do build_version.should_receive(:shellout) .with("git describe", {:live_stream => nil, :cwd => path}) .and_return(mock("ouput", :stdout => git_describe, :exitstatus => 0)) build_version.git_describe end end end