sup 0.9.1 → 0.10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sup might be problematic. Click here for more details.

Files changed (46) hide show
  1. data/CONTRIBUTORS +10 -6
  2. data/History.txt +11 -0
  3. data/ReleaseNotes +10 -0
  4. data/bin/sup +55 -19
  5. data/bin/sup-add +18 -8
  6. data/bin/sup-config +2 -2
  7. data/bin/sup-convert-ferret-index +84 -0
  8. data/bin/sup-dump +4 -3
  9. data/bin/sup-sync +4 -3
  10. data/bin/sup-sync-back +3 -2
  11. data/bin/sup-tweak-labels +3 -3
  12. data/lib/sup.rb +35 -4
  13. data/lib/sup/buffer.rb +12 -6
  14. data/lib/sup/colormap.rb +1 -0
  15. data/lib/sup/crypto.rb +76 -55
  16. data/lib/sup/ferret_index.rb +6 -1
  17. data/lib/sup/index.rb +62 -8
  18. data/lib/sup/logger.rb +2 -1
  19. data/lib/sup/maildir.rb +4 -2
  20. data/lib/sup/mbox/loader.rb +4 -3
  21. data/lib/sup/message-chunks.rb +9 -7
  22. data/lib/sup/message.rb +29 -27
  23. data/lib/sup/mode.rb +11 -4
  24. data/lib/sup/modes/buffer-list-mode.rb +5 -0
  25. data/lib/sup/modes/console-mode.rb +4 -0
  26. data/lib/sup/modes/edit-message-mode.rb +4 -2
  27. data/lib/sup/modes/file-browser-mode.rb +1 -1
  28. data/lib/sup/modes/inbox-mode.rb +18 -1
  29. data/lib/sup/modes/label-list-mode.rb +44 -3
  30. data/lib/sup/modes/text-mode.rb +1 -1
  31. data/lib/sup/modes/thread-index-mode.rb +63 -52
  32. data/lib/sup/modes/thread-view-mode.rb +68 -7
  33. data/lib/sup/poll.rb +20 -5
  34. data/lib/sup/source.rb +1 -0
  35. data/lib/sup/thread.rb +1 -1
  36. data/lib/sup/util.rb +49 -11
  37. data/lib/sup/xapian_index.rb +151 -112
  38. metadata +4 -10
  39. data/lib/sup/hook.rb.BACKUP.8625.rb +0 -158
  40. data/lib/sup/hook.rb.BACKUP.8681.rb +0 -158
  41. data/lib/sup/hook.rb.BASE.8625.rb +0 -155
  42. data/lib/sup/hook.rb.BASE.8681.rb +0 -155
  43. data/lib/sup/hook.rb.LOCAL.8625.rb +0 -142
  44. data/lib/sup/hook.rb.LOCAL.8681.rb +0 -142
  45. data/lib/sup/hook.rb.REMOTE.8625.rb +0 -145
  46. data/lib/sup/hook.rb.REMOTE.8681.rb +0 -145
@@ -10,28 +10,32 @@ Ingmar Vanhassel <ingmar at the exherbo dot orgs>
10
10
  Mark Alexander <marka at the pobox dot coms>
11
11
  Christopher Warrington <chrisw at the rice dot edus>
12
12
  Richard Brown <rbrown at the exherbo dot orgs>
13
+ Anthony Martinez <pi+sup at the pihost dot uss>
13
14
  Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
14
15
  Israel Herraiz <israel.herraiz at the gmail dot coms>
16
+ Tero Tilus <tero at the tilus dot nets>
17
+ Bo Borgerson <gigabo at the gmail dot coms>
18
+ William Erik Baxter <web at the superscript dot coms>
15
19
  Grant Hollingworth <grant at the antiflux dot orgs>
16
20
  Adeodato Simó <dato at the net.com.org dot ess>
17
21
  Edward Z. Yang <ezyang at the mit dot edus>
18
22
  Steve Goldman <sgoldman at the tower-research dot coms>
23
+ Michael Stapelberg <michael at the stapelberg dot des>
19
24
  Decklin Foster <decklin at the red-bean dot coms>
25
+ Eric Sherman <hyperbolist at the gmail dot coms>
20
26
  Cameron Matheson <cam+sup at the cammunism dot orgs>
