Skip to content

Commit fe8f48a

Browse files
initial implementation of DSL
1 parent f29871c commit fe8f48a

19 files changed

+540
-36
lines changed

lib/ferry/configuration.rb

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,142 @@
1-
configuration.rb
1+
require_relative 'configuration/filter'
2+
require_relative 'configuration/question'
3+
require_relative 'configuration/server'
4+
require_relative 'configuration/servers'
5+
6+
module Ferry
7+
class Configuration
8+
9+
def initialize(config = nil)
10+
@config ||= config
11+
end
12+
13+
def self.env
14+
@env ||= new
15+
end
16+
17+
def self.reset!
18+
@env = new
19+
end
20+
21+
def ask(key, default=nil, options={})
22+
question = Question.new(key, default, options)
23+
set(key, question)
24+
end
25+
26+
def set(key, value)
27+
config[key] = value
28+
end
29+
30+
def set_if_empty(key, value)
31+
config[key] = value unless config.has_key? key
32+
end
33+
34+
def delete(key)
35+
config.delete(key)
36+
end
37+
38+
def fetch(key, default=nil, &block)
39+
value = fetch_for(key, default, &block)
40+
while callable_without_parameters?(value)
41+
value = set(key, value.call)
42+
end
43+
return value
44+
end
45+
46+
def keys
47+
config.keys
48+
end
49+
50+
def role(name, hosts, options={})
51+
if name == :all
52+
raise ArgumentError.new("#{name} reserved name for role. Please choose another name")
53+
end
54+
55+
servers.add_role(name, hosts, options)
56+
end
57+
58+
def server(name, properties={})
59+
servers.add_host(name, properties)
60+
end
61+
62+
def roles_for(names)
63+
servers.roles_for(names)
64+
end
65+
66+
def role_properties_for(names, &block)
67+
servers.role_properties_for(names, &block)
68+
end
69+
70+
def primary(role)
71+
servers.fetch_primary(role)
72+
end
73+
74+
def backend
75+
@backend ||= SSHKit
76+
end
77+
78+
attr_writer :backend
79+
80+
def configure_backend
81+
backend.configure do |sshkit|
82+
sshkit.format = fetch(:format)
83+
sshkit.output_verbosity = fetch(:log_level)
84+
sshkit.default_env = fetch(:default_env)
85+
sshkit.backend = fetch(:sshkit_backend, SSHKit::Backend::Netssh)
86+
sshkit.backend.configure do |backend|
87+
backend.pty = fetch(:pty)
88+
backend.connection_timeout = fetch(:connection_timeout)
89+
backend.ssh_options = (backend.ssh_options || {}).merge(fetch(:ssh_options,{}))
90+
end
91+
end
92+
end
93+
94+
def timestamp
95+
@timestamp ||= Time.now.utc
96+
end
97+
98+
def setup_filters
99+
@filters = cmdline_filters.clone
100+
@filters << Filter.new(:role, ENV['ROLES']) if ENV['ROLES']
101+
@filters << Filter.new(:host, ENV['HOSTS']) if ENV['HOSTS']
102+
fh = fetch_for(:filter,{}) || {}
103+
@filters << Filter.new(:host, fh[:host]) if fh[:host]
104+
@filters << Filter.new(:role, fh[:role]) if fh[:role]
105+
end
106+
107+
def add_cmdline_filter(type, values)
108+
cmdline_filters << Filter.new(type, values)
109+
end
110+
111+
def filter list
112+
setup_filters if @filters.nil?
113+
@filters.reduce(list) { |l,f| f.filter l }
114+
end
115+
116+
private
117+
118+
def cmdline_filters
119+
@cmdline_filters ||= []
120+
end
121+
122+
def servers
123+
@servers ||= Servers.new
124+
end
125+
126+
def config
127+
@config ||= Hash.new
128+
end
129+
130+
def fetch_for(key, default, &block)
131+
if block_given?
132+
config.fetch(key, &block)
133+
else
134+
config.fetch(key, default)
135+
end
136+
end
137+
138+
def callable_without_parameters?(x)
139+
x.respond_to?(:call) && ( !x.respond_to?(:arity) || x.arity == 0)
140+
end
141+
end
142+
end

lib/ferry/defaults.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# options for user to set in the deploy.rb
2+
# still not sure what we can put here ...
3+
# see deploy_ferry.rb.erb for ideas

