mailmanager 1.0.14 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Changelog +7 -1
- data/Gemfile.lock +11 -1
- data/README.rdoc +19 -0
- data/config/cucumber.yml +11 -0
- data/features/create_list.feature +18 -0
- data/features/step_definitions/create_list_steps.rb +4 -0
- data/features/step_definitions/global_steps.rb +24 -0
- data/features/support/env.rb +2 -0
- data/lib/mailmanager/lib.rb +37 -1
- data/lib/mailmanager/list.rb +9 -0
- data/lib/mailmanager/version.rb +1 -1
- data/lib/mailmanager.rb +6 -3
- data/mailmanager.gemspec +1 -0
- data/spec/lib/mailmanager/lib_spec.rb +68 -28
- metadata +21 -3
data/.gitignore
CHANGED
data/Changelog
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
Current version is 1.0.
|
1
|
+
Current version is 1.0.15
|
2
|
+
|
3
|
+
changes since 1.0.14
|
4
|
+
- added a Cucumber integration test suite
|
5
|
+
- fixed a list creation bug when Mailman outputs to an aliases db directly
|
6
|
+
- added a delete_list method
|
7
|
+
- raise exception when attempting to create a mailing list that already exists
|
2
8
|
|
3
9
|
changes since 1.0.13
|
4
10
|
- more detailed error report when creating a new list fails
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mailmanager (1.0.
|
4
|
+
mailmanager (1.0.15)
|
5
5
|
json (~> 1.4.6)
|
6
6
|
open4 (~> 1.0.1)
|
7
7
|
|
@@ -14,7 +14,15 @@ GEM
|
|
14
14
|
ci_reporter (1.6.4)
|
15
15
|
builder (>= 2.1.2)
|
16
16
|
columnize (0.3.2)
|
17
|
+
cucumber (0.10.0)
|
18
|
+
builder (>= 2.1.2)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
gherkin (~> 2.3.2)
|
21
|
+
json (~> 1.4.6)
|
22
|
+
term-ansicolor (~> 1.0.5)
|
17
23
|
diff-lcs (1.1.2)
|
24
|
+
gherkin (2.3.3)
|
25
|
+
json (~> 1.4.6)
|
18
26
|
json (1.4.6)
|
19
27
|
linecache19 (0.5.11)
|
20
28
|
ruby_core_source (>= 0.1.4)
|
@@ -37,6 +45,7 @@ GEM
|
|
37
45
|
ruby-debug-base19 (>= 0.11.19)
|
38
46
|
ruby_core_source (0.1.4)
|
39
47
|
archive-tar-minitar (>= 0.5.2)
|
48
|
+
term-ansicolor (1.0.5)
|
40
49
|
|
41
50
|
PLATFORMS
|
42
51
|
ruby
|
@@ -44,6 +53,7 @@ PLATFORMS
|
|
44
53
|
DEPENDENCIES
|
45
54
|
ZenTest (~> 4.4.2)
|
46
55
|
ci_reporter
|
56
|
+
cucumber
|
47
57
|
mailmanager!
|
48
58
|
rspec (~> 2.4.0)
|
49
59
|
ruby-debug19
|
data/README.rdoc
CHANGED
@@ -83,6 +83,25 @@ Exposing new list properties works something like this:
|
|
83
83
|
That should get you started hacking on the gem. If you get stuck or are trying to
|
84
84
|
do anything more complex, please feel free to e-mail me: cap10morgan@gmail.com.
|
85
85
|
|
86
|
+
== Testing
|
87
|
+
|
88
|
+
The RSpec suite should run out of the box with the 'rake spec' command.
|
89
|
+
Feel free to open a GitHub issue if they do not.
|
90
|
+
|
91
|
+
You'll need a local working installation of GNU Mailman 2.1.14 (or a later version
|
92
|
+
of 2.1.x, probably) to run the Cucumber integration tests. Make a symlink to the
|
93
|
+
root directory of your Mailman install in the mailmanager directory. It should be
|
94
|
+
named "mailman". So if you are in the top-level mailmanager directory and your
|
95
|
+
Mailman installation is in /usr/local/mailman, you would run this command:
|
96
|
+
ln -s /usr/local/mailman mailman
|
97
|
+
|
98
|
+
Once that's done, you should be able to just run 'cucumber' in the top-level
|
99
|
+
mailmanager directory.
|
100
|
+
|
101
|
+
_MAKE SURE THIS IS NOT A MAILMAN INSTALLATION YOU CARE ABOUT!_ The Cucumber test
|
102
|
+
suite will start by deleting all mailing lists so it can have a clean slate to
|
103
|
+
test with.
|
104
|
+
|
86
105
|
== Contributing
|
87
106
|
|
88
107
|
- Fork on GitHub
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
<%
|
2
|
+
all_opts = "--color"
|
3
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
4
|
+
rerun_opts = "#{all_opts} " + (rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}")
|
5
|
+
std_opts = "#{all_opts} --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
6
|
+
%>
|
7
|
+
default: <%= std_opts %> features
|
8
|
+
wip: --tags @wip:3 --wip features
|
9
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
10
|
+
autotest: <%= rerun_opts %>
|
11
|
+
autotest-all: <%= std_opts %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: Creating a new list
|
2
|
+
As a developer using MailManager
|
3
|
+
In order to create new mailing lists
|
4
|
+
I want MailManager to offer this feature
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given MailManager is initialized on "./mailman"
|
8
|
+
|
9
|
+
Scenario: Creating a new list
|
10
|
+
Given no lists exist
|
11
|
+
When I create a new list "foo"
|
12
|
+
Then I should have a list named "foo"
|
13
|
+
|
14
|
+
Scenario: Creating a list with the same name as an existing list
|
15
|
+
Given no lists exist
|
16
|
+
When I create a new list "foo"
|
17
|
+
Then it should raise MailManager::ListNameConflictError when I create a new list "foo"
|
18
|
+
And I should have 1 list
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Given /^MailManager is initialized on "([^\"]+)"$/ do |mailman_root|
|
2
|
+
@mailmanager = MailManager.init(mailman_root)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^no lists exist$/ do
|
6
|
+
@mailmanager.list_names.each do |list_name|
|
7
|
+
@mailmanager.delete_list(list_name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^it should raise (.+?) when (.+)$/ do |exception,when_step|
|
12
|
+
lambda {
|
13
|
+
When when_step
|
14
|
+
}.should raise_error(eval(exception))
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^I should have (\d+) lists?$/ do |num|
|
18
|
+
@mailmanager.should have(num.to_i).lists
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^I should have a list named "([^"]*)"$/ do |list_name|
|
22
|
+
@mailmanager.list_names.should include(list_name)
|
23
|
+
end
|
24
|
+
|
data/lib/mailmanager/lib.rb
CHANGED
@@ -3,6 +3,12 @@ module MailManager
|
|
3
3
|
class MailmanExecuteError < StandardError #:nodoc:
|
4
4
|
end
|
5
5
|
|
6
|
+
class ListNotFoundError < StandardError #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class ListNameConflictError < StandardError #:nodoc:
|
10
|
+
end
|
11
|
+
|
6
12
|
class Lib #:nodoc:all
|
7
13
|
|
8
14
|
def mailmanager
|
@@ -15,8 +21,33 @@ module MailManager
|
|
15
21
|
parse_output(cmd, out)
|
16
22
|
end
|
17
23
|
|
24
|
+
def list_names
|
25
|
+
lists.map { |list| list.name }
|
26
|
+
end
|
27
|
+
|
18
28
|
def create_list(params)
|
29
|
+
raise ArgumentError, "Missing :name param" if params[:name].nil?
|
30
|
+
list_name = params[:name]
|
31
|
+
raise ListNameConflictError, "List \"#{list_name}\" already exists" if list_names.include?(list_name)
|
19
32
|
cmd = :newlist
|
33
|
+
# create the list
|
34
|
+
out = command(cmd, params)
|
35
|
+
# get the new list
|
36
|
+
begin
|
37
|
+
get_list(list_name)
|
38
|
+
rescue ListNotFoundError
|
39
|
+
raise MailmanExecuteError, "List creation failed: #{out}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_list(list_name)
|
44
|
+
raise ListNotFoundError, "#{list_name} does not exist" unless list_names.include?(list_name)
|
45
|
+
MailManager::List.new(list_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete_list(params)
|
49
|
+
params = {:name => params} unless params.respond_to?(:has_key?)
|
50
|
+
cmd = :rmlist
|
20
51
|
out = command(cmd, params)
|
21
52
|
parse_output(cmd, out)
|
22
53
|
end
|
@@ -141,7 +172,7 @@ module MailManager
|
|
141
172
|
mailman_cmd = "#{mailmanager.root}/bin/#{cmd.to_s} "
|
142
173
|
# delete opts as we handle them explicitly
|
143
174
|
stdin = nil
|
144
|
-
stdin = opts.delete(:stdin) if opts.has_key?(:stdin)
|
175
|
+
stdin = opts.delete(:stdin) if opts.respond_to?(:has_key?) && opts.has_key?(:stdin)
|
145
176
|
case cmd
|
146
177
|
when :newlist
|
147
178
|
mailman_cmd += "-q "
|
@@ -152,6 +183,9 @@ module MailManager
|
|
152
183
|
escape(opts.delete(key))
|
153
184
|
}.join(' ')
|
154
185
|
mailman_cmd += "#{mailman_cmd_suffix} "
|
186
|
+
when :rmlist
|
187
|
+
raise ArgumentError, "Missing :name param" if opts[:name].nil?
|
188
|
+
mailman_cmd += "#{escape(opts.delete(:name))} "
|
155
189
|
when :withlist
|
156
190
|
raise ArgumentError, "Missing :name param" if opts[:name].nil?
|
157
191
|
proxy_path = File.dirname(__FILE__)
|
@@ -211,6 +245,8 @@ module MailManager
|
|
211
245
|
end
|
212
246
|
raise MailmanExecuteError, "Error getting name of newly created list. Mailman sent:\n#{output}" if list_name.nil?
|
213
247
|
return_obj = MailManager::List.new(list_name)
|
248
|
+
when :rmlist
|
249
|
+
return_obj = output =~ /Removing list info/
|
214
250
|
when :list_lists
|
215
251
|
lists = []
|
216
252
|
puts "Output from Mailman:\n#{output}" if MailManager.debug
|
data/lib/mailmanager/list.rb
CHANGED
@@ -35,6 +35,15 @@ module MailManager
|
|
35
35
|
lib.create_list(params)
|
36
36
|
end
|
37
37
|
|
38
|
+
def self.delete(list_name) #:nodoc:
|
39
|
+
lib.delete_list(list_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Deletes the list, but not the archives
|
43
|
+
def delete
|
44
|
+
self.class.delete(self.name)
|
45
|
+
end
|
46
|
+
|
38
47
|
# Returns the list's email address
|
39
48
|
def address
|
40
49
|
result = lib.list_address(self)
|
data/lib/mailmanager/version.rb
CHANGED
data/lib/mailmanager.rb
CHANGED
@@ -82,7 +82,7 @@ module MailManager
|
|
82
82
|
# Only retrieves the list names, doesn't wrap them in MailManager::List
|
83
83
|
# instances.
|
84
84
|
def list_names
|
85
|
-
|
85
|
+
@lib.list_names
|
86
86
|
end
|
87
87
|
|
88
88
|
# Create a new list. Returns an instance of MailManager::List. Params are:
|
@@ -96,8 +96,11 @@ module MailManager
|
|
96
96
|
# Get an existing list as a MailManager::List instance. Raises an exception if
|
97
97
|
# the list doesn't exist.
|
98
98
|
def get_list(list_name)
|
99
|
-
|
100
|
-
|
99
|
+
@lib.get_list(list_name)
|
100
|
+
end
|
101
|
+
|
102
|
+
def delete_list(list_name)
|
103
|
+
MailManager::List.delete(list_name)
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
data/mailmanager.gemspec
CHANGED
@@ -5,6 +5,14 @@ describe MailManager::Lib do
|
|
5
5
|
let(:subject) { MailManager::Lib.new }
|
6
6
|
let(:fake_root) { '/foo/bar' }
|
7
7
|
let(:process) { mock(Process::Status) }
|
8
|
+
let(:list_result) { <<EOF
|
9
|
+
3 matching mailing lists found:
|
10
|
+
Foo - [no description available]
|
11
|
+
BarBar - Dummy list
|
12
|
+
Mailman - Mailman site list
|
13
|
+
EOF
|
14
|
+
}
|
15
|
+
let(:list_result_after_create) { list_result + "\n Bar - [no description available]\n" }
|
8
16
|
|
9
17
|
before :each do
|
10
18
|
subject.stub(:mailmanager).and_return(mailmanager)
|
@@ -14,47 +22,48 @@ describe MailManager::Lib do
|
|
14
22
|
|
15
23
|
describe "#lists" do
|
16
24
|
it "should return all existing lists" do
|
17
|
-
list_result = <<EOF
|
18
|
-
3 matching mailing lists found:
|
19
|
-
Foo - [no description available]
|
20
|
-
BarBar - Dummy list
|
21
|
-
Mailman - Mailman site list
|
22
|
-
EOF
|
23
25
|
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
24
|
-
and_return([list_result,process])
|
26
|
+
and_return([list_result, process])
|
25
27
|
subject.lists.should have(3).lists
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
describe "#create_list" do
|
32
|
+
before :each do
|
33
|
+
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
34
|
+
and_return([list_result, process])
|
35
|
+
end
|
36
|
+
|
30
37
|
it "should raise an argument error if list name is missing" do
|
31
38
|
lambda {
|
32
39
|
subject.create_list(:admin_email => 'foo@bar.baz', :admin_password => 'qux')
|
33
40
|
}.should raise_error(ArgumentError)
|
34
41
|
end
|
42
|
+
|
35
43
|
it "should raise an argument error if list admin email is missing" do
|
36
44
|
lambda {
|
37
|
-
subject.create_list(:name => '
|
45
|
+
subject.create_list(:name => 'bar', :admin_password => 'qux')
|
38
46
|
}.should raise_error(ArgumentError)
|
39
47
|
end
|
48
|
+
|
40
49
|
it "should raise an argument error if admin password is missing" do
|
41
50
|
lambda {
|
42
|
-
subject.create_list(:name => '
|
51
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz')
|
43
52
|
}.should raise_error(ArgumentError)
|
44
53
|
end
|
45
54
|
|
46
55
|
context "with valid list params" do
|
47
56
|
let(:new_aliases) {
|
48
|
-
['
|
49
|
-
'
|
50
|
-
'
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
'
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
57
|
+
['bar: "|/foo/bar/mail/mailman post bar"',
|
58
|
+
'bar-admin: "|/foo/bar/mail/mailman admin bar"',
|
59
|
+
'bar-bounces: "|/foo/bar/mail/mailman bounces bar"',
|
60
|
+
'bar-confirm: "|/foo/bar/mail/mailman confirm bar"',
|
61
|
+
'bar-join: "|/foo/bar/mail/mailman join bar"',
|
62
|
+
'bar-leave: "|/foo/bar/mail/mailman leave bar"',
|
63
|
+
'bar-owner: "|/foo/bar/mail/mailman owner bar"',
|
64
|
+
'bar-request: "|/foo/bar/mail/mailman request bar"',
|
65
|
+
'bar-subscribe: "|/foo/bar/mail/mailman subscribe bar"',
|
66
|
+
'bar-unsubscribe: "|/foo/bar/mail/mailman unsubscribe bar"']
|
58
67
|
}
|
59
68
|
let(:new_list_return) {
|
60
69
|
prefix =<<EOF
|
@@ -62,24 +71,55 @@ To finish creating your mailing list, you must edit your /etc/aliases (or
|
|
62
71
|
equivalent) file by adding the following lines, and possibly running the
|
63
72
|
`newaliases' program:
|
64
73
|
|
65
|
-
##
|
74
|
+
## bar mailing list
|
66
75
|
EOF
|
67
76
|
prefix+new_aliases.join("\n")
|
68
77
|
}
|
69
|
-
let(:fake_aliases_file) { mock(File) }
|
70
78
|
|
71
|
-
|
72
|
-
|
73
|
-
|
79
|
+
it "should create the list" do
|
80
|
+
subject.should_receive(:run_command).
|
81
|
+
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
82
|
+
and_return([new_list_return, process])
|
83
|
+
subject.should_receive(:run_command).
|
84
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
85
|
+
and_return([list_result, process], [list_result_after_create, process])
|
86
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
87
|
+
:admin_password => 'qux')
|
74
88
|
end
|
75
89
|
|
76
|
-
it "should
|
90
|
+
it "should not rely on the aliases setup output" do
|
91
|
+
# https://www.pivotaltracker.com/story/show/9422507
|
92
|
+
subject.should_receive(:run_command).
|
93
|
+
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
94
|
+
and_return(["", process])
|
77
95
|
subject.should_receive(:run_command).
|
78
|
-
with("#{fake_root}/bin/
|
79
|
-
and_return([
|
80
|
-
subject.create_list(:name => '
|
96
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
97
|
+
and_return([list_result, process], [list_result_after_create, process])
|
98
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
81
99
|
:admin_password => 'qux')
|
82
100
|
end
|
101
|
+
|
102
|
+
it "should raise an exception if the list already exists" do
|
103
|
+
# https://www.pivotaltracker.com/story/show/9421449
|
104
|
+
subject.should_not_receive(:run_command).
|
105
|
+
with("#{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
|
106
|
+
subject.should_receive(:run_command).
|
107
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
108
|
+
and_return([list_result, process])
|
109
|
+
lambda {
|
110
|
+
subject.create_list(:name => 'foo', :admin_email => 'foo@bar.baz',
|
111
|
+
:admin_password => 'qux')
|
112
|
+
}.should raise_error(MailManager::ListNameConflictError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#delete_list" do
|
118
|
+
it "should delete the list" do
|
119
|
+
subject.should_receive(:run_command).
|
120
|
+
with("#{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
|
121
|
+
and_return(["Removing list info", process])
|
122
|
+
subject.delete_list('foo')
|
83
123
|
end
|
84
124
|
end
|
85
125
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 15
|
9
|
+
version: 1.0.15
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Wes Morgan
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01
|
17
|
+
date: 2011-02-01 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -103,6 +103,19 @@ dependencies:
|
|
103
103
|
version: "0"
|
104
104
|
type: :development
|
105
105
|
version_requirements: *id006
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: cucumber
|
108
|
+
prerelease: false
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
106
119
|
description: Ruby wrapper library for GNU Mailman's admin functions
|
107
120
|
email: MorganW@dnc.org
|
108
121
|
executables: []
|
@@ -121,6 +134,11 @@ files:
|
|
121
134
|
- LICENSE
|
122
135
|
- README.rdoc
|
123
136
|
- Rakefile
|
137
|
+
- config/cucumber.yml
|
138
|
+
- features/create_list.feature
|
139
|
+
- features/step_definitions/create_list_steps.rb
|
140
|
+
- features/step_definitions/global_steps.rb
|
141
|
+
- features/support/env.rb
|
124
142
|
- lib/mailmanager.rb
|
125
143
|
- lib/mailmanager/lib.rb
|
126
144
|
- lib/mailmanager/list.rb
|