21
- Tero Tilus <tero at the tilus dot nets>
27
+ Carl Worth <cworth at the cworth dot orgs>
22
28
  Alex Vandiver <alex at the chmrr dot nets>
23
29
  Jeff Balogh <its.jeff.balogh at the gmail dot coms>
24
30
  Andrew Pimlott <andrew at the pimlott dot nets>
25
31
  Peter Harkins <ph at the malaprop dot orgs>
26
- Anthony Martinez <pi at the pihost dot uss>
27
- Carl Worth <cworth at the cworth dot orgs>
28
32
  Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
29
33
  Giorgio Lando <patroclo7 at the gmail dot coms>
30
34
  Benoît PIERRE <benoit.pierre at the gmail dot coms>
35
+ Jonah <Jonah at the GoodCoffee dot cas>
31
36
  ian <ian at the lorf dot orgs>
32
37
  Steven Walter <swalter at the monarch.(none)>
33
- Michael Hamann <michael at the content-space dot des>
34
- Stefan Lundström <lundst at the snabb.(none)>
35
- William Erik Baxter <web at the superscript dot coms>
36
38
  Jon M. Dugan <jdugan at the es dot nets>
39
+ Stefan Lundström <lundst at the snabb.(none)>
40
+ Michael Hamann <michael at the content-space dot des>
37
41
  Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
@@ -1,3 +1,14 @@
1
+ == 0.10 / 2010-01-22
2
+ * Make Xapian backend the default, and add deprecation notice to Ferret indexes.
3
+ * Now Ruby 1.9 compatible (Xapian backend only).
4
+ * Changes are now saved automatically to the index. Pressing "$" now just
5
+ forces a flush of Xapian indexes, which can minimize quit time.
6
+ * Fix problem with replying to Google Groups messages.
7
+ * Allow toggling of line wrap. Useful for long URLs.
8
+ * Multiple attachments can be added at once by specifying a wildcard.
9
+ * New command to save all attachments at once.
10
+ * As always, many bugfixes and tweaks.
11
+
1
12
  == 0.9.1 / 2009-12-10
2
13
  * Make textfield behave more like readline, including C-w
3
14
  * Add ask_for_to config option. You can set all ask_for_* options to false, and
@@ -1,3 +1,13 @@
1
+ Release 0.10:
2
+
3
+ The Xapian backend is now the default. Convert your old, crash-prone Ferret
4
+ index to Xapian by running sup-convert-ferret-index.
5
+
6
+ Using a Ferret backend will produce a deprecation notice, and will not be
7
+ supported in 0.11.
8
+
9
+ Many thanks to Rich Lane.
10
+
1
11
  Release 0.9.1:
2
12
 
3
13
  This is mainly a bugfix release, with a couple minor new features rolled up.
data/bin/sup CHANGED
@@ -1,24 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'ncurses'
5
- require 'curses'
6
- require 'fileutils'
7
- require 'trollop'
8
- require "sup"
9
-
10
- BIN_VERSION = "0.9.1"
11
4
 
12
- unless Redwood::VERSION == BIN_VERSION
13
- $stderr.puts <<EOS
5
+ no_ncursesw = false
6
+ begin
7
+ require 'ncursesw'
8
+ rescue LoadError
9
+ require 'ncurses'
10
+ no_ncursesw = true
11
+ end
14
12
 
15
- Error: version mismatch!
16
- The sup executable is at version #{BIN_VERSION.inspect}.
17
- The sup libraries are at version #{Redwood::VERSION.inspect}.
13
+ require 'fileutils'
14
+ require 'trollop'
15
+ require "sup"; Redwood::check_library_version_against "0.10"
18
16
 
19
- Is your development environment conflicting with rubygems?
20
- EOS
21
- exit(-1)
17
+ if no_ncursesw
18
+ debug "No 'ncursesw' gem detected. Install it for wide character support."
22
19
  end
23
20
 
24
21
  $opts = Trollop::options do
@@ -37,6 +34,7 @@ EOS
37
34
  opt :search, "Search for this query upon startup", :type => String
38
35
  opt :compose, "Compose message to this recipient upon startup", :type => String
