gooddata 0.6.0.pre11 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -1
  3. data/.yardopts +2 -0
  4. data/README.md +6 -3
  5. data/Rakefile +24 -7
  6. data/gooddata +2 -2
  7. data/gooddata.gemspec +4 -3
  8. data/lib/gooddata.rb +17 -12
  9. data/lib/gooddata/bricks/base_downloader.rb +7 -7
  10. data/lib/gooddata/bricks/brick.rb +7 -8
  11. data/lib/gooddata/bricks/bricks.rb +4 -1
  12. data/lib/gooddata/bricks/middleware/base_middleware.rb +2 -2
  13. data/lib/gooddata/bricks/middleware/bench_middleware.rb +5 -6
  14. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +21 -22
  15. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +3 -4
  16. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +14 -14
  17. data/lib/gooddata/bricks/middleware/logger_middleware.rb +6 -6
  18. data/lib/gooddata/bricks/middleware/middleware.rb +4 -1
  19. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +29 -32
  20. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +5 -5
  21. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +6 -8
  22. data/lib/gooddata/bricks/utils.rb +3 -3
  23. data/lib/gooddata/cli/cli.rb +4 -2
  24. data/lib/gooddata/cli/commands/api_cmd.rb +6 -4
  25. data/lib/gooddata/cli/commands/auth_cmd.rb +5 -3
  26. data/lib/gooddata/cli/commands/console_cmd.rb +1 -1
  27. data/lib/gooddata/cli/commands/process_cmd.rb +6 -4
  28. data/lib/gooddata/cli/commands/profile_cmd.rb +5 -3
  29. data/lib/gooddata/cli/commands/project_cmd.rb +24 -22
  30. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +12 -10
  31. data/lib/gooddata/cli/commands/scaffold_cmd.rb +8 -6
  32. data/lib/gooddata/cli/hooks.rb +4 -2
  33. data/lib/gooddata/cli/shared.rb +3 -1
  34. data/lib/gooddata/cli/terminal.rb +16 -0
  35. data/lib/gooddata/client.rb +28 -22
  36. data/lib/gooddata/commands/api.rb +43 -26
  37. data/lib/gooddata/commands/auth.rb +22 -53
  38. data/lib/gooddata/commands/base.rb +2 -0
  39. data/lib/gooddata/commands/commands.rb +3 -0
  40. data/lib/gooddata/commands/datasets.rb +39 -136
  41. data/lib/gooddata/commands/process.rb +134 -130
  42. data/lib/gooddata/commands/profile.rb +2 -0
  43. data/lib/gooddata/commands/projects.rb +91 -129
  44. data/lib/gooddata/commands/runners.rb +11 -11
  45. data/lib/gooddata/commands/scaffold.rb +28 -26
  46. data/lib/gooddata/connection.rb +61 -68
  47. data/lib/gooddata/core/core.rb +1 -2
  48. data/lib/gooddata/data/data.rb +7 -0
  49. data/lib/gooddata/data/guesser.rb +114 -0
  50. data/lib/gooddata/exceptions/command_failed.rb +7 -0
  51. data/lib/gooddata/exceptions/exceptions.rb +7 -0
  52. data/lib/gooddata/{exceptions.rb → exceptions/project_not_found.rb} +2 -2
  53. data/lib/gooddata/extensions/big_decimal.rb +5 -0
  54. data/lib/gooddata/extract.rb +2 -0
  55. data/lib/gooddata/goodzilla/goodzilla.rb +11 -12
  56. data/lib/gooddata/helpers.rb +49 -35
  57. data/lib/gooddata/models/attribute.rb +7 -5
  58. data/lib/gooddata/models/dashboard.rb +44 -45
  59. data/lib/gooddata/models/data_result.rb +10 -13
  60. data/lib/gooddata/models/data_set.rb +6 -6
  61. data/lib/gooddata/models/display_form.rb +4 -4
  62. data/lib/gooddata/models/empty_result.rb +4 -3
  63. data/lib/gooddata/models/fact.rb +5 -5
  64. data/lib/gooddata/models/links.rb +3 -1
  65. data/lib/gooddata/models/metadata.rb +34 -32
  66. data/lib/gooddata/models/metric.rb +33 -34
  67. data/lib/gooddata/models/model.rb +165 -173
  68. data/lib/gooddata/models/models.rb +3 -0
  69. data/lib/gooddata/models/process.rb +18 -17
  70. data/lib/gooddata/models/profile.rb +3 -1
  71. data/lib/gooddata/models/project.rb +107 -35
  72. data/lib/gooddata/models/project_metadata.rb +12 -12
  73. data/lib/gooddata/models/report.rb +31 -30
  74. data/lib/gooddata/models/report_data_result.rb +22 -19
  75. data/lib/gooddata/models/report_definition.rb +101 -80
  76. data/lib/gooddata/version.rb +5 -3
  77. data/lib/templates/bricks/brick.rb.erb +3 -3
  78. data/lib/templates/bricks/main.rb.erb +3 -2
  79. data/lib/templates/project/Goodfile.erb +2 -2
  80. data/lib/templates/project/model/model.rb.erb +19 -19
  81. data/spec/data/.gooddata +4 -0
  82. data/spec/helpers/blueprint_helper.rb +2 -2
  83. data/spec/helpers/cli_helper.rb +28 -0
  84. data/spec/helpers/connection_helper.rb +2 -2
  85. data/spec/integration/command_projects_spec.rb +1 -1
  86. data/spec/integration/create_from_template_spec.rb +12 -0
  87. data/spec/integration/full_project_spec.rb +2 -2
  88. data/spec/integration/partial_md_export_import_spec.rb +36 -0
  89. data/spec/logging_in_logging_out_spec.rb +1 -1
  90. data/spec/spec_helper.rb +29 -2
  91. data/spec/unit/cli/cli_spec.rb +3 -3
  92. data/spec/unit/cli/commands/cmd_api_spec.rb +21 -4
  93. data/spec/unit/cli/commands/cmd_auth_spec.rb +2 -4
  94. data/spec/unit/cli/commands/cmd_process_spec.rb +20 -4
  95. data/spec/unit/cli/commands/cmd_profile_spec.rb +9 -4
  96. data/spec/unit/cli/commands/cmd_project_spec.rb +53 -4
  97. data/spec/unit/cli/commands/cmd_run_ruby_spec.rb +2 -4
  98. data/spec/unit/cli/commands/cmd_scaffold_spec.rb +14 -4
  99. data/spec/unit/commands/command_api_spec.rb +21 -2
  100. data/spec/unit/commands/command_auth_spec.rb +62 -1
  101. data/spec/unit/commands/command_dataset_spec.rb +31 -3
  102. data/spec/unit/commands/command_process_spec.rb +75 -1
  103. data/spec/unit/commands/command_profile_spec.rb +7 -1
  104. data/spec/unit/commands/command_projects_spec.rb +1 -1
  105. data/spec/unit/commands/command_scaffold_spec.rb +46 -1
  106. data/spec/unit/core/connection_spec.rb +1 -0
  107. data/spec/unit/data/guesser_spec.rb +54 -0
  108. data/spec/unit/helpers_spec.rb +47 -0
  109. data/spec/unit/model/schema_builder_spec.rb +2 -0
  110. data/spec/unit/model/tools_spec.rb +89 -0
  111. data/test/test_upload.rb +39 -15
  112. metadata +98 -75
  113. data/test/test_commands.rb +0 -85
  114. data/test/test_guessing.rb +0 -46
  115. data/test/test_model.rb +0 -81
  116. data/test/test_rest_api_basic.rb +0 -41
