#!/usr/bin/env ruby require "shellwords" require "thor" module DokkuInstaller class Cli < Thor desc "config", "Display the app's environment variables" def config run_command "config #{app_name}" end desc "config:get KEY", "Display an environment variable value" def config_get(*args) run_command "config:get #{app_name} #{args.first}" end desc "config:set KEY1=VALUE1 [KEY2=VALUE2 ...]", "Set one or more environment variables" def config_set(*args) run_command "config:set #{app_name} #{args.join(' ')}" end desc "config:unset KEY1 [KEY2 ...]", "Unset one or more environment variables" def config_unset(*args) run_command "config:unset #{app_name} #{args.join(' ')}" end desc "domains", "Display the app's domains" def domains(*args) run_command "domains #{app_name}" end desc "domains:set DOMAIN1 [DOMAIN2 ...]", "Set one or more domains" def domains_set(*args) run_command "domains:set #{app_name} #{args.join(' ')}" end desc "logs [-t]", "Show the last logs for the application (-t follows)" def logs(*args) if args.first && args.first.strip == "-t" command = "ssh dokku@#{domain} logs #{app_name} -t" puts "Running #{command}..." exec(command) else run_command "logs #{app_name}" end end desc "open", "Open the application in your default browser" def open exec("open http://#{app_name}.#{domain}") end desc "postgres:backups", "List available PostgreSQL backups" def postgres_backups command = "ssh -t dokku@#{domain} postgres:backups #{app_name}" puts "Running #{command}..." backups = `#{command}` backups.split("\n").reverse.each_with_index do |line, index| number = "#{index + 1}" if number.length < 2 number = " #{number}" end puts "#{number}. #{line}" end end desc "postgres:backups:create", "Create a new PostgreSQL backup" def postgres_backups_create run_command "postgres:backups:create #{app_name}" end desc "postgres:backups:disable", "Disable daily PostgreSQL backups" def postgres_backups_disable run_command "postgres:backups:disable #{app_name}" end desc "postgres:backups:download ", "Download the numbered PostgreSQL backup" def postgres_backups_download(*args) # Make sure the number is valid number = args.first ? args.first : 1 number = number.to_s.gsub(/\D/, "").to_i if number < 1 puts "Invalid backup number" return end # Get the file name for the numbered backup puts "Getting list of backups..." command = "ssh -t dokku@#{domain} postgres:backups #{app_name}" backups = `#{command}` index = number - 1 backup = backups.split("\n").reverse[index].strip if backup command = "postgres:backups:download #{app_name} #{backup} > #{backup}" puts "Saving to local file: #{backup}" run_command(command) else puts "Invalid backup number" end end desc "postgres:backups:enable", "Enable daily PostgreSQL backups" def postgres_backups_enable run_command "postgres:backups:enable #{app_name}" end desc "restart", "Restart the application" def restart(*args) run_command "restart #{app_name}" end desc "run ", "Run a command in the environment of the application" def walk(*args) command = "#{args.join(' ')}" case command.gsub(" ", "") when "rakedb:drop" puts "You cannot use `rake db:drop`. Use Dokku directly to delete the database." when "rakedb:create" puts "You cannot use `rake db:create`. Use Dokku directly to create the database." else run_command "run #{app_name} #{command}" end end desc "ssl:certificate ", "Add a signed certificate for SSL (server.crt)" def ssl_certificate(*args) file_path = args.first file_contents = File.read(file_path) dokku_command = "echo \"#{file_contents}\" | ssh dokku@#{domain} ssl:certificate #{app_name}" puts "Running #{dokku_command}..." exec(dokku_command) end desc "ssl:key ", "Add a private key for SSL (server.key)" def ssl_key(*args) file_path = args.first file_contents = File.read(file_path) dokku_command = "echo \"#{file_contents}\" | ssh dokku@#{domain} ssl:key #{app_name}" puts "Running #{dokku_command}..." exec(dokku_command) end desc "url", "Show the URL for the application" def url puts "http://#{app_name}.#{domain}" end desc "version", "Show dokku-installer-cli's version" def version puts "Dokku Installer CLI #{DokkuInstaller::VERSION}" end def help(method = nil) method = "walk" if method == "run" super end def method_missing(method, *args, &block) if method.to_s.split(":").length >= 2 self.send(method.to_s.gsub(":", "_"), *args) elsif method == :run self.walk(*args) else super end end private def app_name @app_name ||= git_config_match[2] end def domain @domain ||= git_config_match[1] end def git_config_match @git_config_match ||= begin git_config = File.join(Dir.pwd, ".git", "config") exit unless File.exist?(git_config) git_config = File.read(git_config) match = git_config.match(/url \= dokku@(.*):(.*)\n/).to_a exit unless match match end end def run_command(command) dokku_command = "ssh -t dokku@#{domain} #{command}" puts "Running #{dokku_command}..." exec(dokku_command) end end end DokkuInstaller::Cli.start(ARGV)