commit ed843833f17338fb99a9b8954981b9ea0ed54694
parent a1669cab5edc11e2260898f4592e7f6a1c488544
Author: William Morgan <wmorgan-sup@masanjin.net>
Date: Sun, 3 Jan 2010 09:52:03 -0500
Merge branch 'ferret-deprecation' into next
Diffstat:
11 files changed, 152 insertions(+), 16 deletions(-)
diff --git a/bin/sup b/bin/sup
@@ -48,6 +48,7 @@ EOS
opt :search, "Search for this query upon startup", :type => String
opt :compose, "Compose message to this recipient upon startup", :type => String
opt :subject, "When composing, use this subject", :type => String, :short => "j"
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
end
Trollop::die :subject, "requires --compose" if $opts[:subject] && !$opts[:compose]
@@ -147,9 +148,36 @@ def stop_cursing
end
module_function :start_cursing, :stop_cursing
-Index.init
+Index.init $opts[:index]
Index.lock_interactively or exit
+if Index.is_a_deprecated_ferret_index?
+ FERRET_DEPRECATION_WARNING_FN = File.join BASE_DIR, "you-have-been-warned-about-ferret-deprecation"
+ unless File.exist? FERRET_DEPRECATION_WARNING_FN
+ $stderr.puts <<EOS
+Warning! Your 30-day trial period for using Sup is almost over!
+
+To purchase the full version of Sup, please see http://sup.rubyforge.org/.
+
+Just kidding. BUT! You are using an old Ferret index. The Ferret backend is
+deprecated and support will be removed in the next version of Sup.
+
+You should convert to Xapian before that happens.
+
+The conversion process may take several hours. It is safe and interruptable.
+You can start it at any point by typing:
+
+ sup-convert-ferret-index
+
+Press enter to continue and be on your way. You won't see this message
+again, just a brief reminder at shutdown.
+EOS
+
+ $stdin.gets
+ FileUtils.touch FERRET_DEPRECATION_WARNING_FN
+ end
+end
+
begin
Redwood::start
Index.load
@@ -393,4 +421,8 @@ EOS
end
end
+if Index.is_a_deprecated_ferret_index?
+ puts "Reminder: to update your Ferret index to Xapian, run sup-convert-ferret-index."
+end
+
end
diff --git a/bin/sup-add b/bin/sup-add
@@ -40,6 +40,7 @@ EOS
opt :labels, "A comma-separated set of labels to apply to all messages from this source", :type => String
opt :force_new, "Create a new account for this source, even if one already exists."
opt :force_account, "Reuse previously defined account user@hostname.", :type => String
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
end
Trollop::die "require one or more sources" if ARGV.empty?
@@ -85,7 +86,7 @@ end
$terminal.wrap_at = :auto
Redwood::start
-index = Redwood::Index.init
+index = Redwood::Index.init $opts[:index]
index.lock_interactively or exit
diff --git a/bin/sup-config b/bin/sup-config
@@ -15,7 +15,7 @@ configuration.
Usage:
sup-config
-Options:
+No options.
EOS
end
diff --git a/bin/sup-convert-ferret-index b/bin/sup-convert-ferret-index
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'trollop'
+require 'sup'
+
+STATE_BACKUP_FN = "/tmp/sup-state.txt"
+SOURCE_BACKUP_FN = "sources.yaml-before-xapian-upgrade"
+BIN_DIR = File.dirname __FILE__
+
+$opts = Trollop::options do
+ version "sup-convert-ferret-index (sup #{Redwood::VERSION})"
+ banner <<EOS
+Convert an Sup Ferret index to a Xapian index.
+
+This will be a very slow process, but it will be lossless.
+
+If you interrupt it, nothing bad will happen. However, you will have to
+restart it from scratch.
+
+Usage:
+ sup-convert-ferret-index
+
+Options:
+EOS
+ opt :verbose, "Be verbose", :short => "-v"
+ opt :dry_run, "Don't actually do anything, just print out what would happen.", :short => "-n"
+ opt :version, "Show version information", :short => :none
+end
+
+def build_cmd cmd
+ (ENV["RUBY_INVOCATION"] ? ENV["RUBY_INVOCATION"] + " " : "") + File.join(BIN_DIR, cmd)
+end
+
+def run cmd
+ puts cmd
+ unless $opts[:dry_run]
+ startt = Time.now
+ system cmd or abort
+ printf "(completed in %.1fs)\n", (Time.now - startt)
+ end
+ puts
+end
+
+Redwood::start
+index = Redwood::Index.init
+Trollop::die "you appear to already have a Xapian index--delete #{File.join(Redwood::BASE_DIR, "xapian")} if you really want to do this" unless Redwood::Index.is_a_deprecated_ferret_index?
+
+puts "## Step one: back up all message state to #{STATE_BACKUP_FN}"
+run "#{build_cmd 'sup-dump'} --index ferret > #{STATE_BACKUP_FN}"
+puts "## message state saved to #{STATE_BACKUP_FN}"
+
+source_backup_fn = File.join Redwood::BASE_DIR, SOURCE_BACKUP_FN
+puts "## Step two: back up sources.yaml file to #{source_backup_fn}"
+run "cp #{Redwood::SOURCE_FN} #{source_backup_fn}"
+
+puts "## Step three: build the Xapian index"
+run "#{build_cmd 'sup-sync'} --all --all-sources --index xapian --restore #{STATE_BACKUP_FN} #{$opts[:verbose] ? '--verbose' : ''}"
+puts "## xapian index successfully built!"
+
+puts <<EOS
+
+Congratulations, your index has been upgraded to the Xapian backend.
+From now on, running sup should detect this index automatically.
+
+If you want to revert to the Ferret index:
+1. overwrite #{Redwood::SOURCE_FN} with #{source_backup_fn}
+2. use sup --index ferret, OR delete your #{Redwood::BASE_DIR}/xapian directory"
+Note that the Ferret index will not be supported as of the next Sup release, so
+you probably shouldn't do this.
+
+If you are happy with Xapian and want to reclaim precious hard drive space:
+1. rm #{source_backup_fn}
+2. rm -r #{Redwood::BASE_DIR}/ferret
+
+Happy supping!
+EOS
diff --git a/bin/sup-dump b/bin/sup-dump
@@ -17,11 +17,12 @@ Usage:
sup-dump > <filename>
sup-dump | bzip2 > <filename> # even better
-No options.
+Options:
EOS
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
end
-index = Redwood::Index.init
+index = Redwood::Index.init $opts[:index]
Redwood::SourceManager.init
index.load
diff --git a/bin/sup-sync b/bin/sup-sync
@@ -76,6 +76,7 @@ text <<EOS
Other options:
EOS
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
opt :verbose, "Print message ids as they're processed."
opt :optimize, "As the final operation, optimize the index."
opt :all_sources, "Scan over all sources.", :short => :none
@@ -95,7 +96,7 @@ target = [:new, :changed, :all, :restored].find { |x| opts[x] } || :new
op = [:asis, :restore, :discard].find { |x| opts[x] } || :asis
Redwood::start
-index = Redwood::Index.init
+index = Redwood::Index.init opts[:index]
restored_state = if opts[:restore]
dump = {}
diff --git a/bin/sup-sync-back b/bin/sup-sync-back
@@ -47,6 +47,7 @@ EOS
opt :with_dotlockfile, "Specific dotlockfile location (mbox files only).", :default => "/usr/bin/dotlockfile", :short => :none
opt :dont_use_dotlockfile, "Don't use dotlockfile to lock mbox files. Dangerous if other processes modify them concurrently.", :default => false, :short => :none
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
opt :verbose, "Print message ids as they're processed."
opt :dry_run, "Don't actually modify the index. Probably only useful with --verbose.", :short => "-n"
opt :version, "Show version information", :short => :none
@@ -65,7 +66,7 @@ EOS
end
Redwood::start
-index = Redwood::Index.init
+index = Redwood::Index.init $opts[:index]
index.lock_interactively or exit
deleted_fp, spam_fp = nil
diff --git a/bin/sup-tweak-labels b/bin/sup-tweak-labels
@@ -46,6 +46,7 @@ EOS
Other options:
EOS
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
opt :verbose, "Print message ids as they're processed."
opt :very_verbose, "Print message names and subjects as they're processed."
opt :all_sources, "Scan over all sources.", :short => :none
@@ -60,7 +61,7 @@ remove_labels = opts[:remove].to_set_of_symbols ","
Trollop::die "nothing to do: no labels to add or remove" if add_labels.empty? && remove_labels.empty?
Redwood::start
-index = Redwood::Index.init
+index = Redwood::Index.init $opts[:index]
index.lock_interactively or exit
begin
index.load
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -54,7 +54,7 @@ module Redwood
YAML_DOMAIN = "masanjin.net"
YAML_DATE = "2006-10-01"
- DEFAULT_INDEX = 'ferret'
+ DEFAULT_NEW_INDEX_TYPE = 'xapian'
## record exceptions thrown in threads nicely
@exceptions = []
diff --git a/lib/sup/ferret_index.rb b/lib/sup/ferret_index.rb
@@ -11,6 +11,8 @@ Variables:
subs: The string being searched.
EOS
+ def is_a_deprecated_ferret_index?; true end
+
def initialize dir=BASE_DIR
super
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -23,6 +23,8 @@ class BaseIndex
def method_missing m; @h[m.to_s] end
end
+ def is_a_deprecated_ferret_index?; false end
+
include Singleton
def initialize dir=BASE_DIR
@@ -207,13 +209,31 @@ class BaseIndex
end
end
-index_name = ENV['SUP_INDEX'] || $config[:index] || DEFAULT_INDEX
-case index_name
- when "xapian"; require "sup/xapian_index"
- when "ferret"; require "sup/ferret_index"
- else fail "unknown index type #{index_name.inspect}"
+## just to make the backtraces even more insane, here we engage in yet more
+## method_missing metaprogramming so that Index.init(index_type_name) will
+## magically make Index act like the correct Index class.
+class Index
+ def self.init type=nil
+ ## determine the index type from the many possible ways of setting it
+ type = (type == "auto" ? nil : type) ||
+ ENV['SUP_INDEX'] ||
+ $config[:index] ||
+ (File.exist?(File.join(BASE_DIR, "xapian")) && "xapian") || ## PRIORITIZE THIS
+ (File.exist?(File.join(BASE_DIR, "ferret")) && "ferret") || ## deprioritize this
+ DEFAULT_NEW_INDEX_TYPE
+ begin
+ require "sup/#{type}_index"
+ @klass = Redwood.const_get "#{type.capitalize}Index"
+ @obj = @klass.init
+ rescue LoadError, NameError => e
+ raise "unknown index type #{type.inspect}: #{e.message}"
+ end
+ debug "using #{type} index"
+ @obj
+ end
+
+ def self.instance; @obj end
+ def self.method_missing m, *a, &b; @obj.send(m, *a, &b) end
end
-Index = Redwood.const_get "#{index_name.capitalize}Index"
-debug "using index #{Index.name}"
end