@@ -1,151 +1,155 @@
1
- module GoodData::Command
2
- class Process
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Command
5
+ class Process
6
+ class << self
7
+ def list(options={})
8
+ GoodData.with_project(options[:project_id]) do
9
+ processes = GoodData::Process[:all]
10
+ end
11
+ end
3
12
 
4
- def self.list(options={})
5
- GoodData.with_project(options[:project_id]) do
6
- processes = GoodData::Process[:all]
7
- end
8
- end
13
+ def get(options={})
14
+ id = options[:process_id]
15
+ fail 'Unspecified process id' if id.nil?
9
16
 
10
- def self.get(options={})
11
- id = options[:process_id]
12
- fail "Unspecified process id" if id.nil?
13
-
14
- GoodData.with_project(options[:project_id]) do
15
- GoodData::Process[id]
16
- end
17
- end
17
+ GoodData.with_project(options[:project_id]) do
18
+ GoodData::Process[id]
19
+ end
20
+ end
18
21
 
19
- def self.deploy(dir, options={})
20
- verbose = options[:verbose] || false
21
- GoodData.with_project(options[:project_id]) do
22
- params = options[:params].nil? ? [] : [options[:params]]
23
- deploy_graph(dir, options.merge({:files_to_exclude => params}))
24
- end
25
- end
22
+ def deploy(dir, options={})
23
+ verbose = options[:verbose] || false
24
+ GoodData.with_project(options[:project_id]) do
25
+ params = options[:params].nil? ? [] : [options[:params]]
26
+ deploy_graph(dir, options.merge({:files_to_exclude => params}))
27
+ end
28
+ end
26
29
 
