diff --git a/lib/shanty/discoverers/rubygem_discoverer.rb b/lib/shanty/discoverers/rubygem_discoverer.rb index dc0d8d0..cf12842 100644 --- a/lib/shanty/discoverers/rubygem_discoverer.rb +++ b/lib/shanty/discoverers/rubygem_discoverer.rb @@ -1,5 +1,5 @@ require 'shanty/discoverer' -require 'shanty/projects/rubygem_project' +require 'shanty/plugins/rubygem_plugin' module Shanty # Public: Discoverer for Shantyfiles @@ -9,7 +9,7 @@ class RubygemDiscoverer < Discoverer def discover Dir[File.join(env.root, '**', '*.gemspec')].map do |path| create_project_template(File.absolute_path(File.dirname(path))) do |project_template| - project_template.type = RubygemProject + project_template.plugin(RubygemPlugin) end end end diff --git a/lib/shanty/discoverers/shantyfile_discoverer.rb b/lib/shanty/discoverers/shantyfile_discoverer.rb index fbf143e..d0c9487 100644 --- a/lib/shanty/discoverers/shantyfile_discoverer.rb +++ b/lib/shanty/discoverers/shantyfile_discoverer.rb @@ -1,5 +1,4 @@ require 'shanty/discoverer' -require 'shanty/projects/static_project' module Shanty # Public: Discoverer for Shantyfiles diff --git a/lib/shanty/env.rb b/lib/shanty/env.rb index 3358f2e..2c7022d 100644 --- a/lib/shanty/env.rb +++ b/lib/shanty/env.rb @@ -1,4 +1,5 @@ require 'logger' +require 'pathname' require 'yaml' module Shanty diff --git a/lib/shanty/graph.rb b/lib/shanty/graph.rb index 32d63d5..92c2369 100644 --- a/lib/shanty/graph.rb +++ b/lib/shanty/graph.rb @@ -2,6 +2,8 @@ require 'forwardable' require 'tsort' +require 'shanty/project' + module Shanty # Public: Represents the link graph of projects in the repository. This class is # responsible for collecting up all the information the projects we have, @@ -46,24 +48,24 @@ def by_name(name) find { |project| project.name == name } end - # Public: Returns all projects of the given types. + # Public: Returns all projects that have the given plugin. # - # *types - One or more types to filter by. + # *plugins - One or more plugins to filter by. # # Returns an Array of Project subclasses, one for each project in the # repository. - def all_of_type(*types) - select { |project| types.include?(project.class) } + def all_with_plugin(*plugins) + reject { |project| (project.plugins & plugins).empty? } end - # Public: Returns all the changed projects of the given types. + # Public: Returns all changed projects that have the given plugin. # - # *types - One or more types to filter by. + # *plugins - One or more plugins to filter by. # # Returns an Array of Project subclasses, one for each project in the # repository. - def changed_of_type(*types) - changed.select { |project| types.include?(project.class) } + def changed_with_plugin(*plugins) + changed.reject { |project| (project.plugins & plugins).empty? } end # Public: Given a path to a file or directory (normally a path obtained @@ -107,7 +109,7 @@ def tsort_each_child(project) def projects_by_path @projects_by_path ||= Hash[@project_templates.map do |project_template| - project = project_template.type.new(@env, project_template) + project = Project.new(@env, project_template) project.setup! @project_path_trie[project.path] = project [project.path, project] diff --git a/lib/shanty/plugins/rubygem_plugin.rb b/lib/shanty/plugins/rubygem_plugin.rb new file mode 100644 index 0000000..80b6ac9 --- /dev/null +++ b/lib/shanty/plugins/rubygem_plugin.rb @@ -0,0 +1,14 @@ +require 'shanty/plugin' + +module Shanty + # Public: Rubygem plugin for buildin gems. + module RubygemPlugin + extend Plugin + + subscribe :build, :build_gem + + def build_gem + system 'gem build *.gemspec' + end + end +end diff --git a/lib/shanty/project.rb b/lib/shanty/project.rb index 1a2fd00..1130d77 100644 --- a/lib/shanty/project.rb +++ b/lib/shanty/project.rb @@ -7,7 +7,7 @@ class Project include ActsAsGraphVertex include CallMeRuby - attr_accessor :name, :path, :options, :parents_by_path, :changed + attr_accessor :name, :path, :options, :parents_by_path, :changed, :plugins alias_method :changed?, :changed # Public: Initialise the Project instance. @@ -23,13 +23,11 @@ def initialize(env, project_template) @options = project_template.options @parents_by_path = project_template.parents @changed = false + @plugins = @project_template.plugins end def setup! - @project_template.plugins.each do |plugin| - plugin.add_to_project(self) - end - + @plugins.each { |plugin| plugin.add_to_project(self) } instance_eval(&@project_template.after_create) unless @project_template.after_create.nil? end @@ -43,16 +41,16 @@ def artifact_paths # 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 ActsAsGraphNode mixin. + # parent/children attributes as defined by the ActsAsGraphVertex mixin. # # Returns a simple String representation of this instance. def to_s - "Name: #{name}, Type: #{self.class}" + name end # Public: Overriden String conversion method to return a more detailed # representation of this instance that doesn't include the cyclic - # parent/children attributes as defined by the ActsAsGraphNode mixin. + # parent/children attributes as defined by the ActsAsGraphVertex mixin. # # Returns more detailed String representation of this instance. def inspect diff --git a/lib/shanty/project_template.rb b/lib/shanty/project_template.rb index 743581b..1b04a9c 100644 --- a/lib/shanty/project_template.rb +++ b/lib/shanty/project_template.rb @@ -1,10 +1,9 @@ require 'attr_combined_accessor' -require 'shanty/projects/static_project' module Shanty # Public: Allows creation of a project using a discoverer class ProjectTemplate - attr_combined_accessor :name, :type, :priority, :plugins, :parents, :options + attr_combined_accessor :name, :priority, :plugins, :parents, :options attr_reader :env, :path def initialize(env, path) @@ -14,7 +13,6 @@ def initialize(env, path) @path = path @name = File.basename(path) - @type = StaticProject @priority = 0 @plugins = [] @parents = [] diff --git a/lib/shanty/projects/rubygem_project.rb b/lib/shanty/projects/rubygem_project.rb deleted file mode 100644 index c960b41..0000000 --- a/lib/shanty/projects/rubygem_project.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'shanty/project' - -module Shanty - # Public: Represents a projects created with the Ruby language. - class RubygemProject < Project - subscribe :build, :build_gem - - def build_gem - system 'gem build *.gemspec' - end - end -end diff --git a/lib/shanty/projects/static_project.rb b/lib/shanty/projects/static_project.rb deleted file mode 100644 index 3fd1beb..0000000 --- a/lib/shanty/projects/static_project.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'shanty/project' - -module Shanty - # Public: Base type of project, simply creates a tarball of the directory - class StaticProject < Project - subscribe :build, :tar_project - - def tar_project - system "tar -czvf #{artifact_paths.first} ." - end - - def artifact_paths - [ - File.join(@env.root, 'build', "#{@options['artifact_name'] || @name}-#{@env.build_number}.tar.gz") - ] - end - end -end diff --git a/spec/fixtures/test_unused_plugin.rb b/spec/fixtures/test_unused_plugin.rb new file mode 100644 index 0000000..0fe009e --- /dev/null +++ b/spec/fixtures/test_unused_plugin.rb @@ -0,0 +1,9 @@ +require 'shanty/plugin' + +module Shanty + # Test unused Plugin fixture, used for testing whether looking plugins up by this plugin type, given none of them + # have it included, returns nothing. + module UnusedPlugin + extend Plugin + end +end diff --git a/spec/lib/shanty/graph_spec.rb b/spec/lib/shanty/graph_spec.rb index ee54dce..524e6c0 100644 --- a/spec/lib/shanty/graph_spec.rb +++ b/spec/lib/shanty/graph_spec.rb @@ -1,7 +1,10 @@ require 'spec_helper' require 'tmpdir' require 'shanty/graph' -require 'shanty/projects/static_project' +require 'shanty/project' + +require_fixture 'test_plugin' +require_fixture 'test_unused_plugin' # Allows all classes to be refereneced without the module name module Shanty @@ -15,7 +18,7 @@ module Shanty project_templates[:shanty].parent(missing_parent) expect { subject }.to raise_error("Cannot find project at path #{File.join(root, missing_parent)}, which was "\ - 'specified as a dependency for Name: shanty, Type: Shanty::StaticProject') + 'specified as a dependency for shanty') end end @@ -57,35 +60,35 @@ module Shanty end end - describe('#all_of_type') do - it('returns an empty array when no types are given') do - expect(subject.all_of_type).to be_empty + describe('#all_with_plugin') do + it('returns an empty array when no plugins are given') do + expect(subject.all_with_plugin).to be_empty end - it('returns an empty array when no projects match the types given') do - expect(subject.all_of_type(Project)).to be_empty + it('returns an empty array when no projects match the plugins given') do + expect(subject.all_with_plugin(UnusedPlugin)).to be_empty end - it('returns the correct projects when matching types are given') do - expect(subject.all_of_type(StaticProject)).to match_array(subject) + it('returns the correct projects when matching plugins are given') do + expect(subject.all_with_plugin(TestPlugin)).to match_array(subject) end end - describe('#changed_of_type') do + describe('#changed_with_plugin') do before do subject.first.changed = true end it('returns an empty array when no types are given') do - expect(subject.changed_of_type).to be_empty + expect(subject.changed_with_plugin).to be_empty end it('returns an empty array when no projects match the types given') do - expect(subject.changed_of_type(Project)).to be_empty + expect(subject.changed_with_plugin(UnusedPlugin)).to be_empty end it('returns the correct projects when matching types are given') do - expect(subject.changed_of_type(StaticProject)).to contain_exactly(subject.first) + expect(subject.changed_with_plugin(TestPlugin)).to contain_exactly(subject.first) end end diff --git a/spec/lib/shanty/plugin_spec.rb b/spec/lib/shanty/plugin_spec.rb index 0d51983..9462bcb 100644 --- a/spec/lib/shanty/plugin_spec.rb +++ b/spec/lib/shanty/plugin_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'shanty/plugin' + require_fixture 'test_plugin' require_fixture 'test_project_with_plugin' diff --git a/spec/lib/shanty/plugins/rubygem_plugin_spec.rb b/spec/lib/shanty/plugins/rubygem_plugin_spec.rb new file mode 100644 index 0000000..0f5f745 --- /dev/null +++ b/spec/lib/shanty/plugins/rubygem_plugin_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' +require 'shanty/plugins/rubygem_plugin' + +# All classes referenced belong to the shanty project +module Shanty + RSpec.describe(RubygemPlugin) do + include_context('basics') + subject { Class.new { include RubygemPlugin }.new } + + it('subscribes to the test event') do + expect(RubygemPlugin.callbacks).to include([:build, :build_gem]) + end + + describe('#build_gem') do + it('calls gem build') do + expect(subject).to receive(:system).with('gem build *.gemspec') + + subject.build_gem + end + end + end +end diff --git a/spec/lib/shanty/project_spec.rb b/spec/lib/shanty/project_spec.rb index 73efafb..2906469 100644 --- a/spec/lib/shanty/project_spec.rb +++ b/spec/lib/shanty/project_spec.rb @@ -58,7 +58,7 @@ module Shanty describe('#to_s') do it('returns a simple string representation of the project') do - expect(subject.to_s).to eql("Name: #{project_template.name}, Type: Shanty::Project") + expect(subject.to_s).to eql(project_template.name) end end diff --git a/spec/lib/shanty/project_template_spec.rb b/spec/lib/shanty/project_template_spec.rb index b03daf4..dae778a 100644 --- a/spec/lib/shanty/project_template_spec.rb +++ b/spec/lib/shanty/project_template_spec.rb @@ -38,12 +38,6 @@ module Shanty end end - describe('#type') do - it('defaults the type to StaticProject') do - expect(subject.type).to eql(StaticProject) - end - end - describe('#priority') do it('defaults the priority to 0') do expect(subject.priority).to eql(0) diff --git a/spec/lib/shanty/projects/rubygem_project_spec.rb b/spec/lib/shanty/projects/rubygem_project_spec.rb deleted file mode 100644 index a82b483..0000000 --- a/spec/lib/shanty/projects/rubygem_project_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' -require 'shanty/projects/rubygem_project' - -# All classes referenced belong to the shanty project -module Shanty - RSpec.describe(RubygemProject) do - include_context('graph') - subject { RubygemProject.new(env, project_templates[:shanty]) } - - it('subscribes to the build event') do - expect(RubygemProject.class_callbacks).to include(build: [:build_gem]) - end - - describe('#build_gem') do - it('calls to build the gem') do - expect(subject).to receive(:system).with('gem build *.gemspec') - - subject.build_gem - end - end - end -end diff --git a/spec/lib/shanty/projects/static_project_spec.rb b/spec/lib/shanty/projects/static_project_spec.rb deleted file mode 100644 index e70c212..0000000 --- a/spec/lib/shanty/projects/static_project_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' -require 'shanty/projects/static_project' - -# All classes referenced belong to the shanty project -module Shanty - RSpec.describe(StaticProject) do - include_context('graph') - subject { StaticProject.new(env, project_template) } - - it('subscribes to the build event') do - expect(StaticProject.class_callbacks).to include(build: [:tar_project]) - end - - describe('#tar_project') do - it('gzip tars up the project') do - artifact_path = File.join(env.root, 'build', 'shanty-1.tar.gz') - expect(subject).to receive(:system).with("tar -czvf #{artifact_path} .") - - subject.tar_project - end - end - - describe('#artifact_paths') do - before do - ENV['SHANTY_BUILD_NUMBER'] = '123' - end - - after do - ENV.delete('SHANTY_BUILD_NUMBER') - end - - it('returns the correct path to the tar file') do - expected_path = File.join(env.root, 'build', 'shanty-123.tar.gz') - expect(subject.artifact_paths).to include(expected_path) - end - - it('uses the artifact_name option if set') do - expected_path = File.join(env.root, 'build', 'foo-123.tar.gz') - subject.options['artifact_name'] = 'foo' - expect(subject.artifact_paths).to include(expected_path) - end - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 738b355..f739df6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -8,6 +8,12 @@ require 'shanty/plugins/rspec_plugin' require 'shanty/plugins/rubocop_plugin' +def require_fixture(path) + require File.join(__dir__, 'fixtures', path) +end + +require_fixture 'test_plugin' + I18n.enforce_available_locales = false RSpec.configure do |config| @@ -34,13 +40,11 @@ let(:project_templates) do Hash[project_paths.map do |key, project_path| - [key, Shanty::ProjectTemplate.new(env, project_path).setup!] + pt = Shanty::ProjectTemplate.new(env, project_path) + pt.plugins << Shanty::TestPlugin + [key, pt.setup!] end] end let(:project_template) { project_templates[:shanty] } let(:graph) { Shanty::Graph.new(env, project_templates.values) } end - -def require_fixture(path) - require File.join(__dir__, 'fixtures', path) -end