lib/discourse_theme/cli.rb in discourse_theme-1.0.2 vs lib/discourse_theme/cli.rb in discourse_theme-1.1.0

- old
+ new

@@ -34,11 +34,11 @@ USAGE exit 1 end - def run(args) + def run(args, &block) usage unless args[1] reset = !!args.delete("--reset") command = args[0].to_s.downcase @@ -64,13 +64,15 @@ client = DiscourseTheme::Client.new(dir, settings, reset: reset) theme_list = client.get_themes_list options = {} + if theme_id && theme = theme_list.find { |t| t["id"] == theme_id } 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) @@ -87,10 +89,11 @@ 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 @@ -109,12 +112,14 @@ theme_id: theme_id, components: components, ) UI.progress "Uploading theme from #{dir}" - settings.theme_id = theme_id = uploader.upload_full_theme + settings.theme_id = + theme_id = uploader.upload_full_theme(ignore_files: ignored_migrations(theme, dir)) + UI.success "Theme uploaded (id:#{theme_id})" UI.info "Preview: #{client.url}/?preview_theme_id=#{theme_id}" if client.is_theme_creator UI.info "Manage: #{client.url}/my/themes" @@ -124,11 +129,11 @@ UI.info "Tests: #{client.url}/theme-qunit?id=#{theme_id}" watcher = DiscourseTheme::Watcher.new(dir: dir, uploader: uploader) UI.progress "Watching for changes in #{dir}..." - watcher.watch + watcher.watch(&block) elsif command == "download" client = DiscourseTheme::Client.new(dir, settings, reset: reset) downloader = DiscourseTheme::Downloader.new(dir: dir, client: client) FileUtils.mkdir_p dir unless Dir.exist?(dir) @@ -197,9 +202,46 @@ rescue Interrupt, TTY::Reader::InputInterrupt => e UI.error "Interrupted" end private + + def ignored_migrations(theme, dir) + return [] unless theme && Dir.exist?(File.join(dir, "migrations")) + + existing_migrations = + theme + .dig("theme_fields") + &.filter_map do |theme_field| + theme_field["name"] if theme_field["target"] == "migrations" + end || [] + + new_migrations = + Dir["#{dir}/migrations/**/*.js"] + .reject do |f| + existing_migrations.any? do |existing_migration| + File.basename(f).include?(existing_migration) + end + end + .map { |f| Pathname.new(f).relative_path_from(Pathname.new(dir)).to_s } + + if !new_migrations.empty? + options = { "Yes" => :yes, "No" => :no } + + choice = UI.select(<<~TEXT, options.keys) + Would you like to upload and run the following pending theme migration(s): #{new_migrations.join(", ")} + TEXT + + if options[choice] == :no + UI.warn "Pending theme migrations have not been uploaded, run `discourse_theme upload #{dir}` if you wish to upload and run the theme migrations." + new_migrations + else + [] + end + else + [] + end + end def command?(cmd) exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""] ENV["PATH"] .split(File::PATH_SEPARATOR)