27
- def self.with_deploy(dir, options={}, &block)
28
- verbose = options[:verbose] || false
29
- GoodData.with_project(options[:project_id]) do
30
- params = options[:params].nil? ? [] : [options[:params]]
31
- if block
32
- begin
33
- res = deploy_graph(dir, options.merge({:files_to_exclude => params}))
34
- block.call(res)
35
- ensure
36
- self_link = res && res["process"]["links"]["self"]
37
- GoodData.delete(self_link)
30
+ def with_deploy(dir, options={}, &block)
31
+ verbose = options[:verbose] || false
32
+ GoodData.with_project(options[:project_id]) do |project|
33
+ params = options[:params].nil? ? [] : [options[:params]]
34
+ if block
35
+ begin
36
+ res = deploy_graph(dir, options.merge({:files_to_exclude => params}))
37
+ block.call(res)
38
+ ensure
39
+ self_link = res && res['process']['links']['self']
40
+ GoodData.delete(self_link)
41
+ end
42
+ else
43
+ deploy_graph(dir, options.merge({:files_to_exclude => params}))
44
+ end
38
45
  end
39
- else
40
- deploy_graph(dir, options.merge({:files_to_exclude => params}))
41
46
  end
42
- end
43
- end
44
47
 
45
- def self.execute_process(link, dir, options={})
46
- dir = Pathname(dir)
47
- type = :ruby
48
- if type == :ruby
49
- result = GoodData.post(link, {
50
- :execution => {
51
- :graph => ("./main.rb").to_s,
52
- :params => options[:expanded_params]
53
- }
54
- })
55
- begin
56
- GoodData.poll(result, "executionTask")
57
- rescue RestClient::RequestFailed => e
58
-
59
- ensure
60
- result = GoodData.get(result["executionTask"]["links"]["detail"])
61
- if result["executionDetail"]["status"] == "ERROR"
62
- fail "Runing process failed. You can look at a log here #{result["executionDetail"]["logFileName"]}"
48
+ def execute_process(link, dir, options={})
49
+ dir = Pathname(dir)
50
+ type = :ruby
51
+ if type == :ruby
52
+ result = GoodData.post(link, {
53
+ :execution => {
54
+ :graph => ('./main.rb').to_s,
55
+ :params => options[:expanded_params]
56
+ }
57
+ })
58
+ begin
59
+ GoodData.poll(result, 'executionTask')
60
+ rescue RestClient::RequestFailed => e
61
+
62
+ ensure
63
+ result = GoodData.get(result['executionTask']['links']['detail'])
64
+ if result['executionDetail']['status'] == 'ERROR'
65
+ fail "Runing process failed. You can look at a log here #{result["executionDetail"]["logFileName"]}"
66
+ end
67
+ end
68
+ result
69
+ else
70
+ result = GoodData.post(link, {
71
+ :execution => {
72
+ :graph => dir + 'graphs/main.grf',
73
+ :params => {}
74
+ }
75
+ })
76
+ begin
77
+ GoodData.poll(result, 'executionTask')
78
+ rescue RestClient::RequestFailed => e
79
+
80
+ ensure
81
+ result = GoodData.get(result['executionTask']['links']['detail'])
82
+ if result['executionDetail']['status'] == 'ERROR'
83
+ fail "Runing process failed. You can look at a log here #{result["executionDetail"]["logFileName"]}"
84
+ end
85
+ end
86
+ result
63
87
  end