39
36
  opt :subject, "When composing, use this subject", :type => String, :short => "j"
37
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
40
38
  end
41
39
 
42
40
  Trollop::die :subject, "requires --compose" if $opts[:subject] && !$opts[:compose]
@@ -79,6 +77,7 @@ global_keymap = Keymap.new do |k|
79
77
  k.add :search_unread, "Show all unread messages", 'U'
80
78
  k.add :list_labels, "List labels", 'L'
81
79
  k.add :poll, "Poll for new messages", 'P'
80
+ k.add :poll_unusual, "Poll for new messages from unusual sources", '{'
82
81
  k.add :compose, "Compose new message", 'm', 'c'
83
82
  k.add :nothing, "Do nothing", :ctrl_g
84
83
  k.add :recall_draft, "Edit most recent draft message", 'R'
@@ -135,12 +134,40 @@ def stop_cursing
135
134
  end
136
135
  module_function :start_cursing, :stop_cursing
137
136
 
138
- Index.init
137
+ Index.init $opts[:index]
139
138
  Index.lock_interactively or exit
140
139
 
140
+ if Index.is_a_deprecated_ferret_index?
141
+ FERRET_DEPRECATION_WARNING_FN = File.join BASE_DIR, "you-have-been-warned-about-ferret-deprecation"
142
+ unless File.exist? FERRET_DEPRECATION_WARNING_FN
143
+ $stderr.puts <<EOS
144
+ Warning! Your 30-day trial period for using Sup is almost over!
145
+
146
+ To purchase the full version of Sup, please see http://sup.rubyforge.org/.
147
+
148
+ Just kidding. BUT! You are using an old Ferret index. The Ferret backend is
149
+ deprecated and support will be removed in the next version of Sup.
150
+
151
+ You should convert to Xapian before that happens.
152
+
153
+ The conversion process may take several hours. It is safe and interruptable.
154
+ You can start it at any point by typing:
155
+
156
+ sup-convert-ferret-index
157
+
158
+ Press enter to continue and be on your way. You won't see this message
159
+ again, just a brief reminder at shutdown.
160
+ EOS
161
+
162
+ $stdin.gets
163
+ FileUtils.touch FERRET_DEPRECATION_WARNING_FN
164
+ end
165
+ end
166
+
141
167
  begin
142
168
  Redwood::start
143
169
  Index.load
170
+ Index.start_sync_worker unless $opts[:no_threads]
144
171
 
145
172
  $die = false
146
173
  trap("TERM") { |x| $die = true }
@@ -289,6 +316,10 @@ begin
289
316
  ComposeMode.spawn_nicely
290
317
  when :poll
291
318
  reporting_thread("user-invoked poll") { PollManager.poll }
319
+ when :poll_unusual
320
+ if BufferManager.ask_yes_or_no "Really poll unusual sources?"
321
+ reporting_thread("user-invoked unusual poll") { PollManager.poll_unusual }
322
+ end
292
323
  when :recall_draft
293
324
  case Index.num_results_for :label => :draft
294
325
  when 0
@@ -329,6 +360,7 @@ ensure
329
360
 
330
361
  HookManager.run "shutdown"
331
362
 
363
+ Index.stop_sync_worker
332
364
  Redwood::finish
333
365
  stop_cursing
334
366
  Redwood::Logger.remove_all_sinks!
@@ -359,9 +391,9 @@ unless Redwood::exceptions.empty?
359
391
  $stderr.puts <<EOS
360
392
  ----------------------------------------------------------------
361
393
  I'm very sorry. It seems that an error occurred in Sup. Please
362
- accept my sincere apologies. If you don't mind, please send the
363
- contents of #{BASE_DIR}/exception-log.txt and a brief report of the
364
- circumstances to sup-talk at rubyforge dot orgs so that I might
394
+ accept my sincere apologies. Please submit the contents of
395
+ #{BASE_DIR}/exception-log.txt and a brief report of the
396
+ circumstances to http://masanjin.net/sup-bugs/ so that I might
365
397
  address this problem. Thank you!
366
398
 
367
399
  Sincerely,
@@ -374,4 +406,8 @@ EOS
374
406
  end
375
407
  end
376
408
 
