Skip to content
This repository has been archived by the owner on Apr 6, 2021. It is now read-only.

Artifact types #24

Merged
merged 3 commits into from
Sep 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions lib/shanty/artifact.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'uri'
require 'pathname'

module Shanty
# Public: Contain information on an artifact published by a project
class Artifact
attr_reader :file_extension, :plugin, :uri

# Public: Initialise an artifact instance.
#
# file_extension - The extension of the artifact.
# plugin - The plugin publishing the artifact.
# uri - The URI to the object.
#
# Fails if the URI is not absolute or a scheme is missing.
def initialize(file_extension, plugin, uri)
@file_extension = file_extension
@plugin = plugin
@uri = uri

validate_uri
end

# Public: Whether the underlying URI of the artifact points to a local
# file path.
#
# Returns a Boolean representing whether the artifact is local.
def local?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to add docs for this method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@uri.scheme == 'file'
end

# Public: If the underlying artifact is stored locally, returns the path
# at which the artifact can be found.
#
# Returns a String representing the path at which the artifact can be found.
# Raises RuntimeError if the artifact is not local.
def to_local_path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs for this method, will need to mention the raise in the format described by the TomDoc spec (see http://tomdoc.org/, § "The Returns/Raises").

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

return @uri.path if local?
fail 'URI is not a local resource'
end

# Public: A simple string representation of this artifact.
#
# Returns a String representing the URI at which this artifact can be found.
def to_s
@uri.to_s
end

private

def validate_uri
fail 'Scheme not present on URI' unless @uri.absolute?
fail 'URI is not absolute' if @uri.path.nil?
end
end
end
4 changes: 4 additions & 0 deletions lib/shanty/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def projects
end
end

def artifacts(_)
[]
end

def with_graph(graph)
callbacks = self.class.instance_variable_get(:@with_graph_callbacks)
return [] if callbacks.nil? || callbacks.empty?
Expand Down
2 changes: 1 addition & 1 deletion lib/shanty/plugins/bundler_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class BundlerPlugin < Plugin
projects '**/Gemfile'
subscribe :build, :bundle_install

def bundle_install
def bundle_install(_)
Bundler.with_clean_env do
# FIXME: Add support for the --jobs argument to parallelise the bundler run.
system 'bundle install --quiet'
Expand Down
2 changes: 1 addition & 1 deletion lib/shanty/plugins/cucumber_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def cucumber_projects
end
end

def cucumber
def cucumber(_)
system 'cucumber'
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/shanty/plugins/rspec_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def rspec_projects
end
end

def rspec
def rspec(_)
system 'rspec'
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/shanty/plugins/rubocop_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class RubocopPlugin < Plugin
projects '**/.rubocop.yml'
subscribe :test, :rubocop

def rubocop
def rubocop(_)
system 'rubocop'
end
end
Expand Down
26 changes: 24 additions & 2 deletions lib/shanty/plugins/rubygem_plugin.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
require 'shanty/plugin'
require 'shanty/artifact'

module Shanty
# Public: Rubygem plugin for buildin gems.
class RubygemPlugin < Plugin
ARTIFACT_EXTENSION = 'gem'

tags :rubygem
projects '**/*.gemspec'
subscribe :build, :build_gem

def build_gem
system 'gem build *.gemspec'
def build_gem(project)
gemspec_files(project).each do |file|
system "gem build #{file}"
end
end

def artifacts(project)
gemspec_files(project).flat_map do |file|
gemspec = Gem::Specification.load(file)
Artifact.new(
ARTIFACT_EXTENSION,
'rubygem',
URI("file://#{project.path}/#{gemspec.name}-#{gemspec.version}.#{ARTIFACT_EXTENSION}")
)
end
end

private

def gemspec_files(project)
@gemspec_files ||= project_tree.glob(File.join(project.path, '*.gemspec'))
end
end
end
21 changes: 11 additions & 10 deletions lib/shanty/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Project
include ActsAsGraphVertex
include Env

attr_accessor :name, :path, :tags, :options
attr_accessor :artifacts, :name, :path, :tags, :options

# Multiton or Flyweight pattern - only allow once instance per unique path.
#
Expand Down Expand Up @@ -40,6 +40,7 @@ def initialize(path)
@path = path

@name = File.basename(path)
@artifacts = []
@plugins = []
@tags = []
@options = {}
Expand All @@ -61,22 +62,22 @@ def all_tags
(@tags + @plugins.flat_map { |plugin| plugin.class.tags }).map(&:to_sym).uniq
end

# Public: The artifacts published by this project and any artifacts published
# by any plugins operating on this project.
#
# Returns the Array of Artifacts available for this project.
def all_artifacts
(@artifacts + @plugins.flat_map { |plugin| plugin.artifacts(project) }).uniq
end

def publish(name, *args)
@plugins.each do |plugin|
next unless plugin.subscribed?(name)
logger.info("Executing #{name} on the #{plugin.class} plugin...")
return false if plugin.publish(name, *args) == false
return false if plugin.publish(name, self, *args) == false
end
end

# Public: The absolute paths to the artifacts that would be created by this
# project when built, if any. This is expected to be overriden in subclasses.
#
# Returns an Array of Strings representing the absolute paths to the artifacts.
def artifact_paths
[]
end

# Public: Overriden String conversion method to return a simplified
# representation of this instance that doesn't include the cyclic
# parent/children attributes as defined by the ActsAsGraphVertex mixin.
Expand Down
44 changes: 44 additions & 0 deletions spec/lib/shanty/artifact_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'shanty/artifact'

# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(Artifact) do
subject { described_class.new('html', 'test', uri) }
let(:relative_path_artifact) { described_class.new('html', 'test', URI('file:kim/cage.html')) }
let(:http_artifact) { described_class.new('html', 'test', URI('http://www.nic.com/kim/cage.html')) }
let(:schemless_artifact) { described_class.new('html', 'test', URI('kim/cage.html')) }

let(:uri) { URI('file:///nic/kim/cage.html') }

describe('.new') do
it('fails if the URI is not an absolute path') do
expect { relative_path_artifact }.to raise_error('URI is not absolute')
end

it('fails if there is no scheme present in the URI') do
expect { schemless_artifact }.to raise_error('Scheme not present on URI')
end
end

describe('#local?') do
it('returns false if the file is not a local file') do
expect(http_artifact.local?).to be(false)
end

it('returns true if the file is a local file') do
expect(subject.local?).to be(true)
end
end

describe('#to_local_path') do
it('throws an exception if the resource is not local') do
allow(subject).to receive(:local?).and_return(false)
expect { subject.to_local_path }.to raise_error('URI is not a local resource')
end

it('returns the path if the resource is local') do
expect(subject.to_local_path).to eql('/nic/kim/cage.html')
end
end
end
end
4 changes: 2 additions & 2 deletions spec/lib/shanty/plugins/bundler_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(BundlerPlugin) do
include_context('basics')
include_context('graph')

it('adds the bundler tag') do
expect(described_class).to add_tags(:bundler)
Expand All @@ -22,7 +22,7 @@ module Shanty
it('calls bundler install') do
expect(subject).to receive(:system).with('bundle install --quiet')

subject.bundle_install
subject.bundle_install(project)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/shanty/plugins/cucumber_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(CucumberPlugin) do
include_context('basics')
include_context('graph')

it('adds the cucumber tag') do
expect(described_class).to add_tags(:cucumber)
Expand All @@ -22,7 +22,7 @@ module Shanty
it('calls cucumber') do
expect(subject).to receive(:system).with('cucumber')

subject.cucumber
subject.cucumber(project)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/shanty/plugins/rspec_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(RspecPlugin) do
include_context('basics')
include_context('graph')

it('adds the rspec tag') do
expect(described_class).to add_tags(:rspec)
Expand All @@ -22,7 +22,7 @@ module Shanty
it('calls rspec') do
expect(subject).to receive(:system).with('rspec')

subject.rspec
subject.rspec(project)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/shanty/plugins/rubocop_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(RubocopPlugin) do
include_context('basics')
include_context('graph')

it('adds the rubocop tag') do
expect(described_class).to add_tags(:rubocop)
Expand All @@ -22,7 +22,7 @@ module Shanty
it('calls rubocop') do
expect(subject).to receive(:system).with('rubocop')

subject.rubocop
subject.rubocop(project)
end
end
end
Expand Down
31 changes: 28 additions & 3 deletions spec/lib/shanty/plugins/rubygem_plugin_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
require 'spec_helper'
require 'fileutils'
require 'shanty/plugins/rubygem_plugin'

# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(RubygemPlugin) do
include_context('basics')
include_context('graph')
let(:gemspec_path) { File.join(project_path, 'foo.gemspec') }

before do
File.write(gemspec_path, <<-eof)
Gem::Specification.new do |gem|
gem.name = 'foo'
gem.version = '1.2.3'
end
eof
end

it('adds the rubygem tag') do
expect(described_class).to add_tags(:rubygem)
Expand All @@ -20,9 +31,23 @@ module Shanty

describe('#build_gem') do
it('calls gem build') do
expect(subject).to receive(:system).with('gem build *.gemspec')
expect(subject).to receive(:system).with("gem build #{gemspec_path}")

subject.build_gem(project)
end
end

describe('#artifacts') do
let(:gem_path) { File.join(project_path, 'foo-1.2.3.gem') }

it('lists the project artifacts') do
result = subject.artifacts(project)

subject.build_gem
expect(result.length).to eql(1)
expect(result.first.to_local_path).to eql(gem_path)
expect(result.first.file_extension).to eql('gem')
expect(result.first.local?).to be true
expect(result.first.uri.scheme).to eql('file')
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/lib/shanty/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ module Shanty
it('publishes the event on any listening plugins') do
allow(plugin).to receive(:subscribed?).and_return(true)

expect(plugin).to receive(:publish).with(:foo, :bar, :lux)
expect(plugin).to receive(:publish).with(:foo, subject, :bar, :lux)

subject.publish(:foo, :bar, :lux)
end
Expand All @@ -84,9 +84,9 @@ module Shanty
end
end

describe('#artifact_paths') do
it('defaults the paths to an empty array') do
expect(subject.artifact_paths).to eql([])
describe('#all_artifacts') do
it('defaults the artifacts to an empty array') do
expect(subject.all_artifacts).to eql([])
end
end

Expand Down