From aa9c6b15d3a021709ad5f7b3b653ca914a8c40b8 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Fri, 29 Nov 2013 08:28:20 +0000 Subject: Move themes from vendor/plugins to lib/themes These are essentially required in exactly the same way as before, but from lib/themes rather than vendor/plugins. This is the simplest possible change in order make the themes work outside vendor/plugins, I think, but it's not necessarily ideal. It would be worth considering whether these should be changed to Rails engines, as described here: http://guides.rubyonrails.org/engines.html --- lib/tasks/themes.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/tasks/themes.rake') diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake index 1eed92f1e..78ffe73be 100644 --- a/lib/tasks/themes.rake +++ b/lib/tasks/themes.rake @@ -2,7 +2,7 @@ namespace :themes do def plugin_dir - File.join(Rails.root,"vendor","plugins") + File.join(Rails.root,"lib","themes") end def theme_dir(theme_name) -- cgit v1.2.3 From aa521fc92857502598fb8b91fff6e8930f7eab05 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Tue, 3 Dec 2013 11:36:54 +0000 Subject: Ensure that the lib/themes directory exists before installing to there (An alternative would have been to add an empty lib/themes/.gitkeep file to this directory, but that makes ignoring the installed themes more complicated.) --- lib/tasks/themes.rake | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/tasks/themes.rake') diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake index 78ffe73be..7651145ca 100644 --- a/lib/tasks/themes.rake +++ b/lib/tasks/themes.rake @@ -84,6 +84,7 @@ namespace :themes do end def install_theme(theme_url, verbose, deprecated=false) + FileUtils.mkdir_p plugin_dir deprecation_string = deprecated ? " using deprecated THEME_URL" : "" theme_name = theme_url_to_theme_name theme_url puts "Installing theme #{theme_name}#{deprecation_string} from #{theme_url}" -- cgit v1.2.3 From d4e75c6715c7ab15b257bbdd42625301783e84f6 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Tue, 3 Dec 2013 12:01:07 +0000 Subject: Try to uninstall the old theme from vendor/plugins and lib/themes The theme install task would fail if there's an old theme present in vendor/plugins, since it doesn't try to uninstall the plugin from that location, only the new location. Then when the install.rb in the new plugin runs, it'll complain that there's a public/alavetelitheme symlink already present. This commit changes themes:install to try to uninstall the plugin from both locations. --- lib/tasks/themes.rake | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'lib/tasks/themes.rake') diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake index 7651145ca..65b142a63 100644 --- a/lib/tasks/themes.rake +++ b/lib/tasks/themes.rake @@ -9,6 +9,14 @@ namespace :themes do File.join(plugin_dir, theme_name) end + def old_theme_dir(theme_name) + File.join(Rails.root, "vendor", "plugins", theme_name) + end + + def possible_theme_dirs(theme_name) + [theme_dir(theme_name), old_theme_dir(theme_name)] + end + def checkout(commitish) puts "Checking out #{commitish}" if verbose system "git checkout #{commitish}" @@ -61,13 +69,14 @@ namespace :themes do end def uninstall(theme_name, verbose=false) - dir = theme_dir(theme_name) - if File.directory?(dir) - run_hook(theme_name, 'uninstall', verbose) - puts "Removing '#{dir}'" if verbose - rm_r dir - else - puts "Plugin doesn't exist: #{dir}" + possible_theme_dirs(theme_name).each do |dir| + if File.directory?(dir) + run_hook(theme_name, 'uninstall', verbose) + puts "Removing '#{dir}'" if verbose + rm_r dir + else + puts "Plugin doesn't exist: #{dir}" + end end end @@ -80,7 +89,7 @@ namespace :themes do end def installed?(theme_name) - File.directory?(theme_dir(theme_name)) + possible_theme_dirs(theme_name).any? { |dir| File.directory? dir } end def install_theme(theme_url, verbose, deprecated=false) -- cgit v1.2.3 From 6ada52492dda1cd3d27995d1b9d7a917beef5b1a Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Fri, 6 Dec 2013 12:59:20 +0000 Subject: Make 'rake themes:install' safer for developers Previously, the themes:install rake task would remove the existing theme with 'rm -rf' and re-clone the theme into place. This is unfortunate for a developer who has been making changes to a theme and then runs the rails-post-deploy script, since it calls the themes:install task which will wipe out those changes. In addition, when installing themes it would deliberately remove the .git directory of the theme, so if you do want to work in that theme you'd have to reinitialize the theme directory to be a git repository again. This commit changes the task so that now: - If a theme directory is present but it isn't a git repository, it's moved out of the way. - If there's no theme directory at the expected location after that step, the theme repository is cloned into place - The task ensures that the origin remote points to the theme's URL, and fetches from that remote. - If there are any uncommitted changes in the theme repository or the current commit appears not to have been pushed, the task exits with a helpful error. - The preferred branch or tag is checked out in the theme repository as before. (The uninstall, install and post_install hooks are run as before.) This shouldn't make a difference to deployed instances of Alaveteli but will be helpful for developers who want to work on developing a theme. Fixes #1111. --- lib/tasks/themes.rake | 138 +++++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 59 deletions(-) (limited to 'lib/tasks/themes.rake') diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake index 65b142a63..4a864d141 100644 --- a/lib/tasks/themes.rake +++ b/lib/tasks/themes.rake @@ -1,104 +1,123 @@ +require Rails.root.join('commonlib', 'rblib', 'git') + namespace :themes do - def plugin_dir + # Alias the module so we don't need the MySociety prefix here + Git = MySociety::Git + + def all_themes_dir File.join(Rails.root,"lib","themes") end def theme_dir(theme_name) - File.join(plugin_dir, theme_name) + File.join(all_themes_dir, theme_name) end - def old_theme_dir(theme_name) + def old_all_themes_dir(theme_name) File.join(Rails.root, "vendor", "plugins", theme_name) end def possible_theme_dirs(theme_name) - [theme_dir(theme_name), old_theme_dir(theme_name)] - end - - def checkout(commitish) - puts "Checking out #{commitish}" if verbose - system "git checkout #{commitish}" + [theme_dir(theme_name), old_all_themes_dir(theme_name)] end - def checkout_tag(version) - checkout usage_tag(version) - end - - def checkout_remote_branch(branch) - checkout "origin/#{branch}" + def installed?(theme_name) + possible_theme_dirs(theme_name).any? { |dir| File.directory? dir } end def usage_tag(version) "use-with-alaveteli-#{version}" end - def install_theme_using_git(name, uri, verbose=false, options={}) - install_path = theme_dir(name) - Dir.chdir(plugin_dir) do - clone_command = "git clone #{uri} #{name}" - if system(clone_command) - Dir.chdir install_path do - # First try to checkout a specific branch of the theme - tag_checked_out = checkout_remote_branch(AlaveteliConfiguration::theme_branch) if AlaveteliConfiguration::theme_branch - if !tag_checked_out - # try to checkout a tag exactly matching ALAVETELI VERSION - tag_checked_out = checkout_tag(ALAVETELI_VERSION) - end - if ! tag_checked_out - # if we're on a hotfix release (four sequence elements or more), - # look for a usage tag matching the minor release (three sequence elements) - # and check that out if found - if hotfix_version = /^(\d+\.\d+\.\d+)(\.\d+)+/.match(ALAVETELI_VERSION) - base_version = hotfix_version[1] - tag_checked_out = checkout_tag(base_version) - end - end - if ! tag_checked_out - puts "No specific tag for this version: using HEAD" if verbose - end - puts "removing: .git .gitignore" if verbose - rm_rf %w(.git .gitignore) - end - else - rm_rf install_path - raise "#{clone_command} failed! Stopping." - end - end - end - def uninstall(theme_name, verbose=false) possible_theme_dirs(theme_name).each do |dir| if File.directory?(dir) run_hook(theme_name, 'uninstall', verbose) - puts "Removing '#{dir}'" if verbose - rm_r dir - else - puts "Plugin doesn't exist: #{dir}" end end end def run_hook(theme_name, hook_name, verbose=false) - hook_file = File.join(theme_dir(theme_name), "#{hook_name}.rb") + directory = theme_dir(theme_name) + hook_file = File.join(directory, "#{hook_name}.rb") if File.exist? hook_file - puts "Running #{hook_name} hook for #{theme_name}" if verbose + puts "Running #{hook_name} hook in #{directory}" if verbose load hook_file end end - def installed?(theme_name) - possible_theme_dirs(theme_name).any? { |dir| File.directory? dir } + def move_old_theme(old_theme_directory) + puts "There was an old-style theme at #{old_theme_directory}" if verbose + moved_directory = "#{old_theme_directory}-moved" + begin + File.rename old_theme_directory, moved_directory + rescue Errno::ENOTEMPTY, Errno::EEXIST + raise "Tried to move #{old_theme_directory} out of the way, " \ + "but #{moved_directory} already existed" + end + end + + def committishes_to_try + result = [] + theme_branch = AlaveteliConfiguration::theme_branch + result.push "origin/#{theme_branch}" if theme_branch + result.push usage_tag(ALAVETELI_VERSION) + hotfix_match = /^(\d+\.\d+\.\d+)(\.\d+)+/.match(ALAVETELI_VERSION) + result.push usage_tag(hotfix_match[1]) if hotfix_match + result + end + + def checkout_best_option(theme_name) + theme_directory = theme_dir theme_name + all_failed = true + committishes_to_try.each do |committish| + if Git.committish_exists? theme_directory, committish + puts "Checking out #{committish}" if verbose + Git.checkout theme_directory, committish + all_failed = false + break + else + puts "Failed to find #{committish}; skipping..." if verbose + end + end + puts "Falling to using HEAD instead" if all_failed and verbose end def install_theme(theme_url, verbose, deprecated=false) - FileUtils.mkdir_p plugin_dir + FileUtils.mkdir_p all_themes_dir deprecation_string = deprecated ? " using deprecated THEME_URL" : "" theme_name = theme_url_to_theme_name theme_url puts "Installing theme #{theme_name}#{deprecation_string} from #{theme_url}" + # Make sure any uninstall hooks have been run: uninstall(theme_name, verbose) if installed?(theme_name) - install_theme_using_git(theme_name, theme_url, verbose) + theme_directory = theme_dir theme_name + # Is there an old-style theme directory there? If so, move it + # out of the way so that there's no risk that work is lost: + if File.directory? theme_directory + unless Git.non_bare_repository? theme_directory + move_old_theme theme_directory + end + end + # If there isn't a directory there already, clone it into place: + unless File.directory? theme_directory + unless system "git", "clone", theme_url, theme_directory + raise "Cloning from #{theme_url} to #{theme_directory} failed" + end + end + # Set the URL for origin in case it has changed, and fetch from there: + Git.remote_set_url theme_directory, 'origin', theme_url + Git.fetch theme_directory, 'origin' + # Check that checking-out a new commit will be safe: + unless Git.status_clean theme_directory + raise "There were uncommitted changes in #{theme_directory}" + end + unless Git.is_HEAD_pushed? theme_directory + raise "The current work in #{theme_directory} is unpushed" + end + # Now try to checkout various commits in order of preference: + checkout_best_option theme_name + # Finally run the install hooks: run_hook(theme_name, 'install', verbose) run_hook(theme_name, 'post_install', verbose) end @@ -112,4 +131,5 @@ namespace :themes do install_theme(AlaveteliConfiguration::theme_url, verbose, deprecated=true) end end + end -- cgit v1.2.3