64
88
  end
65
- result
66
- else
67
- result = GoodData.post(link, {
68
- :execution => {
69
- :graph => dir + "graphs/main.grf",
70
- :params => {}
71
- }
72
- })
73
- begin
74
- GoodData.poll(result, "executionTask")
75
- rescue RestClient::RequestFailed => e
76
-
77
- ensure
78
- result = GoodData.get(result["executionTask"]["links"]["detail"])
79
- if result["executionDetail"]["status"] == "ERROR"
80
- fail "Runing process failed. You can look at a log here #{result["executionDetail"]["logFileName"]}"
89
+
90
+ def run(dir, options={})
91
+ email = options[:email]
92
+ verbose = options[:v]
93
+ dir = Pathname(dir)
94
+ name = options[:name] || "Temporary deploy[#{dir}][#{options[:project_name]}]"
95
+
96
+ with_deploy(dir, options.merge(:name => name)) do |deploy_response|
97
+ puts HighLine::color('Executing', HighLine::BOLD) if verbose
98
+ result = execute_process(deploy_response['process']['links']['executions'], dir, options)
81
99
  end
82
100
  end
83
- result
84
- end
85
- end
86
101
 
87
- def self.run(dir, options={})
88
- email = options[:email]
89
- verbose = options[:v]
90
- dir = Pathname(dir)
91
- name = options[:name] || "Temporary deploy[#{dir}][#{options[:project_name]}]"
102
+ private
92
103
 
93
- with_deploy(dir, options.merge(:name => name)) do |deploy_response|
94
- puts HighLine::color("Executing", HighLine::BOLD) if verbose
95
- result = execute_process(deploy_response["process"]["links"]["executions"], dir, options)
96
- end
97
- end
104
+ def deploy_graph(dir, options={})
105
+ dir = Pathname(dir) || fail('Directory is not specified')
106
+ fail "\"#{dir}\" is not a directory" unless dir.directory?
107
+ files_to_exclude = options[:files_to_exclude].map { |p| Pathname(p) }
108
+
109
+ project_id = options[:project_id] || fail('Project Id has to be specified')
98
110
 
99
- private
100
- def self.deploy_graph(dir, options={})
101
- dir = Pathname(dir) || fail("Directory is not specified")
102
- fail "\"#{dir}\" is not a directory" unless dir.directory?
103
- files_to_exclude = options[:files_to_exclude].map {|p| Pathname(p)}
104
-
105
- project_id = options[:project_id] || fail("Project Id has to be specified")
106
-
107
- type = options[:type] || "GRAPH"
108
- deploy_name = options[:name]
109
- verbose = options[:verbose] || false
110
-
111
- puts HighLine::color("Deploying #{dir}", HighLine::BOLD) if verbose
112
- res = nil
113
-
114
- Tempfile.open("deploy-graph-archive") do |temp|
115
- Zip::OutputStream.open(temp.path) do |zio|
116
- FileUtils::cd(dir) do
117
-
118
- files_to_pack = Dir.glob("./**/*").reject {|f| files_to_exclude.include?(Pathname(dir) + f)}
119
- files_to_pack.each do |item|
120
- puts "including #{item}" if verbose
121
- unless File.directory?(item)
122
- zio.put_next_entry(item)
123
- zio.print IO.read(item)
111
+ type = options[:type] || 'GRAPH'
112
+ deploy_name = options[:name]
113
+ verbose = options[:verbose] || false
114
+
115
+ puts HighLine::color("Deploying #{dir}", HighLine::BOLD) if verbose
116
+ res = nil
117
+
118
+ Tempfile.open('deploy-graph-archive') do |temp|
119
+ Zip::OutputStream.open(temp.path) do |zio|
120
+ FileUtils::cd(dir) do
121
+
122
+ files_to_pack = Dir.glob('./**/*').reject { |f| files_to_exclude.include?(Pathname(dir) + f) }
123
+ files_to_pack.each do |item|
124
+ puts "including #{item}" if verbose
125
+ unless File.directory?(item)
126
+ zio.put_next_entry(item)
127
+ zio.print IO.read(item)
128
+ end
129
+ end
124
130
  end
