<commit_before>#
# 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
end<commit_msg>add test coverage for build version alternate path<commit_after>#
# 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
{'fraction_non_alphanumeric': 0.13358524116470327, 'fraction_numerical': 0.046621471438097355, 'mean_word_length': 2.5006808014005055, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2821020', 'n_tokens_mistral': 6634, 'n_tokens_neox': 6005, 'n_words': 1335}