lib/discourse_theme/cli.rb in discourse_theme-0.8.0 vs lib/discourse_theme/cli.rb in discourse_theme-0.9.0
- old
+ new
@@ -1,6 +1,8 @@
# frozen_string_literal: true
+
+require_relative "cli_commands/rspec"
module DiscourseTheme
class Cli
@@cli_settings_filename = File.expand_path("~/.discourse_theme")
def self.settings_file
@@ -10,18 +12,29 @@
def self.settings_file=(filename)
@@cli_settings_filename = filename
end
def usage
- puts "Usage: discourse_theme COMMAND [--reset]"
- puts
- puts "discourse_theme new DIR - Creates a new theme in the designated directory"
- puts "discourse_theme download DIR - Downloads a theme from the server and stores in the designated directory"
- puts "discourse_theme upload DIR - Uploads the theme directory to Discourse"
- puts "discourse_theme watch DIR - Watches the theme directory and synchronizes with Discourse"
- puts
- puts "Use --reset to change the configuration for a directory"
+ puts <<~USAGE
+ Usage: discourse_theme COMMAND [DIR] [OPTIONS]
+
+ Commands:
+ new DIR - Creates a new theme in the specified directory.
+ download DIR - Downloads a theme from the server and stores it in the specified directory.
+ upload DIR - Uploads the theme from the specified directory to Discourse.
+ watch DIR - Watches the theme in the specified directory and synchronizes any changes with Discourse.
+ rspec DIR [OPTIONS] - Runs the RSpec tests in the specified directory. The tests can be run using a local Discourse repository or a Docker container.
+ --headless - Runs the RSpec system type tests in headless mode. Applies to both modes.
+
+ If specified directory has been configured to run in a Docker container, the additional options are supported.
+ --rebuild - Forces a rebuilds of Docker container.
+ --verbose - Runs the command to prepare the Docker container in verbose mode.
+
+ Global Options:
+ --reset - Resets the configuration for the specified directory.
+ USAGE
+
exit 1
end
def run(args)
usage unless args[1]
@@ -36,11 +49,13 @@
theme_id = settings.theme_id
components = settings.components
if command == "new"
- raise DiscourseTheme::ThemeError.new "'#{dir}' is not empty" if Dir.exist?(dir) && !Dir.empty?(dir)
+ if Dir.exist?(dir) && !Dir.empty?(dir)
+ raise DiscourseTheme::ThemeError.new "'#{dir}' is not empty"
+ end
raise DiscourseTheme::ThemeError.new "git is not installed" if !command?("git")
raise DiscourseTheme::ThemeError.new "yarn is not installed" if !command?("yarn")
DiscourseTheme::Scaffold.generate(dir)
watch_theme?(args)
@@ -55,36 +70,47 @@
options["Sync with existing theme: '#{theme["name"]}' (id:#{theme_id})"] = :default
end
options["Create and sync with a new theme"] = :create
options["Select a different theme"] = :select
- choice = UI.select('How would you like to sync this theme?', options.keys)
+ choice = UI.select("How would you like to sync this theme?", options.keys)
if options[choice] == :create
theme_id = nil
elsif options[choice] == :select
themes = render_theme_list(theme_list)
- choice = UI.select('Which theme would you like to sync with?', themes)
+ choice = UI.select("Which theme would you like to sync with?", themes)
theme_id = extract_theme_id(choice)
theme = theme_list.find { |t| t["id"] == theme_id }
end
- about_json = JSON.parse(File.read(File.join(dir, 'about.json'))) rescue nil
+ about_json =
+ begin
+ JSON.parse(File.read(File.join(dir, "about.json")))
+ rescue StandardError
+ nil
+ end
already_uploaded = !!theme
is_component = theme&.[]("component")
component_count = about_json&.[]("components")&.length || 0
if !already_uploaded && !is_component && component_count > 0
options = {}
options["Yes"] = :sync
options["No"] = :none
options = options.sort_by { |_, b| b == components.to_sym ? 0 : 1 }.to_h if components
- choice = UI.select('Would you like to update child theme components?', options.keys)
+ choice = UI.select("Would you like to update child theme components?", options.keys)
settings.components = components = options[choice].to_s
end
- uploader = DiscourseTheme::Uploader.new(dir: dir, client: client, theme_id: theme_id, components: components)
+ uploader =
+ DiscourseTheme::Uploader.new(
+ dir: dir,
+ client: client,
+ theme_id: theme_id,
+ components: components,
+ )
UI.progress "Uploading theme from #{dir}"
settings.theme_id = theme_id = uploader.upload_full_theme
UI.success "Theme uploaded (id:#{theme_id})"
@@ -109,11 +135,11 @@
raise DiscourseTheme::ThemeError.new "'#{dir} is not empty" unless Dir.empty?(dir)
UI.progress "Loading theme list..."
themes = render_theme_list(client.get_themes_list)
- choice = UI.select('Which theme would you like to download?', themes)
+ choice = UI.select("Which theme would you like to download?", themes)
theme_id = extract_theme_id(choice)
UI.progress "Downloading theme into #{dir}"
downloader.download_theme(theme_id)
@@ -122,19 +148,29 @@
UI.success "Theme downloaded"
watch_theme?(args)
elsif command == "upload"
raise DiscourseTheme::ThemeError.new "'#{dir} does not exist" unless Dir.exist?(dir)
- raise DiscourseTheme::ThemeError.new "No theme_id is set, please sync via the 'watch' command initially" if theme_id == 0
+ if theme_id == 0
+ raise DiscourseTheme::ThemeError.new "No theme_id is set, please sync via the 'watch' command initially"
+ end
client = DiscourseTheme::Client.new(dir, settings, reset: reset)
theme_list = client.get_themes_list
theme = theme_list.find { |t| t["id"] == theme_id }
- raise DiscourseTheme::ThemeError.new "theme_id is set, but the theme does not exist in Discourse" unless theme
+ unless theme
+ raise DiscourseTheme::ThemeError.new "theme_id is set, but the theme does not exist in Discourse"
+ end
- uploader = DiscourseTheme::Uploader.new(dir: dir, client: client, theme_id: theme_id, components: components)
+ uploader =
+ DiscourseTheme::Uploader.new(
+ dir: dir,
+ client: client,
+ theme_id: theme_id,
+ components: components,
+ )
UI.progress "Uploading theme (id:#{theme_id}) from #{dir} "
settings.theme_id = theme_id = uploader.upload_full_theme
UI.success "Theme uploaded (id:#{theme_id})"
@@ -142,10 +178,17 @@
if client.is_theme_creator
UI.info "Manage: #{client.root}/my/themes"
else
UI.info "Manage: #{client.root}/admin/customize/themes/#{theme_id}"
end
+ elsif command == "rspec"
+ DiscourseTheme::CliCommands::Rspec.run(
+ settings: settings,
+ dir: dir,
+ args: args,
+ reset: reset,
+ )
else
usage
end
UI.progress "Exiting..."
@@ -156,31 +199,35 @@
end
private
def command?(cmd)
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
- exts.each do |ext|
- exe = File.join(path, "#{cmd}#{ext}")
- return true if File.executable?(exe) && !File.directory?(exe)
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
+ ENV["PATH"]
+ .split(File::PATH_SEPARATOR)
+ .each do |path|
+ exts.each do |ext|
+ exe = File.join(path, "#{cmd}#{ext}")
+ return true if File.executable?(exe) && !File.directory?(exe)
+ end
end
- end
false
end
def watch_theme?(args)
if UI.yes?("Would you like to start 'watching' this theme?")
args[0] = "watch"
- UI.progress "Running discourse_theme #{args.join(' ')}"
+ UI.progress "Running discourse_theme #{args.join(" ")}"
run(args)
end
end
def render_theme_list(themes)
- themes.sort_by { |t| t["updated_at"] }
- .reverse.map { |theme| "#{theme["name"]} (id:#{theme["id"]})" }
+ themes
+ .sort_by { |t| t["updated_at"] }
+ .reverse
+ .map { |theme| "#{theme["name"]} (id:#{theme["id"]})" }
end
def extract_theme_id(rendered_name)
/\(id:([0-9]+)\)$/.match(rendered_name)[1].to_i
end