125
131
  end
126
- end
127
- end
128
132
 
129
- GoodData.upload_to_user_webdav(temp.path)
130
- process_id = options[:process]
131
-
132
- data = {
133
- :process => {
134
- :name => deploy_name,
135
- :path => "/uploads/#{File.basename(temp.path)}",
136
- :type => type
137
- }
138
- }
139
- res = if process_id.nil?
140
- GoodData.post("/gdc/projects/#{GoodData.project.pid}/dataload/processes", data)
141
- else
142
- GoodData.put("/gdc/projects/#{GoodData.project.pid}/dataload/processes/#{process_id}", data)
133
+ GoodData.upload_to_user_webdav(temp.path)
134
+ process_id = options[:process]
135
+
136
+ data = {
137
+ :process => {
138
+ :name => deploy_name,
139
+ :path => "/uploads/#{File.basename(temp.path)}",
140
+ :type => type
141
+ }
142
+ }
143
+ res = if process_id.nil?
144
+ GoodData.post("/gdc/projects/#{GoodData.project.pid}/dataload/processes", data)
145
+ else
146
+ GoodData.put("/gdc/projects/#{GoodData.project.pid}/dataload/processes/#{process_id}", data)
147
+ end
148
+ end
149
+ puts HighLine::color("Deploy DONE #{dir}", HighLine::GREEN) if verbose
150
+ res
143
151
  end
144
152
  end
145
- puts HighLine::color("Deploy DONE #{dir}", HighLine::GREEN) if verbose
146
- res
147
153
  end
148
-
149
-
150
154
  end
151
- end
155
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module GoodData::Command
2
4
  class Profile
3
5
  class << self
@@ -1,147 +1,109 @@
1
+ # encoding: UTF-8
2
+
1
3
  module GoodData::Command
2
4
  class Projects
5
+ class << self
6
+ def list
7
+ GoodData::Project.all
8
+ end
3
9
 
4
- def self.list
5
- GoodData::Project.all
6
- end
7
-
8
- def self.create(options={})
9
- title = options[:title]
10
- summary = options[:summary]
11
- template = options[:template]
12
- token = options[:token]
13
-
14
- GoodData::Project.create(:title => title, :summary => summary, :template => template, :auth_token => token)
15
- end
10
+ # Create new project based on options supplied
11
+ def create(options={})
12
+ title = options[:title]
13
+ summary = options[:summary]
14
+ template = options[:template]
15
+ token = options[:token]
16
16
 
17
- def self.show(id)
18
- GoodData::Project[id]
19
- end
17
+ GoodData::Project.create(:title => title, :summary => summary, :template => template, :auth_token => token)
18
+ end
20
19
 
