lib/almanack/cli.rb
require "thor"
require "pathname"
require "almanack/version"
module Almanack
class CLI < Thor
include Thor::Actions
SKIP_THEMES = %w( starter )
map "--version" => :version
def self.available_themes
dirs = Pathname(__dir__).join("themes").children.select(&:directory?)
dirs.map do |path|
path.basename.to_s unless SKIP_THEMES.include?(path.basename.to_s)
end.compact
end
desc "version", "Show Almanack version"
def version
say "Almanack version #{VERSION} (#{CODENAME})"
end
desc "start", "Start an Almanack server"
option :config, aliases: "-c", desc: "Path to config file"
def start
exec "bundle exec rackup #{options[:config]}"
end
desc "new PATH", "Create a new Almanack project"
option :theme, default: 'legacy', desc: "Which theme to use (available: #{available_themes.join(', ')})"
option :git, type: :boolean, default: true, desc: "Whether to initialize an empty git repo"
def new(path)
@path = Pathname(path).cleanpath
directory "templates/new", @path
if options[:git]
template('templates/gitignore', @path.join(".gitignore"))
end
create_file @path.join('tmp/.keep')
inside @path do
say_status :installing, "bundler dependencies"
system "bundle install --quiet"
if options[:git]
say_status :git, "initializing repository"
git "init"
end
say
say "==> Run your new calendar!"
say
say " cd #{@path}"
say " almanack start"
say
end
end
desc "theme NAME", "Create a new theme"
def theme(name)
directory "lib/almanack/themes/starter", "themes/#{name}"
config_file = Pathname("config.ru")
if config_file.exist?
say_status :update, "config.ru"
set_theme_pattern = /\.theme\s*=\s*['"].*?['"]/
replacement = config_file.read.gsub(set_theme_pattern, ".theme = '#{name}'")
config_file.open('w') { |file| file.puts replacement }
end
end
desc "deploy [NAME]", "Deploy your site to Heroku (requires Heroku toolbelt)"
def deploy(name = nil)
remotes = `git remote -v`
heroku_remote = remotes.lines.find do |remote|
remote.split(' ').first == "heroku"
end
if !heroku_remote
say "No Heroku remote detected."
create_heroku_app(name)
end
current_branch = git("rev-parse --abbrev-ref HEAD")
say "Deploying #{current_branch}..."
run "git push heroku #{current_branch}:master --force"
end
no_tasks do
def create_heroku_app(name)
heroku_command = `which heroku`.strip
if heroku_command.empty?
say "Heroku Toolbelt not detected. Please install from:"
say " https://toolbelt.heroku.com"
abort
end
say_status :heroku, "creating app..."
run "#{heroku_command} create #{name}"
end
def theme_name
options[:theme]
end
def almanack_homepage
Almanack::HOMEPAGE
end
def almanack_issues
Almanack::ISSUES
end
def title
basename = @path.to_s.split('/', 2).last.split('.', 2).first
sanitized = basename.gsub('-', ' ')
sanitized.split(/\s+/).map(&:capitalize).join(' ')
end
def git(command)
output = `git #{command}`
abort "Git failed: #{output}" if $?.exitstatus != 0
output.strip
end
def available_themes
self.class.available_themes
end
end
def self.exit_on_failure?
true
end
def self.source_root
Pathname(__dir__).parent.parent
end
end
end