require "thor" require "guard" require "guard/commander" require "thread" module Vapid # Command line interface class CLI < Thor include Thor::Actions default_task :help GUARDFILE = %( guard 'livereload' do watch('.cache/livereload.txt') watch(%r{templates/.+}) watch(%r{assets/.+}) end ).freeze def self.source_root "#{File.dirname(__FILE__)}/generator_template" end desc "new TARGET", "Create a new project in the TARGET directory" map %w(n -n --new) => :new def new(target) say "== Creating a new Vapid project in #{expanded_target(target)}" directory ".", target inside_target(target) do run "bundle install" end end desc "server", "Start the server" map %w(s -s --server) => :server method_option :port, aliases: %w(-p), type: :numeric method_option :bind, aliases: %w(-b), type: :string def server(target = ".") say "== The Vapid server is loading" inside_target(target) do Thread.new { Server.run! options } Guard.start guardfile_contents: GUARDFILE, watchdir: target, no_interactions: true end say "== The Vapid server is now shut down" end desc "build", "Updates the data model as described in your templates" map %w(b -b --build) => :build def build(target = ".") inside_target(target) do Models.migrate! ensure_user_exists say "== Parsing templates for fields" template_files = Dir[File.join(target, "templates", "**/*")].reject { |f| File.directory? f } Builder.build!(template_files) do |filepath| say " * #{filepath}" end say "== Build complete" end end desc "version", "Show the Vapid version number" map %w(v -v --version) => :version def version say "Vapid #{Vapid::VERSION}" end private def inside_target(target, &block) if !File.exist? File.join(target, "config.ru") say "== Could not find a Vapid project in #{expanded_target(target)}" else FileUtils.mkdir_p File.join(target, ".cache") inside(target, &block) end end def expanded_target(target) File.expand_path(target) end def ensure_user_exists return if Models::User.any? say "== Creating an admin login" email = ask "What is your email address?", default: "admin@example.com" password = ask "Enter a password:", default: "password", echo: false Models::User.create email: email, password: password end end end