#!/usr/bin/env ruby require 'gli' require 'gooddata' require 'highline/import' require 'gooddata/commands/projects' require 'gooddata/commands/auth' require 'gooddata/commands/scaffold' require 'gooddata/commands/process' require 'gooddata/commands/api' require 'gooddata/commands/profile' require 'pp' include GLI::App program_desc 'GoodData Ruby gem - a wrapper over GoodData API and several useful abstractions to make your everyday usage of GoodData easier.' version GoodData::VERSION desc 'GoodData user name' default_value nil arg_name 'gooddata-login' flag [:U,:username] desc 'GoodData password' default_value nil arg_name 'gooddata-password' flag [:P,:password] desc 'Project pid' default_value nil arg_name 'project-id' flag [:p,:project_id] desc 'Server' default_value nil arg_name 'server' flag [:s,:server] desc 'WEBDAV Server. Used for uploads of files' default_value nil arg_name 'web dav server' flag [:w,:webdav_server] desc 'Token for project creation' default_value nil arg_name 'token' flag [:t, :token] desc 'Verbose mode' arg_name 'verbose' switch [:v,:verbose] desc 'Http logger on stdout' arg_name 'logger' switch [:l,:logger] desc 'Describe list here' arg_name 'Describe arguments to list here' command :process do |c| c.desc 'Use when you need to redeploy a process' c.default_value nil c.flag :process_id c.desc 'Specify directory for deployment' c.default_value nil c.flag :dir c.desc 'Specify type of deployment' c.default_value nil c.flag :type c.desc 'Specify name of deployed process' c.default_value nil c.flag :name c.command :list do |list| list.action do |global_options,options,args| pp GoodData::Command::Process.list(options.merge(global_options)) end end c.command :get do |get| get.action do |global_options,options,args| pp GoodData::Command::Process.get(options.merge(global_options)) end end c.command :deploy do |deploy| deploy.action do |global_options,options,args| pp GoodData::Command::Process.deploy(options[:dir], options.merge(global_options)) end end end desc 'Some basic API stuff directly from CLI' arg_name 'info|test|get|delete' command :api do |c| c.command :info do |info| info.action do |global_options,options,args| pp GoodData::Command::Api.info end end c.command :get do |get| get.action do |global_options,options,args| pp GoodData::Command::Api.get(args[0]) end end end desc 'Describe add here' arg_name 'show' command :profile do |c| c.command :show do |show| show.action do |global_options,options,args| pp GoodData::Command::Profile.show() end end end desc 'Scaffold things' arg_name 'show' command :scaffold do |c| c.action do |global_options, options, args| c.command :brick do |brick| brick.arg_name 'name' name = args[1] fail "Name of the brick has to be provided" if name.nil? || name.empty? GoodData::Command::Scaffold.brick(name) end end end desc 'Manage your projects' arg_name 'project_command' command :project do |c| c.command :list do |list| list.action do |global_options,options,args| list = GoodData::Command::Projects.list() puts list.map {|p| [p.uri, p.title].join(",")} end end c.command :jack_in do |jack| jack.action do |global_options,options,args| goodfile = JSON.parse(File.read(GoodData::Helpers.find_goodfile(Pathname('.'))), :symbolize_names => true) model_key = goodfile[:model] blueprint = GoodData::Model::ProjectBlueprint.new(eval(File.read(model_key)).to_hash) if File.exist?(model_key) && !File.directory?(model_key) project_id = global_options[:project_id] || goodfile[:project_id] fail "You have to provide 'project_id'" if project_id.nil? GoodData.with_project(project_id) do |project| puts "Use 'exit' to quit the interactive session. Use 'q' to jump out of displaying a large output." binding.pry(:quiet => true, :prompt => [proc { |target_self, nest_level, pry| "project_live_sesion: " }]) end end end c.command :create do |create| create.action do |global_options,options,args| title = ask "Project name" summary = ask("Project summary") { |q| q.default = "" } template = ask("Project template") token = ask("token") project = GoodData::Command::Projects.create({ :title => title, :summary => summary, :template => template, :token => token }) puts "Project '#{project.title}' with id #{project.uri} created successfully!" end end c.command :delete do |delete| delete.action do |global_options,options,args| id = global_options[:project_id] GoodData::Command::Projects.delete(id) end end c.command :clone do |clone| clone.desc 'Name of the new project' clone.default_value nil clone.arg_name 'cloned_project_name' clone.flag [:n, :name] clone.desc 'Token of the new project' clone.default_value nil clone.arg_name 'token' clone.flag [:t, :token] clone.action do |global_options,options,args| id = global_options[:project_id] name = options[:name] token = options[:token] GoodData::Command::Projects.clone(id, :name => name, :token => token) end end c.command :show do |show| show.action do |global_options,options,args| id = global_options[:project_id] p = GoodData::Command::Projects.show(id) pp p.data end end c.command :build do |show| show.action do |global_options,options,args| goodfile = JSON.parse(File.read(GoodData::Helpers.find_goodfile(Pathname('.'))), :symbolize_names => true) spec_path = goodfile[:model] || fail("You need to specify the path of the build spec") fail "Model path provided in Goodfile \"#{spec_path}\" does not exist" unless File.exist?(spec_path) && !File.directory?(spec_path) opts = options.merge(global_options) spec_path = Pathname(spec_path) content = File.read(spec_path) spec = if (spec_path.extname == ".rb") eval(content) elsif (spec_path.extname == ".json") JSON.parse(spec_path, :symbolize_names => true) end new_project = GoodData::Model::ProjectCreator.migrate(opts.merge(:spec => spec)) puts "Migration was done. New project PID is #{new_project.uri}." end end end desc 'Work with your credentials' command :auth do |c| c.command :store do |store| store.action do |global_options,options,args| GoodData::Command::Auth.store end end end desc 'Run bricks locally' # arg_name 'show' command :run_ruby do |c| c.desc 'Directory of the ruby brick' c.default_value nil c.flag [:d, :dir] c.desc 'Log file. If empty STDOUT will be used instead' c.default_value nil c.flag [:l, :logger] c.desc 'Params file path. Inside should be hash of key values' c.default_value nil c.flag [:params] c.desc 'Run on remote machine' c.switch [:r, :remote] c.desc 'Name of the deployed process' c.default_value nil c.flag [:n, :name] c.action do |global_options, options, args| options[:expanded_params] = if (options[:params]) JSON.parse(File.read(options[:params]), :symbolize_names => true) else {} end opts = options.merge(global_options).merge({:type => "RUBY"}) if options[:remote] fail "You have to specify name of the deploy when deploying remotely" if options[:name].nil? || options[:name].empty? require 'gooddata/commands/process' GoodData::Command::Process.run(options[:dir], opts) do puts "would run" end else require 'gooddata/commands/runners' GoodData::Command::Runners.run_ruby_locally(options[:dir], opts) end end end pre do |global,command,options,args| require 'logger' GoodData.logger = Logger.new(STDOUT) if global[:l] username = global[:username] password = global[:password] token = global[:token] creds = GoodData::Command::Auth.read_credentials username = creds[:username] if username.nil? password = creds[:password] if password.nil? token = creds[:auth_token] if token.nil? global[:token] = token if global[:token].nil? global[:username] = username if global[:username].nil? global[:password] = password if global[:password].nil? GoodData.connect(global.merge(options).merge({ :login => username, :password => password, :server => global[:server], :token => token })) # Pre logic here # Return true to proceed; false to abort and not call the # chosen command # Use skips_pre before a command to skip this block # on that command only true end post do |global,command,options,args| # Post logic here # Use skips_post before a command to skip this # block on that command only end on_error do |exception| # Error logic here # return false to skip default error handling # binding.pry pp exception.backtrace pp exception true end exit run(ARGV)