gooddata 0.5.16 → 0.6.0.pre2

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 (40) hide show
  1. data/Gemfile +2 -0
  2. data/bin/gooddata +291 -8
  3. data/gooddata.gemspec +14 -5
  4. data/lib/gooddata/client.rb +34 -5
  5. data/lib/gooddata/commands/api.rb +27 -30
  6. data/lib/gooddata/commands/process.rb +137 -0
  7. data/lib/gooddata/commands/profile.rb +5 -5
  8. data/lib/gooddata/commands/projects.rb +107 -40
  9. data/lib/gooddata/commands/runners.rb +37 -0
  10. data/lib/gooddata/commands/scaffold.rb +30 -0
  11. data/lib/gooddata/connection.rb +31 -19
  12. data/lib/gooddata/extract.rb +1 -1
  13. data/lib/gooddata/goodzilla/goodzilla.rb +40 -0
  14. data/lib/gooddata/model.rb +418 -138
  15. data/lib/gooddata/models/attribute.rb +24 -0
  16. data/lib/gooddata/models/dashboard.rb +60 -0
  17. data/lib/gooddata/models/data_result.rb +4 -6
  18. data/lib/gooddata/models/data_set.rb +20 -0
  19. data/lib/gooddata/models/display_form.rb +7 -0
  20. data/lib/gooddata/models/fact.rb +17 -0
  21. data/lib/gooddata/models/metadata.rb +69 -17
  22. data/lib/gooddata/models/metric.rb +90 -0
  23. data/lib/gooddata/models/process.rb +112 -0
  24. data/lib/gooddata/models/profile.rb +1 -1
  25. data/lib/gooddata/models/project.rb +85 -29
  26. data/lib/gooddata/models/report.rb +45 -0
  27. data/lib/gooddata/models/report_definition.rb +139 -0
  28. data/lib/gooddata/version.rb +1 -1
  29. data/lib/templates/bricks/brick.rb.erb +7 -0
  30. data/lib/templates/bricks/main.rb.erb +4 -0
  31. data/spec/goodzilla_spec.rb +57 -0
  32. data/spec/model_dsl_spec.rb +22 -0
  33. data/test/test_commands.rb +1 -1
  34. data/test/test_model.rb +6 -6
  35. metadata +137 -16
  36. data/bin/igd.rb +0 -33
  37. data/lib/gooddata/command.rb +0 -75
  38. data/lib/gooddata/commands/help.rb +0 -104
  39. data/lib/gooddata/commands/version.rb +0 -7
  40. data/test/helper.rb +0 -13
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ # gem 'gooddata-bricks-poc', :path => "../gooddata-bricks"
4
+ gemspec
data/bin/gooddata CHANGED
@@ -1,13 +1,296 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'gli'
3
+ require 'gooddata'
4
+ require 'highline/import'
5
+ require 'gooddata/commands/projects'
2
6
 
3
- require 'logger'
7
+ include GLI::App
4
8
 
5
- require 'gooddata'
6
- require 'gooddata/command'
9
+ program_desc 'GoodData Ruby gem - a wrapper over GoodData API and several useful abstractions to make your everyday usage of GoodData easier.'
10
+
11
+ version GoodData::VERSION
12
+
13
+ desc 'GoodData user name'
14
+ default_value nil
15
+ arg_name 'gooddata-login'
16
+ flag [:U,:username]
17
+
18
+ desc 'GoodData password'
19
+ default_value nil
20
+ arg_name 'gooddata-password'
21
+ flag [:P,:password]
22
+
23
+ desc 'Project pid'
24
+ default_value nil
25
+ arg_name 'project-id'
26
+ flag [:p,:project_id]
27
+
28
+ desc 'Server'
29
+ default_value nil
30
+ arg_name 'server'
31
+ flag [:s,:server]
32
+
33
+ desc 'WEBDAV Server. Used for uploads of files'
34
+ default_value nil
35
+ arg_name 'web dav server'
36
+ flag [:w,:webdav_server]
37
+
38
+ desc 'Token for project creation'
39
+ default_value nil
40
+ arg_name 'token'
41
+ flag [:t, :token]
42
+
43
+ desc 'Verbose mode'
44
+ arg_name 'verbose'
45
+ switch [:v,:verbose]
46
+
47
+ desc 'Describe list here'
48
+ arg_name 'Describe arguments to list here'
49
+ command :process do |c|
50
+
51
+ c.desc 'Use when you need to redeploy a process'
52
+ c.default_value nil
53
+ c.flag :process_id
54
+
55
+ c.desc 'Specify directory for deployment'
56
+ c.default_value nil
57
+ c.flag :dir
58
+
59
+ c.action do |global_options,options,args|
60
+ require 'gooddata/commands/process'
61
+ options = options.merge(global_options)
62
+
63
+ case args.first
64
+ when "list"
65
+ pp GoodData::Command::Process.list(options)
66
+ when "get"
67
+ pp GoodData::Command::Process.get(options)
68
+ when "deploy"
69
+ GoodData::Command::Process.deploy_graph(options[:dir], options)
70
+ end
71
+ end
72
+ end
73
+
74
+ desc 'Some basic API stuff directly from CLI'
75
+ arg_name 'info|test|get|delete'
76
+ command :api do |c|
77
+
78
+ c.action do |global_options,options,args|
79
+ require 'gooddata/commands/api'
80
+ options = options.merge(global_options)
81
+
82
+ case args.first
83
+ when "list", "index", "info"
84
+ pp GoodData::Command::Api.info
85
+ when "get"
86
+ pp GoodData::Command::Api.get(args[1])
87
+ when "deploy"
88
+ GoodData::Command::Api.deploy_graph(options[:dir], options)
89
+ end
90
+ end
91
+ end
92
+
93
+
94
+ desc 'Describe add here'
95
+ arg_name 'show'
96
+ command :profile do |c|
97
+ c.action do |global_options, options, args|
98
+ require 'gooddata/commands/profile'
99
+
100
+ case args.first
101
+ when "show"
102
+ pp GoodData::Command::Profile.show()
103
+ else
104
+ raise "command provided not right"
105
+ end
106
+ end
107
+ end
108
+
109
+ desc 'Scaffold things'
110
+ arg_name 'show'
111
+ command :scaffold do |c|
112
+ c.action do |global_options, options, args|
113
+ require 'gooddata/commands/scaffold'
114
+ case args.first
115
+ when "brick"
116
+ pp GoodData::Command::Scaffold.brick(args[1])
117
+ else
118
+ raise "command provided not right"
119
+ end
120
+ end
121
+ end
122
+
123
+ desc 'Manage your projects'
124
+ arg_name 'project_command'
125
+ command :project do |c|
126
+
127
+ c.command :list do |list|
128
+ list.action do |global_options,options,args|
129
+ list = GoodData::Command::Projects.list()
130
+ puts list.map {|p| [p.uri, p.title].join(",")}
131
+ end
132
+ end
133
+
134
+ c.command :create do |create|
135
+ create.action do |global_options,options,args|
136
+ title = ask "Project name"
137
+ summary = ask("Project summary") { |q| q.default = "" }
138
+ template = ask("Project template")
139
+ token = ask("token")
140
+
141
+ project = GoodData::Command::Projects.create({
142
+ :title => title,
143
+ :summary => summary,
144
+ :template => template,
145
+ :token => token
146
+ })
147
+ puts "Project '#{project.title}' with id #{project.uri} created successfully!"
148
+ end
149
+ end
150
+
151
+ c.command :delete do |delete|
152
+ delete.action do |global_options,options,args|
153
+ id = global_options[:project_id]
154
+ GoodData::Command::Projects.delete(id)
155
+ end
156
+ end
157
+
158
+ c.command :clone do |clone|
159
+ clone.desc 'Name of the new project'
160
+ clone.default_value nil
161
+ clone.arg_name 'cloned_project_name'
162
+ clone.flag [:n, :name]
163
+
164
+ clone.desc 'Token of the new project'
165
+ clone.default_value nil
166
+ clone.arg_name 'token'
167
+ clone.flag [:t, :token]
168
+
169
+ clone.action do |global_options,options,args|
170
+ id = global_options[:project_id]
171
+ name = options[:name]
172
+ token = options[:token]
173
+ GoodData::Command::Projects.clone(id, :name => name, :token => token)
174
+ end
175
+ end
176
+
177
+ c.command :show do |show|
178
+ show.action do |global_options,options,args|
179
+ id = global_options[:project_id]
180
+ p = GoodData::Command::Projects.show(id)
181
+ pp p.data
182
+ end
183
+ end
184
+
185
+ c.command :build do |show|
186
+ show.action do |global_options,options,args|
187
+ spec_path = args.first || fail("You need to specify the path of the build spec")
188
+ opts = options.merge(global_options)
189
+ spec_path = Pathname.new(spec_path)
190
+
191
+ content = File.read(spec_path)
192
+ spec = if (spec_path.extname == ".rb")
193
+ eval(content)
194
+ elsif (spec_path.extname == ".json")
195
+ JSON.parse(spec_path, :symbolize_names => true)
196
+ end
197
+ new_project = GoodData::Model::ProjectCreator.migrate(opts.merge(:spec => spec))
198
+ puts "Migration was done. New project PID is #{new_project.uri}."
199
+ end
200
+ end
201
+
202
+ end
203
+
204
+ desc 'Run bricks locally'
205
+ # arg_name 'show'
206
+ command :run_ruby do |c|
207
+
208
+ c.desc 'Directory of the ruby brick'
209
+ c.default_value nil
210
+ c.flag [:d, :dir]
211
+
212
+ c.desc 'Project id for which you would like to run the script'
213
+ c.default_value nil
214
+ c.flag [:p, :project, :project_id, :project_pid]
215
+
216
+ c.desc 'Log file. If empty STDOUT will be used instead'
217
+ c.default_value nil
218
+ c.flag [:l, :logger]
219
+
220
+ c.desc 'Params file path. Inside should be hash of key values'
221
+ c.default_value nil
222
+ c.flag [:params]
223
+
224
+ c.desc 'Run on remote machine'
225
+ c.switch [:r, :remote]
226
+
227
+ c.desc 'Name of the deployed process'
228
+ c.default_value nil
229
+ c.flag [:n, :name]
230
+
231
+
232
+ c.action do |global_options, options, args|
233
+
234
+ opts = options.merge(global_options).merge({:project_id => options[:project], "project_id" => options[:project], :type => "RUBY"})
235
+
236
+ if options[:remote]
237
+ require 'gooddata/commands/process'
238
+ GoodData::Command::Process.run(options[:dir], opts) do
239
+ puts "would run"
240
+ end
241
+ else
242
+ require 'gooddata/commands/runners'
243
+ GoodData::Command::Runners.run_ruby(options[:dir], options)
244
+ end
245
+ end
246
+ end
247
+
248
+ desc 'Manage your projects'
249
+ arg_name 'project_command'
250
+ command :project do |c|
251
+
252
+ c.command :list do |list|
253
+ list.action do |global_options,options,args|
254
+ list = GoodData::Command::Projects.list()
255
+ puts list.map {|p| [p.uri, p.title].join(",")}
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+ pre do |global,command,options,args|
262
+ require 'logger'
263
+ GoodData.logger = Logger.new(STDOUT)
264
+ username = global[:username]
265
+ password = global[:password]
266
+
267
+ GoodData.connect(global.merge(options).merge({
268
+ :login => username,
269
+ :password => password,
270
+ :server => global[:server]
271
+ }))
272
+
273
+ # Pre logic here
274
+ # Return true to proceed; false to abort and not call the
275
+ # chosen command
276
+ # Use skips_pre before a command to skip this block
277
+ # on that command only
278
+ true
279
+ end
280
+
281
+ post do |global,command,options,args|
282
+ # Post logic here
283
+ # Use skips_post before a command to skip this
284
+ # block on that command only
285
+ end
7
286
 
