mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 10:30:01 +08:00
dec68d780c
Missing plugin gems are installed when the app is being loaded. That means when you run `bin/rails plugin:install_all_gems` it first installs missing gems and then reinstalls all gems… Also, the method these rake tasks were using to install gems was very crude, and the regex there was incorrect which resulted in failures in certain cases. Though that didn't matter since those gems were being installed using a correct method just moments before…
255 lines
7.7 KiB
Ruby
255 lines
7.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
directory 'plugins'
|
|
|
|
desc 'install all official plugins (use GIT_WRITE=1 to pull with write access)'
|
|
task 'plugin:install_all_official' do
|
|
skip = Set.new([
|
|
'customer-flair',
|
|
'lazy-yt',
|
|
'poll'
|
|
])
|
|
|
|
map = {
|
|
'Canned Replies' => 'https://github.com/discourse/discourse-canned-replies'
|
|
}
|
|
|
|
STDERR.puts "Allowing write to all repos!" if ENV['GIT_WRITE']
|
|
|
|
Plugin::Metadata::OFFICIAL_PLUGINS.each do |name|
|
|
next if skip.include? name
|
|
repo = map[name] || "https://github.com/discourse/#{name}"
|
|
dir = repo.split('/').last
|
|
path = File.expand_path('plugins/' + dir)
|
|
|
|
if Dir.exist? path
|
|
STDERR.puts "Skipping #{dir} cause it already exists!"
|
|
next
|
|
end
|
|
|
|
if ENV['GIT_WRITE']
|
|
repo = repo.gsub("https://github.com/", "git@github.com:")
|
|
repo += ".git"
|
|
end
|
|
|
|
status = system("git clone #{repo} #{path}")
|
|
unless status
|
|
abort("Failed to clone #{repo}")
|
|
end
|
|
end
|
|
end
|
|
|
|
desc 'install plugin'
|
|
task 'plugin:install', :repo do |t, args|
|
|
repo = ENV['REPO'] || ENV['repo'] || args[:repo]
|
|
name = ENV['NAME'] || ENV['name'] || File.basename(repo, '.git')
|
|
|
|
plugin_path = File.expand_path('plugins/' + name)
|
|
if File.directory?(File.expand_path(plugin_path))
|
|
abort('Plugin directory, ' + plugin_path + ', already exists.')
|
|
end
|
|
|
|
clone_status = system('git clone ' + repo + ' ' + plugin_path)
|
|
unless clone_status
|
|
FileUtils.rm_rf(plugin_path)
|
|
abort('Unable to clone plugin')
|
|
end
|
|
end
|
|
|
|
desc 'update all plugins'
|
|
task 'plugin:update_all' do |t|
|
|
# Loop through each directory
|
|
plugins = Dir.glob(File.expand_path('plugins/*')).select { |f| File.directory? f }
|
|
# run plugin:update
|
|
plugins.each do |plugin|
|
|
next unless File.directory?(plugin + "/.git")
|
|
Rake::Task['plugin:update'].invoke(plugin)
|
|
Rake::Task['plugin:update'].reenable
|
|
end
|
|
Rake::Task['plugin:versions'].invoke
|
|
end
|
|
|
|
desc 'update a plugin'
|
|
task 'plugin:update', :plugin do |t, args|
|
|
plugin = ENV['PLUGIN'] || ENV['plugin'] || args[:plugin]
|
|
plugin_path = plugin
|
|
plugin = File.basename(plugin)
|
|
|
|
unless File.directory?(plugin_path)
|
|
if File.directory?('plugins/' + plugin)
|
|
plugin_path = File.expand_path('plugins/' + plugin)
|
|
else
|
|
abort('Plugin ' + plugin + ' not found')
|
|
end
|
|
end
|
|
|
|
`git -C '#{plugin_path}' fetch origin --tags --force`
|
|
|
|
upstream_branch = `git -C '#{plugin_path}' for-each-ref --format='%(upstream:short)' $(git -C '#{plugin_path}' symbolic-ref -q HEAD)`.strip
|
|
has_origin_main = `git -C '#{plugin_path}' branch -a`.match?(/remotes\/origin\/main$/)
|
|
has_local_main = `git -C '#{plugin_path}' show-ref refs/heads/main`.present?
|
|
|
|
if upstream_branch == "origin/master" && has_origin_main
|
|
puts "Branch has changed to `origin/main`"
|
|
|
|
if has_local_main
|
|
update_status = system("git -C '#{plugin_path}' checkout main")
|
|
abort("Unable to pull latest version of plugin #{plugin_path}") unless update_status
|
|
else
|
|
`git -C '#{plugin_path}' branch -m master main`
|
|
end
|
|
|
|
`git -C '#{plugin_path}' branch -u origin/main main`
|
|
end
|
|
|
|
update_status = system("git -C '#{plugin_path}' pull --no-rebase")
|
|
abort("Unable to pull latest version of plugin #{plugin_path}") unless update_status
|
|
end
|
|
|
|
desc 'pull compatible plugin versions for all plugins'
|
|
task 'plugin:pull_compatible_all' do |t|
|
|
if GlobalSetting.load_plugins?
|
|
STDERR.puts <<~TEXT
|
|
WARNING: Plugins were activated before running `rake plugin:pull_compatible_all`
|
|
You should prefix this command with LOAD_PLUGINS=0
|
|
TEXT
|
|
end
|
|
|
|
# Loop through each directory
|
|
plugins = Dir.glob(File.expand_path('plugins/*')).select { |f| File.directory? f }
|
|
# run plugin:pull_compatible
|
|
plugins.each do |plugin|
|
|
next unless File.directory?(plugin + "/.git")
|
|
Rake::Task['plugin:pull_compatible'].invoke(plugin)
|
|
Rake::Task['plugin:pull_compatible'].reenable
|
|
end
|
|
end
|
|
|
|
desc 'pull a compatible plugin version'
|
|
task 'plugin:pull_compatible', :plugin do |t, args|
|
|
plugin = ENV['PLUGIN'] || ENV['plugin'] || args[:plugin]
|
|
plugin_path = plugin
|
|
plugin = File.basename(plugin)
|
|
|
|
unless File.directory?(plugin_path)
|
|
if File.directory?('plugins/' + plugin)
|
|
plugin_path = File.expand_path('plugins/' + plugin)
|
|
else
|
|
abort('Plugin ' + plugin + ' not found')
|
|
end
|
|
end
|
|
|
|
checkout_version = Discourse.find_compatible_git_resource(plugin_path)
|
|
|
|
# Checkout value of the version compat
|
|
if checkout_version
|
|
puts "checking out compatible #{plugin} version: #{checkout_version}"
|
|
update_status = system("git -C '#{plugin_path}' cat-file -e #{checkout_version} || git -C '#{plugin_path}' fetch --depth 1 $(git -C '#{plugin_path}' rev-parse --symbolic-full-name @{upstream} | awk -F '/' '{print $3}') #{checkout_version}; git -C '#{plugin_path}' reset --hard #{checkout_version}")
|
|
abort('Unable to checkout a compatible plugin version') unless update_status
|
|
else
|
|
puts "#{plugin} is already at latest compatible version"
|
|
end
|
|
end
|
|
|
|
desc 'install all plugin gems'
|
|
task 'plugin:install_all_gems' do |t|
|
|
# Left intentionally blank.
|
|
# When the app is being loaded, all missing gems are installed
|
|
# See: lib/plugin_gem.rb
|
|
puts "Done"
|
|
end
|
|
|
|
desc 'install plugin gems'
|
|
task 'plugin:install_gems', :plugin do |t, args|
|
|
# Left intentionally blank.
|
|
# When the app is being loaded, all missing gems are installed
|
|
# See: lib/plugin_gem.rb
|
|
puts "Done"
|
|
end
|
|
|
|
desc 'run plugin specs'
|
|
task 'plugin:spec', :plugin do |t, args|
|
|
args.with_defaults(plugin: "*")
|
|
params = ENV['RSPEC_FAILFAST'] ? '--profile --fail-fast' : '--profile'
|
|
ruby = `which ruby`.strip
|
|
files = Dir.glob("./plugins/#{args[:plugin]}/spec/**/*_spec.rb").sort
|
|
if files.length > 0
|
|
sh "LOAD_PLUGINS=1 #{ruby} -S rspec #{files.join(' ')} #{params}"
|
|
else
|
|
abort "No specs found."
|
|
end
|
|
end
|
|
|
|
desc 'run plugin qunit tests'
|
|
task 'plugin:qunit', [:plugin, :timeout] do |t, args|
|
|
args.with_defaults(plugin: "*")
|
|
|
|
rake = "#{Rails.root}/bin/rake"
|
|
|
|
cmd = 'LOAD_PLUGINS=1 '
|
|
cmd += 'QUNIT_SKIP_CORE=1 '
|
|
|
|
if args[:plugin] == "*"
|
|
puts "Running qunit tests for all plugins"
|
|
else
|
|
puts "Running qunit tests for #{args[:plugin]}"
|
|
cmd += "QUNIT_SINGLE_PLUGIN='#{args[:plugin]}' "
|
|
end
|
|
|
|
cmd += "#{rake} qunit:test"
|
|
cmd += "[#{args[:timeout]}]" if args[:timeout]
|
|
|
|
system cmd
|
|
exit $?.exitstatus
|
|
end
|
|
|
|
desc 'run all migrations of a plugin'
|
|
namespace 'plugin:migrate' do
|
|
def list_migrations(plugin_name)
|
|
plugin_root = File.join(Rails.root, "plugins", plugin_name)
|
|
migrations_root = File.join(plugin_root, "db", "{post_migrate,migrate}", "*.rb")
|
|
Dir[migrations_root]
|
|
.map do |migration_filename|
|
|
File.basename(migration_filename)[/(^.*?)_/, 1].to_i
|
|
end
|
|
.sort
|
|
end
|
|
|
|
def cmd(operation, migration_number)
|
|
"rails db:migrate:#{operation} LOAD_PLUGINS=1 VERSION=#{migration_number}"
|
|
end
|
|
|
|
task :down, [:plugin] do |t, args|
|
|
list_migrations(args[:plugin]).reverse.each do |migration_number|
|
|
sh cmd(:down, migration_number)
|
|
end
|
|
end
|
|
|
|
task :up, [:plugin] do |t, args|
|
|
list_migrations(args[:plugin]).each do |migration_number|
|
|
sh cmd(:up, migration_number)
|
|
end
|
|
end
|
|
end
|
|
|
|
desc 'display all plugin versions'
|
|
task 'plugin:versions' do |t, args|
|
|
versions =
|
|
Dir
|
|
.glob('*', base: 'plugins')
|
|
.map { |plugin|
|
|
[plugin, "plugins/#{plugin}", "plugins/#{plugin}/.git"]
|
|
}
|
|
.select { |plugin, plugin_dir, plugin_git_dir|
|
|
File.directory?(plugin_dir) && File.directory?(plugin_git_dir)
|
|
}
|
|
.map { |plugin, _, plugin_git_dir|
|
|
version = `git --git-dir \"#{plugin_git_dir}\" rev-parse HEAD`
|
|
abort("unable to get #{plugin} version") unless version
|
|
[plugin, version.strip[0...8]]
|
|
}
|
|
.to_h
|
|
|
|
puts JSON.pretty_generate(versions)
|
|
end
|