* Added rdoc-generation to the cruise task and the artifacts that get saved
authorMichael Granger <mgranger@laika.com>
Sat, 10 May 2008 01:52:42 +0000
changeset 5 804e1c2b9a40
parent 4 8c4ae0797d5f
child 6 66beb495a861
* 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
Rakefile
lib/ezmlm.rb
lib/ezmlm/list.rb
rake/rdoc.rb
spec/ezmlm/list_spec.rb
--- 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
--- 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'
 	
 
 	###############
--- 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
--- 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
--- 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