21
- def self.clone(project_id, options)
22
- with_data = options[:with_data]
23
- with_users = options[:with_users]
24
- title = options[:title]
25
-
26
- export = {
27
- :exportProject => {
28
- :exportUsers => with_users ? 1 : 0,
29
- :exportData => with_data ? 1 : 0
30
- }
31
- }
32
-
33
- result = GoodData.post("/gdc/md/#{project_id}/maintenance/export", export)
34
- export_token = result["exportArtifact"]["token"]
35
- status_url = result["exportArtifact"]["status"]["uri"]
36
-
37
- state = GoodData.get(status_url)["taskState"]["status"]
38
- while state == "RUNNING"
39
- sleep 5
40
- result = GoodData.get(status_url)
41
- state = result["taskState"]["status"]
20
+ # Show existing project
21
+ def show(id)
22
+ GoodData::Project[id]
42
23
  end
43
24
 
44
- old_project = GoodData::Project[project_id]
45
- project_uri = self.create(options.merge({:title => "Clone of #{old_project.title}"}))
46
- new_project = GoodData::Project[project_uri]
25
+ # Clone existing project
26
+ def clone(project_id, options)
27
+ with_data = options[:with_data]
28
+ with_users = options[:with_users]
29
+ title = options[:title]
30
+
31
+ export = {
32
+ :exportProject => {
33
+ :exportUsers => with_users ? 1 : 0,
34
+ :exportData => with_data ? 1 : 0
35
+ }
36
+ }
47
37
 
