@@ -1,5 +1,14 @@
Revision history for Perl extension Email::Stuffer
+0.012 2015-02-15 20:01:01-05:00 America/New_York
+ - test for ENOENT text based on platform under test, not fixed string
+
+0.011 2015-02-15 11:31:01-05:00 America/New_York
+ - autodetect PDF filetype (thanks, mannih)
+
+0.010 2014-04-25 10:24:49-04:00 America/New_York (TRIAL RELEASE)
+ - in case of failure, throw exceptions rather than returning undef
+
0.009 2013-11-24 22:40:49 America/New_York
- update required version of Email::Stuffer
@@ -22,7 +22,7 @@ This is free software, licensed under:
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc.
- 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -1,3 +1,4 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.031.
Changes
LICENSE
MANIFEST
@@ -7,11 +8,13 @@ Makefile.PL
README
dist.ini
lib/Email/Stuffer.pm
-t/000-report-versions-tiny.t
+t/00-report-prereqs.dd
+t/00-report-prereqs.t
t/alternative.t
t/basic.t
t/content_type.t
t/data/body.html
+t/data/empty.pdf
t/data/paypal.gif
t/data/paypal.jpg
t/data/paypal.png
@@ -5,25 +5,24 @@
"Ricardo SIGNES <rjbs@cpan.org>"
],
"dynamic_config" : 0,
- "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830",
+ "generated_by" : "Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
- "version" : "2"
+ "version" : 2
},
"name" : "Email-Stuffer",
"prereqs" : {
"configure" : {
"requires" : {
- "ExtUtils::MakeMaker" : "6.30"
+ "ExtUtils::MakeMaker" : "0"
}
},
"develop" : {
"requires" : {
- "Test::Pod" : "1.41",
- "version" : "0.9901"
+ "Test::Pod" : "1.41"
}
},
"runtime" : {
@@ -40,10 +39,16 @@
}
},
"test" : {
+ "recommends" : {
+ "CPAN::Meta" : "2.120900"
+ },
"requires" : {
"Email::Sender::Transport::Test" : "0.120000",
+ "ExtUtils::MakeMaker" : "0",
+ "File::Spec" : "0",
"File::Spec::Functions" : "0",
"Moo" : "0",
+ "Test::Fatal" : "0",
"Test::More" : "0.96",
"Test::Most" : "0",
"utf8" : "0"
@@ -62,141 +67,193 @@
"web" : "https://github.com/rjbs/Email-Stuffer"
}
},
- "version" : "0.009",
+ "version" : "0.012",
"x_Dist_Zilla" : {
"perl" : {
- "version" : "5.018001"
+ "version" : "5.021008"
},
"plugins" : [
{
"class" : "Dist::Zilla::Plugin::Git::GatherDir",
+ "config" : {
+ "Dist::Zilla::Plugin::GatherDir" : {
+ "exclude_filename" : [],
+ "exclude_match" : [],
+ "follow_symlinks" : "0",
+ "include_dotfiles" : "0",
+ "prefix" : "",
+ "prune_directory" : [],
+ "root" : "."
+ },
+ "Dist::Zilla::Plugin::Git::GatherDir" : {
+ "include_untracked" : "0"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/Git::GatherDir",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed",
"name" : "@RJBS/CheckPrereqsIndexed",
- "version" : "0.009"
+ "version" : "0.015"
},
{
"class" : "Dist::Zilla::Plugin::CheckExtraTests",
"name" : "@RJBS/CheckExtraTests",
- "version" : "0.016"
+ "version" : "0.025"
},
{
"class" : "Dist::Zilla::Plugin::PromptIfStale",
+ "config" : {
+ "Dist::Zilla::Plugin::PromptIfStale" : {
+ "check_all_plugins" : 0,
+ "check_all_prereqs" : 0,
+ "modules" : [
+ "Dist::Zilla::PluginBundle::RJBS"
+ ],
+ "phase" : "build",
+ "skip" : []
+ }
+ },
"name" : "@RJBS/RJBS-Outdated",
- "version" : "0.013"
+ "version" : "0.038"
},
{
"class" : "Dist::Zilla::Plugin::PromptIfStale",
+ "config" : {
+ "Dist::Zilla::Plugin::PromptIfStale" : {
+ "check_all_plugins" : "1",
+ "check_all_prereqs" : 0,
+ "modules" : [],
+ "phase" : "release",
+ "skip" : []
+ }
+ },
"name" : "@RJBS/CPAN-Outdated",
- "version" : "0.013"
+ "version" : "0.038"
},
{
"class" : "Dist::Zilla::Plugin::PruneCruft",
"name" : "@RJBS/@Filter/PruneCruft",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::ManifestSkip",
"name" : "@RJBS/@Filter/ManifestSkip",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::MetaYAML",
"name" : "@RJBS/@Filter/MetaYAML",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::License",
"name" : "@RJBS/@Filter/License",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::Readme",
"name" : "@RJBS/@Filter/Readme",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::ExecDir",
"name" : "@RJBS/@Filter/ExecDir",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::ShareDir",
"name" : "@RJBS/@Filter/ShareDir",
- "version" : "5.006"
- },
- {
- "class" : "Dist::Zilla::Plugin::MakeMaker",
- "name" : "@RJBS/@Filter/MakeMaker",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::Manifest",
"name" : "@RJBS/@Filter/Manifest",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::TestRelease",
"name" : "@RJBS/@Filter/TestRelease",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::ConfirmRelease",
"name" : "@RJBS/@Filter/ConfirmRelease",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::UploadToCPAN",
"name" : "@RJBS/@Filter/UploadToCPAN",
- "version" : "5.006"
+ "version" : "5.031"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MakeMaker",
+ "config" : {
+ "Dist::Zilla::Role::TestRunner" : {
+ "default_jobs" : 9
+ }
+ },
+ "name" : "@RJBS/MakeMaker",
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::AutoPrereqs",
"name" : "@RJBS/AutoPrereqs",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::Git::NextVersion",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::NextVersion" : {
+ "first_version" : "0.001",
+ "version_by_branch" : "0",
+ "version_regexp" : "(?^:^([0-9]+\\.[0-9]+)$)"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/Git::NextVersion",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::PkgVersion",
"name" : "@RJBS/PkgVersion",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::MetaConfig",
"name" : "@RJBS/MetaConfig",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::MetaJSON",
"name" : "@RJBS/MetaJSON",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::NextRelease",
"name" : "@RJBS/NextRelease",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::Test::ChangesHasContent",
"name" : "@RJBS/Test::ChangesHasContent",
- "version" : "0.006"
+ "version" : "0.007"
},
{
"class" : "Dist::Zilla::Plugin::PodSyntaxTests",
"name" : "@RJBS/PodSyntaxTests",
- "version" : "5.006"
+ "version" : "5.031"
},
{
- "class" : "Dist::Zilla::Plugin::ReportVersions::Tiny",
- "name" : "@RJBS/ReportVersions::Tiny",
- "version" : "1.10"
+ "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs",
+ "name" : "@RJBS/Test::ReportPrereqs",
+ "version" : "0.020"
},
{
"class" : "Dist::Zilla::Plugin::Prereqs",
@@ -207,13 +264,15 @@
}
},
"name" : "@RJBS/TestMoreWithSubtests",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::PodWeaver",
"config" : {
"Dist::Zilla::Plugin::PodWeaver" : {
- "config_plugin" : "@RJBS",
+ "config_plugins" : [
+ "@RJBS"
+ ],
"finder" : [
":InstallModules",
":ExecFiles"
@@ -222,158 +281,227 @@
{
"class" : "Pod::Weaver::Plugin::EnsurePod5",
"name" : "@CorePrep/EnsurePod5",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Plugin::H1Nester",
"name" : "@CorePrep/H1Nester",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Plugin::SingleEncoding",
"name" : "@RJBS/SingleEncoding",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Name",
"name" : "@RJBS/Name",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Version",
"name" : "@RJBS/Version",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Region",
"name" : "@RJBS/Prelude",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@RJBS/Synopsis",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@RJBS/Description",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@RJBS/Overview",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@RJBS/Stability",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Attributes",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Methods",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Functions",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Leftovers",
"name" : "@RJBS/Leftovers",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Region",
"name" : "@RJBS/postlude",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Authors",
"name" : "@RJBS/Authors",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Section::Legal",
"name" : "@RJBS/Legal",
- "version" : "4.004"
+ "version" : "4.010"
},
{
"class" : "Pod::Weaver::Plugin::Transformer",
"name" : "@RJBS/List",
- "version" : "4.004"
+ "version" : "4.010"
}
]
}
},
"name" : "@RJBS/PodWeaver",
- "version" : "4.002"
+ "version" : "4.006"
},
{
"class" : "Dist::Zilla::Plugin::GithubMeta",
"name" : "@RJBS/GithubMeta",
- "version" : "0.42"
+ "version" : "0.46"
},
{
"class" : "Dist::Zilla::Plugin::Git::Check",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Check" : {
+ "untracked_files" : "die"
+ },
+ "Dist::Zilla::Role::Git::DirtyFiles" : {
+ "allow_dirty" : [
+ "dist.ini",
+ "Changes"
+ ],
+ "allow_dirty_match" : [],
+ "changelog" : "Changes"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/@Git/Check",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::Git::Commit",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Commit" : {
+ "add_files_in" : [],
+ "commit_msg" : "v%v%n%n%c",
+ "time_zone" : "local"
+ },
+ "Dist::Zilla::Role::Git::DirtyFiles" : {
+ "allow_dirty" : [
+ "dist.ini",
+ "Changes"
+ ],
+ "allow_dirty_match" : [],
+ "changelog" : "Changes"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/@Git/Commit",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::Git::Tag",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Tag" : {
+ "branch" : null,
+ "signed" : 0,
+ "tag" : "0.012",
+ "tag_format" : "%v",
+ "tag_message" : "v%v",
+ "time_zone" : "local"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/@Git/Tag",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::Git::Push",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Push" : {
+ "push_to" : [
+ "origin :",
+ "github :"
+ ],
+ "remotes_must_exist" : 0
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
"name" : "@RJBS/@Git/Push",
- "version" : "2.019"
+ "version" : "2.029"
},
{
"class" : "Dist::Zilla::Plugin::Encoding",
"name" : "Encoding",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":InstallModules",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":IncModules",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":TestFiles",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":ExecFiles",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":ShareFiles",
- "version" : "5.006"
+ "version" : "5.031"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":MainModule",
- "version" : "5.006"
+ "version" : "5.031"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":AllFiles",
+ "version" : "5.031"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":NoFiles",
+ "version" : "5.031"
}
],
"zilla" : {
@@ -381,7 +509,7 @@
"config" : {
"is_trial" : "0"
},
- "version" : "5.006"
+ "version" : "5.031"
}
}
}
@@ -4,144 +4,185 @@ author:
- 'Adam Kennedy <adamk@cpan.org>'
- 'Ricardo SIGNES <rjbs@cpan.org>'
build_requires:
- Email::Sender::Transport::Test: 0.120000
- File::Spec::Functions: 0
- Moo: 0
- Test::More: 0.96
- Test::Most: 0
- utf8: 0
+ Email::Sender::Transport::Test: '0.120000'
+ ExtUtils::MakeMaker: '0'
+ File::Spec: '0'
+ File::Spec::Functions: '0'
+ Moo: '0'
+ Test::Fatal: '0'
+ Test::More: '0.96'
+ Test::Most: '0'
+ utf8: '0'
configure_requires:
- ExtUtils::MakeMaker: 6.30
+ ExtUtils::MakeMaker: '0'
dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830'
+generated_by: 'Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
- version: 1.4
+ version: '1.4'
name: Email-Stuffer
requires:
- Carp: 0
- Email::MIME: 0
- Email::MIME::Creator: 0
- Email::Sender::Simple: 0
- File::Basename: 0
- Params::Util: 1.05
- perl: 5.005
- strict: 0
- warnings: 0
+ Carp: '0'
+ Email::MIME: '0'
+ Email::MIME::Creator: '0'
+ Email::Sender::Simple: '0'
+ File::Basename: '0'
+ Params::Util: '1.05'
+ perl: '5.005'
+ strict: '0'
+ warnings: '0'
resources:
bugtracker: https://github.com/rjbs/Email-Stuffer/issues
homepage: https://github.com/rjbs/Email-Stuffer
repository: https://github.com/rjbs/Email-Stuffer.git
-version: 0.009
+version: '0.012'
x_Dist_Zilla:
perl:
- version: 5.018001
+ version: '5.021008'
plugins:
-
class: Dist::Zilla::Plugin::Git::GatherDir
+ config:
+ Dist::Zilla::Plugin::GatherDir:
+ exclude_filename: []
+ exclude_match: []
+ follow_symlinks: '0'
+ include_dotfiles: '0'
+ prefix: ''
+ prune_directory: []
+ root: .
+ Dist::Zilla::Plugin::Git::GatherDir:
+ include_untracked: '0'
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/Git::GatherDir'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::CheckPrereqsIndexed
name: '@RJBS/CheckPrereqsIndexed'
- version: 0.009
+ version: '0.015'
-
class: Dist::Zilla::Plugin::CheckExtraTests
name: '@RJBS/CheckExtraTests'
- version: 0.016
+ version: '0.025'
-
class: Dist::Zilla::Plugin::PromptIfStale
+ config:
+ Dist::Zilla::Plugin::PromptIfStale:
+ check_all_plugins: 0
+ check_all_prereqs: 0
+ modules:
+ - Dist::Zilla::PluginBundle::RJBS
+ phase: build
+ skip: []
name: '@RJBS/RJBS-Outdated'
- version: 0.013
+ version: '0.038'
-
class: Dist::Zilla::Plugin::PromptIfStale
+ config:
+ Dist::Zilla::Plugin::PromptIfStale:
+ check_all_plugins: '1'
+ check_all_prereqs: 0
+ modules: []
+ phase: release
+ skip: []
name: '@RJBS/CPAN-Outdated'
- version: 0.013
+ version: '0.038'
-
class: Dist::Zilla::Plugin::PruneCruft
name: '@RJBS/@Filter/PruneCruft'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::ManifestSkip
name: '@RJBS/@Filter/ManifestSkip'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::MetaYAML
name: '@RJBS/@Filter/MetaYAML'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::License
name: '@RJBS/@Filter/License'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::Readme
name: '@RJBS/@Filter/Readme'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::ExecDir
name: '@RJBS/@Filter/ExecDir'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::ShareDir
name: '@RJBS/@Filter/ShareDir'
- version: 5.006
- -
- class: Dist::Zilla::Plugin::MakeMaker
- name: '@RJBS/@Filter/MakeMaker'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::Manifest
name: '@RJBS/@Filter/Manifest'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::TestRelease
name: '@RJBS/@Filter/TestRelease'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::ConfirmRelease
name: '@RJBS/@Filter/ConfirmRelease'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::UploadToCPAN
name: '@RJBS/@Filter/UploadToCPAN'
- version: 5.006
+ version: '5.031'
+ -
+ class: Dist::Zilla::Plugin::MakeMaker
+ config:
+ Dist::Zilla::Role::TestRunner:
+ default_jobs: 9
+ name: '@RJBS/MakeMaker'
+ version: '5.031'
-
class: Dist::Zilla::Plugin::AutoPrereqs
name: '@RJBS/AutoPrereqs'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::Git::NextVersion
+ config:
+ Dist::Zilla::Plugin::Git::NextVersion:
+ first_version: '0.001'
+ version_by_branch: '0'
+ version_regexp: (?^:^([0-9]+\.[0-9]+)$)
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/Git::NextVersion'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::PkgVersion
name: '@RJBS/PkgVersion'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::MetaConfig
name: '@RJBS/MetaConfig'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::MetaJSON
name: '@RJBS/MetaJSON'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::NextRelease
name: '@RJBS/NextRelease'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::Test::ChangesHasContent
name: '@RJBS/Test::ChangesHasContent'
- version: 0.006
+ version: '0.007'
-
class: Dist::Zilla::Plugin::PodSyntaxTests
name: '@RJBS/PodSyntaxTests'
- version: 5.006
+ version: '5.031'
-
- class: Dist::Zilla::Plugin::ReportVersions::Tiny
- name: '@RJBS/ReportVersions::Tiny'
- version: 1.10
+ class: Dist::Zilla::Plugin::Test::ReportPrereqs
+ name: '@RJBS/Test::ReportPrereqs'
+ version: '0.020'
-
class: Dist::Zilla::Plugin::Prereqs
config:
@@ -149,12 +190,13 @@ x_Dist_Zilla:
phase: test
type: requires
name: '@RJBS/TestMoreWithSubtests'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::PodWeaver
config:
Dist::Zilla::Plugin::PodWeaver:
- config_plugin: '@RJBS'
+ config_plugins:
+ - '@RJBS'
finder:
- ':InstallModules'
- ':ExecFiles'
@@ -162,127 +204,177 @@ x_Dist_Zilla:
-
class: Pod::Weaver::Plugin::EnsurePod5
name: '@CorePrep/EnsurePod5'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Plugin::H1Nester
name: '@CorePrep/H1Nester'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Plugin::SingleEncoding
name: '@RJBS/SingleEncoding'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Name
name: '@RJBS/Name'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Version
name: '@RJBS/Version'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Region
name: '@RJBS/Prelude'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Generic
name: '@RJBS/Synopsis'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Generic
name: '@RJBS/Description'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Generic
name: '@RJBS/Overview'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Generic
name: '@RJBS/Stability'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Collect
name: Attributes
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Collect
name: Methods
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Collect
name: Functions
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Leftovers
name: '@RJBS/Leftovers'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Region
name: '@RJBS/postlude'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Authors
name: '@RJBS/Authors'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Section::Legal
name: '@RJBS/Legal'
- version: 4.004
+ version: '4.010'
-
class: Pod::Weaver::Plugin::Transformer
name: '@RJBS/List'
- version: 4.004
+ version: '4.010'
name: '@RJBS/PodWeaver'
- version: 4.002
+ version: '4.006'
-
class: Dist::Zilla::Plugin::GithubMeta
name: '@RJBS/GithubMeta'
- version: 0.42
+ version: '0.46'
-
class: Dist::Zilla::Plugin::Git::Check
+ config:
+ Dist::Zilla::Plugin::Git::Check:
+ untracked_files: die
+ Dist::Zilla::Role::Git::DirtyFiles:
+ allow_dirty:
+ - dist.ini
+ - Changes
+ allow_dirty_match: []
+ changelog: Changes
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/@Git/Check'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::Git::Commit
+ config:
+ Dist::Zilla::Plugin::Git::Commit:
+ add_files_in: []
+ commit_msg: v%v%n%n%c
+ time_zone: local
+ Dist::Zilla::Role::Git::DirtyFiles:
+ allow_dirty:
+ - dist.ini
+ - Changes
+ allow_dirty_match: []
+ changelog: Changes
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/@Git/Commit'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::Git::Tag
+ config:
+ Dist::Zilla::Plugin::Git::Tag:
+ branch: ~
+ signed: 0
+ tag: '0.012'
+ tag_format: '%v'
+ tag_message: v%v
+ time_zone: local
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/@Git/Tag'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::Git::Push
+ config:
+ Dist::Zilla::Plugin::Git::Push:
+ push_to:
+ - 'origin :'
+ - 'github :'
+ remotes_must_exist: 0
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
name: '@RJBS/@Git/Push'
- version: 2.019
+ version: '2.029'
-
class: Dist::Zilla::Plugin::Encoding
name: Encoding
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':InstallModules'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':IncModules'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':TestFiles'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':ExecFiles'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':ShareFiles'
- version: 5.006
+ version: '5.031'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':MainModule'
- version: 5.006
+ version: '5.031'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':AllFiles'
+ version: '5.031'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':NoFiles'
+ version: '5.031'
zilla:
class: Dist::Zilla::Dist::Builder
config:
- is_trial: 0
- version: 5.006
+ is_trial: '0'
+ version: '5.031'
@@ -1,23 +1,24 @@
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.031.
use strict;
use warnings;
use 5.005;
-use ExtUtils::MakeMaker 6.30;
+use ExtUtils::MakeMaker;
my %WriteMakefileArgs = (
"ABSTRACT" => "A more casual approach to creating and sending Email:: emails",
"AUTHOR" => "Adam Kennedy <adamk\@cpan.org>, Ricardo SIGNES <rjbs\@cpan.org>",
- "BUILD_REQUIRES" => {},
"CONFIGURE_REQUIRES" => {
- "ExtUtils::MakeMaker" => "6.30"
+ "ExtUtils::MakeMaker" => 0
},
"DISTNAME" => "Email-Stuffer",
"EXE_FILES" => [],
"LICENSE" => "perl",
+ "MIN_PERL_VERSION" => "5.005",
"NAME" => "Email::Stuffer",
"PREREQ_PM" => {
"Carp" => 0,
@@ -31,13 +32,16 @@ my %WriteMakefileArgs = (
},
"TEST_REQUIRES" => {
"Email::Sender::Transport::Test" => "0.120000",
+ "ExtUtils::MakeMaker" => 0,
+ "File::Spec" => 0,
"File::Spec::Functions" => 0,
"Moo" => 0,
+ "Test::Fatal" => 0,
"Test::More" => "0.96",
"Test::Most" => 0,
"utf8" => 0
},
- "VERSION" => "0.009",
+ "VERSION" => "0.012",
"test" => {
"TESTS" => "t/*.t"
}
@@ -50,10 +54,13 @@ my %FallbackPrereqs = (
"Email::MIME::Creator" => 0,
"Email::Sender::Simple" => 0,
"Email::Sender::Transport::Test" => "0.120000",
+ "ExtUtils::MakeMaker" => 0,
"File::Basename" => 0,
+ "File::Spec" => 0,
"File::Spec::Functions" => 0,
"Moo" => 0,
"Params::Util" => "1.05",
+ "Test::Fatal" => 0,
"Test::More" => "0.96",
"Test::Most" => 0,
"strict" => 0,
@@ -1,7 +1,7 @@
This archive contains the distribution Email-Stuffer,
-version 0.009:
+version 0.012:
A more casual approach to creating and sending Email:: emails
@@ -11,3 +11,5 @@ This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
+This README file was generated by Dist::Zilla::Plugin::Readme v5.031.
+
@@ -8,6 +8,6 @@ copyright_year = 2004
[@RJBS]
[Encoding]
-match = ^t/data/paypal
+match = ^t/data/
encoding = bytes
@@ -1,15 +1,169 @@
use strict;
use warnings;
package Email::Stuffer;
-{
- $Email::Stuffer::VERSION = '0.009';
-}
# ABSTRACT: A more casual approach to creating and sending Email:: emails
-
+$Email::Stuffer::VERSION = '0.012';
+#pod =head1 SYNOPSIS
+#pod
+#pod # Prepare the message
+#pod my $body = <<'AMBUSH_READY';
+#pod Dear Santa
+#pod
+#pod I have killed Bun Bun.
+#pod
+#pod Yes, I know what you are thinking... but it was actually a total accident.
+#pod
+#pod I was in a crowded line at a BayWatch signing, and I tripped, and stood on
+#pod his head.
+#pod
+#pod I know. Oops! :/
+#pod
+#pod So anyways, I am willing to sell you the body for $1 million dollars.
+#pod
+#pod Be near the pinhole to the Dimension of Pain at midnight.
+#pod
+#pod Alias
+#pod
+#pod AMBUSH_READY
+#pod
+#pod # Create and send the email in one shot
+#pod Email::Stuffer->from ('cpan@ali.as' )
+#pod ->to ('santa@northpole.org' )
+#pod ->bcc ('bunbun@sluggy.com' )
+#pod ->text_body($body )
+#pod ->attach_file('dead_bunbun_faked.gif' )
+#pod ->send;
+#pod
+#pod =head1 DESCRIPTION
+#pod
+#pod B<The basics should all work, but this module is still subject to
+#pod name and/or API changes>
+#pod
+#pod Email::Stuffer, as its name suggests, is a fairly casual module used
+#pod to stuff things into an email and send them. It is a high-level module
+#pod designed for ease of use when doing a very specific common task, but
+#pod implemented on top of the light and tolerable Email:: modules.
+#pod
+#pod Email::Stuffer is typically used to build emails and send them in a single
+#pod statement, as seen in the synopsis. And it is certain only for use when
+#pod creating and sending emails. As such, it contains no email parsing
+#pod capability, and little to no modification support.
+#pod
+#pod To re-iterate, this is very much a module for those "slap it together and
+#pod fire it off" situations, but that still has enough grunt behind the scenes
+#pod to do things properly.
+#pod
+#pod =head2 Default Transport
+#pod
+#pod Although it cannot be relied upon to work, the default behaviour is to
+#pod use C<sendmail> to send mail, if you don't provide the mail send channel
+#pod with either the C<transport> method, or as an argument to C<send>.
+#pod
+#pod (Actually, the choice of default is delegated to
+#pod L<Email::Sender::Simple>, which makes its own choices. But usually, it
+#pod uses C<sendmail>.)
+#pod
+#pod =head2 Why use this?
+#pod
+#pod Why not just use L<Email::Simple> or L<Email::MIME>? After all, this just adds
+#pod another layer of stuff around those. Wouldn't using them directly be better?
+#pod
+#pod Certainly, if you know EXACTLY what you are doing. The docs are clear enough,
+#pod but you really do need to have an understanding of the structure of MIME
+#pod emails. This structure is going to be different depending on whether you have
+#pod text body, HTML, both, with or without an attachment etc.
+#pod
+#pod Then there's brevity... compare the following roughly equivalent code.
+#pod
+#pod First, the Email::Stuffer way.
+#pod
+#pod Email::Stuffer->to('Simon Cozens<simon@somewhere.jp>')
+#pod ->from('Santa@northpole.org')
+#pod ->text_body("You've been good this year. No coal for you.")
+#pod ->attach_file('choochoo.gif')
+#pod ->send;
+#pod
+#pod And now doing it directly with a knowledge of what your attachment is, and
+#pod what the correct MIME structure is.
+#pod
+#pod use Email::MIME;
+#pod use Email::Sender::Simple;
+#pod use IO::All;
+#pod
+#pod Email::Sender::Simple->try_to_send(
+#pod Email::MIME->create(
+#pod header => [
+#pod To => 'simon@somewhere.jp',
+#pod From => 'santa@northpole.org',
+#pod ],
+#pod parts => [
+#pod Email::MIME->create(
+#pod body => "You've been a good boy this year. No coal for you."
+#pod ),
+#pod Email::MIME->create(
+#pod body => io('choochoo.gif'),
+#pod attributes => {
+#pod filename => 'choochoo.gif',
+#pod content_type => 'image/gif',
+#pod },
+#pod ),
+#pod ],
+#pod );
+#pod );
+#pod
+#pod Again, if you know MIME well, and have the patience to manually code up
+#pod the L<Email::MIME> structure, go do that, if you really want to.
+#pod
+#pod Email::Stuffer as the name suggests, solves one case and one case only:
+#pod generate some stuff, and email it to somewhere, as conveniently as
+#pod possible. DWIM, but do it as thinly as possible and use the solid
+#pod Email:: modules underneath.
+#pod
+#pod =head1 COOKBOOK
+#pod
+#pod Here is another example (maybe plural later) of how you can use
+#pod Email::Stuffer's brevity to your advantage.
+#pod
+#pod =head2 Custom Alerts
+#pod
+#pod package SMS::Alert;
+#pod use base 'Email::Stuffer';
+#pod
+#pod sub new {
+#pod shift()->SUPER::new(@_)
+#pod ->from('monitor@my.website')
+#pod # Of course, we could have pulled these from
+#pod # $MyConfig->{support_tech} or something similar.
+#pod ->to('0416181595@sms.gateway')
+#pod ->transport('SMTP', { host => '123.123.123.123' });
+#pod }
+#pod
+#pod Z<>
+#pod
+#pod package My::Code;
+#pod
+#pod unless ( $Server->restart ) {
+#pod # Notify the admin on call that a server went down and failed
+#pod # to restart.
+#pod SMS::Alert->subject("Server $Server failed to restart cleanly")
+#pod ->send;
+#pod }
+#pod
+#pod =head1 METHODS
+#pod
+#pod As you can see from the synopsis, all methods that B<modify> the
+#pod Email::Stuffer object returns the object, and thus most normal calls are
+#pod chainable.
+#pod
+#pod However, please note that C<send>, and the group of methods that do not
+#pod change the Email::Stuffer object B<do not> return the object, and thus
+#pod B<are not> chainable.
+#pod
+#pod =cut
use 5.005;
use strict;
-use Carp ();
+use Carp qw(croak);
use File::Basename ();
use Params::Util 1.05 qw(_INSTANCE _INSTANCEDOES);
use Email::MIME ();
@@ -19,6 +173,11 @@ use Email::Sender::Simple ();
#####################################################################
# Constructor and Accessors
+#pod =method new
+#pod
+#pod Creates a new, empty, Email::Stuffer object.
+#pod
+#pod =cut
sub new {
my $class = ref $_[0] || $_[0];
@@ -39,6 +198,12 @@ sub _self {
ref($either) ? $either : $either->new;
}
+#pod =method header_names
+#pod
+#pod Returns, as a list, all of the headers currently set for the Email
+#pod For backwards compatibility, this method can also be called as B[headers].
+#pod
+#pod =cut
sub header_names {
shift()->{email}->header_names;
@@ -48,18 +213,25 @@ sub headers {
shift()->{email}->header_names; ## This is now header_names, headers is depreciated
}
+#pod =method parts
+#pod
+#pod Returns, as a list, the L<Email::MIME> parts for the Email
+#pod
+#pod =cut
sub parts {
grep { defined $_ } @{shift()->{parts}};
}
-
-
-
-
#####################################################################
# Header Methods
+#pod =method header $header => $value
+#pod
+#pod Sets a named header in the email. Multiple calls with the same $header
+#pod will overwrite previous calls $value.
+#pod
+#pod =cut
sub header {
my $self = shift()->_self;
@@ -68,30 +240,55 @@ sub header {
return $self;
}
+#pod =method to $address
+#pod
+#pod Sets the To: header in the email
+#pod
+#pod =cut
sub to {
my $self = shift()->_self;
$self->{email}->header_str_set(To => join(q{, }, @_)) ? $self : undef;
}
+#pod =method from $address
+#pod
+#pod Sets the From: header in the email
+#pod
+#pod =cut
sub from {
my $self = shift()->_self;
$self->{email}->header_str_set(From => shift) ? $self : undef;
}
+#pod =method cc $address
+#pod
+#pod Sets the Cc: header in the email
+#pod
+#pod =cut
sub cc {
my $self = shift()->_self;
$self->{email}->header_str_set(Cc => join(q{, }, @_)) ? $self : undef;
}
+#pod =method bcc $address
+#pod
+#pod Sets the Bcc: header in the email
+#pod
+#pod =cut
sub bcc {
my $self = shift()->_self;
$self->{email}->header_str_set(Bcc => join(q{, }, @_)) ? $self : undef;
}
+#pod =method subject $text
+#pod
+#pod Sets the Subject: header in the email
+#pod
+#pod =cut
sub subject {
my $self = shift()->_self;
@@ -101,6 +298,15 @@ sub subject {
#####################################################################
# Body and Attachments
+#pod =method text_body $body [, $header => $value, ... ]
+#pod
+#pod Sets the text body of the email. Unless specified, all the appropriate
+#pod headers are set for you. You may override any as needed. See
+#pod L<Email::MIME> for the actual headers to use.
+#pod
+#pod If C<$body> is undefined, this method will do nothing.
+#pod
+#pod =cut
sub text_body {
my $self = shift()->_self;
@@ -124,6 +330,15 @@ sub text_body {
$self;
}
+#pod =method html_body $body [, $header => $value, ... ]
+#pod
+#pod Set the HTML body of the email. Unless specified, all the appropriate
+#pod headers are set for you. You may override any as needed. See
+#pod L<Email::MIME> for the actual headers to use.
+#pod
+#pod If C<$body> is undefined, this method will do nothing.
+#pod
+#pod =cut
sub html_body {
my $self = shift()->_self;
@@ -146,6 +361,14 @@ sub html_body {
$self;
}
+#pod =method attach $contents [, $header => $value, ... ]
+#pod
+#pod Adds an attachment to the email. The first argument is the file contents
+#pod followed by (as for text_body and html_body) the list of headers to use.
+#pod Email::Stuffer should TRY to guess the headers right, but you may wish
+#pod to provide them anyway to be sure. Encoding is Base64 by default.
+#pod
+#pod =cut
sub _detect_content_type {
my ($filename, $body) = @_;
@@ -161,6 +384,7 @@ sub _detect_content_type {
'htm' => 'text/html',
'html' => 'text/html',
'css' => 'text/css',
+ 'pdf' => 'application/pdf',
}->{$1};
return $content_type if defined $content_type;
}
@@ -170,11 +394,13 @@ sub _detect_content_type {
(GIF8) # gif
| (\xff\xd8) # jpeg
| (\x89PNG) # png
+ | (%PDF-) # pdf
)
/x) {
return 'image/gif' if $1;
return 'image/jpeg' if $2;
return 'image/png' if $3;
+ return 'application/pdf' if $4;
}
return 'application/octet-stream';
}
@@ -209,10 +435,17 @@ sub attach {
$self;
}
+#pod =method attach_file $file [, $header => $value, ... ]
+#pod
+#pod Attachs a file that already exists on the filesystem to the email.
+#pod C<attach_file> will auto-detect the MIME type, and use the file's
+#pod current name when attaching.
+#pod
+#pod =cut
sub attach_file {
my $self = shift;
- my $body_arg = shift;
+ my $body_arg = shift;
my $name = undef;
my $body = undef;
@@ -222,17 +455,21 @@ sub attach_file {
$body = $body_arg->all;
# Support file names
- } elsif ( defined $body_arg and -f $body_arg ) {
+ } elsif ( defined $body_arg and Params::Util::_STRING($body_arg) ) {
+ croak "No such file '$body_arg'" unless -f $body_arg;
$name = $body_arg;
- $body = _slurp( $body_arg ) or return undef;
+ $body = _slurp( $body_arg );
# That's it
} else {
- return undef;
+ my $type = ref($body_arg) || "<$body_arg>";
+ croak "Expected a file name or an IO::All::File derivative, got $type";
}
# Clean the file name
- $name = File::Basename::basename($name) or return undef;
+ $name = File::Basename::basename($name);
+
+ croak("basename somehow returned undef") unless defined $name;
# Now attach as normal
$self->attach( $body, name => $name, filename => $name, @_ );
@@ -242,13 +479,33 @@ sub attach_file {
sub _slurp {
my $file = shift;
local $/ = undef;
- local *SLURP;
- open( SLURP, "<$file" ) or return undef;
- my $source = <SLURP>;
- close( SLURP ) or return undef;
+
+ open my $slurp, '<:raw', $file or croak("error opening $file: $!");
+ my $source = <$slurp>;
+ close( $slurp ) or croak "error after slurping $file: $!";
\$source;
}
+#pod =method transport
+#pod
+#pod $stuffer->transport( $moniker, @options )
+#pod
+#pod or
+#pod
+#pod $stuffer->transport( $transport_obj )
+#pod
+#pod The C<transport> method specifies the L<Email::Sender> transport that
+#pod you want to use to send the email, and any options that need to be
+#pod used to instantiate the transport. C<$moniker> is used as the transport
+#pod name; if it starts with an equals sign (C<=>) then the text after the
+#pod sign is used as the class. Otherwise, the text is prepended by
+#pod C<Email::Sender::Transport::>. In neither case will a module be
+#pod automatically loaded.
+#pod
+#pod Alternatively, you can pass a complete transport object (which must be
+#pod an L<Email::Sender::Transport> object) and it will be used as is.
+#pod
+#pod =cut
sub transport {
my $self = shift;
@@ -270,39 +527,42 @@ sub transport {
$self;
}
-
-
-
-
#####################################################################
# Output Methods
+#pod =method email
+#pod
+#pod Creates and returns the full L<Email::MIME> object for the email.
+#pod
+#pod =cut
sub email {
my $self = shift;
my @parts = $self->parts;
- ### Lyle Hopkins, code added to Fix single part, and multipart/alternative problems
- if ( scalar( @{ $self->{parts} } ) >= 3 ) {
- ## multipart/mixed
- $self->{email}->parts_set( \@parts );
- }
- ## Check we actually have any parts
- elsif ( scalar( @{ $self->{parts} } ) ) {
- if ( _INSTANCE($parts[0], 'Email::MIME') && _INSTANCE($parts[1], 'Email::MIME') ) {
- ## multipart/alternate
- $self->{email}->header_set( 'Content-Type' => 'multipart/alternative' );
- $self->{email}->parts_set( \@parts );
- }
- ## As @parts is $self->parts without the blanks, we only need check $parts[0]
- elsif ( _INSTANCE($parts[0], 'Email::MIME') ) {
- ## single part text/plain
- _transfer_headers( $self->{email}, $parts[0] );
- $self->{email} = $parts[0];
- }
- }
+ ### Lyle Hopkins, code added to Fix single part, and multipart/alternative
+ ### problems
+ if (scalar(@{ $self->{parts} }) >= 3) {
+ ## multipart/mixed
+ $self->{email}->parts_set(\@parts);
+ } elsif (scalar(@{ $self->{parts} })) {
+ ## Check we actually have any parts
+ if ( _INSTANCE($parts[0], 'Email::MIME')
+ && _INSTANCE($parts[1], 'Email::MIME')
+ ) {
+ ## multipart/alternate
+ $self->{email}->header_set('Content-Type' => 'multipart/alternative');
+ $self->{email}->parts_set(\@parts);
+ } elsif (_INSTANCE($parts[0], 'Email::MIME')) {
+ ## As @parts is $self->parts without the blanks, we only need check
+ ## $parts[0]
+ ## single part text/plain
+ _transfer_headers($self->{email}, $parts[0]);
+ $self->{email} = $parts[0];
+ }
+ }
- $self->{email};
+ $self->{email};
}
# Support coercion to an Email::MIME
@@ -330,11 +590,24 @@ sub _transfer_headers {
}
}
+#pod =method as_string
+#pod
+#pod Returns the string form of the email. Identical to (and uses behind the
+#pod scenes) Email::MIME-E<gt>as_string.
+#pod
+#pod =cut
sub as_string {
shift()->email->as_string;
}
+#pod =method send
+#pod
+#pod Sends the email via L<Email::Sender::Simple>.
+#pod
+#pod On failure, returns false.
+#pod
+#pod =cut
sub send {
my $self = shift;
@@ -352,6 +625,13 @@ sub send {
);
}
+#pod =method send_or_die
+#pod
+#pod Sends the email via L<Email::Sender::Simple>.
+#pod
+#pod On failure, throws an exception.
+#pod
+#pod =cut
sub send_or_die {
my $self = shift;
@@ -369,10 +649,21 @@ sub send_or_die {
);
}
-
-
1;
+#pod =head1 TO DO
+#pod
+#pod =for :list
+#pod * Fix a number of bugs still likely to exist
+#pod * Write more tests.
+#pod * Add any additional small bit of automation that isn't too expensive
+#pod
+#pod =head1 SEE ALSO
+#pod
+#pod L<Email::MIME>, L<Email::Sender>, L<http://ali.as/>
+#pod
+#pod =cut
+
__END__
=pod
@@ -385,7 +676,7 @@ Email::Stuffer - A more casual approach to creating and sending Email:: emails
=head1 VERSION
-version 0.009
+version 0.012
=head1 SYNOPSIS
@@ -411,11 +702,11 @@ version 0.009
AMBUSH_READY
# Create and send the email in one shot
- Email::Stuffer->from ('cpan@ali.as' )
- ->to ('santa@northpole.org' )
- ->bcc ('bunbun@sluggy.com' )
- ->text_body($body )
- ->attach_file('dead_bunbun_faked.gif' )
+ Email::Stuffer->from ('cpan@ali.as' )
+ ->to ('santa@northpole.org' )
+ ->bcc ('bunbun@sluggy.com' )
+ ->text_body($body )
+ ->attach_file('dead_bunbun_faked.gif' )
->send;
=head1 DESCRIPTION
@@ -505,6 +796,14 @@ Email:: modules underneath.
=head1 METHODS
+As you can see from the synopsis, all methods that B<modify> the
+Email::Stuffer object returns the object, and thus most normal calls are
+chainable.
+
+However, please note that C<send>, and the group of methods that do not
+change the Email::Stuffer object B<do not> return the object, and thus
+B<are not> chainable.
+
=head2 new
Creates a new, empty, Email::Stuffer object.
@@ -642,16 +941,6 @@ Z<>
->send;
}
-=head1 METHODS
-
-As you can see from the synopsis, all methods that B<modify> the
-Email::Stuffer object returns the object, and thus most normal calls are
-chainable.
-
-However, please note that C<send>, and the group of methods that do not
-change the Email::Stuffer object B<do not> return the object, and thus
-B<are not> chainable.
-
=head1 TO DO
=over 4
@@ -0,0 +1,43 @@
+do { my $x = {
+ 'configure' => {
+ 'requires' => {
+ 'ExtUtils::MakeMaker' => '0'
+ }
+ },
+ 'develop' => {
+ 'requires' => {
+ 'Test::Pod' => '1.41'
+ }
+ },
+ 'runtime' => {
+ 'requires' => {
+ 'Carp' => '0',
+ 'Email::MIME' => '0',
+ 'Email::MIME::Creator' => '0',
+ 'Email::Sender::Simple' => '0',
+ 'File::Basename' => '0',
+ 'Params::Util' => '1.05',
+ 'perl' => '5.005',
+ 'strict' => '0',
+ 'warnings' => '0'
+ }
+ },
+ 'test' => {
+ 'recommends' => {
+ 'CPAN::Meta' => '2.120900'
+ },
+ 'requires' => {
+ 'Email::Sender::Transport::Test' => '0.120000',
+ 'ExtUtils::MakeMaker' => '0',
+ 'File::Spec' => '0',
+ 'File::Spec::Functions' => '0',
+ 'Moo' => '0',
+ 'Test::Fatal' => '0',
+ 'Test::More' => '0.96',
+ 'Test::Most' => '0',
+ 'utf8' => '0'
+ }
+ }
+ };
+ $x;
+ }
\ No newline at end of file
@@ -0,0 +1,183 @@
+#!perl
+
+use strict;
+use warnings;
+
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.020
+
+use Test::More tests => 1;
+
+use ExtUtils::MakeMaker;
+use File::Spec;
+
+# from $version::LAX
+my $lax_version_re =
+ qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
+ |
+ (?:\.[0-9]+) (?:_[0-9]+)?
+ ) | (?:
+ v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
+ |
+ (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
+ )
+ )/x;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_pre = "CPAN::Meta::Prereqs";
+my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _max {
+ my $max = shift;
+ $max = ( $_ > $max ) ? $_ : $max for @_;
+ return $max;
+}
+
+sub _merge_prereqs {
+ my ($collector, $prereqs) = @_;
+
+ # CPAN::Meta::Prereqs object
+ if (ref $collector eq $cpan_meta_pre) {
+ return $collector->with_merged_prereqs(
+ CPAN::Meta::Prereqs->new( $prereqs )
+ );
+ }
+
+ # Raw hashrefs
+ for my $phase ( keys %$prereqs ) {
+ for my $type ( keys %{ $prereqs->{$phase} } ) {
+ for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
+ $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
+ }
+ }
+ }
+
+ return $collector;
+}
+
+my @include = qw(
+
+);
+
+my @exclude = qw(
+
+);
+
+# Add static prereqs to the included modules list
+my $static_prereqs = do 't/00-report-prereqs.dd';
+
+# Merge all prereqs (either with ::Prereqs or a hashref)
+my $full_prereqs = _merge_prereqs(
+ ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
+ $static_prereqs
+);
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META ) {
+ if ( my $meta = eval { CPAN::Meta->load_file($source) } ) {
+ $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
+ }
+}
+else {
+ $source = 'static metadata';
+}
+
+my @full_reports;
+my @dep_errors;
+my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
+
+# Add static includes into a fake section
+for my $mod (@include) {
+ $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
+ next unless $req_hash->{$phase};
+ next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
+
+ for my $type ( qw(requires recommends suggests conflicts modules) ) {
+ next unless $req_hash->{$phase}{$type};
+
+ my $title = ucfirst($phase).' '.ucfirst($type);
+ my @reports = [qw/Module Want Have/];
+
+ for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
+ next if $mod eq 'perl';
+ next if grep { $_ eq $mod } @exclude;
+
+ my $file = $mod;
+ $file =~ s{::}{/}g;
+ $file .= ".pm";
+ my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
+
+ my $want = $req_hash->{$phase}{$type}{$mod};
+ $want = "undef" unless defined $want;
+ $want = "any" if !$want && $want == 0;
+
+ my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
+
+ if ($prefix) {
+ my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
+ $have = "undef" unless defined $have;
+ push @reports, [$mod, $want, $have];
+
+ if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
+ if ( $have !~ /\A$lax_version_re\z/ ) {
+ push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
+ }
+ elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
+ push @dep_errors, "$mod version '$have' is not in required range '$want'";
+ }
+ }
+ }
+ else {
+ push @reports, [$mod, $want, "missing"];
+
+ if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
+ push @dep_errors, "$mod is not installed ($req_string)";
+ }
+ }
+ }
+
+ if ( @reports ) {
+ push @full_reports, "=== $title ===\n\n";
+
+ my $ml = _max( map { length $_->[0] } @reports );
+ my $wl = _max( map { length $_->[1] } @reports );
+ my $hl = _max( map { length $_->[2] } @reports );
+
+ if ($type eq 'modules') {
+ splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
+ push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
+ }
+ else {
+ splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
+ push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+ }
+
+ push @full_reports, "\n";
+ }
+ }
+}
+
+if ( @full_reports ) {
+ diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
+}
+
+if ( @dep_errors ) {
+ diag join("\n",
+ "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n",
+ "The following REQUIRED prerequisites were not satisfied:\n",
+ @dep_errors,
+ "\n"
+ );
+}
+
+pass;
+
+# vim: ts=4 sts=4 sw=4 et:
@@ -1,84 +0,0 @@
-use strict;
-use warnings;
-use Test::More 0.88;
-# This is a relatively nice way to avoid Test::NoWarnings breaking our
-# expectations by adding extra tests, without using no_plan. It also helps
-# avoid any other test module that feels introducing random tests, or even
-# test plans, is a nice idea.
-our $success = 0;
-END { $success && done_testing; }
-
-# List our own version used to generate this
-my $v = "\nGenerated by Dist::Zilla::Plugin::ReportVersions::Tiny v1.10\n";
-
-eval { # no excuses!
- # report our Perl details
- my $want = '5.005';
- $v .= "perl: $] (wanted $want) on $^O from $^X\n\n";
-};
-defined($@) and diag("$@");
-
-# Now, our module version dependencies:
-sub pmver {
- my ($module, $wanted) = @_;
- $wanted = " (want $wanted)";
- my $pmver;
- eval "require $module;";
- if ($@) {
- if ($@ =~ m/Can't locate .* in \@INC/) {
- $pmver = 'module not found.';
- } else {
- diag("${module}: $@");
- $pmver = 'died during require.';
- }
- } else {
- my $version;
- eval { $version = $module->VERSION; };
- if ($@) {
- diag("${module}: $@");
- $pmver = 'died during VERSION check.';
- } elsif (defined $version) {
- $pmver = "$version";
- } else {
- $pmver = '<undef>';
- }
- }
-
- # So, we should be good, right?
- return sprintf('%-45s => %-10s%-15s%s', $module, $pmver, $wanted, "\n");
-}
-
-eval { $v .= pmver('Carp','any version') };
-eval { $v .= pmver('Email::MIME','any version') };
-eval { $v .= pmver('Email::MIME::Creator','any version') };
-eval { $v .= pmver('Email::Sender::Simple','any version') };
-eval { $v .= pmver('Email::Sender::Transport::Test','0.120000') };
-eval { $v .= pmver('ExtUtils::MakeMaker','6.30') };
-eval { $v .= pmver('File::Basename','any version') };
-eval { $v .= pmver('File::Spec::Functions','any version') };
-eval { $v .= pmver('Moo','any version') };
-eval { $v .= pmver('Params::Util','1.05') };
-eval { $v .= pmver('Test::More','0.96') };
-eval { $v .= pmver('Test::Most','any version') };
-eval { $v .= pmver('strict','any version') };
-eval { $v .= pmver('utf8','any version') };
-eval { $v .= pmver('warnings','any version') };
-
-
-# All done.
-$v .= <<'EOT';
-
-Thanks for using my code. I hope it works for you.
-If not, please try and include this output in the bug report.
-That will help me reproduce the issue and solve your problem.
-
-EOT
-
-diag($v);
-ok(1, "we really didn't test anything, just reporting data");
-$success = 1;
-
-# Work around another nasty module on CPAN. :/
-no warnings 'once';
-$Template::Test::NO_FLUSH = 1;
-exit 0;
@@ -3,7 +3,8 @@ use strict;
use warnings;
use File::Spec::Functions ':ALL';
-use Test::More tests => 59;
+use Test::More tests => 62;
+use Test::Fatal;
use Email::Stuffer;
my $TEST_GIF = catfile( 't', 'data', 'paypal.gif' );
@@ -101,4 +102,29 @@ like( $email, qr/phase-n/, 'Email contains to string' );
like( $email, qr/Hello/, 'Email contains subject string' );
like( $email, qr/I am an email/, 'Email contains text_body' );
like( $email, qr{Content-Type: text/plain; name="dist\.ini"}, 'Email contains attachment content-Type' );
+
+# attach_file with no such file
+my $error = exception { Email::Stuffer->attach_file( 'no such file' ) };
+like $error,
+ qr/No such file 'no such file'/,
+ 'attach_file croaks when passed a bad file name';
+
+# attach_file with a non-file object
+$error = exception { Email::Stuffer->attach_file( $rv2 ) };
+like $error,
+ qr/Expected a file name or an IO::All::File derivative, got Email::Sender::Success/,
+ 'attach_file croaks when passed a bad reference';
+
+my $enoent = do {
+ use Errno 'ENOENT';
+ local $! = ENOENT;
+ "$!";
+};
+
+# _slurp croaks when passed a bad file
+$error = exception { Email::Stuffer::_slurp( 'no such file' ) };
+like $error,
+ qr/\Aerror opening no such file: \Q$enoent/,
+ '_slurp croaks when passed a bad filename';
+
1;
@@ -1,7 +1,7 @@
use strict;
use warnings;
use utf8;
-use Test::More tests => 11;
+use Test::More tests => 14;
use File::Spec::Functions ':ALL';
use Email::Stuffer;
@@ -14,6 +14,9 @@ ok( -f $TEST_JPG, "Found test image: $TEST_JPG" );
my $TEST_PNG = catfile( 't', 'data', 'paypal.png' );
ok( -f $TEST_PNG, "Found test image: $TEST_PNG" );
+my $TEST_PDF = catfile( 't', 'data', 'empty.pdf' );
+ok( -f $TEST_PDF, "Found test pdf: $TEST_PDF" );
+
my $mail = Email::Stuffer->from ('cpan@example.com' )
->to ('santa@example.com' )
->text_body("YAY")
@@ -23,8 +26,10 @@ my $mail = Email::Stuffer->from ('cpan@example.com' )
->attach(slurp($TEST_JPG))
->attach_file($TEST_PNG)
->attach(slurp($TEST_PNG))
+ ->attach_file($TEST_PDF)
+ ->attach(slurp($TEST_PDF))
->email;
-is(0+$mail->parts, 7);
+is(0+$mail->parts, 9);
like([$mail->parts]->[0]->content_type, qr(^text/plain));
like([$mail->parts]->[1]->content_type, qr(^image/gif));
like([$mail->parts]->[2]->content_type, qr(^image/gif));
@@ -32,6 +37,8 @@ like([$mail->parts]->[3]->content_type, qr(^image/jpeg));
like([$mail->parts]->[4]->content_type, qr(^image/jpeg));
like([$mail->parts]->[5]->content_type, qr(^image/png));
like([$mail->parts]->[6]->content_type, qr(^image/png));
+like([$mail->parts]->[7]->content_type, qr(^application/pdf));
+like([$mail->parts]->[8]->content_type, qr(^application/pdf));
sub slurp {
my $fname = shift;
diff --git a/var/tmp/source/RJBS/Email-Stuffer-0.012/Email-Stuffer-0.012/t/data/empty.pdf b/var/tmp/source/RJBS/Email-Stuffer-0.012/Email-Stuffer-0.012/t/data/empty.pdf
new file mode 100644
index 00000000..acbb7916
Binary files /dev/null and b/var/tmp/source/RJBS/Email-Stuffer-0.012/Email-Stuffer-0.012/t/data/empty.pdf differ
@@ -4,7 +4,7 @@ use Test::More tests => 2;
note 'Checking Changes';
my $changes_file = 'Changes';
-my $newver = '0.009';
+my $newver = '0.012';
my $trial_token = '-TRIAL';
SKIP: {
@@ -1,7 +1,6 @@
#!perl
+# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
use Test::More;
-
-eval "use Test::Pod 1.41";
-plan skip_all => "Test::Pod 1.41 required for testing POD" if $@;
+use Test::Pod 1.41;
all_pod_files_ok();