8
- args = ARGV.dup
9
- ARGV.clear
10
- command = args.shift.strip rescue 'help'
287
+ on_error do |exception|
288
+ # Error logic here
289
+ # return false to skip default error handling
290
+ # binding.pry
291
+ pp exception.backtrace
292
+ pp exception
293
+ true
294
+ end
11
295
 
12
- GoodData.logger = Logger.new(STDOUT) if ENV['DEBUG']
13
- GoodData::Command.run command, args
296
+ exit run(ARGV)
data/gooddata.gemspec CHANGED
@@ -2,8 +2,8 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- $:.push File.expand_path("../lib/gooddata", __FILE__)
6
- require "version"
5
+ $:.push File.expand_path("../lib/", __FILE__)
6
+ require "gooddata/version"
7
7
 
8
8
  Gem::Specification.new do |s|
9
9
  s.name = %q{gooddata}
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.date = %q{2012-12-17}
16
16
  s.description = %q{Use the Gooddata::Client class to integrate GoodData into your own application or use the CLI to work with GoodData directly from the command line.}
17
17
  s.email = %q{pavel@gooddata.com}
18
- s.executables = ["igd.rb", "gooddata"]
18
+ s.executables = ["gooddata"]
19
19
  s.extra_rdoc_files = [
20
20
  "LICENSE",
21
21
  "README.rdoc"
@@ -25,12 +25,21 @@ Gem::Specification.new do |s|
25
25
  s.require_paths = ["lib"]
26
26
  s.rubygems_version = "1.3.7"
27
27
 
28
- s.add_development_dependency "bundler", "~> 1.3"
28
+ s.add_development_dependency "bundler"
29
29
  s.add_development_dependency "thoughtbot-shoulda"
30
+ s.add_development_dependency "pry"
31
+ s.add_development_dependency "rake"
32
+ s.add_development_dependency "rspec"
33
+
30
34
  s.add_dependency "parseconfig"
31
35
  s.add_dependency "json_pure"
32
36
  s.add_dependency "rest-client"
33
37
  s.add_dependency "json"
34
- s.add_dependency "rubyzip", "< 1.0.0"
38
+ s.add_dependency "rubyzip"
39
+ s.add_dependency "highline"
40
+ s.add_dependency "gli"
41
+ s.add_dependency "pry"
42
+ s.add_dependency "erubis"
43
+
35
44
  end
36
45
 
@@ -1,5 +1,6 @@
1
1
  require 'gooddata/version'
2
2
  require 'gooddata/connection'
3
+ require 'active_support/core_ext/string'
3
4
 
4
5
  # fastercsv is built in Ruby 1.9
5
6
  if RUBY_VERSION < "1.9"
@@ -84,8 +85,14 @@ module GoodData
84
85
  # * +user+ - A GoodData username
85
86
  # * +password+ - A GoodData password
86
87
  #
87
- def connect(user, password, url = nil, options={})
88
- threaded[:connection] = Connection.new user, password, url, options
88
+ def connect(options=nil, second_options=nil, third_options={})
89
+ if options.is_a? Hash
90
+ threaded[:connection] = Connection.new(options[:login], options[:password], options)
91
+ GoodData.project = options[:project] if options[:project]
92
+ elsif options.is_a?(String) && second_options.is_a?(String)
93
+ threaded[:connection] = Connection.new(options, second_options, third_options)
94
+ end
95
+
89
96
  end
90
97
 
91
98
  # Hepler for starting with SST easier
@@ -114,6 +121,25 @@ module GoodData
114
121
  connection
115
122
  end
116
123
 
124
+ def with_project(project, &bl)
125
+ old_project = GoodData.project
126
+ begin
127
+ GoodData.use(project)
128
+ server_url = case GoodData.project.data["content"]["cluster"]
129
+ when "na1"
130
+ "https://na1.gooddata.com"
131
+ else
132
+ "https://secure.gooddata.com"
133
+ end
134
+ connection.url = server_url
135
+ bl.call(project)
136
+ rescue Exception => e
137
+ fail e
138
+ ensure
139
+ GoodData.project = old_project
140
+ end
141
+ end
142
+
117
143
  # Returns the active GoodData connection earlier initialized via
118
144
  # GoodData.connect call
119
145
  #
@@ -140,6 +166,8 @@ module GoodData
140
166
  def project=(project)
141
167
  if project.is_a? Project
142
168
  threaded[:project] = project
169
+ elsif project.nil?
170
+ threaded[:project] = nil
143
171
  else
144
172
  threaded[:project] = Project[project]
145
173
  end
@@ -214,13 +242,14 @@ module GoodData
214
242
  connection.delete path, options
215
243
  end
216
244
 
217
- def poll(result, key)
245
+ def poll(result, key, options={})
246
+ sleep_interval = options[:sleep_interval] || 10
218
247
  link = result[key]["links"]["poll"]
219
248
  response = GoodData.get(link, :process => false)
220
249
  while response.code != 204
221
- sleep 5
250
+ sleep sleep_interval
222
251
  GoodData.connection.retryable(:tries => 3, :on => RestClient::InternalServerError) do
223
- sleep 5
252
+ sleep sleep_interval
224
253
  response = GoodData.get(link, :process => false)
225
254
  end
226
255
  end
@@ -1,37 +1,34 @@
1
1
  module GoodData::Command
2
- class Api < Base
3
- def info
4
- json = gooddata.release_info
5
- puts "GoodData API"
6
- puts " Version: #{json['releaseName']}"
7
- puts " Released: #{json['releaseDate']}"
8
- puts " For more info see #{json['releaseNotesUri']}"
9
- end
10
- alias :index :info
2
+ class Api
3
+ class << self
4
+ def info
5
+ json = {}
6
+ puts "GoodData API"
7
+ puts " Version: #{json['releaseName']}"
8
+ puts " Released: #{json['releaseDate']}"
9
+ puts " For more info see #{json['releaseNotesUri']}"
10
+ end
11
+ alias :index :info
11
12
 
12
- def test
13
- connect
14
- if GoodData.test_login
15
- puts "Succesfully logged in as #{GoodData.profile.user}"
16
- else
17
- puts "Unable to log in to GoodData server!"
13
+ def test
14
+ if GoodData.test_login
15
+ puts "Succesfully logged in as #{GoodData.profile.user}"
16
+ else
17
+ puts "Unable to log in to GoodData server!"
18
+ end
18
19
  end
19
- end
20
20
 
21
- def get
22
- path = args.shift rescue nil
23
- raise(CommandFailed, "Specify the path you want to GET.") if path.nil?
24
- connect
25
- result = GoodData.get path
26
- jj result rescue puts result
27
- end
21
+ def get(path)
22
+ raise(CommandFailed, "Specify the path you want to GET.") if path.nil?
23
+ result = GoodData.get path
24
+ result rescue puts result
25
+ end
28
26
 
29
- def delete
30
- path = args.shift rescue nil
31
- raise(CommandFailed, "Specify the path you want to DELETE.") if path.nil?
32
- connect
33
- result = GoodData.delete path
34
- jj result rescue puts result
27
+ def delete(path)
28
+ raise(CommandFailed, "Specify the path you want to DELETE.") if path.nil?
29
+ result = GoodData.delete path
30
+ result rescue puts result
31
+ end
35
32
  end
36
33
  end
37
- end
34
+ end