409
+ if Index.is_a_deprecated_ferret_index?
410
+ puts "Reminder: to update your Ferret index to Xapian, run sup-convert-ferret-index."
411
+ end
412
+
377
413
  end
@@ -4,7 +4,7 @@ require 'uri'
4
4
  require 'rubygems'
5
5
  require 'highline/import'
6
6
  require 'trollop'
7
- require "sup"
7
+ require "sup"; Redwood::check_library_version_against "0.10"
8
8
 
9
9
  $opts = Trollop::options do
10
10
  version "sup-add (sup #{Redwood::VERSION})"
@@ -39,6 +39,8 @@ EOS
39
39
  opt :unusual, "Do not automatically poll these sources for new messages."
40
40
  opt :labels, "A comma-separated set of labels to apply to all messages from this source", :type => String
41
41
  opt :force_new, "Create a new account for this source, even if one already exists."
42
+ opt :force_account, "Reuse previously defined account user@hostname.", :type => String
43
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
42
44
  end
43
45
 
44
46
  Trollop::die "require one or more sources" if ARGV.empty?
@@ -56,13 +58,20 @@ def get_login_info uri, sources
56
58
 
57
59
  username, password = nil, nil
58
60
  unless accounts.empty? || $opts[:force_new]
59
- say "Would you like to use the same account as for a previous source for #{uri}?"
60
- choose do |menu|
61
- accounts.each do |host, olduser, oldpw|
62
- menu.choice("Use the account info for #{olduser}@#{host}") { username, password = olduser, oldpw }
61
+ if $opts[:force_account]
62
+ host, username, password = accounts.find { |h, u, p| $opts[:force_account] == "#{u}@#{h}" }
63
+ unless username && password
64
+ say "No previous account #{$opts[:force_account].inspect} found."
65
+ end
66
+ else
67
+ say "Would you like to use the same account as for a previous source for #{uri}?"
68
+ choose do |menu|
69
+ accounts.each do |host, olduser, oldpw|
70
+ menu.choice("Use the account info for #{olduser}@#{host}") { username, password = olduser, oldpw }
71
+ end
72
+ menu.choice("Use a new account") { }
73
+ menu.prompt = "Account selection? "
63
74
  end
64
- menu.choice("Use a new account") { }
65
- menu.prompt = "Account selection? "
66
75
  end
67
76
  end
68
77
 
@@ -77,7 +86,8 @@ end
77
86
 
78
87
  $terminal.wrap_at = :auto
79
88
  Redwood::start
80
- index = Redwood::Index.init
89
+ index = Redwood::Index.init $opts[:index]
90
+ index.load
81
91
 
82
92
  index.lock_interactively or exit
83
93
 
@@ -4,7 +4,7 @@ require 'rubygems'
4
4
  require 'highline/import'
5
5
  require 'yaml'
6
6
  require 'trollop'
7
- require "sup"
7
+ require "sup"; Redwood::check_library_version_against "0.10"
8
8
 
9
9
  $opts = Trollop::options do
10
10
  version "sup-config (sup #{Redwood::VERSION})"
@@ -15,7 +15,7 @@ configuration.
15
15
  Usage:
16
16
  sup-config
17
17
 
18
- Options:
18
+ No options.
19
19
  EOS
20
20
  end
