* 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
This commit is contained in:
parent
8ff689e698
commit
cf10ef2d7b
5 changed files with 126 additions and 61 deletions
5
Rakefile
5
Rakefile
|
|
@ -132,7 +132,7 @@ end
|
||||||
|
|
||||||
### Cruisecontrol task
|
### Cruisecontrol task
|
||||||
desc "Cruisecontrol build"
|
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?
|
raise "Artifacts dir not set." if ARTIFACTS_DIR.to_s.empty?
|
||||||
artifact_dir = ARTIFACTS_DIR.cleanpath
|
artifact_dir = ARTIFACTS_DIR.cleanpath
|
||||||
artifact_dir.mkpath
|
artifact_dir.mkpath
|
||||||
|
|
@ -140,6 +140,9 @@ task :cruise => [:clean, :coverage, :package] do |task|
|
||||||
$stderr.puts "Copying coverage stats..."
|
$stderr.puts "Copying coverage stats..."
|
||||||
FileUtils.cp_r( 'coverage', artifact_dir )
|
FileUtils.cp_r( 'coverage', artifact_dir )
|
||||||
|
|
||||||
|
$stderr.puts "Copying documentation..."
|
||||||
|
FileUtils.cp_r( 'docs/api', artifact_dir + 'rdoc' )
|
||||||
|
|
||||||
$stderr.puts "Copying packages..."
|
$stderr.puts "Copying packages..."
|
||||||
FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir )
|
FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir )
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ module Ezmlm
|
||||||
|
|
||||||
|
|
||||||
require 'ezmlm/list'
|
require 'ezmlm/list'
|
||||||
|
require 'ezmlm/listdaemon'
|
||||||
|
|
||||||
|
|
||||||
###############
|
###############
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ class Ezmlm::List
|
||||||
def initialize( listdir )
|
def initialize( listdir )
|
||||||
listdir = Pathname.new( listdir ) if !listdir.is_a?( Pathname )
|
listdir = Pathname.new( listdir ) if !listdir.is_a?( Pathname )
|
||||||
@listdir = listdir
|
@listdir = listdir
|
||||||
|
|
||||||
|
# Cached lookups
|
||||||
|
@config = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -42,6 +45,25 @@ class Ezmlm::List
|
||||||
attr_reader :listdir
|
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
|
### Return the number of messages in the list archive
|
||||||
def message_count
|
def message_count
|
||||||
numfile = self.listdir + 'num'
|
numfile = self.listdir + 'num'
|
||||||
|
|
@ -64,14 +86,26 @@ class Ezmlm::List
|
||||||
end
|
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.
|
### Return the email address of the list's owner.
|
||||||
def owner
|
def owner
|
||||||
config = self.listdir + 'config'
|
self.config['5']
|
||||||
if config.read =~ /^5:([^\n]+)$/m
|
|
||||||
return $1
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,7 +182,7 @@ class Ezmlm::List
|
||||||
# Find the last numbered file under the last numbered directory we found
|
# Find the last numbered file under the last numbered directory we found
|
||||||
# above.
|
# above.
|
||||||
last_post_path = Pathname.glob( last_archdir + '[0-9]*' ).
|
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 ] \
|
raise RuntimeError, "unexpectedly empty archive directory '%s'" % [ last_archdir ] \
|
||||||
unless last_post_path
|
unless last_post_path
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,14 @@
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
require 'pathname'
|
||||||
|
basedir = Pathname.new( __FILE__ ).dirname.parent
|
||||||
|
docsdir = basedir + 'docs'
|
||||||
|
|
||||||
|
$LOAD_PATH << docsdir.to_s
|
||||||
|
}
|
||||||
|
|
||||||
require 'rake/rdoctask'
|
require 'rake/rdoctask'
|
||||||
|
|
||||||
### Task: rdoc
|
### Task: rdoc
|
||||||
|
|
|
||||||
|
|
@ -29,25 +29,42 @@ describe Ezmlm::List do
|
||||||
|
|
||||||
|
|
||||||
LISTDIR = Pathname.new( 'list' )
|
LISTDIR = Pathname.new( 'list' )
|
||||||
|
|
||||||
TEST_SUBSCRIBERS = %w[
|
TEST_SUBSCRIBERS = %w[
|
||||||
pete.chaffee@toadsmackers.com
|
pete.chaffee@toadsmackers.com
|
||||||
dolphinzombie@alahalohamorra.com
|
dolphinzombie@alahalohamorra.com
|
||||||
piratebanker@yahoo.com
|
piratebanker@yahoo.com
|
||||||
]
|
]
|
||||||
|
|
||||||
TEST_MODERATORS = %w[
|
TEST_MODERATORS = %w[
|
||||||
dolphinzombie@alahalohamorra.com
|
dolphinzombie@alahalohamorra.com
|
||||||
]
|
]
|
||||||
|
TEST_LIST_NAME = 'waffle-lovers'
|
||||||
|
TEST_LIST_HOST = 'lists.syrup.info'
|
||||||
TEST_OWNER = 'listowner@rumpus-the-whale.info'
|
TEST_OWNER = 'listowner@rumpus-the-whale.info'
|
||||||
|
|
||||||
TEST_CUSTOM_MODERATORS_DIR = '/foo/bar/clowns'
|
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 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
|
### List manager functions
|
||||||
|
|
@ -60,6 +77,49 @@ describe Ezmlm::List do
|
||||||
end
|
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
|
it "can return a list of subscribers' email addresses" do
|
||||||
subscribers_dir = LISTDIR + 'subscribers'
|
subscribers_dir = LISTDIR + 'subscribers'
|
||||||
|
|
||||||
|
|
@ -313,61 +373,20 @@ describe Ezmlm::List do
|
||||||
|
|
||||||
### List owner
|
### 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
|
it "returns nil when the list doesn't have an owner in its config" do
|
||||||
config_path_obj = mock( "Config path object" )
|
@list.stub!( :config ).and_return({ '5' => nil })
|
||||||
@listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj )
|
|
||||||
config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITHOUT_OWNER )
|
|
||||||
|
|
||||||
@list.owner.should == nil
|
@list.owner.should == nil
|
||||||
end
|
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
|
it "can return the email address of the list owner" do
|
||||||
config_path_obj = mock( "Config path object" )
|
@list.stub!( :config ).and_return({ '5' => TEST_OWNER })
|
||||||
@listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj )
|
|
||||||
config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITH_OWNER )
|
|
||||||
|
|
||||||
@list.owner.should == TEST_OWNER
|
@list.owner.should == TEST_OWNER
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### Archive functions
|
### Archive functions
|
||||||
###
|
###
|
||||||
|
|
@ -402,12 +421,13 @@ describe Ezmlm::List do
|
||||||
|
|
||||||
TEST_ARCHIVE_DIR = LISTDIR + 'archive'
|
TEST_ARCHIVE_DIR = LISTDIR + 'archive'
|
||||||
TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ]
|
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
|
before( :each ) do
|
||||||
@archive_dir = TEST_ARCHIVE_DIR.dup
|
@archive_dir = TEST_ARCHIVE_DIR.dup
|
||||||
@archive_subdirs = TEST_ARCHIVE_SUBDIRS.dup
|
@archive_subdirs = TEST_ARCHIVE_SUBDIRS.dup
|
||||||
@archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn }
|
@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
|
TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue