--- /dev/null
+#!/usr/bin/env perl
+
+use File::Which;
+use Email::EzPz::List;
+use strictures 1;
+
+{
+ package Eval::WithLexicals::Scratchpad;
+
+ use vars qw($list);
+
+ $list = Email::EzPz::List->new(
+ ezmlm_bindir => $ARGV[0],
+ list_dir => $ARGV[1],
+ );
+}
+
+do +which('tinyrepl');
+
+exit 0;
--- /dev/null
+package Email::EzPz::List;
+
+use Module::Runtime qw(use_module);
+use Moo;
+
+with 'Email::EzPz::ListCore';
+
+sub sublist_type { () }
+
+foreach my $type (qw(allow deny mod digest)) {
+ has $type => (
+ is => 'ro',
+ lazy => 1,
+ default => sub { shift->_build_sublist($type) }
+ );
+}
+
+sub _build_sublist {
+ my ($self, $type) = @_;
+ return use_module('Email::EzPz::SubList')->new(
+ (map +($_ => $self->$_), qw(list_dir ezmlm_bindir)),
+ sublist_type => $type
+ );
+}
+
+1;
--- /dev/null
+package Email::EzPz::ListCore;
+
+use Moo::Role;
+use IO::All;
+use IPC::System::Simple qw(run capture);
+
+has list_dir => (is => 'ro', required => 1);
+
+has ezmlm_bindir => (is => 'ro', required => 1);
+
+requires 'sublist_type';
+
+sub _command_path {
+ my ($self, $command) = @_;
+ return io->dir($self->ezmlm_bindir)->catfile("ezmlm-${command}");
+}
+
+sub _command_args {
+ my ($self, $command, @args) = @_;
+ return (
+ $self->_command_path($command),
+ $self->list_dir,
+ $self->sublist_type,
+ @args
+ );
+}
+
+sub _call_command {
+ my ($self, @cmd) = @_;
+ run $self->_command_args(@cmd);
+}
+
+sub _capture_command {
+ my ($self, @cmd) = @_;
+ map { chomp; $_ } capture $self->_command_args(@cmd);
+}
+
+sub add_member {
+ my ($self, $member) = @_;
+ $self->_call_command(sub => $member);
+ return $member;
+}
+
+sub remove_member {
+ my ($self, $member) = @_;
+ $self->_call_command(unsub => $member);
+ return $member;
+}
+
+sub members {
+ my ($self) = @_;
+ $self->_capture_command('list');
+}
+
+1;
--- /dev/null
+package Email::EzPz::SubList;
+
+use Moo;
+
+has sublist_type => (is => 'ro', required => 1);
+
+with 'Email::EzPz::ListCore';
+
+1;