taketo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +9 -0
- data/Gemfile.lock +44 -0
- data/LICENSE.txt +20 -0
- data/README.md +42 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/bin/taketo +72 -0
- data/features/connect_to_server.feature +25 -0
- data/features/step_definitions/main_steps.rb +10 -0
- data/features/support/env.rb +12 -0
- data/lib/taketo/commands/ssh_command.rb +44 -0
- data/lib/taketo/commands.rb +6 -0
- data/lib/taketo/constructs/config.rb +16 -0
- data/lib/taketo/constructs/environment.rb +18 -0
- data/lib/taketo/constructs/project.rb +17 -0
- data/lib/taketo/constructs/server.rb +13 -0
- data/lib/taketo/constructs.rb +6 -0
- data/lib/taketo/constructs_factory.rb +22 -0
- data/lib/taketo/dsl.rb +90 -0
- data/lib/taketo/support/eval_delegator.rb +25 -0
- data/lib/taketo/support.rb +7 -0
- data/lib/taketo.rb +9 -0
- data/spec/integration/dsl_integration_spec.rb +48 -0
- data/spec/lib/commands/ssh_command_spec.rb +43 -0
- data/spec/lib/constructs/config_spec.rb +17 -0
- data/spec/lib/constructs/environment_spec.rb +28 -0
- data/spec/lib/constructs/project_spec.rb +21 -0
- data/spec/lib/constructs/server_spec.rb +41 -0
- data/spec/lib/constructs_factory_spec.rb +28 -0
- data/spec/lib/dsl_spec.rb +108 -0
- data/spec/lib/support/eval_delegator_spec.rb +37 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/helpers/dsl_spec_helper.rb +59 -0
- data/spec/support/matchers/be_appropriate_construct_matcher.rb +38 -0
- data/spec/support/matchers/enclose_scope_matcher.rb +18 -0
- metadata +147 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
aruba (0.4.11)
|
5
|
+
childprocess (>= 0.2.3)
|
6
|
+
cucumber (>= 1.1.1)
|
7
|
+
ffi (>= 1.0.11)
|
8
|
+
rspec (>= 2.7.0)
|
9
|
+
builder (3.0.0)
|
10
|
+
childprocess (0.3.2)
|
11
|
+
ffi (~> 1.0.6)
|
12
|
+
cucumber (1.2.1)
|
13
|
+
builder (>= 2.1.2)
|
14
|
+
diff-lcs (>= 1.1.3)
|
15
|
+
gherkin (~> 2.11.0)
|
16
|
+
json (>= 1.4.6)
|
17
|
+
diff-lcs (1.1.3)
|
18
|
+
ffi (1.0.11)
|
19
|
+
gherkin (2.11.0)
|
20
|
+
json (>= 1.4.6)
|
21
|
+
json (1.7.3)
|
22
|
+
multi_json (1.3.6)
|
23
|
+
rake (0.9.2.2)
|
24
|
+
rspec (2.10.0)
|
25
|
+
rspec-core (~> 2.10.0)
|
26
|
+
rspec-expectations (~> 2.10.0)
|
27
|
+
rspec-mocks (~> 2.10.0)
|
28
|
+
rspec-core (2.10.1)
|
29
|
+
rspec-expectations (2.10.0)
|
30
|
+
diff-lcs (~> 1.1.3)
|
31
|
+
rspec-mocks (2.10.1)
|
32
|
+
simplecov (0.6.4)
|
33
|
+
multi_json (~> 1.0)
|
34
|
+
simplecov-html (~> 0.5.3)
|
35
|
+
simplecov-html (0.5.3)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
aruba
|
42
|
+
rake
|
43
|
+
rspec
|
44
|
+
simplecov
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Vladimir
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Take Me To
|
2
|
+
==========
|
3
|
+
|
4
|
+
[](http://travis-ci.org/v-yarotsky/taketo)
|
5
|
+
|
6
|
+
A tiny helper utility to make access to servers eaiser for different projects and environments.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
------
|
10
|
+
|
11
|
+
puts a config into ```~/.taketo.rc.rb```:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
project :my_project do
|
15
|
+
environment :staging do
|
16
|
+
server :s1 do
|
17
|
+
host "1.2.3.4"
|
18
|
+
port 10001
|
19
|
+
user "app"
|
20
|
+
localtion "/var/app"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
Then execute:
|
27
|
+
|
28
|
+
```taketo my_project staging s1 [command to execute, bash by default]```
|
29
|
+
|
30
|
+
To-Do:
|
31
|
+
------
|
32
|
+
|
33
|
+
* Add support for defaults
|
34
|
+
* Add support for generating shortcuts
|
35
|
+
|
36
|
+
The Changelog:
|
37
|
+
--------------
|
38
|
+
|
39
|
+
### v0.0.1 (13.06.2012) ###
|
40
|
+
* Initial release
|
41
|
+
* Support for simplest configs
|
42
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake'
|
14
|
+
require 'rake/testtask'
|
15
|
+
require 'cucumber'
|
16
|
+
require 'cucumber/rake/task'
|
17
|
+
|
18
|
+
Rake::TestTask.new do |t|
|
19
|
+
t.test_files = Dir.glob('spec/**/*_spec.rb')
|
20
|
+
t.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
24
|
+
t.cucumber_opts = "features --tags ~@wip --format pretty -x"
|
25
|
+
t.fork = false
|
26
|
+
end
|
27
|
+
|
28
|
+
task :default => [:test, :features]
|
29
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/taketo
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'taketo'
|
7
|
+
require 'taketo/constructs_factory'
|
8
|
+
require 'taketo/commands'
|
9
|
+
require 'optparse'
|
10
|
+
rescue LoadError => e #development
|
11
|
+
$: << File.expand_path('../../lib', __FILE__)
|
12
|
+
require 'bundler/setup'
|
13
|
+
retry
|
14
|
+
end
|
15
|
+
|
16
|
+
Signal.trap("SIGINT") do
|
17
|
+
puts "Terminating"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
include Taketo
|
22
|
+
|
23
|
+
def parse_options
|
24
|
+
options = { :config => File.join(ENV['HOME'], ".taketo.rc.rb") }
|
25
|
+
|
26
|
+
OptionParser.new do |opts|
|
27
|
+
opts.banner = <<-DESC
|
28
|
+
A tiny helper utility to make access to servers
|
29
|
+
eaiser for different projects and environments.
|
30
|
+
DESC
|
31
|
+
|
32
|
+
opts.on("-c CONFIG", "--config") do |c|
|
33
|
+
options[:config] = c
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("--dry-run") do |v|
|
37
|
+
options[:dry_run] = v
|
38
|
+
end
|
39
|
+
end.parse!
|
40
|
+
|
41
|
+
options
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_config(options)
|
45
|
+
factory = Taketo::ConstructsFactory.new
|
46
|
+
|
47
|
+
Taketo::DSL.new(factory).configure do
|
48
|
+
config_text = File.read(options[:config])
|
49
|
+
eval config_text, binding, options[:config], 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
options = parse_options
|
54
|
+
config = parse_config(options)
|
55
|
+
|
56
|
+
project, environment, server = ARGV.shift(3).map(&:to_sym)
|
57
|
+
|
58
|
+
server = begin
|
59
|
+
config.projects.fetch(project).environments.fetch(environment).servers.fetch(server)
|
60
|
+
rescue KeyError => e
|
61
|
+
raise ArgumentError, e
|
62
|
+
end
|
63
|
+
|
64
|
+
remote_command = ARGV.join(" ")
|
65
|
+
remote_command = "bash" if remote_command.empty?
|
66
|
+
command_to_execute = Commands::SSHCommand.new(server).render(remote_command)
|
67
|
+
if options[:dry_run]
|
68
|
+
puts command_to_execute
|
69
|
+
else
|
70
|
+
system command_to_execute
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature:
|
2
|
+
In order to be able to access my servers quickly
|
3
|
+
As a developer
|
4
|
+
I want to have a nifty little utility
|
5
|
+
configurable with simple DSL
|
6
|
+
|
7
|
+
Scenario: SSH to server
|
8
|
+
When I have the following config in "/tmp/taketo_test_cfg.rb"
|
9
|
+
"""
|
10
|
+
project :slots do
|
11
|
+
environment :staging do
|
12
|
+
server :s1 do
|
13
|
+
host "1.2.3.4"
|
14
|
+
user "deployer"
|
15
|
+
location "/var/apps/slots"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
"""
|
21
|
+
And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run slots staging s1`
|
22
|
+
Then the output should contain
|
23
|
+
"""
|
24
|
+
ssh -t "deployer"@"1.2.3.4" "cd '/var/apps/slots'; RAILS_ENV=staging bash"
|
25
|
+
"""
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'aruba/cucumber'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
ENV['PATH'] = "#{File.expand_path('../../../bin', __FILE__)}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
7
|
+
|
8
|
+
After do
|
9
|
+
if defined? @config_path and File.exist?(@config_path)
|
10
|
+
FileUtils.rm(@config_path)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Taketo
|
4
|
+
module Commands
|
5
|
+
class SSHCommand
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@server, :host, :port, :username, :default_location
|
9
|
+
|
10
|
+
def initialize(server, options = {})
|
11
|
+
@server = server
|
12
|
+
@environment = @server.environment
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(command = "bash")
|
16
|
+
%Q[ssh -t #{port} #{username}#{host} "#{[location, environment, command].compact.join(" ")}"].gsub(/ +/, " ")
|
17
|
+
end
|
18
|
+
|
19
|
+
def host
|
20
|
+
unless @server.host
|
21
|
+
raise ArgumentError, "host for server #{@server.name} in #{@environment.name} is not defined!"
|
22
|
+
end
|
23
|
+
%Q["#{@server.host}"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def port
|
27
|
+
%Q[-p #{@server.port}] if @server.port
|
28
|
+
end
|
29
|
+
|
30
|
+
def username
|
31
|
+
%Q["#{@server.username}"@] if @server.username
|
32
|
+
end
|
33
|
+
|
34
|
+
def location
|
35
|
+
%Q[cd '#{@server.default_location}';] if @server.default_location
|
36
|
+
end
|
37
|
+
|
38
|
+
def environment
|
39
|
+
%Q[RAILS_ENV=#{@environment.name}]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Taketo
|
2
|
+
module Constructs
|
3
|
+
class Environment
|
4
|
+
attr_reader :name, :servers
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@servers = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def append_server(server)
|
12
|
+
server.environment = self
|
13
|
+
@servers[server.name] = server
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Taketo
|
2
|
+
module Constructs
|
3
|
+
class Project
|
4
|
+
attr_reader :name, :environments
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@environments = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def append_environment(environment)
|
12
|
+
@environments[environment.name] = environment
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'taketo/constructs'
|
2
|
+
|
3
|
+
module Taketo
|
4
|
+
class ConstructsFactory
|
5
|
+
def create_config
|
6
|
+
Constructs::Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_project(*args)
|
10
|
+
Constructs::Project.new(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_environment(*args)
|
14
|
+
Constructs::Environment.new(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_server(*args)
|
18
|
+
Constructs::Server.new(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/taketo/dsl.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'taketo/support'
|
2
|
+
|
3
|
+
module Taketo
|
4
|
+
class DSL
|
5
|
+
class ScopeError < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def define_scope(scope, parent_scope)
|
9
|
+
define_method scope do |name, &block|
|
10
|
+
unless current_scope?(parent_scope)
|
11
|
+
raise ScopeError,
|
12
|
+
"#{scope} can't be defined in #{current_scope} scope"
|
13
|
+
end
|
14
|
+
scope_object = @factory.send("create_#{scope}", name)
|
15
|
+
in_scope(scope, scope_object) do
|
16
|
+
block.call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def define_attribute(name, parent_scope, &block)
|
22
|
+
define_method name do |attribute|
|
23
|
+
unless server_scope?
|
24
|
+
raise ScopeError,
|
25
|
+
"#{name} can't be defined in #{current_scope} scope"
|
26
|
+
end
|
27
|
+
instance_exec(attribute, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :current_scope_object, :config
|
33
|
+
|
34
|
+
def initialize(factory)
|
35
|
+
@factory = factory
|
36
|
+
@scope = [:config]
|
37
|
+
@config = @current_scope_object = factory.create_config
|
38
|
+
end
|
39
|
+
|
40
|
+
def configure(&block)
|
41
|
+
instance_eval(&block)
|
42
|
+
@config
|
43
|
+
end
|
44
|
+
|
45
|
+
define_scope :project, :config
|
46
|
+
define_scope :environment, :project
|
47
|
+
define_scope :server, :environment
|
48
|
+
|
49
|
+
define_attribute :host, :server do |hostname|
|
50
|
+
current_scope_object.host = hostname
|
51
|
+
end
|
52
|
+
|
53
|
+
define_attribute :port, :server do |port_number|
|
54
|
+
current_scope_object.port = port_number
|
55
|
+
end
|
56
|
+
|
57
|
+
define_attribute :user, :server do |username|
|
58
|
+
current_scope_object.username = username
|
59
|
+
end
|
60
|
+
|
61
|
+
define_attribute :location, :server do |path|
|
62
|
+
current_scope_object.default_location = path
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def current_scope
|
68
|
+
@scope.last
|
69
|
+
end
|
70
|
+
|
71
|
+
def current_scope?(scope)
|
72
|
+
current_scope == scope
|
73
|
+
end
|
74
|
+
|
75
|
+
[:config, :project, :environment, :server].each do |scope|
|
76
|
+
define_method("#{scope}_scope?") { current_scope == scope }
|
77
|
+
end
|
78
|
+
|
79
|
+
def in_scope(scope, new_scope_object)
|
80
|
+
parent_scope_object, @current_scope_object = @current_scope_object, new_scope_object
|
81
|
+
@scope << scope
|
82
|
+
yield
|
83
|
+
parent_scope_object.send("append_#{scope}", current_scope_object)
|
84
|
+
@scope.pop
|
85
|
+
@current_scope_object = parent_scope_object
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Taketo
|
2
|
+
module Support
|
3
|
+
|
4
|
+
##
|
5
|
+
# This module allows to use external
|
6
|
+
# methods in block used by instance_eval,
|
7
|
+
# that it effectively mimics real closure
|
8
|
+
#
|
9
|
+
module EvalDelegator
|
10
|
+
def evaluate(&block)
|
11
|
+
@external_self = eval "self", block.binding
|
12
|
+
self.instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(method_name, *args, &block)
|
16
|
+
if @external_self.respond_to?(method_name)
|
17
|
+
@external_self.send(method_name, *args, &block)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/taketo.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/dsl'
|
3
|
+
|
4
|
+
describe "Taketo DSL" do
|
5
|
+
it "should parse config and instantiate objects" do
|
6
|
+
factory = Taketo::ConstructsFactory.new
|
7
|
+
config = Taketo::DSL.new(factory).configure do
|
8
|
+
project :slots do
|
9
|
+
environment :staging do
|
10
|
+
server :staging do
|
11
|
+
host "127.0.0.2"
|
12
|
+
user "deployer"
|
13
|
+
location "/var/app"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
environment :production do
|
18
|
+
{
|
19
|
+
:s1 => "127.0.0.3",
|
20
|
+
:s2 => "127.0.0.4",
|
21
|
+
}.each do |server_name, host_name|
|
22
|
+
server server_name do
|
23
|
+
host host_name
|
24
|
+
location "/var/app"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
config.projects.length.should == 1
|
32
|
+
project = config.projects[:slots]
|
33
|
+
project.name.should == :slots
|
34
|
+
|
35
|
+
project.environments.length.should == 2
|
36
|
+
staging = project.environments[:staging]
|
37
|
+
|
38
|
+
staging.servers.length.should == 1
|
39
|
+
staging_server = staging.servers[:staging]
|
40
|
+
staging_server.host.should == "127.0.0.2"
|
41
|
+
staging_server.username.should == "deployer"
|
42
|
+
staging_server.default_location.should == "/var/app"
|
43
|
+
|
44
|
+
production = project.environments[:production]
|
45
|
+
production.servers.length.should == 2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/commands/ssh_command'
|
3
|
+
|
4
|
+
include Taketo::Commands
|
5
|
+
|
6
|
+
describe "SSH Command" do
|
7
|
+
let(:environment) { stub(:Environment, :name => :staging) }
|
8
|
+
let(:server) do
|
9
|
+
stub(:Server, :name => :s1,
|
10
|
+
:host => "1.2.3.4",
|
11
|
+
:port => 22,
|
12
|
+
:username => "deployer",
|
13
|
+
:default_location => "/var/app",
|
14
|
+
:environment => environment)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:ssh_command) { SSHCommand.new(server) }
|
18
|
+
|
19
|
+
it "should compose command based on provided server object" do
|
20
|
+
ssh_command.render("bash").should == %q[ssh -t -p 22 "deployer"@"1.2.3.4" "cd '/var/app'; RAILS_ENV=staging bash"]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should ignore absent parts" do
|
24
|
+
server.stub(:port => nil)
|
25
|
+
server.stub(:username => nil)
|
26
|
+
ssh_command.render("bash").should == %q[ssh -t "1.2.3.4" "cd '/var/app'; RAILS_ENV=staging bash"]
|
27
|
+
|
28
|
+
server.stub(:default_location => nil)
|
29
|
+
ssh_command.render("bash").should == %q[ssh -t "1.2.3.4" "RAILS_ENV=staging bash"]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should require host" do
|
33
|
+
server.stub(:host => nil)
|
34
|
+
expect do
|
35
|
+
ssh_command.render("bash")
|
36
|
+
end.to raise_error ArgumentError, /host/
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have 'bash' as command default" do
|
40
|
+
ssh_command.render.should =~ /bash/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/constructs/config'
|
3
|
+
|
4
|
+
include Taketo
|
5
|
+
|
6
|
+
describe "Config" do
|
7
|
+
let(:config) { Taketo::Constructs::Config.new }
|
8
|
+
|
9
|
+
describe "#append_project" do
|
10
|
+
it "should add project to config's projects collection" do
|
11
|
+
project = stub(:name => :foo)
|
12
|
+
config.append_project(project)
|
13
|
+
config.projects[:foo].should == project
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/constructs/environment'
|
3
|
+
|
4
|
+
include Taketo
|
5
|
+
|
6
|
+
describe "Environment" do
|
7
|
+
let(:environment) { Taketo::Constructs::Environment.new(:foo) }
|
8
|
+
|
9
|
+
it "should have name" do
|
10
|
+
environment.name.should == :foo
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#append_server" do
|
14
|
+
let(:server) { mock(:Server, :name => :foo).as_null_object }
|
15
|
+
|
16
|
+
it "should add a server to environment's servers collection" do
|
17
|
+
environment.append_server(server)
|
18
|
+
environment.servers[:foo].should == server
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set environment attribute on a server to self" do
|
22
|
+
server.should_receive(:environment=).with(environment)
|
23
|
+
environment.append_server(server)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/constructs/project'
|
3
|
+
|
4
|
+
include Taketo
|
5
|
+
|
6
|
+
describe "Project" do
|
7
|
+
let(:project) { Taketo::Constructs::Project.new(:foo) }
|
8
|
+
|
9
|
+
it "should have name" do
|
10
|
+
project.name.should == :foo
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#append_environment" do
|
14
|
+
it "should add an environment to project's environments collection" do
|
15
|
+
environment = stub(:name => :foo)
|
16
|
+
project.append_environment(environment)
|
17
|
+
project.environments[:foo].should == environment
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/constructs/server'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
include Taketo
|
6
|
+
|
7
|
+
describe "Server" do
|
8
|
+
let(:server) { Taketo::Constructs::Server.new(:foo) }
|
9
|
+
|
10
|
+
it "should have name" do
|
11
|
+
server.name.should == :foo
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should set host" do
|
15
|
+
server.host = "foo"
|
16
|
+
server.host.should == "foo"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set port" do
|
20
|
+
server.port = "foo"
|
21
|
+
server.port.should == "foo"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set username" do
|
25
|
+
server.username = "foo"
|
26
|
+
server.username.should == "foo"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set default_location" do
|
30
|
+
server.default_location = "foo"
|
31
|
+
server.default_location.should == "foo"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set environment" do
|
35
|
+
environment = stub(:Environment)
|
36
|
+
server.environment = environment
|
37
|
+
server.environment.should == environment
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/constructs_factory'
|
3
|
+
|
4
|
+
include Taketo
|
5
|
+
|
6
|
+
describe "ConstructsFactory" do
|
7
|
+
let(:factory) { Taketo::ConstructsFactory.new }
|
8
|
+
|
9
|
+
specify "#create_config should create a config object" do
|
10
|
+
factory.create_config.should be_an_instance_of(Taketo::Constructs::Config)
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "#create_project should create a project object" do
|
14
|
+
project = factory.create_project(:foo)
|
15
|
+
project.should be_an_instance_of(Taketo::Constructs::Project)
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "#create_environment should create an environment object" do
|
19
|
+
environment = factory.create_environment(:foo)
|
20
|
+
environment.should be_an_instance_of(Taketo::Constructs::Environment)
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "#create_server should create a server object" do
|
24
|
+
server = factory.create_server(:foo)
|
25
|
+
server.should be_an_instance_of(Taketo::Constructs::Server)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'support/helpers/dsl_spec_helper'
|
3
|
+
require 'taketo/dsl'
|
4
|
+
|
5
|
+
include Taketo
|
6
|
+
|
7
|
+
describe "DSL" do
|
8
|
+
extend DSLSpec
|
9
|
+
include DSLSpec
|
10
|
+
|
11
|
+
shared_examples "a scope" do |scope_name, parent_scope_name|
|
12
|
+
parent_scope = scopes[parent_scope_name]
|
13
|
+
|
14
|
+
it { should enclose_scope(scope_name).under(parent_scope) }
|
15
|
+
it { should be_appropriate_construct(scope_name, :foo).under(parent_scope) }
|
16
|
+
|
17
|
+
scopes.except(parent_scope_name).each do |inappropriate_scope|
|
18
|
+
it { should_not be_appropriate_construct(scope_name, :foo).under(inappropriate_scope) }
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should create a #{scope_name} and set it as current scope object" do
|
22
|
+
factory.should_receive("create_#{scope_name}").with(:bar)
|
23
|
+
dsl(parent_scope, factory.send("create_#{parent_scope_name}")) do |c|
|
24
|
+
c.send(scope_name, :bar) do
|
25
|
+
c.current_scope_object.should == factory.send(scope_name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not leak #{scope_name} as current scope object" do
|
31
|
+
dsl(parent_scope, factory.send("create_#{parent_scope_name}")) do |c|
|
32
|
+
c.send(scope_name, :bar) {}
|
33
|
+
c.current_scope_object.should_not == factory.send(scope_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should add a #{scope_name} to the #{parent_scope_name}'s #{scope_name}s collection" do
|
38
|
+
dsl(parent_scope, factory.send("create_#{parent_scope_name}")) do |c|
|
39
|
+
c.current_scope_object.should_receive("append_#{scope_name}").with(factory.send("create_#{scope_name}", :bar))
|
40
|
+
c.send(scope_name, :bar) {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
shared_examples "an attribute" do |attribute_name, parent_scope_name, parent_scope_method, example_value|
|
46
|
+
parent_scope = scopes[parent_scope_name]
|
47
|
+
|
48
|
+
it { should be_appropriate_construct(attribute_name, example_value).under(parent_scope) }
|
49
|
+
|
50
|
+
scopes.except(parent_scope_name).each do |inaproppriate_scope|
|
51
|
+
it { should_not be_appropriate_construct(attribute_name, example_value).under(inaproppriate_scope) }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should set #{parent_scope_method.to_s.gsub('=', '')} attribute on current server" do
|
55
|
+
dsl(parent_scope, factory.send("create_#{parent_scope_name}", :foo)) do |c|
|
56
|
+
factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value)
|
57
|
+
c.send(attribute_name, example_value)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#project" do
|
63
|
+
it_behaves_like "a scope", :project, :config
|
64
|
+
|
65
|
+
describe "#environment" do
|
66
|
+
it_behaves_like "a scope", :environment, :project
|
67
|
+
|
68
|
+
describe "#server" do
|
69
|
+
it_behaves_like "a scope", :server, :environment
|
70
|
+
|
71
|
+
describe "#host" do
|
72
|
+
it_behaves_like "an attribute", :host, :server, :host=, "127.0.0.2"
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#port" do
|
76
|
+
it_behaves_like "an attribute", :port, :server, :port=, 4096
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#user" do
|
80
|
+
it_behaves_like "an attribute", :user, :server, :username=, "deployer"
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#location" do
|
84
|
+
it_behaves_like "an attribute", :location, :server, :default_location=, "/var/app/"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#current_scope_object" do
|
91
|
+
it "should be config initially" do
|
92
|
+
dsl do |c|
|
93
|
+
c.current_scope_object.should == factory.config
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should correspond to current scope" do
|
98
|
+
dsl(:project, factory.create_project(:foo)) do |c|
|
99
|
+
c.current_scope_object.should == factory.project
|
100
|
+
end
|
101
|
+
|
102
|
+
dsl(:server, factory.create_server(:foo)) do |c|
|
103
|
+
c.current_scope_object.should == factory.server
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require 'taketo/support/eval_delegator'
|
3
|
+
|
4
|
+
class EvalDelegatorContext
|
5
|
+
include Taketo::Support::EvalDelegator
|
6
|
+
|
7
|
+
def foo
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Taketo::Support::EvalDelegator do
|
12
|
+
describe "#evaluate" do
|
13
|
+
it "should execute methods on context if it responds" do
|
14
|
+
expect do
|
15
|
+
EvalDelegatorContext.new.evaluate { foo }
|
16
|
+
end.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should delegate unknown methods to calling context" do
|
20
|
+
class << self
|
21
|
+
define_method(:bar) {}
|
22
|
+
end
|
23
|
+
|
24
|
+
expect do
|
25
|
+
EvalDelegatorContext.new.evaluate { bar }
|
26
|
+
end.not_to raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should pass local variables through the scopes" do
|
30
|
+
baz = :foo
|
31
|
+
expect do
|
32
|
+
EvalDelegatorContext.new.evaluate { baz }
|
33
|
+
end.not_to raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
if ENV['COVERAGE']
|
5
|
+
require 'simplecov'
|
6
|
+
SimpleCov.start
|
7
|
+
end
|
8
|
+
|
9
|
+
$: << File.expand_path('../../lib', __FILE__)
|
10
|
+
|
11
|
+
require 'rspec'
|
12
|
+
require 'rspec/autorun'
|
13
|
+
|
14
|
+
require 'taketo/dsl'
|
15
|
+
|
16
|
+
Dir[File.dirname(__FILE__) + "/support/matchers/*.rb"].each {|f| require f}
|
17
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module DSLSpec
|
2
|
+
class TestConstructsFactory
|
3
|
+
attr_reader :config, :project, :environment, :server
|
4
|
+
|
5
|
+
def create_config
|
6
|
+
@config ||= RSpec::Mocks::Mock.new(:Config).as_null_object
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_project(name = :foo)
|
10
|
+
@project ||= RSpec::Mocks::Mock.new(:Project, :name => name).as_null_object
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_environment(name = :foo)
|
14
|
+
@environment ||= RSpec::Mocks::Mock.new(:Environment, :name => name).as_null_object
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_server(name = :foo)
|
18
|
+
@server ||= RSpec::Mocks::Mock.new(:Server, :name => name).as_null_object
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def factory
|
23
|
+
@factory ||= TestConstructsFactory.new
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
config.after(:each) do
|
28
|
+
@factory = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def dsl(scope = [:config], scope_object = nil)
|
33
|
+
context = DSL.new(factory)
|
34
|
+
|
35
|
+
def context.set_scope(s, obj)
|
36
|
+
@scope = s
|
37
|
+
@current_scope_object = obj
|
38
|
+
end
|
39
|
+
|
40
|
+
context.set_scope(scope, scope_object || factory.create_config)
|
41
|
+
|
42
|
+
yield context
|
43
|
+
end
|
44
|
+
|
45
|
+
def scopes
|
46
|
+
scopes_hash = {
|
47
|
+
:config => [:config],
|
48
|
+
:project => [:config, :project],
|
49
|
+
:environment => [:config, :project, :environment],
|
50
|
+
:server => [:config, :project, :environment, :server]
|
51
|
+
}
|
52
|
+
|
53
|
+
def scopes_hash.except(*keys)
|
54
|
+
self.values_at(*(self.keys - keys))
|
55
|
+
end
|
56
|
+
|
57
|
+
scopes_hash
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'taketo/dsl'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :be_appropriate_construct do |construct, *args|
|
4
|
+
chain(:under) do |enclosing_scope|
|
5
|
+
@enclosing_scope = enclosing_scope
|
6
|
+
end
|
7
|
+
|
8
|
+
match do |actual|
|
9
|
+
unless @enclosing_scope
|
10
|
+
raise ArgumentError, "#under must be called to set enclosing scope"
|
11
|
+
end
|
12
|
+
|
13
|
+
@result = true
|
14
|
+
dsl(@enclosing_scope) do |c|
|
15
|
+
begin
|
16
|
+
c.send(construct, *args) {}
|
17
|
+
rescue Taketo::DSL::ScopeError => e
|
18
|
+
@result = false
|
19
|
+
rescue
|
20
|
+
#nothing
|
21
|
+
end
|
22
|
+
end
|
23
|
+
@result
|
24
|
+
end
|
25
|
+
|
26
|
+
description do
|
27
|
+
"#{name_to_sentence} ##{construct}(#{args.join(", ")}) under #{@enclosing_scope.inspect}"
|
28
|
+
end
|
29
|
+
|
30
|
+
failure_message_for_should do |actual|
|
31
|
+
"expected construct #{construct} to be appropriate under #{@enclosing_scope.inspect} scope"
|
32
|
+
end
|
33
|
+
|
34
|
+
failure_message_for_should_not do |actual|
|
35
|
+
"expected construct #{construct} not to be appropriate under #{@enclosing_scope.inspect} scope"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec::Matchers.define :enclose_scope do |expected_scope|
|
2
|
+
chain(:under) do |scope|
|
3
|
+
@external_scope = scope
|
4
|
+
end
|
5
|
+
|
6
|
+
match do |actual|
|
7
|
+
@result = true
|
8
|
+
dsl(@external_scope || [:config]) do |c|
|
9
|
+
@result &= !c.send(:current_scope?, expected_scope)
|
10
|
+
c.send(expected_scope, :foo) do
|
11
|
+
@result &= c.send(:current_scope?, expected_scope)
|
12
|
+
end
|
13
|
+
@result &= !c.send(:current_scope?, expected_scope)
|
14
|
+
end
|
15
|
+
@result
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: taketo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vladimir Yarotsky
|
9
|
+
- Maksim Yermalovich
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-06-13 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.10'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '2.10'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rake
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0.9'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.9'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: aruba
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.4'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.4'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: simplecov
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0.6'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0.6'
|
79
|
+
description:
|
80
|
+
email: vladimir.yarotksy@gmail.com
|
81
|
+
executables:
|
82
|
+
- taketo
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- bin/taketo
|
87
|
+
- lib/taketo/commands/ssh_command.rb
|
88
|
+
- lib/taketo/commands.rb
|
89
|
+
- lib/taketo/constructs/config.rb
|
90
|
+
- lib/taketo/constructs/environment.rb
|
91
|
+
- lib/taketo/constructs/project.rb
|
92
|
+
- lib/taketo/constructs/server.rb
|
93
|
+
- lib/taketo/constructs.rb
|
94
|
+
- lib/taketo/constructs_factory.rb
|
95
|
+
- lib/taketo/dsl.rb
|
96
|
+
- lib/taketo/support/eval_delegator.rb
|
97
|
+
- lib/taketo/support.rb
|
98
|
+
- lib/taketo.rb
|
99
|
+
- spec/integration/dsl_integration_spec.rb
|
100
|
+
- spec/lib/commands/ssh_command_spec.rb
|
101
|
+
- spec/lib/constructs/config_spec.rb
|
102
|
+
- spec/lib/constructs/environment_spec.rb
|
103
|
+
- spec/lib/constructs/project_spec.rb
|
104
|
+
- spec/lib/constructs/server_spec.rb
|
105
|
+
- spec/lib/constructs_factory_spec.rb
|
106
|
+
- spec/lib/dsl_spec.rb
|
107
|
+
- spec/lib/support/eval_delegator_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
- spec/support/helpers/dsl_spec_helper.rb
|
110
|
+
- spec/support/matchers/be_appropriate_construct_matcher.rb
|
111
|
+
- spec/support/matchers/enclose_scope_matcher.rb
|
112
|
+
- features/connect_to_server.feature
|
113
|
+
- features/step_definitions/main_steps.rb
|
114
|
+
- features/support/env.rb
|
115
|
+
- Gemfile
|
116
|
+
- Gemfile.lock
|
117
|
+
- Rakefile
|
118
|
+
- LICENSE.txt
|
119
|
+
- README.md
|
120
|
+
- VERSION
|
121
|
+
homepage: http://github.com/v-yarotsky/taketo
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 1.3.6
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.8.21
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: A tiny helper utility to make access to servers eaiser for different projects
|
146
|
+
and environments
|
147
|
+
test_files: []
|