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

Commit

Permalink
Artifact types
Browse files Browse the repository at this point in the history
- add artifact class
- modify rubygem plugin to publish artifacts for each project
  • Loading branch information
janstenpickle committed Sep 25, 2015
1 parent 654addb commit 24d5394
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 12 deletions.
44 changes: 44 additions & 0 deletions lib/shanty/artifact.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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
# the mime type is not valid
def initialize(file_extension, plugin, uri)
@file_extension = file_extension
@plugin = plugin
@uri = uri
validate_uri
end

def local?
@uri.scheme == 'file'
end

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

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 @@ -44,6 +44,10 @@ def projects
end
end

def artifacts(*)
[]
end

def with_graph(graph)
(@with_graph_callbacks || []).each { |callback| callback.call(graph) }
end
Expand Down
14 changes: 14 additions & 0 deletions lib/shanty/plugins/rubygem_plugin.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
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'
end

def artifacts(project)
Dir[File.join(project.path, '*.gemspec')].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
end
end
19 changes: 10 additions & 9 deletions lib/shanty/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Project
include Env
include ProjectDsl

attr_accessor :path, :parents_by_path, :tags
attr_accessor :artifacts, :path, :parents_by_path, :tags

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

@name = File.basename(path)
@artifacts = []
@plugins = []
@parents_by_path = []
@tags = []
Expand Down Expand Up @@ -70,6 +71,14 @@ 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 an Array of Artifacts representing published binaries
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)
Expand All @@ -78,14 +87,6 @@ def publish(name, *args)
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
40 changes: 40 additions & 0 deletions spec/lib/shanty/artifact_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'shanty/artifact'

# All classes referenced belong to the shanty project
module Shanty
RSpec.describe(Artifact) do
subject { Artifact.new('html', 'test', uri) }

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

it('works with a local file') do
expect(subject.local?).to be(true)
expect(subject.to_local_path).to eql('/nic/kim/cage.html')
end
end

describe('#noscheme') do
let(:uri) { URI('kim/cage.html') }
it('fails if there is no scheme present in the URI') do
expect { subject }.to raise_error('Scheme not present on URI')
end
end

describe('#notabsolute') do
let(:uri) { URI('file:kim/cage.html') }
it('fails if the URI is not an absolute path') do
expect { subject }.to raise_error('URI is not absolute')
end
end

describe('#remotefile') do
let(:uri) { URI('http://www.nic.com/kim/cage.html') }

it('fails when converting to a local path if the resource is not local') do
expect(subject.local?).to be(false)
expect { subject.to_local_path }.to raise_error('URI is not a local resource')
end
end
end
end
13 changes: 13 additions & 0 deletions spec/lib/shanty/plugins/rubygem_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,18 @@ module Shanty
subject.build_gem
end
end

describe('#artifacts') do
it('lists the project artifacts') do
path = File.join(File.dirname(__FILE__), '..', '..', '..', '..')
result = subject.artifacts(Project.new(path))

expect(result.length).to eql(1)
expect(File.dirname(result.first.to_local_path)).to eql(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
end
6 changes: 3 additions & 3 deletions spec/lib/shanty/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,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

0 comments on commit 24d5394

Please sign in to comment.