# HG changeset patch # User Michael Granger # Date 1210384362 0 # Node ID 804e1c2b9a40362a2a2b0e4cfe1814a35901633f # Parent 8c4ae0797d5fe5a29b92be65452adf76db95a306 * Added rdoc-generation to the cruise task and the artifacts that get saved * Added Darkfish external and fixed up the RDoc generation task to use it * Factored out the config-file reading from #owner into a generic config reader, and then added some methods to access config values * Fixed the message-file sort block * Added a DRb service daemon: Ezmlm::ListDaemon diff -r 8c4ae0797d5f -r 804e1c2b9a40 Rakefile --- a/Rakefile Fri May 09 17:51:36 2008 +0000 +++ b/Rakefile Sat May 10 01:52:42 2008 +0000 @@ -132,7 +132,7 @@ ### Cruisecontrol task desc "Cruisecontrol build" -task :cruise => [:clean, :coverage, :package] do |task| +task :cruise => [:clean, :coverage, :rdoc, :package] do |task| raise "Artifacts dir not set." if ARTIFACTS_DIR.to_s.empty? artifact_dir = ARTIFACTS_DIR.cleanpath artifact_dir.mkpath @@ -140,6 +140,9 @@ $stderr.puts "Copying coverage stats..." FileUtils.cp_r( 'coverage', artifact_dir ) + $stderr.puts "Copying documentation..." + FileUtils.cp_r( 'docs/api', artifact_dir + 'rdoc' ) + $stderr.puts "Copying packages..." FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir ) end diff -r 8c4ae0797d5f -r 804e1c2b9a40 lib/ezmlm.rb --- a/lib/ezmlm.rb Fri May 09 17:51:36 2008 +0000 +++ b/lib/ezmlm.rb Sat May 10 01:52:42 2008 +0000 @@ -35,7 +35,7 @@ require 'ezmlm/list' - + require 'ezmlm/listdaemon' ############### diff -r 8c4ae0797d5f -r 804e1c2b9a40 lib/ezmlm/list.rb --- a/lib/ezmlm/list.rb Fri May 09 17:51:36 2008 +0000 +++ b/lib/ezmlm/list.rb Sat May 10 01:52:42 2008 +0000 @@ -31,6 +31,9 @@ def initialize( listdir ) listdir = Pathname.new( listdir ) if !listdir.is_a?( Pathname ) @listdir = listdir + + # Cached lookups + @config = nil end @@ -42,6 +45,25 @@ attr_reader :listdir + ### Return the configured name of the list (without the host) + def name + return self.config[ 'L' ] + end + + + ### Return the configured host of the list + def host + return self.config[ 'H' ] + end + + + ### Return the configured address of the list (in list@host form) + def address + return "%s@%s" % [ self.name, self.host ] + end + alias_method :fullname, :address + + ### Return the number of messages in the list archive def message_count numfile = self.listdir + 'num' @@ -62,16 +84,28 @@ mail = self.last_post or return nil return mail.from end + + + ### Return the list config as a Hash + def config + unless @config + configfile = self.listdir + 'config' + raise "List config file %p does not exist" % [ configfile ] unless configfile.exist? + + @config = configfile.read.scan( /^(\S):([^\n]*)$/m ).inject({}) do |h,pair| + key,val = *pair + h[key] = val + h + end + end + + return @config + end ### Return the email address of the list's owner. def owner - config = self.listdir + 'config' - if config.read =~ /^5:([^\n]+)$/m - return $1 - else - return nil - end + self.config['5'] end @@ -148,7 +182,7 @@ # Find the last numbered file under the last numbered directory we found # above. last_post_path = Pathname.glob( last_archdir + '[0-9]*' ). - sort_by {|pn| Integer(pn.basename.to_s) }.last + sort_by {|pn| pn.basename.to_s }.last raise RuntimeError, "unexpectedly empty archive directory '%s'" % [ last_archdir ] \ unless last_post_path diff -r 8c4ae0797d5f -r 804e1c2b9a40 rake/rdoc.rb --- a/rake/rdoc.rb Fri May 09 17:51:36 2008 +0000 +++ b/rake/rdoc.rb Sat May 10 01:52:42 2008 +0000 @@ -3,6 +3,14 @@ # $Id$ # +BEGIN { + require 'pathname' + basedir = Pathname.new( __FILE__ ).dirname.parent + docsdir = basedir + 'docs' + + $LOAD_PATH << docsdir.to_s +} + require 'rake/rdoctask' ### Task: rdoc diff -r 8c4ae0797d5f -r 804e1c2b9a40 spec/ezmlm/list_spec.rb --- a/spec/ezmlm/list_spec.rb Fri May 09 17:51:36 2008 +0000 +++ b/spec/ezmlm/list_spec.rb Sat May 10 01:52:42 2008 +0000 @@ -29,25 +29,42 @@ LISTDIR = Pathname.new( 'list' ) - TEST_SUBSCRIBERS = %w[ pete.chaffee@toadsmackers.com dolphinzombie@alahalohamorra.com piratebanker@yahoo.com ] - TEST_MODERATORS = %w[ dolphinzombie@alahalohamorra.com ] - + TEST_LIST_NAME = 'waffle-lovers' + TEST_LIST_HOST = 'lists.syrup.info' TEST_OWNER = 'listowner@rumpus-the-whale.info' - TEST_CUSTOM_MODERATORS_DIR = '/foo/bar/clowns' - - - + TEST_CONFIG = <<-"EOF".gsub( /^\t+/, '' ) + F:-aBCDeFGHijKlMnOpQrStUVWXYZ + X: + D:/var/qmail/alias/lists/waffle-lovers/ + T:/var/qmail/alias/.qmail-waffle-lovers + L:#{TEST_LIST_NAME} + H:#{TEST_LIST_HOST} + C: + 0: + 3: + 4: + 5:#{TEST_OWNER} + 6: + 7: + 8: + 9: + EOF + it "can create a new list" + it "can add a new subscriber" + it "can remove a current subscriber" + it "can edit the list's text files" + ### ### List manager functions @@ -60,6 +77,49 @@ end + it "can return the configured list name" do + @list.stub!( :config ).and_return({ 'L' => :the_list_name }) + @list.name.should == :the_list_name + end + + + it "can return the configured list host" do + @list.stub!( :config ).and_return({ 'H' => :the_list_host }) + @list.host.should == :the_list_host + end + + + it "can return the configured list address" do + @list.stub!( :config ).and_return({ 'L' => TEST_LIST_NAME, 'H' => TEST_LIST_HOST }) + @list.address.should == "%s@%s" % [ TEST_LIST_NAME, TEST_LIST_HOST ] + end + + + CONFIG_KEYS = %w[ F X D T L H C 0 3 4 5 6 7 8 9 ] + + it "can fetch the list config as a Hash" do + config_path = mock( "Mock config path" ) + @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path ) + config_path.should_receive( :exist? ).and_return( true ) + config_path.should_receive( :read ).and_return( TEST_CONFIG ) + + @list.config.should be_an_instance_of( Hash ) + @list.config.should have( CONFIG_KEYS.length ).members + @list.config.keys.should include( *CONFIG_KEYS ) + end + + + it "raises an error if the list config file doesn't exist" do + config_path = mock( "Mock config path" ) + @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path ) + config_path.should_receive( :exist? ).and_return( false ) + + lambda { + @list.config + }.should raise_error( RuntimeError, /does not exist/ ) + end + + it "can return a list of subscribers' email addresses" do subscribers_dir = LISTDIR + 'subscribers' @@ -313,61 +373,20 @@ ### List owner - TEST_CONFIG_WITHOUT_OWNER = <<-"EOF".gsub( /^\t+/, '' ) - F:-aBCDeFGHijKlMnOpQrStUVWXYZ - X: - D:/var/qmail/alias/lists/waffle-lovers/ - T:/var/qmail/alias/.qmail-waffle-lovers - L:waffle-lovers - H:lists.syrup.info - C: - 0: - 3: - 4: - 5: - 6: - 7: - 8: - 9: - EOF - it "returns nil when the list doesn't have an owner in its config" do - config_path_obj = mock( "Config path object" ) - @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj ) - config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITHOUT_OWNER ) - + @list.stub!( :config ).and_return({ '5' => nil }) @list.owner.should == nil end - TEST_CONFIG_WITH_OWNER = <<-"EOF".gsub( /^\t+/, '' ) - F:-aBCDeFGHijKlMnOpQrStUVWXYZ - X: - D:/var/qmail/alias/lists/waffle-lovers/ - T:/var/qmail/alias/.qmail-waffle-lovers - L:waffle-lovers - H:lists.syrup.info - C: - 0: - 3: - 4: - 5:#{TEST_OWNER} - 6: - 7: - 8: - 9: - EOF - it "can return the email address of the list owner" do - config_path_obj = mock( "Config path object" ) - @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj ) - config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITH_OWNER ) - + @list.stub!( :config ).and_return({ '5' => TEST_OWNER }) @list.owner.should == TEST_OWNER end end + ### ### Archive functions ### @@ -402,12 +421,13 @@ TEST_ARCHIVE_DIR = LISTDIR + 'archive' TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ] + TEST_POST_FILES = %w[ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 ] before( :each ) do @archive_dir = TEST_ARCHIVE_DIR.dup @archive_subdirs = TEST_ARCHIVE_SUBDIRS.dup @archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn } - @archive_post_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| + @archive_post_paths = TEST_POST_FILES.collect {|pn| TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn } end