class Codelation::Cli

Constants

ATOM_APP_DOWNLOAD_URL
POSTGRES_APP_DOWNLOAD_URL
PSEQUEL_APP_DOWNLOAD_URL
RUBY_VERSION
SEQUEL_PRO_APP_DOWNLOAD_URL

Public Class Methods

source_root() click to toggle source

This is the directory where your templates should be placed.

# File lib/codelation/base.rb, line 36
def self.source_root
  File.expand_path("../../../resources", __FILE__)
end

Public Instance Methods

development_install() click to toggle source
# File lib/codelation/development.rb, line 17
def development_install
  print_heading("Installing Dependencies")
  install_dependencies

  unless Dir.exist?("/Applications/Atom.app")
    print_heading("Installing Atom.app")
    install_atom
  end

  print_heading("Installing Atom Packages")
  install_atom_packages

  print_heading("Installing Dot Files")
  install_dot_files

  unless Dir.exist?("/Applications/Postgres.app")
    print_heading("Installing Postgres.app")
    install_postgres
  end

  unless Dir.exist?("/Applications/PSequel.app")
    print_heading("Installing PSequel.app")
    install_psequel
  end

  print_heading("Installing Ruby")
  install_ruby

  unless Dir.exist?("/Applications/Sequel Pro.app")
    print_heading("Installing Sequel Pro.app")
    install_sequel_pro
  end

  `source ~/.bash_profile`

  print_heading("Adding $PATH to Atom Init Script")
  add_atom_init_script
end
help(method = nil) click to toggle source

Add the ablitity to print help for commands like:

`codelation help development:install`

This would print help for the method:

`development_install`

@param method [String]

Calls superclass method
# File lib/codelation/base.rb, line 12
def help(method = nil)
  if method.to_s.split(":").length >= 2
    method = method.to_s.gsub(":", "_")
  elsif method.to_s == "run"
    method = "walk"
  end
  super
end
method_missing(method, *args, &block) click to toggle source

Add the ablitity to run commands like:

`codelation development:install`

This would run the defined method:

`development_install`
Calls superclass method
# File lib/codelation/base.rb, line 25
def method_missing(method, *args, &block)
  if method.to_s.split(":").length >= 2
    self.send(method.to_s.gsub(":", "_"), *args)
  elsif method.to_s == "run"
    self.walk(*args)
  else
    super
  end
end
rails_new() click to toggle source
# File lib/codelation/rails/new.rb, line 13
def rails_new
  github_url = ask("Enter the project's GitHub URL (or enter an app name):")
  return if github_url.blank?

  print_heading("Generating New Rails Application")
  app_name = github_url.split("/").last.gsub(".git", "")

  print_command("Cloning the Rails project template")
  run_command("git clone https://github.com/codelation/rails-project-template.git #{app_name}")

  print_command("Deleting the template's git history")
  FileUtils.rm_rf("./#{app_name}/.git")

  print_command("Configuring your application")
  replace_app_name(app_name)
  generate_secret_tokens(app_name)

  Dir.chdir(app_name) do
    print_command("Initializing git repository")
    run_command("git init")
    run_command("git remote add origin #{github_url}.git")
    run_command("git add .")
    run_command('git commit -m "Initial commit"')

    print_command("Installing dependencies")
    run_command("bundle install")
    run_command("npm install")
    run_command("node_modules/.bin/bower install")

    return if no?("-----> Setup database? [y/N]")
    run_command("rake db:setup")
  end
end
update() click to toggle source
# File lib/codelation/get_version.rb, line 8
def update
  command = "gem install codelation-cli"
  puts "Running #{command}..."
  exec(command)
end
version() click to toggle source
# File lib/codelation/get_version.rb, line 15
def version
  gem_version = "v#{Codelation::VERSION}"

  # Grab the latest version of the RubyGem
  rubygems_json = open("https://rubygems.org/api/v1/gems/codelation-cli.json").read
  rubygems_version = "v#{Yajl::Parser.parse(rubygems_json)['version'].strip}"

  upgrade_message = ""
  if gem_version != rubygems_version
    upgrade_message = " Run `codelation update` to install"
  end

  puts
  puts "Codelation CLI"
  puts "  Installed: #{gem_version}"
  puts "  Latest:    #{rubygems_version}#{upgrade_message}"
  puts
end

Private Instance Methods

add_atom_init_script() click to toggle source

Add the path to the Atom Init Script

# File lib/codelation/development/atom.rb, line 10
def add_atom_init_script
  init_path = File.expand_path("~/.atom/init.coffee")
  return if File.read(init_path).include?("process.env.PATH")
  path = `echo $PATH`.strip
  append_to_file "~/.atom/init.coffee", "process.env.PATH = \"#{path}\""
end
apm_install(package) click to toggle source

Install an Atom package @param [String] package

# File lib/codelation/development/atom_packages.rb, line 13
def apm_install(package)
  print_command("Installing #{package}")
  `/Applications/Atom.app/Contents/Resources/app/apm/bin/apm install #{package}`