lib/ferry/deploy.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
deploy.rb
1+
require 'ferry/framework'
2+
3+
load File.expand_path("../tasks/deploy.rake", __FILE__)

lib/ferry/dotfile.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
dotfile.rb
1+
dotfile = Pathname.new(File.join(Dir.home, '.ferryfile'))
2+
load dotfile if dotfile.file?

lib/ferry/dsl.rb

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,64 @@
1-
dsl.rb
1+
require 'etc'
2+
require 'ferry/dsl/task_enhancements'
3+
require 'ferry/dsl/paths'
4+
require 'ferry/dsl/stages'
5+
require 'ferry/dsl/env'
6+
require 'ferry/configuration/filter'
7+
8+
module Ferry
9+
module DSL
10+
include TaskEnhancements
11+
include Env
12+
include Paths
13+
include Stages
14+
15+
def invoke(task, *args)
16+
Rake::Task[task].invoke(*args)
17+
end
18+
19+
def t(key, options={})
20+
I18n.t(key, options.merge(scope: :ferry))
21+
end
22+
23+
def scm
24+
fetch(:scm)
25+
end
26+
27+
def sudo(*args)
28+
execute :sudo, *args
29+
end
30+
31+
def revision_log_message
32+
fetch(:revision_log_message,
33+
t(:revision_log_message,
34+
branch: fetch(:branch),
35+
user: local_user,
36+
sha: fetch(:current_revision),
37+
release: fetch(:release_timestamp))
38+
)
39+
end
40+
41+
def rollback_log_message
42+
t(:rollback_log_message, user: local_user, release: fetch(:rollback_timestamp))
43+
end
44+
45+
def local_user
46+
fetch(:local_user)
47+
end
48+
49+
def lock(locked_version)
50+
VersionValidator.new(locked_version).verify
51+
end
52+
53+
def on(hosts, options={}, &block)
54+
subset_copy = Marshal.dump(Configuration.env.filter(hosts))
55+
SSHKit::Coordinator.new(Marshal.load(subset_copy)).each(options, &block)
56+
end
57+
58+
def run_locally(&block)
59+
SSHKit::Backend::Local.new(&block).run
60+
end
61+
62+
end
63+
end
64+
self.extend Ferry::DSL

lib/ferry/dsl/env.rb

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,81 @@
1-
env.rb
1+
module Ferry
2+
module DSL
3+
module Env
4+
5+
def configure_backend
6+
env.configure_backend
7+
end
8+
9+
def fetch(key, default=nil, &block)
10+
env.fetch(key, default, &block)
11+
end
12+
13+
def any?(key)
14+
value = fetch(key)
15+
if value && value.respond_to?(:any?)
16+
value.any?
17+
else
18+
!fetch(key).nil?
19+
end
20+
end
21+
22+
def set(key, value)
23+
env.set(key, value)
24+
end
25+
26+
def set_if_empty(key, value)
27+
env.set_if_empty(key, value)
28+
end
29+
30+
def delete(key)
31+
env.delete(key)
32+
end
33+
34+
def ask(key, value, options={})
35+
env.ask(key, value, options)
36+
end
37+
38+
def role(name, servers, options={})
39+
env.role(name, servers, options)
40+
end
41+
42+
def server(name, properties={})
43+
env.server(name, properties)
44+
end
45+
46+
def roles(*names)
47+
env.roles_for(names.flatten)
48+
end
49+
50+
def role_properties(*names, &block)
51+
env.role_properties_for(names, &block)
52+
end
53+
54+
def release_roles(*names)
55+
if names.last.is_a? Hash
56+
names.last.merge!({ :exclude => :no_release })
57+
else
58+
names << { exclude: :no_release }
59+
end
60+
roles(*names)
61+
end
62+
63+
def primary(role)
64+
env.primary(role)
65+
end
66+
67+
def env
68+
Configuration.env
69+
end
70+
71+
def release_timestamp
72+
env.timestamp.strftime("%Y%m%d%H%M%S")
73+
end
74+
75+
def asset_timestamp
76+
env.timestamp.strftime("%Y%m%d%H%M.%S")
77+
end
78+
79+
end
80+
end
81+
end

0 commit comments

Comments
 (0)