gooddata 0.6.10 → 0.6.11
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +6 -0
- data/README.md +1 -0
- data/gooddata.gemspec +38 -40
- data/lib/gooddata/bricks/base_downloader.rb +1 -1
- data/lib/gooddata/bricks/middleware/base_middleware.rb +36 -0
- data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +8 -38
- data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +14 -0
- data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +7 -6
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +7 -5
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +1 -1
- data/lib/gooddata/bricks/middleware/restforce_middleware.rb +20 -14
- data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +33 -0
- data/lib/gooddata/cli/commands/api_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/auth_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/console_cmd.rb +2 -2
- data/lib/gooddata/cli/commands/process_cmd.rb +54 -7
- data/lib/gooddata/cli/commands/project_cmd.rb +9 -9
- data/lib/gooddata/cli/commands/projects_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/run_ruby_cmd.rb +24 -7
- data/lib/gooddata/cli/commands/scaffold_cmd.rb +2 -2
- data/lib/gooddata/cli/commands/user_cmd.rb +1 -1
- data/lib/gooddata/cli/hooks.rb +3 -3
- data/lib/gooddata/commands/datasets.rb +1 -1
- data/lib/gooddata/commands/project.rb +2 -2
- data/lib/gooddata/commands/role.rb +1 -1
- data/lib/gooddata/commands/runners.rb +2 -2
- data/lib/gooddata/connection.rb +2 -2
- data/lib/gooddata/core/nil_logger.rb +1 -1
- data/lib/gooddata/core/rest.rb +12 -8
- data/lib/gooddata/data/guesser.rb +1 -1
- data/lib/gooddata/exceptions/attr_element_not_found.rb +1 -1
- data/lib/gooddata/extensions/enumerable.rb +1 -1
- data/lib/gooddata/extensions/hash.rb +20 -0
- data/lib/gooddata/helpers/csv_helper.rb +1 -1
- data/lib/gooddata/helpers/global_helpers.rb +59 -1
- data/lib/gooddata/mixins/md_lock.rb +83 -0
- data/lib/gooddata/mixins/md_object_indexer.rb +1 -1
- data/lib/gooddata/mixins/md_object_query.rb +1 -1
- data/lib/gooddata/mixins/md_relations.rb +0 -9
- data/lib/gooddata/models/dashboard_builder.rb +1 -1
- data/lib/gooddata/models/domain.rb +2 -2
- data/lib/gooddata/models/empty_result.rb +5 -5
- data/lib/gooddata/models/execution.rb +74 -0
- data/lib/gooddata/models/execution_detail.rb +74 -0
- data/lib/gooddata/models/membership.rb +1 -1
- data/lib/gooddata/models/metadata/attribute.rb +4 -6
- data/lib/gooddata/models/metadata/dashboard.rb +2 -0
- data/lib/gooddata/models/metadata/fact.rb +2 -2
- data/lib/gooddata/models/metadata/metric.rb +4 -1
- data/lib/gooddata/models/metadata/report.rb +84 -34
- data/lib/gooddata/models/metadata/report_definition.rb +28 -17
- data/lib/gooddata/models/metadata.rb +1 -1
- data/lib/gooddata/models/model.rb +1 -1
- data/lib/gooddata/models/process.rb +70 -54
- data/lib/gooddata/models/profile.rb +47 -10
- data/lib/gooddata/models/project.rb +74 -30
- data/lib/gooddata/models/project_blueprint.rb +9 -10
- data/lib/gooddata/models/project_builder.rb +2 -2
- data/lib/gooddata/models/project_creator.rb +4 -4
- data/lib/gooddata/models/report_data_result.rb +1 -1
- data/lib/gooddata/models/schedule.rb +39 -32
- data/lib/gooddata/models/to_manifest.rb +5 -5
- data/lib/gooddata/models/to_wire.rb +3 -3
- data/lib/gooddata/rest/client.rb +64 -31
- data/lib/gooddata/rest/connection.rb +7 -7
- data/lib/gooddata/rest/connections/dummy_connection.rb +5 -5
- data/lib/gooddata/rest/connections/rest_client_connection.rb +106 -44
- data/lib/gooddata/rest/object.rb +1 -1
- data/lib/gooddata/version.rb +1 -1
- data/spec/bricks/bricks_spec.rb +67 -0
- data/spec/bricks/default-config.json +8 -0
- data/spec/data/gooddata_version_process/gooddata_version.rb +3 -0
- data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
- data/spec/data/ruby_params_process/ruby_params.rb +3 -0
- data/spec/helpers/process_helper.rb +12 -0
- data/spec/helpers/schedule_helper.rb +21 -0
- data/spec/integration/create_project_spec.rb +19 -0
- data/spec/integration/full_process_schedule_spec.rb +129 -8
- data/spec/integration/full_project_spec.rb +52 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/core/rest_spec.rb +76 -3
- data/spec/unit/helpers_spec.rb +43 -0
- data/spec/unit/models/metric_spec.rb +33 -0
- data/spec/unit/models/params_spec.rb +96 -0
- data/spec/unit/models/profile_spec.rb +16 -0
- data/spec/unit/models/schedule_spec.rb +12 -3
- metadata +350 -187
- data/lib/gooddata/helper/class_helper.rb +0 -1
- data/lib/gooddata/helper/helpers.rb +0 -8
@@ -1,9 +1,14 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'pry'
|
4
|
+
require 'zip'
|
4
5
|
|
6
|
+
require_relative '../helpers/global_helpers'
|
5
7
|
require_relative '../rest/resource'
|
6
8
|
|
9
|
+
require_relative 'execution_detail'
|
10
|
+
require_relative 'schedule'
|
11
|
+
|
7
12
|
module GoodData
|
8
13
|
class Process < GoodData::Rest::Object
|
9
14
|
attr_reader :data
|
@@ -82,48 +87,7 @@ module GoodData
|
|
82
87
|
project = GoodData::Project[p, opts]
|
83
88
|
fail ArgumentError, 'Wrong :project specified' if project.nil?
|
84
89
|
|
85
|
-
|
86
|
-
puts 'Creating package for upload'
|
87
|
-
Tempfile.open('deploy-graph-archive') do |temp|
|
88
|
-
Zip::OutputStream.open(temp.path) do |zio|
|
89
|
-
FileUtils.cd(path.parent) do
|
90
|
-
files_to_pack = [path.basename]
|
91
|
-
files_to_pack.each do |item|
|
92
|
-
puts "including #{item}"
|
93
|
-
unless File.directory?(item)
|
94
|
-
zio.put_next_entry(item)
|
95
|
-
zio.print IO.read(item)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
client.upload_to_user_webdav(temp.path, opts)
|
102
|
-
temp.path
|
103
|
-
end
|
104
|
-
elsif !path.directory?
|
105
|
-
client.upload_to_user_webdav(path, opts)
|
106
|
-
path
|
107
|
-
else
|
108
|
-
Tempfile.open('deploy-graph-archive') do |temp|
|
109
|
-
Zip::OutputStream.open(temp.path) do |zio|
|
110
|
-
FileUtils.cd(path) do
|
111
|
-
|
112
|
-
files_to_pack = Dir.glob('./**/*').reject { |f| files_to_exclude.include?(Pathname(path) + f) }
|
113
|
-
files_to_pack.each do |item|
|
114
|
-
puts "including #{item}"
|
115
|
-
unless File.directory?(item)
|
116
|
-
zio.put_next_entry(item)
|
117
|
-
zio.print IO.read(item)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
client.upload_to_user_webdav(temp.path, opts)
|
124
|
-
temp.path
|
125
|
-
end
|
126
|
-
end
|
90
|
+
zip_and_upload path, files_to_exclude, opts
|
127
91
|
end
|
128
92
|
|
129
93
|
# Deploy a new process or redeploy existing one.
|
@@ -134,7 +98,7 @@ module GoodData
|
|
134
98
|
# @option options [String] :name Readable name of the process
|
135
99
|
# @option options [String] :process_id ID of a process to be redeployed (do not set if you want to create a new process)
|
136
100
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
137
|
-
def deploy(path, options = {})
|
101
|
+
def deploy(path, options = { :client => GoodData.client, :project => GoodData.project })
|
138
102
|
client = options[:client]
|
139
103
|
fail ArgumentError, 'No :client specified' if client.nil?
|
140
104
|
|
@@ -174,6 +138,46 @@ module GoodData
|
|
174
138
|
puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
|
175
139
|
process
|
176
140
|
end
|
141
|
+
|
142
|
+
# ----------------------------- Private Stuff
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def zip_and_upload(path, files_to_exclude, opts = {})
|
147
|
+
def with_zip(opts = {})
|
148
|
+
Tempfile.open('deploy-graph-archive') do |temp|
|
149
|
+
zip_filename = temp.path
|
150
|
+
File.open(zip_filename, 'w') do |zip|
|
151
|
+
Zip::File.open(zip.path, Zip::File::CREATE) do |zipfile|
|
152
|
+
yield zipfile
|
153
|
+
end
|
154
|
+
end
|
155
|
+
client.upload_to_user_webdav(temp.path, opts)
|
156
|
+
temp.path
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
puts 'Creating package for upload'
|
161
|
+
if !path.directory? && (path.extname == '.grf' || path.extname == '.rb')
|
162
|
+
with_zip(opts) do |zipfile|
|
163
|
+
zipfile.add(File.basename(path), path)
|
164
|
+
end
|
165
|
+
|
166
|
+
elsif !path.directory?
|
167
|
+
client.upload_to_user_webdav(path, opts)
|
168
|
+
path
|
169
|
+
else
|
170
|
+
with_zip(opts) do |zipfile|
|
171
|
+
Dir[File.join(path, '**', '**')].reject { |f| files_to_exclude.include?(Pathname(path) + f) }.each do |file|
|
172
|
+
file_pathname = Pathname.new(file)
|
173
|
+
puts "Including item #{file_pathname}"
|
174
|
+
file_relative_pathname = file_pathname.relative_path_from(Pathname.new(path))
|
175
|
+
zipfile.add(file_relative_pathname, file)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
# -----------------------------
|
177
181
|
end
|
178
182
|
|
179
183
|
def initialize(data)
|
@@ -193,7 +197,15 @@ module GoodData
|
|
193
197
|
# @option options [String] :name Readable name of the process
|
194
198
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
195
199
|
def deploy(path, options = {})
|
196
|
-
Process.deploy(path, options.merge(:process_id => process_id))
|
200
|
+
Process.deploy(path, options.merge(:process_id => process_id, :client => client, :project => project))
|
201
|
+
end
|
202
|
+
|
203
|
+
# Downloads the process from S3 in a zipped form.
|
204
|
+
#
|
205
|
+
# @return [IO] The stream of data that represents a zipped deployed process.
|
206
|
+
def download
|
207
|
+
link = links['source']
|
208
|
+
client.get(link, process: false) { |_, _, result| RestClient.get(result.to_hash['location'].first) }
|
197
209
|
end
|
198
210
|
|
199
211
|
def process
|
@@ -245,14 +257,7 @@ module GoodData
|
|
245
257
|
end
|
246
258
|
|
247
259
|
def execute(executable, options = {})
|
248
|
-
|
249
|
-
hidden_params = options[:hidden_params] || {}
|
250
|
-
result = client.post(executions_link,
|
251
|
-
:execution => {
|
252
|
-
:graph => executable.to_s,
|
253
|
-
:params => params,
|
254
|
-
:hiddenParams => hidden_params
|
255
|
-
})
|
260
|
+
result = start_execution(executable, options)
|
256
261
|
begin
|
257
262
|
client.poll_on_code(result['executionTask']['links']['poll'])
|
258
263
|
rescue RestClient::RequestFailed => e
|
@@ -260,10 +265,21 @@ module GoodData
|
|
260
265
|
ensure
|
261
266
|
result = client.get(result['executionTask']['links']['detail'])
|
262
267
|
if result['executionDetail']['status'] == 'ERROR'
|
263
|
-
fail "Runing process failed. You can look at a log here #{result[
|
268
|
+
fail "Runing process failed. You can look at a log here #{result['executionDetail']['logFileName']}"
|
264
269
|
end
|
265
270
|
end
|
266
|
-
result
|
271
|
+
client.create(GoodData::ExecutionDetail, result, client: client, project: project)
|
272
|
+
end
|
273
|
+
|
274
|
+
def start_execution(executable, options = {})
|
275
|
+
params = options[:params] || {}
|
276
|
+
hidden_params = options[:hidden_params] || {}
|
277
|
+
client.post(executions_link,
|
278
|
+
:execution => {
|
279
|
+
:graph => executable.to_s,
|
280
|
+
:params => GoodData::Helpers.encode_params(params, false),
|
281
|
+
:hiddenParams => GoodData::Helpers.encode_params(hidden_params, true)
|
282
|
+
})
|
267
283
|
end
|
268
284
|
end
|
269
285
|
end
|
@@ -43,7 +43,31 @@ module GoodData
|
|
43
43
|
:timezone
|
44
44
|
]
|
45
45
|
|
46
|
+
PROFILE_PATH = '/gdc/account/profile/%s'
|
47
|
+
|
46
48
|
class << self
|
49
|
+
# Get profile by ID or URI
|
50
|
+
#
|
51
|
+
# @param id ID or URI of user to be found
|
52
|
+
# @param [Hash] opts Additional optional options
|
53
|
+
# @option opts [GoodData::Rest::Client] :client Client used for communication with server
|
54
|
+
# @return GoodData::Profile User Profile
|
55
|
+
def [](id, opts = { client: GoodData.connection })
|
56
|
+
return id if id.instance_of?(GoodData::Profile) || id.respond_to?(:profile?) && id.profile?
|
57
|
+
|
58
|
+
if id.to_s !~ %r{^(\/gdc\/account\/profile\/)?[a-zA-Z\d]+$}
|
59
|
+
fail(ArgumentError, 'wrong type of argument. Should be either project ID or path')
|
60
|
+
end
|
61
|
+
|
62
|
+
id = id.match(/[a-zA-Z\d]+$/)[0] if id =~ /\//
|
63
|
+
|
64
|
+
c = client(opts)
|
65
|
+
fail ArgumentError, 'No :client specified' if c.nil?
|
66
|
+
|
67
|
+
response = c.get(PROFILE_PATH % id)
|
68
|
+
c.factory.create(Profile, response)
|
69
|
+
end
|
70
|
+
|
47
71
|
# Apply changes to object.
|
48
72
|
#
|
49
73
|
# @param obj [GoodData::Profile] Object to be modified
|
@@ -110,13 +134,13 @@ module GoodData
|
|
110
134
|
next
|
111
135
|
end
|
112
136
|
|
113
|
-
if user_existing
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
137
|
+
next if user_existing == user_new
|
138
|
+
|
139
|
+
diff = self.diff(user_existing, user_new)
|
140
|
+
res[:changed] << {
|
141
|
+
:user => user_existing,
|
142
|
+
:diff => diff
|
143
|
+
}
|
120
144
|
end
|
121
145
|
|
122
146
|
tmp = Hash[list2.map { |v| [v.email, v] }]
|
@@ -250,6 +274,15 @@ module GoodData
|
|
250
274
|
@json['accountSetting']['firstName'] = val
|
251
275
|
end
|
252
276
|
|
277
|
+
# Get full name
|
278
|
+
#
|
279
|
+
# @return String Full Name
|
280
|
+
def full_name
|
281
|
+
"#{first_name} #{last_name}"
|
282
|
+
end
|
283
|
+
|
284
|
+
alias_method :title, :full_name
|
285
|
+
|
253
286
|
# Gets the last name
|
254
287
|
#
|
255
288
|
# @return [String] Last name
|
@@ -293,17 +326,21 @@ module GoodData
|
|
293
326
|
#
|
294
327
|
# @return [String] Phone
|
295
328
|
def phone
|
296
|
-
@json['accountSetting']['
|
329
|
+
@json['accountSetting']['phoneNumber'] || ''
|
297
330
|
end
|
298
331
|
|
332
|
+
alias_method :phone_number, :phone
|
333
|
+
|
299
334
|
# Set the phone
|
300
335
|
#
|
301
336
|
# @param val [String] Phone to be set
|
302
337
|
def phone=(val)
|
303
338
|
@dirty ||= phone != val
|
304
|
-
@json['accountSetting']['
|
339
|
+
@json['accountSetting']['phoneNumber'] = val
|
305
340
|
end
|
306
341
|
|
342
|
+
alias_method :phone_number=, :phone=
|
343
|
+
|
307
344
|
# Gets the position in company
|
308
345
|
#
|
309
346
|
# @return [String] Position in company
|
@@ -331,7 +368,7 @@ module GoodData
|
|
331
368
|
|
332
369
|
# Saves object if dirty, clears dirty flag
|
333
370
|
def save!
|
334
|
-
if @dirty
|
371
|
+
if @dirty # rubocop:disable Style/GuardClause
|
335
372
|
raw = @json.dup
|
336
373
|
raw['accountSetting'].delete('login')
|
337
374
|
|
@@ -51,7 +51,7 @@ module GoodData
|
|
51
51
|
# - /gdc/projects/<id>
|
52
52
|
# - <id>
|
53
53
|
#
|
54
|
-
def [](id, opts = {})
|
54
|
+
def [](id, opts = { client: GoodData.connection })
|
55
55
|
return id if id.instance_of?(GoodData::Project) || id.respond_to?(:project?) && id.project?
|
56
56
|
|
57
57
|
if id == :all
|
@@ -83,8 +83,8 @@ module GoodData
|
|
83
83
|
c = client(opts)
|
84
84
|
fail ArgumentError, 'No :client specified' if c.nil?
|
85
85
|
|
86
|
-
auth_token = opts[:auth_token]
|
87
|
-
fail 'You have to provide your token for creating projects as :auth_token parameter' if auth_token.nil? || auth_token.empty?
|
86
|
+
auth_token = opts[:auth_token]
|
87
|
+
fail ArgumentError, 'You have to provide your token for creating projects as :auth_token parameter' if auth_token.nil? || auth_token.empty?
|
88
88
|
|
89
89
|
json = {
|
90
90
|
'project' =>
|
@@ -123,7 +123,7 @@ module GoodData
|
|
123
123
|
project
|
124
124
|
end
|
125
125
|
|
126
|
-
def find(
|
126
|
+
def find(_opts = {}, client = GoodData::Rest::Client.client)
|
127
127
|
user = client.user
|
128
128
|
user.projects['projects'].map do |project|
|
129
129
|
client.create(GoodData::Project, project)
|
@@ -157,17 +157,34 @@ module GoodData
|
|
157
157
|
if metric.is_a?(String)
|
158
158
|
GoodData::Metric.xcreate(metric, options.merge(default))
|
159
159
|
else
|
160
|
-
GoodData::Metric.xcreate(metric.merge(default))
|
160
|
+
GoodData::Metric.xcreate(options[:expression], metric.merge(options.merge(default)))
|
161
161
|
end
|
162
162
|
end
|
163
163
|
alias_method :create_metric, :add_metric
|
164
164
|
|
165
|
+
# Creates new instance of report in context of project
|
166
|
+
#
|
167
|
+
# @param [options] Optional report options
|
168
|
+
# @return [GoodData::Report] Instance of new report
|
165
169
|
def add_report(options = {})
|
166
170
|
rep = GoodData::Report.create(options.merge(client: client, project: self))
|
167
171
|
rep.save
|
168
172
|
end
|
169
173
|
alias_method :create_report, :add_report
|
170
174
|
|
175
|
+
# Creates new instance of report definition in context of project
|
176
|
+
# This report definition can be used for creating of GoodData::Report
|
177
|
+
#
|
178
|
+
# @param [json] Raw report definition json
|
179
|
+
# @return [GoodData::ReportDefinition] Instance of new report definition
|
180
|
+
def add_report_definition(json)
|
181
|
+
rd = GoodData::ReportDefinition.new(json)
|
182
|
+
rd.client = client
|
183
|
+
rd.project = self
|
184
|
+
rd.save
|
185
|
+
end
|
186
|
+
alias_method :create_report_definition, :add_report_definition
|
187
|
+
|
171
188
|
# Returns an indication whether current user is admin in this project
|
172
189
|
#
|
173
190
|
# @return [Boolean] True if user has admin role in the project, false otherwise.
|
@@ -215,15 +232,38 @@ module GoodData
|
|
215
232
|
|
216
233
|
# Clones project
|
217
234
|
#
|
235
|
+
# @param options [Hash] Export options
|
236
|
+
# @option options [Boolean] :data Clone project with data
|
237
|
+
# @option options [Boolean] :users Clone project with users
|
238
|
+
# @option options [String] :authorized_users Comma separated logins of authorized users. Users that can use the export
|
218
239
|
# @return [GoodData::Project] Newly created project
|
219
240
|
def clone(options = {})
|
220
|
-
# TODO: Refactor so if export or import fails the new_project will be cleaned
|
221
|
-
with_data = options[:data].nil? ? true : options[:data]
|
222
|
-
with_users = options[:users].nil? ? false : options[:users]
|
223
241
|
a_title = options[:title] || "Clone of #{title}"
|
224
242
|
|
225
|
-
|
226
|
-
|
243
|
+
begin
|
244
|
+
# Create the project first so we know that it is passing.
|
245
|
+
# What most likely is wrong is the token and the export actaully takes majority of the time
|
246
|
+
new_project = GoodData::Project.create(options.merge(:title => a_title, :client => client))
|
247
|
+
export_token = export_clone(options)
|
248
|
+
new_project.import_clone(export_token)
|
249
|
+
rescue
|
250
|
+
new_project.delete if new_project
|
251
|
+
raise
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Export a clone from a project to be later imported.
|
256
|
+
# If you do not want to do anything special and you do not need fine grained
|
257
|
+
# controle use clone method which does all the heavy lifting for you.
|
258
|
+
#
|
259
|
+
# @param options [Hash] Export options
|
260
|
+
# @option options [Boolean] :data Clone project with data
|
261
|
+
# @option options [Boolean] :users Clone project with users
|
262
|
+
# @option options [String] :authorized_users Comma separated logins of authorized users. Users that can use the export
|
263
|
+
# @return [String] token of the export
|
264
|
+
def export_clone(options = {})
|
265
|
+
with_data = options[:data].nil? ? true : options[:data]
|
266
|
+
with_users = options[:users].nil? ? false : options[:users]
|
227
267
|
|
228
268
|
export = {
|
229
269
|
:exportProject => {
|
@@ -231,28 +271,34 @@ module GoodData
|
|
231
271
|
:exportData => with_data ? 1 : 0
|
232
272
|
}
|
233
273
|
}
|
274
|
+
export[:exportProject][:authorizedUsers] = options[:authorized_users] if options[:authorized_users]
|
234
275
|
|
235
276
|
result = client.post("/gdc/md/#{obj_id}/maintenance/export", export)
|
236
|
-
export_token = result['exportArtifact']['token']
|
237
|
-
|
238
277
|
status_url = result['exportArtifact']['status']['uri']
|
239
278
|
client.poll_on_response(status_url) do |body|
|
240
279
|
body['taskState']['status'] == 'RUNNING'
|
241
280
|
end
|
281
|
+
result['exportArtifact']['token']
|
282
|
+
end
|
242
283
|
|
284
|
+
# Imports a clone into current project. The project has to be freshly
|
285
|
+
# created.
|
286
|
+
#
|
287
|
+
# @param export_token [String] Export token of the package to be imported
|
288
|
+
# @return [Project] current project
|
289
|
+
def import_clone(export_token)
|
243
290
|
import = {
|
244
291
|
:importProject => {
|
245
292
|
:token => export_token
|
246
293
|
}
|
247
294
|
}
|
248
295
|
|
249
|
-
result = client.post("/gdc/md/#{
|
296
|
+
result = client.post("/gdc/md/#{obj_id}/maintenance/import", import)
|
250
297
|
status_url = result['uri']
|
251
298
|
client.poll_on_response(status_url) do |body|
|
252
299
|
body['taskState']['status'] == 'RUNNING'
|
253
300
|
end
|
254
|
-
|
255
|
-
new_project
|
301
|
+
self
|
256
302
|
end
|
257
303
|
|
258
304
|
def compute_report(spec = {})
|
@@ -298,7 +344,7 @@ module GoodData
|
|
298
344
|
|
299
345
|
# Deletes dashboards for project
|
300
346
|
def delete_dashboards
|
301
|
-
Dashboard.all.map { |data| Dashboard[data['link']] }.each
|
347
|
+
Dashboard.all.map { |data| Dashboard[data['link']] }.each(&:delete)
|
302
348
|
end
|
303
349
|
|
304
350
|
def deploy_process(path, options = {})
|
@@ -400,10 +446,10 @@ module GoodData
|
|
400
446
|
role_name.downcase!
|
401
447
|
role_list.each do |role|
|
402
448
|
return role if role.uri == role_name ||
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
449
|
+
role.identifier.downcase == role_name ||
|
450
|
+
role.identifier.downcase.gsub(/role$/, '') == role_name ||
|
451
|
+
role.title.downcase == role_name ||
|
452
|
+
role.summary.downcase == role_name
|
407
453
|
end
|
408
454
|
nil
|
409
455
|
end
|
@@ -419,14 +465,14 @@ module GoodData
|
|
419
465
|
name.downcase!
|
420
466
|
user_list.each do |user|
|
421
467
|
return user if user.uri.downcase == name ||
|
422
|
-
|
423
|
-
|
468
|
+
user.login.downcase == name ||
|
469
|
+
user.email.downcase == name
|
424
470
|
end
|
425
471
|
nil
|
426
472
|
end
|
427
473
|
|
428
474
|
# Exports project users to file
|
429
|
-
def import_users(path, opts = { :header => true }, &
|
475
|
+
def import_users(path, opts = { :header => true }, &_block)
|
430
476
|
opts[:path] = path
|
431
477
|
|
432
478
|
##########################
|
@@ -609,7 +655,7 @@ module GoodData
|
|
609
655
|
# @return [GoodData::Fact | Array<GoodData::Fact>] fact instance or list
|
610
656
|
def labels(id = :all, opts = {})
|
611
657
|
if id == :all
|
612
|
-
attributes.pmapcat
|
658
|
+
attributes.pmapcat(&:labels).uniq
|
613
659
|
else
|
614
660
|
GoodData::Label[id, opts.merge(project: self, client: client)]
|
615
661
|
end
|
@@ -700,7 +746,7 @@ module GoodData
|
|
700
746
|
objs = objs.pmap { |obj| objects(obj) }
|
701
747
|
export_payload = {
|
702
748
|
:partialMDExport => {
|
703
|
-
:uris => objs.map
|
749
|
+
:uris => objs.map(&:uri)
|
704
750
|
}
|
705
751
|
}
|
706
752
|
result = client.post("#{md['maintenance']}/partialmdexport", export_payload)
|
@@ -961,7 +1007,7 @@ module GoodData
|
|
961
1007
|
list = list.map do |user|
|
962
1008
|
{
|
963
1009
|
:user => user,
|
964
|
-
:roles => new_users_map[user.email].json['user']['content']['role'].split(' ').map
|
1010
|
+
:roles => new_users_map[user.email].json['user']['content']['role'].split(' ').map(&:downcase).sort
|
965
1011
|
}
|
966
1012
|
end
|
967
1013
|
|
@@ -976,9 +1022,7 @@ module GoodData
|
|
976
1022
|
#
|
977
1023
|
# @param list List of users to be disabled
|
978
1024
|
def users_remove(list)
|
979
|
-
list.pmap
|
980
|
-
user.disable
|
981
|
-
end
|
1025
|
+
list.pmap(&:disable)
|
982
1026
|
end
|
983
1027
|
|
984
1028
|
# Update user
|
@@ -1022,7 +1066,7 @@ module GoodData
|
|
1022
1066
|
#
|
1023
1067
|
# @param list List of users to be updated
|
1024
1068
|
# @param role_list Optional list of cached roles to prevent unnecessary server round-trips
|
1025
|
-
def set_users_roles(list,
|
1069
|
+
def set_users_roles(list, _role_list = roles)
|
1026
1070
|
list.pmap do |user_hash|
|
1027
1071
|
user = user_hash[:user]
|
1028
1072
|
roles = user_hash[:role] || user_hash[:roles]
|
@@ -353,16 +353,15 @@ module GoodData
|
|
353
353
|
def lint(full = false)
|
354
354
|
errors = []
|
355
355
|
find_star_centers.each do |dataset|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
end
|
356
|
+
next unless dataset.anchor?
|
357
|
+
errors << {
|
358
|
+
type: :anchor_on_fact_dataset,
|
359
|
+
dataset_name: dataset.name,
|
360
|
+
anchor_name: dataset.anchor[:name]
|
361
|
+
}
|
363
362
|
end
|
364
363
|
|
365
|
-
date_facts = datasets.mapcat
|
364
|
+
date_facts = datasets.mapcat(&:date_facts)
|
366
365
|
date_facts.each do |date_fact|
|
367
366
|
errors << {
|
368
367
|
type: :date_fact,
|
@@ -414,7 +413,7 @@ module GoodData
|
|
414
413
|
when :stupid
|
415
414
|
reports = suggest_metrics.reduce([]) do |a, e|
|
416
415
|
star, metrics = e
|
417
|
-
metrics.each
|
416
|
+
metrics.each(&:save)
|
418
417
|
reports_stubs = metrics.map do |m|
|
419
418
|
breaks = can_break(star).map { |ds, aM| ds.identifier_for(aM) }
|
420
419
|
# [breaks.sample((breaks.length/10.0).ceil), m]
|
@@ -443,7 +442,7 @@ module GoodData
|
|
443
442
|
# @return [Array<Hash>]
|
444
443
|
def suggest_metrics
|
445
444
|
stars = find_star_centers
|
446
|
-
metrics = stars.map
|
445
|
+
metrics = stars.map(&:suggest_metrics)
|
447
446
|
stars.zip(metrics)
|
448
447
|
end
|
449
448
|
|
@@ -15,7 +15,7 @@ module GoodData
|
|
15
15
|
pb
|
16
16
|
end
|
17
17
|
|
18
|
-
def create(title,
|
18
|
+
def create(title, _options = {}, &block)
|
19
19
|
pb = ProjectBuilder.new(title)
|
20
20
|
block.call(pb)
|
21
21
|
pb
|
@@ -104,7 +104,7 @@ module GoodData
|
|
104
104
|
eliminate_empty = options[:eliminate_empty] || false
|
105
105
|
|
106
106
|
if eliminate_empty
|
107
|
-
JSON.pretty_generate(to_hash.reject { |
|
107
|
+
JSON.pretty_generate(to_hash.reject { |_k, v| v.is_a?(Enumerable) && v.empty? })
|
108
108
|
else
|
109
109
|
JSON.pretty_generate(to_hash)
|
110
110
|
end
|
@@ -66,7 +66,7 @@ module GoodData
|
|
66
66
|
# pp response
|
67
67
|
while response.code != 200
|
68
68
|
sleep 1
|
69
|
-
|
69
|
+
GoodData::Rest::Client.retryable(:tries => 3, :on => RestClient::InternalServerError) do
|
70
70
|
sleep 1
|
71
71
|
response = client.get(link, :process => false)
|
72
72
|
# pp response
|
@@ -106,7 +106,7 @@ module GoodData
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
def migrate_users(
|
109
|
+
def migrate_users(_project, spec)
|
110
110
|
spec.each do |user|
|
111
111
|
puts "Would migrate user #{user}"
|
112
112
|
# project.add_user(user)
|
@@ -114,7 +114,7 @@ module GoodData
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def load(project, spec)
|
117
|
-
if spec.key?(:uploads)
|
117
|
+
if spec.key?(:uploads) # rubocop:disable Style/GuardClause
|
118
118
|
spec[:uploads].each do |load|
|
119
119
|
schema = GoodData::Model::Schema.new(spec[:datasets].find { |d| d[:name] == load[:dataset] })
|
120
120
|
project.upload(load[:source], schema, load[:mode])
|
@@ -122,7 +122,7 @@ module GoodData
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
def execute_tests(
|
125
|
+
def execute_tests(_project, spec)
|
126
126
|
spec.each do |assert|
|
127
127
|
result = GoodData::ReportDefinition.execute(assert[:report])
|
128
128
|
fail "Test did not pass. Got #{result.table.inspect}, expected #{assert[:result].inspect}" if result.table != assert[:result]
|