skytap-yf 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/Gemfile +4 -0
- data/README.md +0 -0
- data/README.rdoc +6 -0
- data/api_schema.yaml +1016 -0
- data/bin/skytap +4 -0
- data/ca-bundle.crt +3721 -0
- data/data/.DS_Store +0 -0
- data/lib/skytap/api_schema.rb +11 -0
- data/lib/skytap/command_line.rb +145 -0
- data/lib/skytap/commands/base.rb +294 -0
- data/lib/skytap/commands/help.rb +82 -0
- data/lib/skytap/commands/http.rb +196 -0
- data/lib/skytap/commands/root.rb +79 -0
- data/lib/skytap/commands.rb +9 -0
- data/lib/skytap/core_ext.rb +8 -0
- data/lib/skytap/error.rb +4 -0
- data/lib/skytap/help_templates/help.erb +52 -0
- data/lib/skytap/ip_address.rb +63 -0
- data/lib/skytap/logger.rb +52 -0
- data/lib/skytap/plugins/vm_copy_to_region.rb +200 -0
- data/lib/skytap/plugins/vm_download.rb +431 -0
- data/lib/skytap/plugins/vm_upload.rb +401 -0
- data/lib/skytap/requester.rb +134 -0
- data/lib/skytap/response.rb +61 -0
- data/lib/skytap/skytaprc.rb +28 -0
- data/lib/skytap/subnet.rb +92 -0
- data/lib/skytap/templates.rb +216 -0
- data/lib/skytap/version.rb +5 -0
- data/lib/skytap.rb +149 -0
- data/skytap.gemspec +25 -0
- data/skytap.rdoc +5 -0
- metadata +143 -0
@@ -0,0 +1,216 @@
|
|
1
|
+
#TODO:NLA Move this monkey patch elsewhere.
|
2
|
+
module Terminal
|
3
|
+
class Table
|
4
|
+
def additional_column_widths
|
5
|
+
return [] if style.width.nil?
|
6
|
+
spacing = style.width - columns_width
|
7
|
+
if spacing < 0
|
8
|
+
# SKYTAP: Modify this line not to raise an execption.
|
9
|
+
return []
|
10
|
+
else
|
11
|
+
per_col = spacing / number_of_columns
|
12
|
+
arr = (1...number_of_columns).to_a.map { |i| per_col }
|
13
|
+
other_cols = arr.inject(0) { |s, i| s + i }
|
14
|
+
arr << spacing - other_cols
|
15
|
+
arr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Skytap
|
22
|
+
module Templates
|
23
|
+
class Base < OpenStruct
|
24
|
+
|
25
|
+
# The template can refer to hash keys as if they were local variables.
|
26
|
+
def self.render(hash)
|
27
|
+
attrs = {'description' => 'DEFAULT DESCRIPTION HERE'}.merge(hash)
|
28
|
+
new(attrs).render
|
29
|
+
end
|
30
|
+
|
31
|
+
def template_str
|
32
|
+
raise 'must be overridden'
|
33
|
+
end
|
34
|
+
|
35
|
+
def render
|
36
|
+
# Allow -%> to trim surrounding whitespace in ERB.
|
37
|
+
trim_mode_char = '-'
|
38
|
+
ERB.new(template_str, nil, trim_mode_char).result(binding)
|
39
|
+
end
|
40
|
+
|
41
|
+
def indent(msg='', width=5)
|
42
|
+
msg ||= ''
|
43
|
+
msg.split("\n").collect do |line|
|
44
|
+
(' ' * width) << line
|
45
|
+
end.join("\n")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Help < Base
|
50
|
+
TEMPLATE = File.expand_path(File.join(File.dirname(__FILE__), 'help_templates', 'help.erb'))
|
51
|
+
|
52
|
+
def self.render(command)
|
53
|
+
new('command' => command).render
|
54
|
+
end
|
55
|
+
|
56
|
+
def template_str
|
57
|
+
File.open(TEMPLATE, &:read)
|
58
|
+
end
|
59
|
+
|
60
|
+
def header(name)
|
61
|
+
name.bright
|
62
|
+
end
|
63
|
+
|
64
|
+
def error_msg
|
65
|
+
if command.error
|
66
|
+
"Error: ".color(:red).bright << command.error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def subcommands
|
71
|
+
@subcommands ||= command.class.subcommand_banners
|
72
|
+
end
|
73
|
+
|
74
|
+
#TODO:NLA These two methods are from
|
75
|
+
#https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb#L61-71,
|
76
|
+
#which is under the MIT license. Figure out how to cite it properly.
|
77
|
+
def detect_terminal_size
|
78
|
+
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
|
79
|
+
[ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
80
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput')
|
81
|
+
[`tput cols`.to_i, `tput lines`.to_i]
|
82
|
+
elsif STDIN.tty? && command_exists?('stty')
|
83
|
+
`stty size`.scan(/\d+/).map { |s| s.to_i }.reverse
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
rescue
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
# Determines if a shell command exists by searching for it in ENV['PATH'].
|
91
|
+
def command_exists?(command)
|
92
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
|
93
|
+
end
|
94
|
+
|
95
|
+
def hard_wrap(text, line_width)
|
96
|
+
breaking_word_wrap(text, :line_width => line_width)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Taken from http://apidock.com/rails/ActionView/Helpers/TextHelper/word_wrap#1023-word-wrap-with-breaking-long-words
|
100
|
+
def breaking_word_wrap(text, *args)
|
101
|
+
options = args.extract_options!
|
102
|
+
unless args.blank?
|
103
|
+
options[:line_width] = args[0] || 80
|
104
|
+
end
|
105
|
+
options.reverse_merge!(:line_width => 80)
|
106
|
+
text = text.split(" ").collect do |word|
|
107
|
+
word.length > options[:line_width] ? word.gsub(/(.{1,#{options[:line_width]}})/, "\\1 ") : word
|
108
|
+
end * " "
|
109
|
+
text.split("\n").collect do |line|
|
110
|
+
line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
|
111
|
+
end * "\n"
|
112
|
+
end
|
113
|
+
|
114
|
+
def global_options_table
|
115
|
+
min_width, max_width = 70, 120
|
116
|
+
indentation = 5
|
117
|
+
tty_cols = [detect_terminal_size.try(:first) || 80, min_width].max
|
118
|
+
width = [tty_cols, max_width].min - indentation
|
119
|
+
option_col_width = CommandLine.global_options.values.collect(&:signature).collect(&:length).max
|
120
|
+
padding = 7
|
121
|
+
|
122
|
+
table = Terminal::Table.new do |t|
|
123
|
+
t.style = {:width => width}
|
124
|
+
t.headings = ['Option'.underline, 'Description'.underline]
|
125
|
+
desc_col_width = width - option_col_width - padding
|
126
|
+
t.rows = CommandLine.global_options.values.inject([]) do |acc, opt|
|
127
|
+
acc << [
|
128
|
+
opt.signature,
|
129
|
+
description_cell(opt, desc_col_width)
|
130
|
+
]
|
131
|
+
|
132
|
+
# Add separator unless we're at the very end.
|
133
|
+
acc << :separator unless acc.length == 2 * CommandLine.global_options.values.length - 1
|
134
|
+
acc
|
135
|
+
end
|
136
|
+
end
|
137
|
+
indent(table.to_s, indentation)
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def description_cell(option, col_width)
|
142
|
+
[description(option, col_width),
|
143
|
+
default(option, col_width),
|
144
|
+
choices(option, col_width)].compact.join("\n")
|
145
|
+
end
|
146
|
+
|
147
|
+
def description(option, col_width)
|
148
|
+
if option.desc.present?
|
149
|
+
hard_wrap(option.desc, col_width) << "\n"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def default(option, col_width)
|
154
|
+
if option.default.present? && option.show_default?
|
155
|
+
hard_wrap("Default: #{option.default}", col_width)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def choices(option, col_width)
|
160
|
+
if option.choices.present?
|
161
|
+
hard_wrap("Options: #{option.choices.join(', ')}", col_width)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def parameters_table
|
166
|
+
min_width, max_width = 70, 120
|
167
|
+
indentation = 5
|
168
|
+
tty_cols = [detect_terminal_size.try(:first) || 80, min_width].max
|
169
|
+
width = [tty_cols, max_width].min - indentation
|
170
|
+
left_col_width = command.parameters.collect{|name, _| name}.collect(&:length).max || 0
|
171
|
+
padding = 7
|
172
|
+
|
173
|
+
table = Terminal::Table.new do |t|
|
174
|
+
t.style = {:width => width}
|
175
|
+
t.headings = ['Parameter'.underline << "\n#{'*'.color(:cyan)} = required", 'Description'.underline]
|
176
|
+
desc_col_width = width - left_col_width - padding
|
177
|
+
|
178
|
+
t.rows = command.parameters.inject([]) do |acc, hash|
|
179
|
+
name = hash.keys.first
|
180
|
+
info = hash[name]
|
181
|
+
|
182
|
+
acc << [
|
183
|
+
info['required'] ? ('*'.color(:cyan) << name) : (' ' << name),
|
184
|
+
param_description_cell(info, desc_col_width)
|
185
|
+
]
|
186
|
+
|
187
|
+
# Add separator unless we're at the very end.
|
188
|
+
acc << :separator unless acc.length == 2 * command.parameters.length - 1
|
189
|
+
acc
|
190
|
+
end
|
191
|
+
end
|
192
|
+
indent(table.to_s, indentation)
|
193
|
+
end
|
194
|
+
|
195
|
+
#TODO:NLA Lots of duplication here (see methods in class Help, above.
|
196
|
+
def param_description_cell(param, col_width)
|
197
|
+
[param_description(param, col_width),
|
198
|
+
param_examples(param, col_width)].compact.join("\n")
|
199
|
+
end
|
200
|
+
|
201
|
+
def param_description(param, col_width)
|
202
|
+
if param['description'].present?
|
203
|
+
hard_wrap(param['description'], col_width) << "\n"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def param_examples(param, col_width)
|
208
|
+
if param['examples'].present?
|
209
|
+
param['examples'].collect do |example|
|
210
|
+
hard_wrap("Example: #{example}", col_width)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
data/lib/skytap.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Standard library
|
2
|
+
require 'net/https'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'net/https'
|
5
|
+
require 'net/ftp'
|
6
|
+
require 'uri'
|
7
|
+
require 'base64'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'yaml'
|
10
|
+
require 'erb'
|
11
|
+
require 'cgi'
|
12
|
+
require 'optparse'
|
13
|
+
require 'set'
|
14
|
+
require 'json'
|
15
|
+
|
16
|
+
# Gems
|
17
|
+
require 'rainbow'
|
18
|
+
require 'active_support/core_ext'
|
19
|
+
require 'terminal-table'
|
20
|
+
|
21
|
+
# Skytap files
|
22
|
+
require 'skytap/version'
|
23
|
+
require 'skytap/core_ext'
|
24
|
+
require 'skytap/error'
|
25
|
+
require 'skytap/command_line'
|
26
|
+
require 'skytap/commands'
|
27
|
+
require 'skytap/logger'
|
28
|
+
require 'skytap/api_schema'
|
29
|
+
require 'skytap/response'
|
30
|
+
require 'skytap/subnet'
|
31
|
+
|
32
|
+
module Skytap
|
33
|
+
extend self
|
34
|
+
|
35
|
+
SCHEMA = Skytap::ApiSchema.get
|
36
|
+
BASE_RESOURCES = %w[asset
|
37
|
+
configuration
|
38
|
+
credential
|
39
|
+
export
|
40
|
+
import
|
41
|
+
ip
|
42
|
+
template
|
43
|
+
user
|
44
|
+
vm]
|
45
|
+
|
46
|
+
# Returns a numeric code indicating exit status; 0 iff success.
|
47
|
+
def exec! #TODO:NLA Rename to something indicating that this is called when running from a command-line context.
|
48
|
+
response = begin
|
49
|
+
args, global_options, command_options = CommandLine.parse(ARGV)
|
50
|
+
|
51
|
+
logger = Logger.new(global_options[:'log-level'])
|
52
|
+
|
53
|
+
# Disable color if needed. We don't unconditionally execute this line so that
|
54
|
+
# color is still disabled for non-TTY terminals irrespective of the colorize
|
55
|
+
# setting.
|
56
|
+
Sickill::Rainbow.enabled = false unless global_options[:colorize]
|
57
|
+
|
58
|
+
build_response(Commands::Root.go!(logger, args, global_options, command_options))
|
59
|
+
rescue SystemExit
|
60
|
+
raise
|
61
|
+
rescue Interrupt
|
62
|
+
return 0
|
63
|
+
rescue Exception => ex
|
64
|
+
log_exception(ex, args, global_options, command_options)
|
65
|
+
build_response(ex)
|
66
|
+
end
|
67
|
+
|
68
|
+
if response.error?
|
69
|
+
if logger
|
70
|
+
logger.info response.error_message
|
71
|
+
else
|
72
|
+
$stderr.puts response.error_message
|
73
|
+
end
|
74
|
+
return 1
|
75
|
+
else
|
76
|
+
return 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Invokes the command in a way suitable for Ruby programs which use Skytap as
|
81
|
+
# a third-party library, or for Skytap plugins.
|
82
|
+
def invoke(username, api_token, args, command_options = {}, global_options = {}, &invoker)
|
83
|
+
#TODO:NLA This is hacky, and basically just to get the defaults for global options. FIXME
|
84
|
+
_, loaded_global_options, _ = CommandLine.parse([])
|
85
|
+
global_options = loaded_global_options.merge(global_options).merge(:username => username, :'api-token' => api_token)
|
86
|
+
|
87
|
+
if args.is_a?(String)
|
88
|
+
args = args.split
|
89
|
+
end
|
90
|
+
|
91
|
+
logger = Logger.new(global_options[:'log-level']).tap do |l|
|
92
|
+
l.mute! unless l.log_level == 'verbose'
|
93
|
+
end
|
94
|
+
|
95
|
+
build_response(Commands::Root.go!(logger, args, global_options, command_options, true, &invoker))
|
96
|
+
end
|
97
|
+
|
98
|
+
def invoke!(*args, &block)
|
99
|
+
resp = invoke(*args, &block)
|
100
|
+
if resp.error?
|
101
|
+
raise Skytap::Error.new resp.error_message
|
102
|
+
else
|
103
|
+
resp.payload
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def specification
|
108
|
+
resources.inject({}) do |acc, resource|
|
109
|
+
acc[resource] = SCHEMA[resource] || {}
|
110
|
+
acc
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def build_response(result)
|
118
|
+
Response.build(result)
|
119
|
+
end
|
120
|
+
|
121
|
+
def resources
|
122
|
+
SCHEMA.keys | BASE_RESOURCES
|
123
|
+
end
|
124
|
+
|
125
|
+
def log_exception(ex, args, global_options, command_options)
|
126
|
+
begin
|
127
|
+
global_options.try(:delete, :'api-token')
|
128
|
+
message = "#{Time.now}: -- #{args.inspect} -- #{global_options.inspect} -- " +
|
129
|
+
"#{command_options.inspect} -- #{Skytap::VERSION} -- " +
|
130
|
+
"#{ex} (#{ex.class.name})\n#{ex.backtrace.join("\n")}\n"
|
131
|
+
|
132
|
+
File.open(File.expand_path(File.join(ENV['HOME'], '.skytap.log')), 'a') do |f|
|
133
|
+
f << message
|
134
|
+
end
|
135
|
+
|
136
|
+
if global_options.try(:[], :'log-level') == 'verbose'
|
137
|
+
puts message
|
138
|
+
end
|
139
|
+
rescue
|
140
|
+
# No-op
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
Skytap::Commands::Root.populate_with(Skytap.specification)
|
146
|
+
|
147
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'skytap', 'plugins', '*.rb')) do |path|
|
148
|
+
require path
|
149
|
+
end
|
data/skytap.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'skytap/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "skytap-yf"
|
8
|
+
gem.version = Skytap::VERSION
|
9
|
+
gem.authors = ["Yonah Forst"]
|
10
|
+
gem.email = ["joshblour@hotmail.com"]
|
11
|
+
gem.description = %q{integrates with skytap api}
|
12
|
+
gem.summary = %q{desc}
|
13
|
+
gem.homepage = ""
|
14
|
+
gem.add_dependency 'activesupport'
|
15
|
+
gem.add_dependency 'json_pure'
|
16
|
+
gem.add_dependency 'rainbow'
|
17
|
+
gem.add_dependency 'terminal-table'
|
18
|
+
|
19
|
+
|
20
|
+
gem.files = `git ls-files`.split($/)
|
21
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
22
|
+
gem.require_paths = ["lib"]
|
23
|
+
|
24
|
+
|
25
|
+
end
|
data/skytap.rdoc
ADDED
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skytap-yf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Yonah Forst
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !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: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json_pure
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rainbow
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: terminal-table
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: integrates with skytap api
|
79
|
+
email:
|
80
|
+
- joshblour@hotmail.com
|
81
|
+
executables:
|
82
|
+
- skytap
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .DS_Store
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- README.rdoc
|
90
|
+
- api_schema.yaml
|
91
|
+
- bin/skytap
|
92
|
+
- ca-bundle.crt
|
93
|
+
- data/.DS_Store
|
94
|
+
- lib/skytap.rb
|
95
|
+
- lib/skytap/api_schema.rb
|
96
|
+
- lib/skytap/command_line.rb
|
97
|
+
- lib/skytap/commands.rb
|
98
|
+
- lib/skytap/commands/base.rb
|
99
|
+
- lib/skytap/commands/help.rb
|
100
|
+
- lib/skytap/commands/http.rb
|
101
|
+
- lib/skytap/commands/root.rb
|
102
|
+
- lib/skytap/core_ext.rb
|
103
|
+
- lib/skytap/error.rb
|
104
|
+
- lib/skytap/help_templates/help.erb
|
105
|
+
- lib/skytap/ip_address.rb
|
106
|
+
- lib/skytap/logger.rb
|
107
|
+
- lib/skytap/plugins/vm_copy_to_region.rb
|
108
|
+
- lib/skytap/plugins/vm_download.rb
|
109
|
+
- lib/skytap/plugins/vm_upload.rb
|
110
|
+
- lib/skytap/requester.rb
|
111
|
+
- lib/skytap/response.rb
|
112
|
+
- lib/skytap/skytaprc.rb
|
113
|
+
- lib/skytap/subnet.rb
|
114
|
+
- lib/skytap/templates.rb
|
115
|
+
- lib/skytap/version.rb
|
116
|
+
- skytap.gemspec
|
117
|
+
- skytap.rdoc
|
118
|
+
homepage: ''
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 1.8.23
|
139
|
+
signing_key:
|
140
|
+
specification_version: 3
|
141
|
+
summary: desc
|
142
|
+
test_files: []
|
143
|
+
has_rdoc:
|