21
21
 
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require "sup"; Redwood::check_library_version_against "0.10"
6
+
7
+ STATE_BACKUP_FN = "/tmp/sup-state.txt"
8
+ SOURCE_BACKUP_FN = "sources.yaml-before-xapian-upgrade"
9
+ BIN_DIR = File.dirname __FILE__
10
+
11
+ $opts = Trollop::options do
12
+ version "sup-convert-ferret-index (sup #{Redwood::VERSION})"
13
+ banner <<EOS
14
+ Convert an Sup Ferret index to a Xapian index.
15
+
16
+ This will be a very slow process, but it will be lossless.
17
+
18
+ If you interrupt it, nothing bad will happen. However, you will have to
19
+ restart it from scratch.
20
+
21
+ Usage:
22
+ sup-convert-ferret-index
23
+
24
+ Options:
25
+ EOS
26
+ opt :verbose, "Be verbose", :short => "-v"
27
+ opt :dry_run, "Don't actually do anything, just print out what would happen.", :short => "-n"
28
+ opt :force, "Force overwrite of an old Xapian index"
29
+ opt :version, "Show version information", :short => :none
30
+ end
31
+
32
+ def build_cmd cmd
33
+ (ENV["RUBY_INVOCATION"] ? ENV["RUBY_INVOCATION"] + " " : "") + File.join(BIN_DIR, cmd)
34
+ end
35
+
36
+ def run cmd
37
+ puts cmd
38
+ unless $opts[:dry_run]
39
+ startt = Time.now
40
+ system cmd or abort
41
+ printf "(completed in %.1fs)\n", (Time.now - startt)
42
+ end
43
+ puts
44
+ end
45
+
46
+ begin
47
+ require 'xapian'
48
+ rescue LoadError
49
+ Trollop::die "you don't have the xapian gem installed, so this script won't do much for you--`gem install xapian` (or xapian-full) first"
50
+ end
51
+
52
+ Redwood::start
53
+ index = Redwood::Index.init
54
+ Trollop::die "you appear to already have a Xapian index--delete #{File.join(Redwood::BASE_DIR, "xapian")} or use --force if you really want to do this" unless Redwood::Index.is_a_deprecated_ferret_index? || $opts[:force]
55
+
56
+ puts "## Step one: back up all message state to #{STATE_BACKUP_FN}"
57
+ run "#{build_cmd 'sup-dump'} --index ferret > #{STATE_BACKUP_FN}"
58
+ puts "## message state saved to #{STATE_BACKUP_FN}"
59
+
60
+ source_backup_fn = File.join Redwood::BASE_DIR, SOURCE_BACKUP_FN
61
+ puts "## Step two: back up sources.yaml file to #{source_backup_fn}"
62
+ run "cp #{Redwood::SOURCE_FN} #{source_backup_fn}"
63
+
64
+ puts "## Step three: build the Xapian index"
65
+ run "#{build_cmd 'sup-sync'} --all --all-sources --index xapian --restore #{STATE_BACKUP_FN} #{$opts[:verbose] ? '--verbose' : ''}"
66
+ puts "## xapian index successfully built!"
67
+
68
+ puts <<EOS
69
+
70
+ Congratulations, your index has been upgraded to the Xapian backend.
71
+ From now on, running sup should detect this index automatically.
72
+
73
+ If you want to revert to the Ferret index:
74
+ 1. overwrite #{Redwood::SOURCE_FN} with #{source_backup_fn}
75
+ 2. use sup --index ferret, OR delete your #{Redwood::BASE_DIR}/xapian directory"
76
+ Note that the Ferret index will not be supported as of the next Sup release, so
77
+ you probably shouldn't do this.
78
+
79
+ If you are happy with Xapian and want to reclaim precious hard drive space:
80
+ 1. rm #{source_backup_fn}
81
+ 2. rm -r #{Redwood::BASE_DIR}/ferret
82
+
83
+ Happy supping!
84
+ EOS
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'trollop'
5
- require "sup"
5
+ require "sup"; Redwood::check_library_version_against "0.10"
6
6
 
7
7
  $opts = Trollop::options do
8
8
  version "sup-dump (sup #{Redwood::VERSION})"
@@ -17,11 +17,12 @@ Usage:
17
17
  sup-dump > <filename>
18
18
  sup-dump | bzip2 > <filename> # even better
19
19
 
20
- No options.
20
+ Options:
21
21
  EOS
22
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
22
23
  end
23
24
 
24
- index = Redwood::Index.init
25
+ index = Redwood::Index.init $opts[:index]
25
26
  Redwood::SourceManager.init
26
27
  index.load
27
28
 
@@ -3,7 +3,7 @@
3
3
  require 'uri'
4
4
  require 'rubygems'
5
5
  require 'trollop'
6
- require "sup"
6
+ require "sup"; Redwood::check_library_version_against "0.10"
7
7
 
8
8
  PROGRESS_UPDATE_INTERVAL = 15 # seconds
9
9
 
@@ -76,6 +76,7 @@ text <<EOS
76
76
 
77
77
  Other options:
78
78
  EOS
79
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
79
80
  opt :verbose, "Print message ids as they're processed."