48
- import = {
49
- :importProject => {
50
- :token => export_token
38
+ result = GoodData.post("/gdc/md/#{project_id}/maintenance/export", export)
39
+ export_token = result['exportArtifact']['token']
40
+ status_url = result['exportArtifact']['status']['uri']
41
+
42
+ state = GoodData.get(status_url)['taskState']['status']
43
+ while state == 'RUNNING'
44
+ sleep 5
45
+ result = GoodData.get(status_url)
46
+ state = result['taskState']['status']
47
+ end
48
+
49
+ old_project = GoodData::Project[project_id]
50
+ project_uri = self.create(options.merge({:title => "Clone of #{old_project.title}"}))
51
+ new_project = GoodData::Project[project_uri]
52
+
53
+ import = {
54
+ :importProject => {
55
+ :token => export_token
56
+ }
51
57
  }
52
- }
53
- result = GoodData.post("/gdc/md/#{new_project.obj_id}/maintenance/import", import)
54
- status_url = result["uri"]
55
- state = GoodData.get(status_url)["taskState"]["status"]
56
- while state == "RUNNING"
57
- sleep 5
58
- result = GoodData.get(status_url)
59
- state = result["taskState"]["status"]
58
+ result = GoodData.post("/gdc/md/#{new_project.obj_id}/maintenance/import", import)
59
+ status_url = result['uri']
60
+ state = GoodData.get(status_url)['taskState']['status']
61
+ while state == 'RUNNING'
62
+ sleep 5
63
+ result = GoodData.get(status_url)
64
+ state = result['taskState']['status']
65
+ end
66
+ true
60
67
  end
61
- true
62
- end
63
68
 
64
- def self.delete(project_id)
65
- p = GoodData::Project[project_id]
66
- p.delete
67
- end
69
+ # Delete existing project
70
+ def delete(project_id)
71
+ p = GoodData::Project[project_id]
72
+ p.delete
73
+ end
68
74
 
69
- def self.get_spec_and_project_id(base_path)
70
- goodfile_path = GoodData::Helpers.find_goodfile(Pathname(base_path))
71
- fail "Goodfile could not be located in any parent directory. Please make sure you are inside a gooddata project folder." if goodfile_path.nil?
72
- goodfile = JSON.parse(File.read(goodfile_path), :symbolize_names => true)
73
- spec_path = goodfile[:model] || fail("You need to specify the path of the build spec")
74
- fail "Model path provided in Goodfile \"#{spec_path}\" does not exist" unless File.exist?(spec_path) && !File.directory?(spec_path)
75
-
76
- spec_path = Pathname(spec_path)
77
-
78
- content = File.read(spec_path)
79
- spec = if (spec_path.extname == ".rb")
80
- eval(content)
81
- elsif (spec_path.extname == ".json")
82
- JSON.parse(spec_path, :symbolize_names => true)
83
- end
84
- [spec, goodfile[:project_id]]
85
- end
75
+ # Get Spec and ID (of project)
76
+ def get_spec_and_project_id(base_path)
77
+ goodfile_path = GoodData::Helpers.find_goodfile(Pathname(base_path))
78
+ fail 'Goodfile could not be located in any parent directory. Please make sure you are inside a gooddata project folder.' if goodfile_path.nil?
79
+ goodfile = MultiJson.load(File.read(goodfile_path), :symbolize_keys => true)
80
+ spec_path = goodfile[:model] || fail('You need to specify the path of the build spec')
81
+ fail "Model path provided in Goodfile \"#{spec_path}\" does not exist" unless File.exist?(spec_path) && !File.directory?(spec_path)
82
+
83
+ spec_path = Pathname(spec_path)
84
+
85
+ content = File.read(spec_path)
86
+ spec = if (spec_path.extname == '.rb')
87
+ eval(content)
88
+ elsif (spec_path.extname == '.json')
89
+ MultiJson.load(spec_path, :symbolize_keys => true)
90
+ end
91
+ [spec, goodfile[:project_id]]
92
+ end
86
93
 
87
- def self.update(options={})
88
- project = options[:project]
89
- project_id = project && project.pid
90
- fail "You have to provide 'project_id'. You can either provide it through -p flag or even better way is to fill it in in your Goodfile under key \"project_id\". If you just started a project you have to create it first. One way might be through \"gooddata project build\"" if project_id.nil? || project_id.empty?
91
- GoodData::Model::ProjectCreator.migrate(:spec => options[:spec], :project => project_id)
92
- end
94
+ # Update project
95
+ def update(options={})
96
+ project = options[:project]
97
+ project_id = project && project.pid
98
+ fail 'You have to provide "project_id". You can either provide it through -p flag or even better way is to fill it in in your Goodfile under key "project_id". If you just started a project you have to create it first. One way might be through "gooddata project build"' if project_id.nil? || project_id.empty?
99
+ GoodData::Model::ProjectCreator.migrate(:spec => options[:spec], :project => project_id)
100
+ end
93
101
 
94
- def self.build(options={})
95
- GoodData::Model::ProjectCreator.migrate(:spec => options[:spec], :token => options[:token])
102
+ # Build project
103
+ def build(options={})
104
+ GoodData::Model::ProjectCreator.migrate(:spec => options[:spec], :token => options[:token])
105
+ end
96
106
  end
97
-
98
107
  end
99
108
  end
100
109
 
101
- # module GoodData
102
- # module Command
103
- # class Projects
104
- # class << self
105
- # def list
106
- # Project.all
107
- # end
108
- # alias :index :list
109
- #
110
- # def create
111
- # title = ask "Project name"
112
- # summary = ask "Project summary"
113
- # template = ask "Project template", :default => ''
114
- #
115
- # project = Project.create :title => title, :summary => summary, :template => template
116
- #
117
- # puts "Project '#{project.title}' with id #{project.uri} created successfully!"
118
- # end
119
- #
120
- # def show
121
- # id = args.shift rescue nil
122
- # raise(CommandFailed, "Specify the project key you wish to show.") if id.nil?
123
- # connect
124
- # pp Project[id].to_json
125
- # end
126
- #
127
- # def delete
128
- # raise(CommandFailed, "Specify the project key(s) for the project(s) you wish to delete.") if args.size == 0
129
- # connect
130
- # while args.size > 0
131
- # id = args.shift
132
- # project = Project[id]
133
- # ask "Do you want to delete the project '#{project.title}' with id #{project.uri}", :answers => %w(y n) do |answer|
134
- # case answer
135
- # when 'y' then
136
- # puts "Deleting #{project.title}..."
137
- # project.delete
138
- # puts "Project '#{project.title}' with id #{project.uri} deleted successfully!"
139
- # when 'n' then
140
- # puts "Aborting..."
141
- # end
142
- # end
143
- # end
144
- # end
145
- # end
146
- # end
147
- # end