Skip to content

Commit

Permalink
Merge pull request ManageIQ#17755 from Fryguy/plugin_versions
Browse files Browse the repository at this point in the history
Add Vmdb::Plugins#versions
  • Loading branch information
bdunne authored Aug 6, 2018
2 parents 4e2609e + dbd79bf commit 97b4735
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
48 changes: 48 additions & 0 deletions lib/vmdb/plugins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def init
register_models
end

def versions
each_with_object({}) do |engine, hash|
hash[engine] = version(engine)
end
end

def ansible_content
@ansible_content ||= begin
require_relative 'plugins/ansible_content'
Expand Down Expand Up @@ -91,6 +97,48 @@ def register_models

private

# Determine the version of the specified engine
#
# If the gem is
# - git based, pointing to a branch: <branch>@<sha>
# - git based, pointing to a tag: <tag>@<sha>
# - git based, pointing to a sha: <sha>
# - path based, with git, on a branch: <branch>@<sha>
# - path based, with git, on a tag: <tag>@<sha>
# - path based, with git, on a sha: <sha>
# - path based, without git: nil
# - a real gem: <gem_version>
def version(engine)
spec = bundler_specs_by_path[engine.root.to_s]

case spec.source
when Bundler::Source::Git
[
spec.source.branch || spec.source.options["tag"],
spec.source.revision.presence[0, 8]
].compact.join("@").presence
when Bundler::Source::Path
if engine.root.join(".git").exist?
branch = sha = nil
Dir.chdir(engine.root) do
branch = `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip.presence
branch = nil if branch == "HEAD"
branch ||= `git describe --tags --exact-match HEAD 2>/dev/null`.strip.presence

sha = `git rev-parse HEAD 2>/dev/null`.strip[0, 8].presence
end

[branch, sha].compact.join("@").presence
end
when Bundler::Source::Rubygems
spec.version
end
end

def bundler_specs_by_path
@bundler_specs_by_path ||= Bundler.environment.specs.index_by(&:full_gem_path)
end

def content_directories(engine, subfolder)
Dir.glob(engine.root.join("content", subfolder, "*"))
end
Expand Down
130 changes: 130 additions & 0 deletions spec/lib/vmdb/plugins_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,134 @@
ManageIQ::UI::Classic::Engine
)
end

it ".versions" do
versions = described_class.versions

expect(versions).to be_kind_of(Hash)
expect(versions.keys).to match_array described_class.all
end

describe ".version (private)" do
subject { described_class.send(:instance).send(:version, engine) }

let(:engine) { Class.new(Rails::Engine) }

def clear_versions_caches
described_class.send(:instance).instance_variable_set(:@bundler_specs_by_path, nil)
end

before { clear_versions_caches }
after { clear_versions_caches }

def with_temp_dir(_options)
Dir.mktmpdir("plugins_spec") do |dir|
allow(engine).to receive(:root).and_return(Pathname.new(dir))
yield dir
end
end

def with_temp_git_dir(options)
with_temp_dir(options) do |dir|
sha = nil

Dir.chdir(dir) do
`
git init &&
touch foo && git add -A && git commit -m "Added foo" &&
touch foo2 && git add -A && git commit -m "Added foo2"
`

if options[:branch] == "master"
sha = `git rev-parse HEAD`.strip
else
sha = `git rev-parse HEAD~`.strip
`git checkout #{"-b #{options[:branch]}" if options[:branch]} #{sha} 2>/dev/null`
`git tag #{options[:tag]}` if options[:tag]
end
end

yield dir, sha
end
end

def with_spec(type, options = {})
raise "Unexpected type '#{type}'" unless %i(git path_with_git path).include?(type)

source =
if type == :git
instance_double(Bundler::Source::Git, :branch => options[:branch], :options => {"tag" => options[:tag]})
else
instance_double(Bundler::Source::Path)
end

allow(Bundler::Source::Git).to receive(:===).with(source).and_return(type == :git)
allow(Bundler::Source::Path).to receive(:===).with(source).and_return(type != :git)

method = (type == :path ? :with_temp_dir : :with_temp_git_dir)

send(method, options) do |dir, sha|
expect(source).to receive(:revision).and_return(sha) if type == :git

spec = instance_double(Gem::Specification, :full_gem_path => dir, :source => source)
expect(Bundler.environment).to receive(:specs).and_return([spec])

yield(sha && sha[0, 8])
end
end

it "git based, on master" do
with_spec(:git, :branch => "master") do |sha|
expect(subject).to eq("master@#{sha}")
end
end

it "git based, on a branch" do
with_spec(:git, :branch => "my_branch") do |sha|
expect(subject).to eq("my_branch@#{sha}")
end
end

it "git based, on a tag" do
with_spec(:git, :tag => "my_tag") do |sha|
expect(subject).to eq("my_tag@#{sha}")
end
end

it "git based, on a sha" do
with_spec(:git) do |sha|
expect(subject).to eq(sha)
end
end

it "path based, with git, on master" do
with_spec(:path_with_git, :branch => "master") do |sha|
expect(subject).to eq("master@#{sha}")
end
end

it "path based, with git, on a branch" do
with_spec(:path_with_git, :branch => "my_branch") do |sha|
expect(subject).to eq("my_branch@#{sha}")
end
end

it "path based, with git, on a tag" do
with_spec(:path_with_git, :tag => "my_tag") do |sha|
expect(subject).to eq("my_tag@#{sha}")
end
end

it "path based, with git, on a sha" do
with_spec(:path_with_git) do |sha|
expect(subject).to eq(sha)
end
end

it "path based, without git" do
with_spec(:path) do
expect(subject).to be_nil
end
end
end
end

0 comments on commit 97b4735

Please sign in to comment.