80
81
  opt :optimize, "As the final operation, optimize the index."
81
82
  opt :all_sources, "Scan over all sources.", :short => :none
@@ -95,7 +96,7 @@ target = [:new, :changed, :all, :restored].find { |x| opts[x] } || :new
95
96
  op = [:asis, :restore, :discard].find { |x| opts[x] } || :asis
96
97
 
97
98
  Redwood::start
98
- index = Redwood::Index.init
99
+ index = Redwood::Index.init opts[:index]
99
100
 
100
101
  restored_state = if opts[:restore]
101
102
  dump = {}
@@ -226,7 +227,7 @@ begin
226
227
  elapsed = last_info_time - start_time
227
228
  pctdone = source.respond_to?(:pct_done) ? source.pct_done : 100.0 * (source.cur_offset.to_f - source.start_offset).to_f / (source.end_offset - source.start_offset).to_f
228
229
  remaining = (100.0 - pctdone) * (elapsed.to_f / pctdone)
229
- printf "## read %dm (about %.0f%%) @ %.1fm/s. %s elapsed, about %s remaining\n", num_scanned, pctdone, num_scanned / elapsed, elapsed.to_time_s, remaining.to_time_s
230
+ printf "## read %dm (~%.0f%%) @ %.1fm/s. %s elapsed, ~%s remaining, offset #{source.cur_offset}\n", num_scanned, pctdone, num_scanned / elapsed, elapsed.to_time_s, remaining.to_time_s
230
231
  end
231
232
  end
232
233
 
@@ -5,7 +5,7 @@ require 'uri'
5
5
  require 'tempfile'
6
6
  require 'trollop'
7
7
  require 'enumerator'
8
- require "sup"
8
+ require "sup"; Redwood::check_library_version_against "0.10"
9
9
 
10
10
  ## save a message 'm' to an open file pointer 'fp'
11
11
  def save m, fp
@@ -47,6 +47,7 @@ EOS
47
47
  opt :with_dotlockfile, "Specific dotlockfile location (mbox files only).", :default => "/usr/bin/dotlockfile", :short => :none
48
48
  opt :dont_use_dotlockfile, "Don't use dotlockfile to lock mbox files. Dangerous if other processes modify them concurrently.", :default => false, :short => :none
49
49
 
50
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
50
51
  opt :verbose, "Print message ids as they're processed."
51
52
  opt :dry_run, "Don't actually modify the index. Probably only useful with --verbose.", :short => "-n"
52
53
  opt :version, "Show version information", :short => :none
@@ -65,7 +66,7 @@ EOS
65
66
  end
66
67
 
67
68
  Redwood::start
68
- index = Redwood::Index.init
69
+ index = Redwood::Index.init opts[:index]
69
70
  index.lock_interactively or exit
70
71
 
71
72
  deleted_fp, spam_fp = nil
@@ -3,7 +3,7 @@
3
3
  require 'rubygems'
4
4
  require 'trollop'
5
5
  require 'enumerator'
6
- require "sup"
6
+ require "sup"; Redwood::check_library_version_against "0.10"
7
7
 
8
8
  class Float
9
9
  def to_s; sprintf '%.2f', self; end
@@ -46,6 +46,7 @@ EOS
46
46
 
47
47
  Other options:
48
48
  EOS
49
+ opt :index, "Use this index type ('auto' for autodetect)", :default => "auto"
49
50
  opt :verbose, "Print message ids as they're processed."
50
51
  opt :very_verbose, "Print message names and subjects as they're processed."
51
52
  opt :all_sources, "Scan over all sources.", :short => :none
@@ -58,10 +59,9 @@ add_labels = opts[:add].to_set_of_symbols ","
58
59
  remove_labels = opts[:remove].to_set_of_symbols ","
59
60
 
60
61
  Trollop::die "nothing to do: no labels to add or remove" if add_labels.empty? && remove_labels.empty?
61
- Trollop::die "no sources specified" if ARGV.empty?
62
62
 
63
63
  Redwood::start
64
- index = Redwood::Index.init
64
+ index = Redwood::Index.init opts[:index]
65
65
  index.lock_interactively or exit
66
66
  begin
67
67
  index.load