diff --git a/app/controllers/admin/upgrade_controller.rb b/app/controllers/admin/upgrade_controller.rb new file mode 100644 index 000000000..096265108 --- /dev/null +++ b/app/controllers/admin/upgrade_controller.rb @@ -0,0 +1,20 @@ +# EXPERIMENTAL: front end for upgrading your instance using the web UI + +class Admin::UpgradeController < Admin::AdminController + + before_filter :ensure_admin + skip_before_filter :check_xhr + + layout 'no_js' + + def index + require_dependency 'upgrade/git_repo' + @main_repo = Upgrade::GitRepo.new(Rails.root) + end + + protected + + def ensure_admin + raise Discourse::InvalidAccess.new unless current_user.admin? + end +end diff --git a/app/views/admin/upgrade/.index.html.erb.swn b/app/views/admin/upgrade/.index.html.erb.swn new file mode 100644 index 000000000..c3303d86e Binary files /dev/null and b/app/views/admin/upgrade/.index.html.erb.swn differ diff --git a/app/views/admin/upgrade/_git_status.html.erb b/app/views/admin/upgrade/_git_status.html.erb new file mode 100644 index 000000000..eb615ddb1 --- /dev/null +++ b/app/views/admin/upgrade/_git_status.html.erb @@ -0,0 +1,10 @@ +<% if repo.valid? %> + Current version: <%= repo.latest_local_commit %> (<%= time_ago_in_words repo.latest_local_commit_date %> ago), + Remote version: <%= repo.latest_origin_commit %> (<%= time_ago_in_words repo.latest_origin_commit_date %> ago) + <% if repo.commits_behind > 0 %> + commits behind: <%= repo.commits_behind %> + + <% end %> +<% else %> + Not under source control. +<% end %> diff --git a/app/views/admin/upgrade/index.html.erb b/app/views/admin/upgrade/index.html.erb new file mode 100644 index 000000000..5c2325902 --- /dev/null +++ b/app/views/admin/upgrade/index.html.erb @@ -0,0 +1,18 @@ +

Discourse

+

+<%= render partial: 'git_status', locals: {repo: @main_repo} %> +

+ +

Plugins

+ + +

Processes

+ +

Log

diff --git a/config/routes.rb b/config/routes.rb index 3b578152c..48db18e57 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,6 +21,7 @@ Discourse::Application.routes.draw do namespace :admin, constraints: StaffConstraint.new do get '' => 'admin#index' + resources :site_settings, constraints: AdminConstraint.new get 'reports/:type' => 'reports#show' @@ -96,7 +97,10 @@ Discourse::Application.routes.draw do delete 'key' => 'api#revoke_key' end end - end + + get 'upgrade' => 'upgrade#index' + + end # admin namespace get 'email_preferences' => 'email#preferences_redirect', :as => 'email_preferences_redirect' get 'email/unsubscribe/:key' => 'email#unsubscribe', as: 'email_unsubscribe' diff --git a/lib/upgrade/git_repo.rb b/lib/upgrade/git_repo.rb new file mode 100644 index 000000000..c4499185f --- /dev/null +++ b/lib/upgrade/git_repo.rb @@ -0,0 +1,69 @@ +module Upgrade; end + +# like Grit just very very minimal +class Upgrade::GitRepo + attr_reader :path + + def initialize(path) + @path = path + @memoize = {} + end + + def valid? + File.directory?("#{path}/.git") + end + + def latest_local_commit + run "rev-parse --short HEAD" + end + + def latest_origin_commit + run "rev-parse --short #{tracking_branch}" + end + + def latest_origin_commit_date + commit_date(latest_origin_commit) + end + + def latest_local_commit_date + commit_date(latest_local_commit) + end + + def commits_behind + run("rev-list --count #{tracking_branch}..HEAD").to_i + end + + def url + url = run "config --get remote.origin.url" + if url =~ /^git/ + # hack so it works with git urls + url = "https://github.com/#{url.split(":")[1]}" + end + end + + protected + + def commit_date(commit) + unix_timestamp = run('show -s --format="%ct" ' << commit).to_i + Time.at(unix_timestamp).to_datetime + end + + def tracking_branch + run "for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)" + end + + def ensure_updated + @updated ||= Thread.new do + # this is a very slow operation, make it async + `cd #{path} && git remote update` + end + end + + def run(cmd) + ensure_updated + @memoize[cmd] ||= `cd #{path} && git #{cmd}`.strip + rescue => e + p e + end + +end