1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
require Rails.root.join('commonlib', 'rblib', 'git')
namespace :themes do
# 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(all_themes_dir, theme_name)
end
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_all_themes_dir(theme_name)]
end
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 uninstall(theme_name, verbose=false)
possible_theme_dirs(theme_name).each do |dir|
if File.directory?(dir)
run_hook(theme_name, 'uninstall', verbose)
end
end
end
def run_hook(theme_name, hook_name, verbose=false)
directory = theme_dir(theme_name)
hook_file = File.join(directory, "#{hook_name}.rb")
if File.exist? hook_file
puts "Running #{hook_name} hook in #{directory}" if verbose
load hook_file
end
end
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
minor_match = /^(\d+\.\d+)(\.\d+)+/.match(ALAVETELI_VERSION)
result.push usage_tag(minor_match[1]) if minor_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 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)
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
desc "Install themes specified in the config file's THEME_URLS"
task :install => :environment do
verbose = true
AlaveteliConfiguration::theme_urls.each{ |theme_url| install_theme(theme_url, verbose) }
if ! AlaveteliConfiguration::theme_url.blank?
# Old version of the above, for backwards compatibility
install_theme(AlaveteliConfiguration::theme_url, verbose, deprecated=true)
end
end
end
|