end
brew_install(formula) click to toggle source
# File lib/codelation/development/dependencies.rb, line 22
def brew_install(formula)
  run_command("brew unlink #{formula}") if outdated_formulas.include?("#{formula}\n")
  run_command("brew install #{formula}")
end
download_file(url) click to toggle source

Download a file with a progress bar. @param url [String] The url of the file to be downloaded @param file_name [String] The name of the file to be saved

# File lib/codelation/development/install_methods.rb, line 16
def download_file(url)
  print_command("Downloading from: #{url}")
  progress_bar = nil
  @download_uri = open(url,
    allow_redirections: :all,
    content_length_proc: -> (content_length) {
      if content_length && content_length > 0
        progress_bar = ProgressBar.new("       ", content_length)
        progress_bar.file_transfer_mode
      end
    },
    progress_proc: -> (size) {
      progress_bar.set(size) if progress_bar
    }
  )
  puts "" # Needed to avoid progress bar weirdness
  write_downloaded_file(@download_uri)
end
extract_app_from_zip(app_name, zip_file_path) click to toggle source

Extract an app from a zip file to /Applications and delete the zip file. @param app_name [String] The name of the app, including .app @param zip_file_path [String] The full path to the zip file containing the app

# File lib/codelation/development/install_methods.rb, line 52
def extract_app_from_zip(app_name, zip_file_path)
  print_command("Extracting #{app_name} to /Applications")

  # Delete existing app
  FileUtils.rm_rf("/Applications/#{app_name}") if Dir.exist?("/Applications/#{app_name}")

  # Extract app from zip file to /Applications
  extract_from_zip("/Applications", zip_file_path)
end
extract_from_zip(unzip_path, zip_file_path) click to toggle source

Extract files from a zip file to the specified path and delete the zip file. @param unzip_path [String] The full path to unzip the files to @param zip_file_path [String] The full path to the zip file containing the app

# File lib/codelation/development/install_methods.rb, line 65
def extract_from_zip(unzip_path, zip_file_path)
  `unzip -o #{zip_file_path} -d #{unzip_path}`
  File.delete(zip_file_path)
end
generate_secret_tokens(app_name) click to toggle source

Generate secret tokens for development and test environments

# File lib/codelation/rails/new.rb, line 50
def generate_secret_tokens(app_name)
  secrets_path = "./#{app_name}/config/secrets.yml"
  original_text = File.read(secrets_path)
  File.open(secrets_path, "w") do |file|
    file.puts original_text
      .gsub("development_secret_key_base", SecureRandom.hex(64))
      .gsub("test_secret_key_base", SecureRandom.hex(64))
  end
end
install_atom() click to toggle source

Install Atom.app

# File lib/codelation/development/atom.rb, line 18
def install_atom
  zip_file_path = download_file(ATOM_APP_DOWNLOAD_URL)
  extract_app_from_zip("Atom.app", zip_file_path)
end
install_atom_packages() click to toggle source

Install Atom.app Packages

# File lib/codelation/development/atom_packages.rb, line 19
def install_atom_packages
  packages = %w(
    linter
    linter-csslint
    linter-erb
    linter-jshint
    linter-php
    linter-rubocop
    linter-ruby
    linter-scss-lint
    linter-shellcheck
    pretty-json
    rails-snippets
    remote-atom
  )
  packages.each do |package|
    apm_install(package)
  end
end
install_dependencies() click to toggle source

Install dependencies for building and installing everything else.

# File lib/codelation/development/dependencies.rb, line 8
def install_dependencies
  unless `which brew`.length > 1
    print_command("Installing Homebrew from http://brew.sh")
    print_command("Re-run `codelation developer:install after Homebrew has been installed`")
    sleep 3
    exec('ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"')
  end
  run_command("brew update")
  formulas = %w(bash chruby diff-so-fancy git heroku-toolbelt imagemagick node openssl ruby-install shellcheck v8 wget)
  formulas.each do |formula|
    brew_install(formula)
  end
end
install_dot_files() click to toggle source

Install dot files and load them into ~/.bash_profile

# File lib/codelation/development/dot_files.rb, line 9
def install_dot_files
  # Create the directory ~/.codelation/bash if it doesn't exist
  bash_directory = File.expand_path("~/.codelation/bash")
  FileUtils.rm_rf(bash_directory) if Dir.exist?(bash_directory)
  FileUtils.mkdir_p(bash_directory)

  # Copy dot files to ~/.codelation
  copy_file "dot_files/.codelation.bash",     "~/.codelation/bash/.codelation.bash"
  copy_file "dot_files/.git-completion.bash", "~/.codelation/bash/.git-completion.bash"
  copy_file "dot_files/.git-prompt.sh",       "~/.codelation/bash/.git-prompt.sh"
  copy_file "dot_files/.jshintrc",            "~/.jshintrc"
  copy_file "dot_files/.rubocop.yml",         "~/.rubocop.yml"
  copy_file "dot_files/.scss-lint.yml",       "~/.scss-lint.yml"

  # Add `source ~/.codelation.bash` to ~/.bash_profile if it doesn't exist
  FileUtils.touch(File.expand_path("~/.bash_profile"))
  append_to_file "~/.bash_profile", "source ~/.codelation/bash/.codelation.bash"
