class Fanforce::CLI require 'fileutils' def get_heroku_app_name(app, environment) heroku_app_name = "#{environment==:production ? 'prd' : 'stg'}-#{app.dir_name}" heroku_app_name.length > 30 ? heroku_app_name.gsub!(/(a|e|i|o|u)/, '') : heroku_app_name end def setup_files(app) if File.directory?("#{app.dir}/tmp") puts "#{'Found '.format(:green,:bold)} #{app.dir_name}/tmp/" else Dir.mkdir("#{app.dir}/tmp") puts "#{'Created'.format(:green,:bold)} #{app.dir_name}/tmp/" end if File.exists?("#{app.dir}/config.ru") app.update_file(:config_ru) puts "#{'Updated'.format(:green,:bold)} #{app.dir_name}/config.ru" else app.create_file(:config_ru) puts "#{'Created'.format(:green,:bold)} #{app.dir_name}/config.ru" end if File.exists?("#{app.dir}/.gitignore") app.update_file(:gitignore) puts "#{'Updated'.format(:green,:bold)} #{app.dir_name}/.gitignore" else app.create_file(:gitignore) puts "#{'Created'.format(:green,:bold)} #{app.dir_name}/.gitignore" end if File.exists?("#{app.dir}/Gemfile") app.update_file(:gemfile) puts "#{'Updated'.format(:green,:bold)} #{app.dir_name}/Gemfile" else app.create_file(:gemfile) puts "#{'Created'.format(:green,:bold)} #{app.dir_name}/Gemfile" end if File.exists?("#{app.dir}/Rakefile") app.update_file(:rakefile) puts "#{'Updated'.format(:green,:bold)} #{app.dir_name}/Rakefile" else app.create_file(:rakefile) puts "#{'Created'.format(:green,:bold)} #{app.dir_name}/Rakefile" end restart(app, :development) end def setup_envs(app, environment) environments = environment == :all ? [:development, :staging, :production] : [environment] if !File.exists?("#{$HomeDir}/.env/_bind.yml") return puts "#{'Oops'.format(:bold)}... you must setup .env/_bind.yml before trying to update env variables." end environments.each do |environment| vars = Env.vars_by_app(environment)[app.dir_name] has_workers = File.directory?("#{app.dir}/workers") ? true : false next puts "#{'Skipped'.format(:bold)} #{environment.to_s.titleize} has 0 env variables" if vars.blank? or vars.size == 0 puts "#{'Updated'.format(:green,:bold)} #{environment.to_s.titleize}#{has_workers ? '... and workers have' : ' has'} #{vars.size} env variables" push_env_to(environment, app, vars) end end def setup_pow(app) Run.pow_create(app, app.root_domain) Run.pow_create(app, Fanforce.default_short_domain) end def setup_local_git(app) if Run.git_init.include?('Reinitialized') puts "#{'Found '.format(:green,:bold)}" + 'local repository' else puts "#{'Initialized '.format(:green,:bold)}" + 'local repository' Run.git_add Run.git_first_commit puts "#{'Created '.format(:green,:bold)}" + 'initial fanforce commit' end end def setup_bitbucket(app) bitbucket = BitBucket.new(login: $Config[:bitbucket][:user], password: $Config[:bitbucket][:password]) begin find_bitbucket_repo(bitbucket, app.dir_name) "#{'Found '.format(:green,:bold)}" + "#{app.dir_name} repository already exists on bitbucket" rescue create_bitbucket_repo(bitbucket, app.dir_name) puts "#{'Created '.format(:green,:bold)}" + "#{app.dir_name} repository on bitbucket" end if (`git remote`).split(/\r?\n/).include?($Config[:bitbucket][:user]) puts "#{'Updated '.format(:green,:bold)}" + "git remote for #{$Config[:bitbucket][:user]}" `git remote rm #{$Config[:bitbucket][:user]}` elsif (`git remote`).split(/\r?\n/).include?('bitbucket') `git remote rm bitbucket` puts "#{'Removed '.format(:red,:bold)}" + "git remote for #{$Config[:bitbucket][:user]}" puts "#{'Created '.format(:green,:bold)}" + "git remote for bitbucket" else puts "#{'Created '.format(:green,:bold)}" + "git remote for bitbucket" end `git remote add bitbucket git@bitbucket.org:#{$Config[:bitbucket][:user]}/#{app.dir_name}.git` puts "#{'Pushing '.format(:green,:bold)}" + "latest commit to #{$Config[:bitbucket][:user]}..." Run.command("git push bitbucket --all") end def find_bitbucket_repo(bitbucket, repo) bitbucket.repos.find($Config[:bitbucket][:user], repo) end def create_bitbucket_repo(bitbucket, repo) bitbucket.repos.create(name: repo, is_private: true) rescue BitBucket::Error::Unauthorized => e raise "Bitbucket user #{$Config[:bitbucket][:user]} does not seem to exist: #{e.message}" raise end def auth_heroku(environment) @heroku ||= {} @heroku[environment] ||= Heroku::API.new(:username => $Config[:heroku][environment][:user], :password => $Config[:heroku][environment][:password]) rescue Exception => e raise "Heroku user #{$Config[:heroku][environment][:user]} does not seem to exist: #{e.message}" if e.response.status == 404 raise end def setup_heroku(app, environment) return puts "OOPS... #{environment.to_s.upcase}".format(:red,:bold) + ' has not been setup for Heroku' if $Config[:heroku].blank? or $Config[:heroku][environment].blank? heroku = auth_heroku(environment) heroku_app_name = get_heroku_app_name(app, environment) begin heroku.get_app(heroku_app_name) puts "#{'Found '.format(:green,:bold)}" + "#{environment} app on heroku (#{heroku_app_name})" rescue heroku.post_app(name: heroku_app_name) puts "#{'Created '.format(:green,:bold)}" + "#{environment} on heroku (#{heroku_app_name})" end vars = Env.vars_by_app(environment)[app.dir_name] heroku.put_config_vars(heroku_app_name, vars) if vars # Setup standard app domain domain = "#{app._id}.#{Fanforce.apps_base_domain}" domain_found = heroku.get_domains(heroku_app_name).body.inject(false) {|result, d| d['domain'] == domain ? (break true) : false } if domain_found puts "#{'Found '.format(:green,:bold)}" + "#{domain} domain on #{environment}" else heroku.post_domain(heroku_app_name, domain) puts "#{'Added '.format(:green,:bold)}" + "#{domain} domain to #{environment}" end # Setup default short domain domain = "#{app._id}.#{Fanforce.default_short_domain}" domain_found = heroku.get_domains(heroku_app_name).body.inject(false) {|result, d| d['domain'] == domain ? (break true) : false } if domain_found puts "#{'Found '.format(:green,:bold)}" + "#{domain} domain on #{environment}" else heroku.post_domain(heroku_app_name, domain) puts "#{'Added '.format(:green,:bold)}" + "#{domain} domain to #{environment}" end remote_name = "#{environment==:staging ? 'stg' : 'prd'}-heroku" if (`git remote`).split(/\r?\n/).include?(remote_name) puts "#{'Updated '.format(:green,:bold)}" + "git remote for #{remote_name}" `git remote rm #{remote_name}` else puts "#{'Created '.format(:green,:bold)}" + "git remote for #{remote_name}" end `git remote add #{remote_name} git@#{$Config[:heroku][environment][:git_ssh_domain] || 'heroku.com'}:#{heroku_app_name}.git` puts "#{'Pushing '.format(:green,:bold)}" + "latest commit to #{remote_name}..." Run.command("git push #{remote_name} master") end ###################################################################################################################### def push_env_to(environment, app, vars, create_worker_env=true) vars.each {|k,v| puts " - #{k}" } workers_dir = "#{app.dir}/workers" workers_env_dir = "#{workers_dir}/.env" if create_worker_env and File.directory?(workers_dir) and vars['IRON_PROJECT_ID'] FileUtils.mkdir_p(workers_env_dir) unless File.directory?(workers_env_dir) File.open("#{workers_env_dir}/#{environment}.rb", 'w') {|f| f.write convert_hash_to_ruby_env(vars) } end if environment == :development app.update_file(:powenv) File.open("#{app.dir}/.appenv", 'w') {|f| f.write convert_hash_to_shell_env(vars) } else return if $Config[:heroku][environment].blank? heroku = auth_heroku(environment) heroku_app_name = get_heroku_app_name(app, environment) heroku.put_config_vars(heroku_app_name, vars) end restart(app, environment) end def convert_hash_to_shell_env(hash) hash.inject('') {|script, (k,v)| script += "export #{k}=#{v.to_s.to_json}\n" } end def convert_hash_to_ruby_env(hash) hash.inject('') {|script, (k,v)| script += "ENV['#{k}']=#{v.to_s.to_json}\n" } end end