bowler 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -0
- data/Rakefile +18 -0
- data/bin/bowl +5 -0
- data/lib/bowler/cli.rb +35 -0
- data/lib/bowler/dependency_tree.rb +30 -0
- data/lib/bowler/dsl.rb +52 -0
- data/lib/bowler/version.rb +3 -0
- data/lib/bowler.rb +11 -0
- data/spec/dependency_tree_spec.rb +50 -0
- data/spec/dsl_spec.rb +71 -0
- data/spec/fixtures/dependency_tree_pinfile +5 -0
- data/spec/fixtures/dsl_invalid_pinfile +3 -0
- data/spec/fixtures/dsl_valid_pinfile +4 -0
- data/spec/helpers/definition_helper.rb +19 -0
- metadata +105 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rdoc/task"
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RDoc::Task.new do |rd|
|
8
|
+
rd.rdoc_files.include("lib/**/*.rb")
|
9
|
+
rd.rdoc_dir = "rdoc"
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Run specs"
|
13
|
+
RSpec::Core::RakeTask.new do |t|
|
14
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
15
|
+
# Put spec opts in a file named .rspec in root
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :spec
|
data/bin/bowl
ADDED
data/lib/bowler/cli.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Bowler
|
4
|
+
class CLI
|
5
|
+
|
6
|
+
def self.start(processes)
|
7
|
+
tree = Bowler::DependencyTree.load
|
8
|
+
process_list = processes.map(&:to_sym)
|
9
|
+
|
10
|
+
launch_string = tree.process_list_for(process_list)
|
11
|
+
|
12
|
+
logger.info "Starting #{tree.dependencies_for(process_list).join(', ')}.."
|
13
|
+
|
14
|
+
start_foreman_with launch_string
|
15
|
+
rescue PinfileNotFound
|
16
|
+
logger.error "Bowler could not find a Pinfile in the current directory."
|
17
|
+
rescue PinfileError => e
|
18
|
+
logger.error "Bowler could not load the Pinfile due to an error: #{e}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.logger
|
22
|
+
@logger ||= Logger.new(STDOUT)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.build_command(launch_string)
|
26
|
+
"foreman start -c #{launch_string}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def self.start_foreman_with(launch_string)
|
31
|
+
exec ( self.build_command launch_string )
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Bowler
|
2
|
+
|
3
|
+
class DependencyTree
|
4
|
+
|
5
|
+
# Load the Pinfile
|
6
|
+
def self.load(absolute_path = nil)
|
7
|
+
absolute_path ||= File.join( Dir.pwd, 'Pinfile' )
|
8
|
+
definition = DSL.evaluate(absolute_path)
|
9
|
+
self.new(definition)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(definition)
|
13
|
+
@definition = definition
|
14
|
+
end
|
15
|
+
|
16
|
+
def dependencies_for(processes)
|
17
|
+
processes.inject([]) do |array, p|
|
18
|
+
array += [ (@definition.tree[p] || []), p ].flatten
|
19
|
+
end.uniq
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_list_for(processes)
|
23
|
+
on = dependencies_for(processes)
|
24
|
+
off = @definition.processes.reject {|i| on.include? i }
|
25
|
+
|
26
|
+
[ on.map {|x| "#{x}=1" }, off.map {|x| "#{x}=0" } ].flatten.sort.join(',')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/bowler/dsl.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Bowler
|
2
|
+
class DSL
|
3
|
+
attr_reader :processes, :global_dependencies
|
4
|
+
|
5
|
+
def self.evaluate(pinfile)
|
6
|
+
dsl = new
|
7
|
+
dsl.eval_pinfile(pinfile)
|
8
|
+
dsl.to_definition
|
9
|
+
end
|
10
|
+
|
11
|
+
def eval_pinfile(pinfile)
|
12
|
+
raise PinfileNotFound unless File.exists?(pinfile)
|
13
|
+
file = File.read(pinfile)
|
14
|
+
instance_eval( file )
|
15
|
+
rescue SyntaxError => e
|
16
|
+
raise PinfileError, e
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@processes = []
|
21
|
+
@global_dependencies = []
|
22
|
+
@specified_dependencies = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def dependency(*dependencies)
|
26
|
+
@global_dependencies += [dependencies].flatten
|
27
|
+
end
|
28
|
+
|
29
|
+
def process(params)
|
30
|
+
if params.is_a? Hash
|
31
|
+
parent = params.keys.first
|
32
|
+
dependencies = [params.values.first]
|
33
|
+
|
34
|
+
@processes << { :process => parent, :dependencies => [dependencies].flatten }
|
35
|
+
@specified_dependencies += dependencies.flatten
|
36
|
+
else
|
37
|
+
@processes << { :process => params, :dependencies => [ ] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_definition
|
42
|
+
definition = {
|
43
|
+
:tree => @processes.each_with_object({}) {|p, hash|
|
44
|
+
hash[p[:process]] = (p[:dependencies] + @global_dependencies).uniq
|
45
|
+
},
|
46
|
+
:processes => (@processes.map {|x| x[:process]} + @global_dependencies + @specified_dependencies).uniq
|
47
|
+
}
|
48
|
+
OpenStruct.new(definition)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/bowler.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'bowler'
|
2
|
+
require_relative 'helpers/definition_helper'
|
3
|
+
|
4
|
+
module Bowler
|
5
|
+
|
6
|
+
describe DependencyTree do
|
7
|
+
|
8
|
+
include DefinitionHelper
|
9
|
+
|
10
|
+
context "given a Pinfile" do
|
11
|
+
it "should load a dependency tree" do
|
12
|
+
tree = DependencyTree.load File.join( File.dirname(__FILE__), 'fixtures', 'dependency_tree_pinfile' )
|
13
|
+
|
14
|
+
tree.should be_instance_of DependencyTree
|
15
|
+
tree.dependencies_for([:foo]).should =~ [:bar, :foo, :required]
|
16
|
+
tree.dependencies_for([:nyan]).should =~ [:bar, :foo, :nyan, :required]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "given an array of one process" do
|
21
|
+
before do
|
22
|
+
@tree = DependencyTree.new stub_definition
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should find the correct dependencies" do
|
26
|
+
@tree.dependencies_for([:app1]).should =~ [:app2, :app3, :app1]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should give a correct process list" do
|
30
|
+
@tree.process_list_for([:app2]).should == "a=0,app1=0,app2=1,app3=1,b=0,c=0,other=0"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "given an array of multiple processes" do
|
35
|
+
before do
|
36
|
+
@tree = DependencyTree.new stub_definition
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should find the correct dependencies" do
|
40
|
+
@tree.dependencies_for([:app1, :other]).should =~ [:app2, :app3, :app1, :a, :b, :c, :other]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should give a correct process list" do
|
44
|
+
@tree.process_list_for([:app2, :other]).should == "a=1,app1=0,app2=1,app3=1,b=1,c=1,other=1"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/spec/dsl_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'bowler'
|
2
|
+
|
3
|
+
module Bowler
|
4
|
+
|
5
|
+
describe DSL do
|
6
|
+
|
7
|
+
include DefinitionHelper
|
8
|
+
|
9
|
+
context "given a valid pinfile" do
|
10
|
+
it "should return a valid definition" do
|
11
|
+
path_to_pinfile = File.join( File.dirname(__FILE__), 'fixtures', 'dsl_valid_pinfile' )
|
12
|
+
definition = DSL.evaluate path_to_pinfile
|
13
|
+
|
14
|
+
definition.should be_instance_of OpenStruct
|
15
|
+
definition.tree.should == {
|
16
|
+
:app => [ :database, :tiles, :templates ],
|
17
|
+
:tiles => [ :database, :templates ]
|
18
|
+
}
|
19
|
+
definition.processes.should =~ [ :app, :database, :templates, :tiles ]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "given an invalid pinfile" do
|
24
|
+
it "should raise a gem-defined exception" do
|
25
|
+
path_to_pinfile = File.join( File.dirname(__FILE__), 'fixtures', 'dsl_invalid_pinfile' )
|
26
|
+
expect do
|
27
|
+
DSL.evaluate path_to_pinfile
|
28
|
+
end.to raise_error(PinfileError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "given a process" do
|
33
|
+
before do
|
34
|
+
@dsl = DSL.new
|
35
|
+
@dsl.process :test
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should update the processes list with the specified process" do
|
39
|
+
@dsl.processes.should == [{ :process => :test, :dependencies => [] }]
|
40
|
+
@dsl.to_definition.processes.should == [ :test ]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "given a process with dependencies" do
|
45
|
+
before do
|
46
|
+
@dsl = DSL.new
|
47
|
+
@dsl.process :test => [ :dependency1, :dependency2 ]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should update the processes list with all specified processes" do
|
51
|
+
@dsl.processes.should == [{ :process => :test, :dependencies => [:dependency1, :dependency2] }]
|
52
|
+
@dsl.to_definition.processes.should =~ [ :dependency1, :dependency2, :test ]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "given global dependencies" do
|
57
|
+
before do
|
58
|
+
@dsl = DSL.new
|
59
|
+
@dsl.dependency :global1, :global2
|
60
|
+
@dsl.dependency :global3
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should update the processes list with all specified processes" do
|
64
|
+
@dsl.global_dependencies.should =~ [:global1, :global2, :global3]
|
65
|
+
@dsl.to_definition.processes.should =~ [ :global1, :global2, :global3 ]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bowler
|
2
|
+
module DefinitionHelper
|
3
|
+
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
def stub_definition
|
7
|
+
OpenStruct.new ({
|
8
|
+
:processes => [ :app1, :app2, :app3, :other, :a, :b, :c ],
|
9
|
+
:tree => {
|
10
|
+
:app1 => [ :app2, :app3 ],
|
11
|
+
:app2 => [ :app3 ],
|
12
|
+
:app3 => [ ],
|
13
|
+
:other => [ :a, :b, :c ]
|
14
|
+
}
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bowler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jordan Hatch
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-16 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: foreman
|
16
|
+
requirement: &70276368515620 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70276368515620
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70276368514980 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.2.2
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70276368514980
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70276368514300 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.8.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70276368514300
|
47
|
+
description:
|
48
|
+
email:
|
49
|
+
- jordan@jordanh.net
|
50
|
+
executables:
|
51
|
+
- bowl
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- lib/bowler/cli.rb
|
56
|
+
- lib/bowler/dependency_tree.rb
|
57
|
+
- lib/bowler/dsl.rb
|
58
|
+
- lib/bowler/version.rb
|
59
|
+
- lib/bowler.rb
|
60
|
+
- README.md
|
61
|
+
- Rakefile
|
62
|
+
- spec/dependency_tree_spec.rb
|
63
|
+
- spec/dsl_spec.rb
|
64
|
+
- spec/fixtures/dependency_tree_pinfile
|
65
|
+
- spec/fixtures/dsl_invalid_pinfile
|
66
|
+
- spec/fixtures/dsl_valid_pinfile
|
67
|
+
- spec/helpers/definition_helper.rb
|
68
|
+
- bin/bowl
|
69
|
+
homepage:
|
70
|
+
licenses: []
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
hash: 1393360155367898551
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
hash: 1393360155367898551
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.12
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: A wrapper for large Foreman-managed apps with dependent processes
|
99
|
+
test_files:
|
100
|
+
- spec/dependency_tree_spec.rb
|
101
|
+
- spec/dsl_spec.rb
|
102
|
+
- spec/fixtures/dependency_tree_pinfile
|
103
|
+
- spec/fixtures/dsl_invalid_pinfile
|
104
|
+
- spec/fixtures/dsl_valid_pinfile
|
105
|
+
- spec/helpers/definition_helper.rb
|