taketo 0.0.10 → 0.1.0

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.
Files changed (51) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +14 -30
  3. data/README.md +4 -0
  4. data/Rakefile +4 -8
  5. data/VERSION +1 -1
  6. data/bin/taketo +5 -5
  7. data/lib/taketo/config_printer_visitor.rb +6 -22
  8. data/lib/taketo/config_traverser.rb +4 -33
  9. data/lib/taketo/config_validator.rb +1 -1
  10. data/lib/taketo/config_visitor.rb +15 -1
  11. data/lib/taketo/constructs/base_construct.rb +30 -6
  12. data/lib/taketo/constructs/config.rb +5 -0
  13. data/lib/taketo/constructs/environment.rb +6 -3
  14. data/lib/taketo/constructs/project.rb +3 -3
  15. data/lib/taketo/constructs/server.rb +3 -4
  16. data/lib/taketo/constructs.rb +6 -1
  17. data/lib/taketo/destination_resolver.rb +37 -52
  18. data/lib/taketo/dsl.rb +6 -3
  19. data/lib/taketo/printer.rb +29 -0
  20. data/lib/taketo/ssh_config_generator_visitor.rb +8 -22
  21. data/spec/acceptance/command_spec.rb +20 -0
  22. data/spec/acceptance/config_dsl_spec.rb +277 -0
  23. data/spec/acceptance/config_validation_spec.rb +109 -0
  24. data/spec/acceptance/connect_to_server_spec.rb +60 -0
  25. data/spec/acceptance/error_handling_spec.rb +31 -0
  26. data/spec/acceptance/generate_ssh_config_spec.rb +44 -0
  27. data/spec/acceptance/help_spec.rb +74 -0
  28. data/spec/acceptance/location_spec.rb +21 -0
  29. data/spec/acceptance_spec_helper.rb +71 -0
  30. data/spec/lib/taketo/config_traverser_spec.rb +20 -33
  31. data/spec/lib/taketo/config_validator_spec.rb +4 -4
  32. data/spec/lib/taketo/config_visitor_spec.rb +0 -4
  33. data/spec/lib/taketo/constructs/base_construct_spec.rb +37 -5
  34. data/spec/lib/taketo/constructs/environment_spec.rb +1 -1
  35. data/spec/lib/taketo/constructs/project_spec.rb +0 -6
  36. data/spec/lib/taketo/constructs/server_spec.rb +1 -3
  37. data/spec/lib/taketo/destination_resolver_spec.rb +21 -54
  38. data/spec/lib/taketo/dsl_spec.rb +46 -44
  39. data/spec/spec_helper.rb +1 -1
  40. data/spec/support/helpers/construct_spec_helper.rb +29 -0
  41. metadata +94 -82
  42. data/features/commands.feature +0 -36
  43. data/features/config.feature +0 -177
  44. data/features/config_validation.feature +0 -43
  45. data/features/connect_to_server.feature +0 -87
  46. data/features/default_server_config.feature +0 -41
  47. data/features/error_handling.feature +0 -29
  48. data/features/generate_ssh_config.feature +0 -44
  49. data/features/help.feature +0 -76
  50. data/features/step_definitions/main_steps.rb +0 -16
  51. data/features/support/env.rb +0 -14
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source :rubygems
3
3
  group :development do
4
4
  gem "rspec", "~> 2.11"
5
5
  gem "rake", "~> 0.9"
6
- gem "aruba", "~> 0.4"
7
6
  gem 'simplecov', '~> 0.6', :require => false
7
+ gem 'open4', '~> 1.3'
8
8
  end
9
9
 
data/Gemfile.lock CHANGED
@@ -1,44 +1,28 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
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
4
  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.11.0)
25
- rspec-core (~> 2.11.0)
26
- rspec-expectations (~> 2.11.0)
27
- rspec-mocks (~> 2.11.0)
28
- rspec-core (2.11.1)
29
- rspec-expectations (2.11.3)
5
+ multi_json (1.3.7)
6
+ open4 (1.3.0)
7
+ rake (0.9.5)
8
+ rspec (2.12.0)
9
+ rspec-core (~> 2.12.0)
10
+ rspec-expectations (~> 2.12.0)
11
+ rspec-mocks (~> 2.12.0)
12
+ rspec-core (2.12.0)
13
+ rspec-expectations (2.12.0)
30
14
  diff-lcs (~> 1.1.3)
