spacialdb 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/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