end
install_gems() click to toggle source

Install the Ruby gems needed for development.

# File lib/codelation/development/ruby.rb, line 30
def install_gems
  %w(bundler codelation-cli dogids-cli rubocop scss_lint).each do |gem|
    print_command("gem install #{gem}")
    `gem install #{gem}`
  end
end
install_postgres() click to toggle source

Install Postgres.app

# File lib/codelation/development/postgres.rb, line 10
def install_postgres
  zip_file_path = download_file(POSTGRES_APP_DOWNLOAD_URL)
  extract_app_from_zip("Postgres.app", zip_file_path)
end
install_psequel() click to toggle source

Install PSequel.app

# File lib/codelation/development/psequel.rb, line 10
def install_psequel
  zip_file_path = download_file(PSEQUEL_APP_DOWNLOAD_URL)
  extract_app_from_zip("PSequel.app", zip_file_path)
end
install_ruby() click to toggle source

Install Ruby binary and add it to PATH.

# File lib/codelation/development/ruby.rb, line 11
def install_ruby
  return if `ruby -v`.include?(RUBY_VERSION)

  # Make sure chruby is loaded
  `source ~/.bash_profile`

  # Remove existing Ruby install from older version
  ruby_directory = File.expand_path("~/.codelation/ruby")
  FileUtils.rm_rf(ruby_directory) if Dir.exist?(ruby_directory)

  print_command("Installing Ruby #{RUBY_VERSION}")
  `ruby-install ruby #{RUBY_VERSION}`

  print_heading("Installing Ruby Gems")
  `chruby #{RUBY_VERSION}`
  install_gems
end
install_sequel_pro() click to toggle source

Install Sequel Pro.app

# File lib/codelation/development/sequel_pro.rb, line 10
def install_sequel_pro
  zip_file_path = download_file(SEQUEL_PRO_APP_DOWNLOAD_URL)
  extract_app_from_zip("Sequel Pro.app", zip_file_path)
end
outdated_formulas() click to toggle source
# File lib/codelation/development/dependencies.rb, line 27
def outdated_formulas
  @outdated_formulas ||= `brew outdated`
end
print_command(command) click to toggle source

Print a message to the terminal about a command that's going to run. @param command [String]

print_heading(heading) click to toggle source

Print a heading to the terminal for commands that are going to be run. @param heading [String]

rails_project_template_files() click to toggle source

The files that contain any version of “Rails Project Template” that need to be replaced with the new app's name. @return [Array]

# File lib/codelation/rails/new.rb, line 63
def rails_project_template_files
  [
    "config/initializers/active_admin.rb",
    "config/initializers/session_store.rb",
    "config/locales/en.yml",
    "config/application.rb",
    "config/database.yml",
    "config/routes.rb",
    "bower.json",
    "package.json",
    "README.md"
  ]
end
replace_app_name(app_name) click to toggle source

Replaces all versions of “Rails Project Template” with the app name equivalent. @param app_name [String]

# File lib/codelation/rails/new.rb, line 79
def replace_app_name(app_name)
  app_title = app_name.titleize
  app_class_name = app_name.underscore.camelize
  app_underscored_name = app_name.underscore

  rails_project_template_files.each do |file_path|
    relative_path = File.join("./#{app_name}", file_path)
    original_text = File.read(relative_path)
    File.open(relative_path, "w") do |file|
      file.puts original_text
        .gsub("Rails Project Template", app_title)
        .gsub("RailsProjectTemplate", app_class_name)
        .gsub("rails_project_template", app_underscored_name)
        .gsub("rails-project-template", app_name)
    end
  end
end
run_command(command) click to toggle source

Run a command with Bash after first printing the command to the terminal. @param command [String]

# File lib/codelation/base.rb, line 56
def run_command(command)
  print_command(command)
  `#{command}`
end
write_downloaded_file(uri) click to toggle source

Save the file downloaded with download_file to ~/.codelation/temp. @param uri [URI] The URI of the file to be saved

# File lib/codelation/development/install_methods.rb, line 37
def write_downloaded_file(uri)
  # Create the directory ~/.codelation/temp if it doesn't exist
  FileUtils.mkdir_p(File.expand_path("~/.codelation/temp"))

  file_name = File.basename(uri.path)
  @downloaded_file_path = File.expand_path(File.join("~/.codelation", "temp", file_name))
  open(@downloaded_file_path, "wb") do |file|
    file.write(@download_uri.read)
  end
  @downloaded_file_path
end