lib/theme-juice/commands/create.rb
# encoding: UTF-8
module ThemeJuice
module Commands
class Create < Command
TEMPLATES = {
"themejuice/sprout" => "git@github.com:ezekg/theme-juice-starter.git",
"wordpress/wordpress" => "git@github.com:WordPress/WordPress.git",
"other (specify)" => nil,
"none" => false
}
def initialize(opts = {})
super
init_project
runner do |tasks|
tasks << Tasks::CreateConfirm.new
tasks << Tasks::Location.new
tasks << Tasks::Template.new
tasks << Tasks::VMBox.new
tasks << Tasks::VMPlugins.new
tasks << Tasks::VMLocation.new
tasks << Tasks::VMCustomfile.new
tasks << Tasks::Database.new
if @env.nginx
tasks << Tasks::Nginx.new
else
tasks << Tasks::Apache.new
end
if @project.no_env
tasks << Tasks::WPConfig.new
else
tasks << Tasks::DotEnv.new
end
tasks << Tasks::Landrush.new
tasks << Tasks::ForwardPorts.new
tasks << Tasks::SyncedFolder.new
tasks << Tasks::DNS.new
tasks << Tasks::WPCLI.new
tasks << Tasks::Repo.new
tasks << Tasks::VMProvision.new
tasks << Tasks::ImportDatabase.new
tasks << Tasks::CreateSuccess.new
end
end
private
def init_project
@project.use_defaults = @opts.fetch("use_defaults") { false }
@project.bare = @opts.fetch("bare") { false }
@project.skip_repo = @opts.fetch("skip_repo") { false }
@project.skip_db = @opts.fetch("skip_db") { false }
@project.no_wp = @opts.fetch("no_wp") { false }
@project.no_wp_cli = @opts.fetch("no_wp_cli") { false }
@project.no_db = @opts.fetch("no_db") { false }
@project.wp_config_modify = @opts.fetch("wp_config_modify") { false }
@project.no_config = @opts.fetch("no_config") { false }
@project.no_ssl = @opts.fetch("no_ssl") { false }
@project.no_env = @opts.fetch("no_env") { @project.wp_config_modify }
@project.name = @opts.fetch("name") { name }
@project.location = @opts.fetch("location") { location }
# Assume bare if the project path isn't empty (template install will fail)
unless @project.bare || Dir["#{@project.location}/*"].empty?
@project.template = false
@project.bare = true
@io.notice "Project location is not empty. Assuming you meant to run a setup..."
end
@project.url = @opts.fetch("url") { url }
@project.xip_url = @opts.fetch("xip_url") { xip_url }
@project.template = @opts.fetch("template") { template }
@project.template_revision = @opts.fetch("template_revision") { template_revision }
@project.repository = @opts.fetch("repository") { repository }
@project.db_host = @opts.fetch("db_host") { db_host }
@project.db_name = @opts.fetch("db_name") { db_name }
@project.db_user = @opts.fetch("db_user") { db_user }
@project.db_pass = @opts.fetch("db_pass") { db_pass }
@project.db_import = @opts.fetch("db_import") { db_import }
@project.vm_root
@project.vm_location
@project.vm_srv
# TODO: Think up a nicer way of implementing additional logic
# Special cases for location paths
case @project.location
when "."
@project.location = "#{Dir.pwd}"
when /^~/
@project.location = File.expand_path @project.location
end
end
def name
name =
begin
raise NoMethodError unless @config.exist?
@io.say "Inferred project name '#{@config.project.name}' from existing config...", {
:color => :yellow, :icon => :notice }
@config.project.name
rescue NoMethodError
if @env.yolo
Faker::Internet.domain_word
else
@io.ask "What's the project name? (lowercase letters, numbers and dashes only)"
end
end
valid_name? name
name
end
def valid_name?(name)
if name.empty?
@io.error "Project name '#{name}' looks like it's empty. Aborting mission."
end
"#{name}".match /[^0-9a-z\.\-]/ do |char|
@io.error "Project name contains an invalid character '#{char}'. This name is used internally for a ton of stuff, so that's not gonna work. Aborting mission."
end
true
end
def clean_name
"#{@project.name}".gsub(/[^\w]/, "_")[0..10]
end
def location
path = "#{Dir.pwd}"
if @project.use_defaults
location = File.absolute_path @project.name, path
else
location = File.expand_path @io.ask("Where do you want to setup the project?",
:default => path, :path => true), path
end
location
end
def url
url =
begin
raise NoMethodError unless @config.exist?
@io.say "Inferred project url '#{@config.project.url}' from existing config...", {
:color => :yellow, :icon => :notice }
@config.project.url
rescue NoMethodError
if @project.use_defaults
"#{@project.name}.dev"
else
@io.ask "What do you want the development url to be? (this should end in '.dev')", :default => "#{@project.name}.dev"
end
end
valid_url? url
url
end
def valid_url?(url)
unless "#{url}".match /\.dev$/
@io.error "Your development url '#{url}' doesn't end with '.dev'. This is used internally by Landrush, so that's not gonna work. Aborting mission."
end
"#{url}".match /[^0-9a-z\.\-]/ do |char|
@io.error "Your development url contains an invalid character '#{char}'. Aborting mission."
end
true
end
def xip_url
xip_url = @project.url.gsub /\.dev$/, ""
xip_url
end
def template
return false if @project.bare
if @project.use_defaults
template = TEMPLATES["themejuice/sprout"]
else
choice = @io.choose "Which starter template would you like to use?", :blue, TEMPLATES.keys
case choice
when /themejuice/i
@io.say "Awesome choice!", :color => :green, :icon => :success
when /wordpress/i
@project.wp_config_modify = true
@project.no_config = true
@project.no_wp_cli = true
@project.no_env = true
@io.say "This is a stock WordPress install, so I'll go ahead and modify the 'wp-config' file for you.", {
:color => :yellow, :icon => :notice }
when /other/i
TEMPLATES[choice] = @io.ask "What is the repository URL of the starter template that you would like to clone?"
when /none/i
@project.bare = true
@io.say "Next time you need to create a project without a starter template, you can just run the 'setup' command instead.", {
:color => :yellow, :icon => :notice }
end
template = TEMPLATES[choice]
end
template
end
def template_revision
return nil if @project.bare
revision = nil
case @project.template
when /wordpress/i
revision = @io.ask "Which version of WordPress would you like to use?", {
:default => "master" }
end
revision
end
def repository
return false if @project.skip_repo || @project.use_defaults
if @io.agree? "Would you like to initialize a new Git repository?"
repo = @io.ask "What is the repository URL?", :indent => 2
else
repo = false
end
repo
end
%w[host name user pass].each do |task|
define_method "db_#{task}" do
return false if @project.no_db
default = case task
when "host" then "localhost"
when "name" then "#{clean_name}_db"
when "user" then "#{clean_name}_user"
when "pass" then Faker::Internet.password(24)
end
if @project.skip_db || @project.use_defaults
res = default
else
res = @io.ask "Database #{task}", :default => default
end
res
end
end
def db_import
return false if @project.no_db || @project.skip_db || @project.use_defaults
if @io.agree? "Would you like to import an existing database?"
db = @io.ask "Where is the database file?", {
:indent => 2, :path => true }
else
db = false
end
db
end
end
end
end