31
- rspec-mocks (2.11.3)
32
- simplecov (0.6.4)
15
+ rspec-mocks (2.12.0)
16
+ simplecov (0.7.1)
33
17
  multi_json (~> 1.0)
34
- simplecov-html (~> 0.5.3)
35
- simplecov-html (0.5.3)
18
+ simplecov-html (~> 0.7.1)
19
+ simplecov-html (0.7.1)
36
20
 
37
21
  PLATFORMS
38
22
  ruby
39
23
 
40
24
  DEPENDENCIES
41
- aruba (~> 0.4)
25
+ open4 (~> 1.3)
42
26
  rake (~> 0.9)
43
27
  rspec (~> 2.11)
44
28
  simplecov (~> 0.6)
data/README.md CHANGED
@@ -144,6 +144,10 @@ An SSH config file can be generated from taketo config. To do so, run ```taketo
144
144
  The Changelog:
145
145
  --------------
146
146
 
147
+ ### v0.1.0 (04.12.2012) ###
148
+ * Servers can now be outside projects and environments (userful for standalone servers)
149
+ * SSH config is being generated both for hostnames and global aliases
150
+
147
151
  ### v0.0.10 (17.11.2012) ###
148
152
  * Add ability to generate ssh config
149
153
 
data/Rakefile CHANGED
@@ -12,22 +12,18 @@ end
12
12
 
13
13
  require 'rake'
14
14
  require 'rspec/core/rake_task'
15
- require 'cucumber'
16
- require 'cucumber/rake/task'
17
15
 
18
16
  RSpec::Core::RakeTask.new do |t|
19
17
  t.pattern = 'spec/lib/**/*_spec.rb'
20
18
  end
21
19
 
22
- RSpec::Core::RakeTask.new do |t|
20
+ RSpec::Core::RakeTask.new(:integration_spec) do |t|
23
21
  t.pattern = 'spec/integration/**/*_spec.rb'
24
- t.name = :integration_spec
25
22
  end
26
23
 
27
- Cucumber::Rake::Task.new(:features) do |t|
28
- t.cucumber_opts = "features --tags ~@wip --format pretty -x"
29
- t.fork = false
24
+ RSpec::Core::RakeTask.new(:acceptance_spec) do |t|
25
+ t.pattern = 'spec/acceptance/**/*_spec.rb'
30
26
  end
31
27
 
32
- task :default => [:spec, :features]
28
+ task :default => [:spec, :acceptance_spec]
33
29
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.1.0
data/bin/taketo CHANGED
@@ -1,9 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- if ENV["TAKETO_DEV"]
4
- $:.unshift(File.expand_path('../../lib', __FILE__))
5
- end
6
-
7
3
  require 'rubygems'
8
4
 
9
5
  require 'taketo'
@@ -121,6 +117,10 @@ rescue SystemExit
121
117
  # Do nothing
122
118
  rescue Exception => e
123
119
  STDERR.puts "An error occurred: #{e.message}"
124
- raise if options && options[:debug]
120
+ if options && options[:debug]
121
+ STDERR.puts e.backtrace
122
+ raise
123
+ end
124
+ exit 1
125
125
  end
126
126
 
@@ -1,16 +1,14 @@
1
1
  require 'taketo/config_visitor'
2
+ require 'taketo/printer'
2
3
 
3
4
  module Taketo
4
5
  class ConfigPrinterVisitor < ConfigVisitor
5
- def initialize
6
- @indent_level = 0
7
- @result = ""
8
- end
6
+ include Printer
9
7
 
10
8
  visit Config do |config|
11
9
  indent(0) do
12
10
  if config.has_projects?
13
- put "Default destination: #{config.default_destination}" if config.default_destination
11
+ put_optional "Default destination:", config.default_destination
14
12
  else
15
13
  put "There are no projects yet..."
16
14
  end
@@ -37,9 +35,9 @@ module Taketo
37
35
  put "Server: #{server.name}"
38
36
  indent do
39
37
  put "Host: #{server.host}"
40
- put "Port: #{server.port}" if server.port
41
- put "User: #{server.username}" if server.username
42
- put "Default location: #{server.default_location}" if server.default_location
38
+ put_optional "Port:", server.port
39
+ put_optional "User:", server.username
40
+ put_optional "Default location:", server.default_location
43
41
  put "Default command: #{server.default_command}"
44
42
  put "Environment: " + server.environment_variables.map { |n, v| "#{n}=#{v}" }.join(" ")
45
43
  put "Commands:" if server.has_commands?
@@ -50,20 +48,6 @@ module Taketo
50
48
  visit Command do |command|
51
49
  indent(4) { put command.name.to_s + (" - " + command.description if command.description).to_s }
52
50
  end
53
-
54
- def result
55
- @result.chomp
56
- end
57
-
58
- def indent(level = nil)
59
- @first_indent ||= level || @indent_level
60
- level ? @indent_level = level - @first_indent : @indent_level += 1
61
- yield
62
- end
63
-
64
- def put(str = nil)
65
- @result += (" " * @indent_level + str.to_s).rstrip.chomp + "\n"
66
- end
67
51
  end
68
52
  end
69
53
 
@@ -3,53 +3,24 @@ require 'forwardable'
3
3
 
4
4
  module Taketo
5
5
  class ConfigTraverser
6
- LEVELS = { :config => 1, :project => 2, :environment => 3, :server => 4, :command => 5 }.freeze
7
- PLURALS = { :config => :configs, :project => :projects, :environment => :environments, :server => :servers, :command => :commands }.freeze
8
-
9
- class NodeWithPath < SimpleDelegator
10
- extend Forwardable
11
- def_delegators :__getobj__, :class, :ancestors, :== # avoid ancestry tree troubles
12
-
13
- attr_reader :path
14
-
15
- def initialize(node, path_string)
16
- super(node)
17
- @path = path_string.freeze
18
- end
19
- end
20
-
21
6
  def initialize(root)
22
7
  @root = root
23
8
  end
24
9
 
25
10
  def visit_depth_first(visitor)
26
- parents = []
27
- path_stack = [wrap_node_with_path(parents, @root)]
11
+ path_stack = [@root]
28
12
 
29
13
  while path_stack.any?
30
14
  node = path_stack.pop
31
15
  visitor.visit(node)
32
16
 
33
- next_level_node_type = LEVELS.respond_to?(:key) ? LEVELS.key(LEVELS[node.node_type] + 1) : LEVELS.index(LEVELS[node.node_type] + 1)
34
- if next_level_node_type && node.has_nodes?(PLURALS[next_level_node_type])
35
- parents << node
36
- node.nodes(PLURALS[next_level_node_type]).reverse_each do |n|
37
- n = wrap_node_with_path(parents, n)
38
- path_stack.push(n)
17
+ node.class.node_types.each do |node_type|
18
+ node.nodes(node_type).reverse_each do |n|
19
+ path_stack.push(n)
39
20
  end
40
21
  end
41
22
  end
42
23
  end
43
-
44
- private
45
-
46
- def wrap_node_with_path(parents, node)
47
- NodeWithPath.new(node, path(parents, node))
48
- end
49
-
50
- def path(parents, node)
51
- parents.map(&:name).reject(&:nil?).concat([node.name]).join(":")
52
- end
53
24
  end
54
25
  end
55
26
 
@@ -10,7 +10,7 @@ module Taketo
10
10
  end
11
11
 
12
12
  visit Config do |c|
13
- raise ConfigError, "There are no projects. Add some to your config (~/.taketo.rc.rb by default)" unless c.has_projects?
13
+ raise ConfigError, "There are no servers. Add some to your config (~/.taketo.rc.rb by default)" unless c.has_servers?
14
14
  end
15
15
 
16
16
  visit Project do |p|
@@ -21,8 +21,22 @@ module Taketo
21
21
  next unless respond_to?(method_name)
22
22
  return send(method_name, obj)
23
23
  end
24
+ end
25
+ end
26
+
27
+ def SimpleCollector(*types)
28
+ Class.new(ConfigVisitor) do
29
+ attr_reader :result
24
30
 
25
- raise "Don't know how to visit #{obj.class}"
31
+ def initialize
32
+ @result = []
33
+ end
34
+
35
+ types.each do |t|
36
+ visit t do |n|
37
+ @result << n
38
+ end
39
+ end
26
40
  end
27
41
  end
28
42
  end
@@ -4,14 +4,17 @@ require 'taketo/associated_nodes'
4
4
  module Taketo
5
5
  module Constructs
6
6
  class BaseConstruct
7
-
8
7
  include AssociatedNodes
9
- attr_reader :name, :default_server_config
8
+
9
+ attr_accessor :parent
10
+ attr_reader :name
11
+ attr_writer :default_server_config
10
12
 
11
13
  def initialize(name)
12
14
  super
13
15
  @name = name
14
16
  @default_server_config = proc {}
17
+ @parent = NullConstruct
15
18
  end
16
19
 
17
20
  def node_type
@@ -22,19 +25,40 @@ module Taketo
22
25
  ##
23
26
  # Override in subclasses if needed
24
27
  def parent=(parent)
25
- @default_server_config = parent.default_server_config
28
+ @parent = parent
26
29
  end
27
30
 
28
- def default_server_config=(config)
29
- default = @default_server_config
30
- @default_server_config = proc { instance_eval(&default); instance_eval(&config) }
31
+ def parents
32
+ result = []
33
+ p = parent
34
+ while p != NullConstruct
35
+ result << p
36
+ p = p.parent
37
+ end
38
+ result
39
+ end
40
+
41
+ def path
42
+ parents.reverse_each.map(&:name).concat([self.name]).reject(&:nil?).join(":")
43
+ end
44
+
45
+ def default_server_config
46
+ parent_default_server_config = parent.default_server_config
47
+ own_default_server_config = @default_server_config
48
+ proc { instance_eval(&parent_default_server_config); instance_eval(&own_default_server_config)}
31
49
  end
32
50
 
33
51
  def qualified_name
34
52
  "#{node_type} #{self.name}"
35
53
  end
54
+ end
36
55
 
56
+ class NullConstructClass
57
+ def default_server_config; proc {}; end
37
58
  end
59
+
60
+ NullConstruct = NullConstructClass.new
61
+
38
62
  end
39
63
  end
40
64
 
@@ -5,12 +5,17 @@ module Taketo
5
5
  module Constructs
6
6
  class Config < BaseConstruct
7
7
  has_nodes :projects, :project
8
+ has_nodes :servers, :server
8
9
 
9
10
  attr_accessor :default_destination
10
11
 
11
12
  def initialize(*args)
12
13
  super(nil)
13
14
  end
15
+
16
+ def has_servers?
17
+ has_nodes?(:servers) || projects.any?(&:has_servers?)
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -1,4 +1,5 @@
1
1
  require 'taketo/constructs/base_construct'
2
+ require 'taketo/constructs/project'
2
3
  require 'taketo/support'
3
4
 
4
5
  module Taketo
@@ -6,14 +7,16 @@ module Taketo
6
7
  class Environment < BaseConstruct
7
8
  has_nodes :servers, :server
8
9
 
9
- attr_accessor :project
10
-
11
10
  def initialize(name)
12
11
  super(name)
13
12
  end
14
13
 
15
14
  def project_name
16
- @project.name if defined? @project
15
+ if parent.is_a?(Project)
16
+ parent.name
17
+ else
18
+ ""
19
+ end
17
20
  end
18
21
  end
19
22
  end
@@ -5,10 +5,10 @@ module Taketo
5
5
  module Constructs
6
6
  class Project < BaseConstruct
7
7
  has_nodes :environments, :environment
8
+ has_nodes :servers, :server
8
9
 
9
- def append_environment(environment)
10
- environment.project = self
11
- super
10
+ def has_servers?
11
+ has_nodes?(:servers) || environments.any?(&:has_servers?)
12
12
  end
13
13
  end
14
14
  end
@@ -6,7 +6,7 @@ module Taketo
6
6
  module Constructs
7
7
  class Server < BaseConstruct
8
8
  attr_reader :environment_variables
9
- attr_accessor :host, :port, :username, :default_location, :default_command, :environment, :global_alias, :identity_file
9
+ attr_accessor :host, :port, :username, :default_location, :default_command, :global_alias, :identity_file
10
10
 
11
11
  has_nodes :commands, :command
12
12
 
@@ -19,10 +19,9 @@ module Taketo
19
19
  @environment_variables.merge!(env_variables)
20
20
  end
21
21
 
22
- def parent=(environment)
23
- env(:RAILS_ENV => environment.name.to_s)
24
- @environment = environment
22
+ def parent=(parent)
25
23
  super
24
+ env(:RAILS_ENV => parent.name.to_s) if parent.is_a?(Environment)
26
25
  end
27
26
 
28
27
  def default_command
@@ -3,4 +3,9 @@ module Taketo
3
3
  end
4
4
  end
5
5
 
6
- Dir.glob(File.expand_path('../constructs/*.rb', __FILE__)).each { |c| require c }
6
+ require 'taketo/constructs/base_construct'
7
+ require 'taketo/constructs/config'
8
+ require 'taketo/constructs/project'
9
+ require 'taketo/constructs/environment'
10
+ require 'taketo/constructs/server'
11
+ require 'taketo/constructs/command'
@@ -1,81 +1,66 @@
1
+ require 'taketo/config_visitor'
2
+ require 'taketo/config_traverser'
3
+
1
4
  module Taketo
2
5
  class AmbiguousDestinationError < StandardError; end
3
6
  class NonExistentDestinationError < StandardError; end
4
7
 
5
8
  class DestinationResolver
6
- class Path
7
- PATH = [[:project, :projects], [:environment, :environments], [:server, :servers]].freeze
8
-
9
- class PathNode < Struct.new(:name, :singular, :plural); end
10
-
11
- def initialize(names)
12
- names = names.split(":").map(&:to_sym)
13
- @path = PATH.each_with_index.map { |n, i| PathNode.new(names[i], *n) }
14
- end
15
-
16
- def specified
17
- @path.reject { |n| n.name.nil? }
18
- end
19
-
20
- def unspecified
21
- @path - specified
22
- end
23
- end
24
-
25
9
  def initialize(config, path)
26
10
  @config = config
27
11
  if String(path).empty? && !String(config.default_destination).empty?
28
12
  path = config.default_destination
29
13
  end
30
- @path_str = path.dup
31
- @path = Path.new(path)
14
+ @path = path
15
+ @traverser = ConfigTraverser.new(@config)
32
16
  end
33
17
 
34
- def resolve
35
- resolve_by_global_alias || resolve_by_path
36
- end
37
-
38
- def get_node(node = @config, remaining_path = @path.specified)
39
- handling_failure do
40
- return node if remaining_path.empty?
41
- next_in_path = remaining_path.shift
42
- node = node.find(next_in_path.singular, next_in_path.name)
43
- get_node(node, remaining_path)
18
+ def servers
19
+ @servers ||= begin
20
+ collector = SimpleCollector(Taketo::Constructs::Server).new
21
+ @traverser.visit_depth_first(collector)
22
+ collector.result
44
23
  end
45
24
  end
46
25
 
47
- private
26
+ def resolve
27
+ resolve_by_global_alias || resolve_by_path
28
+ end
48
29
 
49
30
  def resolve_by_global_alias
50
- aliases_and_servers = Hash[servers_with_aliases]
51
- aliases_and_servers[@path_str.to_sym] unless String(@path_str).empty?
31
+ unless @path.to_s.empty?
32
+ servers.select(&:global_alias).detect { |s| s.global_alias == @path.to_sym }
33
+ end
52
34
  end
53
35
 
54
36
  def resolve_by_path
55
- node = get_node
56
- get_only_server(node)
37
+ matching_servers = servers.select { |s| s.path =~ /^#@path/ }
38
+ disambiguate(matching_servers)
57
39
  end
58
40
 
59
- def get_only_server(node, remaining_path = @path.unspecified)
60
- return node if remaining_path.empty?
61
- next_in_path = remaining_path.shift
62
- nested_nodes = node.nodes(next_in_path.plural)
63
- if nested_nodes.one?
64
- node = nested_nodes.first
65
- get_only_server(node, remaining_path)
66
- else
67
- raise AmbiguousDestinationError, "There are multiple #{next_in_path.plural} for #{node.node_type} #{node.name}: #{nested_nodes.map(&:name).join(", ")}"
68
- end
41
+ def get_node
42
+ matching_nodes = nodes.select { |n| n.path == @path }
43
+ disambiguate(matching_nodes)
69
44
  end
70
45
 
71
- def handling_failure(message = nil)
72
- yield
73
- rescue KeyError, NonExistentDestinationError
74
- raise NonExistentDestinationError, message || $!.message
46
+ def nodes
47
+ @nodes ||= begin
48
+ collector = SimpleCollector(Taketo::Constructs::BaseConstruct).new
49
+ @traverser.visit_depth_first(collector)
50
+ collector.result
51
+ end
75
52
  end
76
53
 
77
- def servers_with_aliases
78
- @config.nodes(:projects).map { |p| p.nodes(:environments).map { |e| e.nodes(:servers).reject { |s| s.global_alias.nil? }.map { |s| [s.global_alias, s] } } }.flatten(2)
54
+ def disambiguate(results)
55
+ case results.length
56
+ when 0
57
+ raise NonExistentDestinationError, "Can't find server for path #@path"
58
+ when 1
59
+ results.first
60
+ else
61
+ raise AmbiguousDestinationError,
62
+ "There are multiple possible destinations: #{results.map(&:path).join(", ")}"
63
+ end
79
64
  end
80
65
  end
81
66
  end
data/lib/taketo/dsl.rb CHANGED
@@ -6,9 +6,12 @@ module Taketo
6
6
  class ConfigError < StandardError; end
7
7
 
8
8
  class << self
9
- def define_scope(scope, parent_scope, options = {}, &block)
9
+ def define_scope(scope, *args, &block)
10
+ options = args.last.is_a?(Hash) ? args.pop : {}
11
+ parent_scopes = args
12
+
10
13
  define_method scope do |*args, &blk|
11
- ensure_nesting_allowed!(scope, parent_scope)
14
+ ensure_nesting_allowed!(scope, parent_scopes)
12
15
  name = args.shift || options[:default_name] or raise(ArgumentError, "Name not specified")
13
16
 
14
17
  scope_object = current_scope_object.find(scope, name) { @factory.create(scope, name) }
@@ -54,7 +57,7 @@ module Taketo
54
57
  define_scope :project, :config
55
58
  define_scope :environment, :project
56
59
 
57
- define_scope :server, :environment, :default_name => :default do |s|
60
+ define_scope :server, :environment, :project, :config, :default_name => :default do |s|
58
61
  instance_eval(&s.default_server_config)
59
62
  end
60
63
 
@@ -0,0 +1,29 @@
1
+ module Taketo
2
+ module Printer
3
+ def initialize
4
+ @indent_level = 0
5
+ @print_result = ""
6
+ end
7
+
8
+ def result
9
+ @print_result.chomp
10
+ end
11
+
12
+ private
13
+
14
+ def indent(level = nil)
15
+ @first_indent ||= level || @indent_level
16
+ level ? @indent_level = level - @first_indent : @indent_level += 1
17
+ yield
18
+ end
19
+
20
+ def put(str = nil)
21
+ @print_result += (" " * @indent_level + str.to_s).rstrip.chomp + "\n"
22
+ end
23
+
24
+ def put_optional(str, value)
25
+ put "#{str} #{value}" if value
26
+ end
27
+ end
28
+ end
29
+
@@ -1,36 +1,22 @@
1
1
  require 'taketo/config_visitor'
2
+ require 'taketo/printer'
2
3
 
3
4
  module Taketo
4
5
  class SSHConfigGeneratorVisitor < ConfigVisitor
5
- def initialize
6
- @result = ""
7
- end
6
+ include Printer
8
7
 
9
8
  visit Server do |server|
10
- put "Host #{server.global_alias || server.host}"
9
+ put_server(server, server.global_alias) unless server.global_alias.to_s.empty?
10
+ put_server(server, server.host)
11
+ end
12
+
13
+ def put_server(server, host)
14
+ put "Host #{host}"
11
15
  put "Hostname #{server.host}"
12
16
  put_optional "Port", server.port
13
17
  put_optional "User", server.username
14
18
  put_optional "IdentityFile", server.identity_file
15
19
  put
16
20
  end
17
-
18
- visit Object do |_|
19
- # catch all
20
- end
21
-
22
- def result
23
- @result.chomp
24
- end
25
-
26
- private
27
-
28
- def put(str = "")
29
- @result += str + "\n"
30
- end
31
-
32
- def put_optional(str, value)
33
- put "#{str} #{value}" if value
34
- end
35
21
  end
36
22
  end