spacialdb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -0
- data/bin/spacialdb +14 -0
- data/lib/spacialdb/auth.rb +189 -0
- data/lib/spacialdb/client.rb +102 -0
- data/lib/spacialdb/command/auth.rb +36 -0
- data/lib/spacialdb/command/base.rb +135 -0
- data/lib/spacialdb/command/db.rb +41 -0
- data/lib/spacialdb/command/help.rb +155 -0
- data/lib/spacialdb/command/version.rb +16 -0
- data/lib/spacialdb/command.rb +142 -0
- data/lib/spacialdb/helpers.rb +81 -0
- data/lib/spacialdb/version.rb +3 -0
- data/lib/spacialdb.rb +3 -0
- data/lib/vendor/okjson.rb +582 -0
- data/spec/client_spec.rb +32 -0
- data/spec/command/db_spec.rb +27 -0
- data/spec/command/version_spec.rb +15 -0
- data/spec/commmad_spec.rb +12 -0
- data/spec/spec_helper.rb +28 -0
- metadata +91 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spacialdb/helpers'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module Spacialdb
|
5
|
+
module Command
|
6
|
+
class InvalidCommand < RuntimeError; end
|
7
|
+
class CommandFailed < RuntimeError; end
|
8
|
+
|
9
|
+
extend Spacialdb::Helpers
|
10
|
+
|
11
|
+
def self.load
|
12
|
+
Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do |file|
|
13
|
+
require file
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.commands
|
18
|
+
@@commands ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.command_aliases
|
22
|
+
@@command_aliases ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.namespaces
|
26
|
+
@namespaces ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.register_command(command)
|
30
|
+
commands[command[:command]] = command
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.register_namespace(namespace)
|
34
|
+
namespaces[namespace[:name]] = namespace
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.current_command
|
38
|
+
@current_command
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.global_options
|
42
|
+
@global_options ||= []
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.global_option(name, *args)
|
46
|
+
global_options << { :name => name, :args => args }
|
47
|
+
end
|
48
|
+
|
49
|
+
global_option :db, "--db DB", "-d"
|
50
|
+
global_option :confirm, "--confirm DB"
|
51
|
+
|
52
|
+
def self.run(cmd, args=[])
|
53
|
+
|
54
|
+
command = parse(cmd)
|
55
|
+
|
56
|
+
unless command
|
57
|
+
error " ! #{cmd} is not a spacialdb command. See 'spacialdb help'."
|
58
|
+
return
|
59
|
+
end
|
60
|
+
|
61
|
+
@current_command = cmd
|
62
|
+
|
63
|
+
opts = {}
|
64
|
+
invalid_options = []
|
65
|
+
|
66
|
+
parser = OptionParser.new do |parser|
|
67
|
+
global_options.each do |global_option|
|
68
|
+
parser.on(*global_option[:args]) do |value|
|
69
|
+
opts[global_option[:name]] = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
command[:options].each do |name, option|
|
73
|
+
parser.on("-#{option[:short]}", "--#{option[:long]}", option[:desc]) do |value|
|
74
|
+
opts[name.gsub("-", "_").to_sym] = value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
parser.order!(args) do |nonopt|
|
81
|
+
invalid_options << nonopt
|
82
|
+
end
|
83
|
+
rescue OptionParser::InvalidOption => ex
|
84
|
+
invalid_options << ex.args.first
|
85
|
+
retry
|
86
|
+
end
|
87
|
+
|
88
|
+
if opts[:help]
|
89
|
+
run "help", [cmd]
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
args.concat(invalid_options)
|
94
|
+
|
95
|
+
begin
|
96
|
+
object = command[:klass].new(args.dup, opts.dup)
|
97
|
+
object.send(command[:method])
|
98
|
+
rescue InvalidCommand
|
99
|
+
error "Unknown command. Run 'spacialdb help' for usage information."
|
100
|
+
rescue RestClient::Unauthorized
|
101
|
+
puts "Authentication failure"
|
102
|
+
run "login"
|
103
|
+
retry
|
104
|
+
rescue RestClient::ResourceNotFound => e
|
105
|
+
error extract_not_found(e.http_body)
|
106
|
+
rescue RestClient::RequestFailed => e
|
107
|
+
error extract_error(e.http_body)
|
108
|
+
rescue RestClient::RequestTimeout
|
109
|
+
error "API request timed out. Please try again, or contact support@spacialdb.com if this issue persists."
|
110
|
+
rescue CommandFailed => e
|
111
|
+
error e.message
|
112
|
+
end
|
113
|
+
rescue OptionParser::ParseError => ex
|
114
|
+
commands[cmd] ? run("help", [cmd]) : run("help")
|
115
|
+
rescue Interrupt => e
|
116
|
+
error "\n[canceled]"
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.parse(cmd)
|
120
|
+
commands[cmd] || commands[command_aliases[cmd]]
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.extract_not_found(body)
|
124
|
+
body =~ /^[\w\s]+ not found$/ ? body : "Resource not found"
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.extract_error(body)
|
128
|
+
msg = parse_error_json(body) || parse_error_plain(body) || 'Internal server error'
|
129
|
+
msg.split("\n").map { |line| ' ! ' + line }.join("\n")
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.parse_error_json(body)
|
133
|
+
json = json_decode(body.to_s)
|
134
|
+
json ? json['error'] : nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.parse_error_plain(body)
|
138
|
+
return unless body.respond_to?(:headers) && body.headers[:content_type].to_s.include?("text/plain")
|
139
|
+
body.to_s
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "vendor/okjson"
|
2
|
+
|
3
|
+
module Spacialdb
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
def display(msg="", newline=true)
|
7
|
+
if newline
|
8
|
+
puts(msg)
|
9
|
+
else
|
10
|
+
print(msg)
|
11
|
+
STDOUT.flush
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def error(msg)
|
16
|
+
STDERR.puts(msg)
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def ask
|
21
|
+
gets.strip
|
22
|
+
end
|
23
|
+
|
24
|
+
def echo_off
|
25
|
+
system "stty -echo"
|
26
|
+
end
|
27
|
+
|
28
|
+
def echo_on
|
29
|
+
system "stty echo"
|
30
|
+
end
|
31
|
+
|
32
|
+
def home_directory
|
33
|
+
ENV['HOME']
|
34
|
+
end
|
35
|
+
|
36
|
+
def redisplay(line, line_break = false)
|
37
|
+
display("\r\e[0K#{line}", line_break)
|
38
|
+
end
|
39
|
+
|
40
|
+
def confirm_command(db = db)
|
41
|
+
raise(Spacialdb::Command::CommandFailed, "No db specified.\nSet it by adding --db <db name>") unless db
|
42
|
+
|
43
|
+
confirmed_db = extract_option('--confirm', false)
|
44
|
+
if confirmed_db
|
45
|
+
unless confirmed_db == db
|
46
|
+
raise(Spacialdb::Command::CommandFailed, "Confirmed db #{confirmed_db} did not match the selected db #{db}.")
|
47
|
+
end
|
48
|
+
return true
|
49
|
+
else
|
50
|
+
display
|
51
|
+
display " ! WARNING: Potentially Destructive Action"
|
52
|
+
display " ! This command will affect the db: #{db}"
|
53
|
+
display " ! To proceed, type \"#{db}\" or re-run this command with --confirm #{db}"
|
54
|
+
display
|
55
|
+
display "> ", false
|
56
|
+
if ask.downcase != db
|
57
|
+
display " ! Input did not match #{db}. Aborted."
|
58
|
+
false
|
59
|
+
else
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def longest(items)
|
66
|
+
items.map(&:to_s).map(&:length).sort.last
|
67
|
+
end
|
68
|
+
|
69
|
+
def json_encode(object)
|
70
|
+
OkJson.encode(object)
|
71
|
+
rescue OkJson::ParserError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def json_decode(json)
|
76
|
+
OkJson.decode(json)
|
77
|
+
rescue OkJson::ParserError
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/spacialdb.rb
ADDED