FEATURE: Rake themes installer (#7848)
* Delete remote_theme when deleting the theme * Install themes and theme components through rake * Removed unnecessary test
This commit is contained in:
parent
72bac61c90
commit
1318e0b288
|
@ -22,7 +22,7 @@ class Theme < ActiveRecord::Base
|
|||
has_many :child_themes, -> { order(:name) }, through: :child_theme_relation, source: :child_theme
|
||||
has_many :parent_themes, -> { order(:name) }, through: :parent_theme_relation, source: :parent_theme
|
||||
has_many :color_schemes
|
||||
belongs_to :remote_theme, autosave: true
|
||||
belongs_to :remote_theme, autosave: true, dependent: :destroy
|
||||
|
||||
has_one :settings_field, -> { where(target_id: Theme.targets[:settings], name: "yaml") }, class_name: 'ThemeField'
|
||||
has_one :javascript_cache, dependent: :destroy
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemesInstallTask
|
||||
def self.install(yml)
|
||||
counts = { installed: 0, updated: 0, skipped: 0, errors: 0 }
|
||||
log = []
|
||||
themes = YAML::load(yml)
|
||||
themes.each do |theme|
|
||||
name = theme[0]
|
||||
val = theme[1]
|
||||
installer = new(val)
|
||||
|
||||
if installer.theme_exists?
|
||||
log << "#{name}: is already installed"
|
||||
counts[:skipped] += 1
|
||||
else
|
||||
begin
|
||||
installer.install
|
||||
log << "#{name}: installed from #{installer.url}"
|
||||
counts[:installed] += 1
|
||||
rescue RemoteTheme::ImportError, Discourse::InvalidParameters => err
|
||||
log << "#{name}: #{err.message}"
|
||||
counts[:errors] += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return log, counts
|
||||
end
|
||||
|
||||
attr_reader :url, :options
|
||||
|
||||
def initialize(url_or_options = nil)
|
||||
if url_or_options.is_a?(Hash)
|
||||
@url = url_or_options.fetch("url")
|
||||
@options = url_or_options
|
||||
else
|
||||
@url = url_or_options
|
||||
@options = {}
|
||||
end
|
||||
end
|
||||
|
||||
def theme_exists?
|
||||
RemoteTheme
|
||||
.where(remote_url: url)
|
||||
.where(branch: options.fetch("branch", nil))
|
||||
.exists?
|
||||
end
|
||||
|
||||
def install
|
||||
theme = RemoteTheme.import_theme(url, Discourse.system_user, private_key: options["private_key"], branch: options["branch"])
|
||||
theme.set_default! if options.fetch("default", false)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'yaml'
|
||||
|
||||
# == YAML file format
|
||||
#
|
||||
# 2 different formats are accepted:
|
||||
#
|
||||
# theme_name: https://github.com/example/theme.git
|
||||
#
|
||||
# theme_name:
|
||||
# url: https://github.com/example/theme.git
|
||||
# branch: abc
|
||||
# private_key: ...
|
||||
# default: true
|
||||
#
|
||||
# In the second form, only the url is required.
|
||||
#
|
||||
desc "Install themes & theme components"
|
||||
task "themes:install" => :environment do
|
||||
yml = (STDIN.tty?) ? '' : STDIN.read
|
||||
if yml == ''
|
||||
puts
|
||||
puts "Please specify a themes yml file"
|
||||
puts "Example: rake themes:install < themes.yml"
|
||||
exit 1
|
||||
end
|
||||
|
||||
log, counts = ThemesInstallTask.install(yml)
|
||||
|
||||
puts log
|
||||
|
||||
puts
|
||||
puts "Results:"
|
||||
puts " Installed: #{counts[:installed]}"
|
||||
puts " Updated: #{counts[:updated]}"
|
||||
puts " Skipped: #{counts[:skipped]}"
|
||||
puts " Errors: #{counts[:errors]}"
|
||||
|
||||
if counts[:errors] > 0
|
||||
exit 1
|
||||
end
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ThemesInstallTask do
|
||||
|
||||
before do
|
||||
Discourse::Application.load_tasks
|
||||
end
|
||||
|
||||
let(:github_repo) { 'https://github.com/example/theme.git' }
|
||||
let(:branch) { 'master' }
|
||||
|
||||
describe '.new' do
|
||||
context 'with url' do
|
||||
subject { described_class.new(github_repo) }
|
||||
|
||||
it 'configures the url' do
|
||||
expect(subject.url).to eq github_repo
|
||||
end
|
||||
|
||||
it 'initializes without options' do
|
||||
expect(subject.options).to eq({})
|
||||
end
|
||||
end
|
||||
|
||||
context 'with options' do
|
||||
subject { described_class.new(options) }
|
||||
let(:options) { { 'url' => github_repo, 'branch' => branch } }
|
||||
|
||||
it 'configures the url' do
|
||||
expect(subject.url).to eq github_repo
|
||||
end
|
||||
|
||||
it 'initializes options' do
|
||||
expect(subject.options).to eq("url" => github_repo, "branch" => branch)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#theme_exists?' do
|
||||
let(:theme) { Fabricate(:theme) }
|
||||
subject { described_class.new(options) }
|
||||
|
||||
context 'without branch' do
|
||||
let(:options) { github_repo }
|
||||
|
||||
it 'returns true when a branchless theme exists' do
|
||||
theme.create_remote_theme(remote_url: github_repo)
|
||||
expect(subject.theme_exists?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when the url exists but with a branch' do
|
||||
theme.create_remote_theme(remote_url: github_repo, branch: branch)
|
||||
expect(subject.theme_exists?).to be false
|
||||
end
|
||||
|
||||
it 'returns false when it doesnt exist' do
|
||||
theme.create_remote_theme(remote_url: 'https://github.com/example/different_theme.git')
|
||||
expect(subject.theme_exists?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'with branch' do
|
||||
let(:options) { { 'url' => github_repo, 'branch' => branch } }
|
||||
|
||||
it 'returns false when a branchless theme exists' do
|
||||
theme.create_remote_theme(remote_url: github_repo)
|
||||
expect(subject.theme_exists?).to be false
|
||||
end
|
||||
|
||||
it 'returns true when the url exists with a branch' do
|
||||
theme.create_remote_theme(remote_url: github_repo, branch: branch)
|
||||
expect(subject.theme_exists?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when it doesnt exist' do
|
||||
theme.create_remote_theme(remote_url: 'https://github.com/example/different_theme.git')
|
||||
expect(subject.theme_exists?).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue