File Coverage

blib/lib/Dist/PolicyFiles.pm
Criterion Covered Total %
statement 90 90 100.0
branch 19 24 79.1
condition 12 19 63.1
subroutine 21 21 100.0
pod 10 10 100.0
total 152 164 92.6


line stmt bran cond sub pod time code
1             package Dist::PolicyFiles;
2              
3 5     5   257643 use 5.014;
  5         17  
4 5     5   23 use strict;
  5         13  
  5         104  
5 5     5   21 use warnings;
  5         22  
  5         250  
6              
7 5     5   26 use feature ':5.10';
  5         8  
  5         4123  
8              
9             our $VERSION = '0.07';
10              
11              
12 5     5   31 use Carp;
  5         14  
  5         315  
13 5     5   26 use File::Basename;
  5         7  
  5         352  
14 5     5   2047 use File::Spec::Functions;
  5         3328  
  5         398  
15              
16 5     5   2267 use Software::Security::Policy::Individual;
  5         169709  
  5         190  
17 5     5   38 use Text::Template;
  5         14  
  5         284  
18 5     5   2326 use GitHub::Config::SSH::UserData qw(get_user_data_from_ssh_cfg);
  5         113653  
  5         472  
19              
20              
21 5     5   52 use constant INTERNAL_CONTRIB_MD => <<'EOT';
  5         9  
  5         6532  
22             # Contributing to This Perl Module
23              
24             Thank you for your interest in contributing!
25              
26             ## Reporting Issues
27              
28             Please open a
29             [CPAN request]({$cpan_rt})
30             or a
31             [GitHub Issue]({$github_i})
32             if you encounter a bug or have a suggestion.
33             Include the following if possible:
34              
35             - A clear description of the issue
36             - A minimal code example that reproduces it
37             - Expected and actual behavior
38             - Perl version and operating system
39              
40             ## Submitting Code
41              
42             Pull requests are welcome! To contribute code:
43              
44             1. Fork the repository and create a descriptive branch name.
45             2. Write tests for any new feature or bug fix.
46             3. Ensure all tests pass using `prove -l t/` or `make test`.
47             4. Follow the existing code style, especially:
48             - No tabs please
49             - No trailing whitespace please
50             - 2 spaces indentation
51             5. In your pull request, briefly explain your changes and their motivation.
52              
53              
54             ## Creating a Distribution (Release)
55              
56             This module uses MakeMaker for creating releases (`make dist`).
57              
58              
59             ## Licensing
60              
61             By submitting code, you agree that your contributions may be distributed under the same license as the project.
62              
63             Thank you for helping improve this module!
64              
65             EOT
66             #Don't append a semicolon to the line above!
67              
68              
69             sub new {
70 17     17 1 525710 my $class = shift;
71 17         131 my %args = (dir => '.', prefix => q{}, @_);
72 17         44 state $allowed = {map {$_ => undef} qw(dir
  28         75  
73             email
74             full_name
75             login
76             module
77             prefix
78             uncapitalize)};
79 17         75 $args{uncapitalize} = !!$args{uncapitalize};
80 17         115 foreach my $arg (keys(%args)) {
81 86 100       340 croak("$arg: unsupported argument") if !exists($allowed->{$arg});
82 85 100       456 croak("$arg: value is not a scalar") if ref($args{$arg});
83             }
84 14         67 delete @args{ grep { !defined $args{$_} } keys %args };
  75         171  
85 14 100       43 do {croak("$_: missing mandatory argument") if !exists($args{$_})} for (qw(login module));
  26         573  
86 11         43 my $self = bless(\%args, $class);
87 11 100 100     78 if (!(exists($self->{email}) && exists($self->{full_name}))) {
88 8         50 my $udata = get_user_data_from_ssh_cfg($self->{login});
89             $self->{email} //= $udata->{email2} // $udata->{email}
90 6   66     11368 // die("Could not determine email address"); # Should never happen.
      50        
      66        
91             $self->{full_name} //= $udata->{full_name}
92 6   50     53 // die("Could not determine user's full name"); # Should never happen.
      66        
93             }
94 9         34 return $self;
95             }
96              
97              
98 2     2 1 868 sub dir {$_[0]->{dir}}
99 5     5 1 3789 sub email {$_[0]->{email}}
100 5     5 1 2105 sub full_name {$_[0]->{full_name}}
101 1     1 1 1419 sub login {$_[0]->{login}}
102 1     1 1 1311 sub module {$_[0]->{module}}
103 2     2 1 1466 sub prefix {$_[0]->{prefix}}
104 3     3 1 1115 sub uncapitalize {$_[0]->{uncapitalize}}
105              
106              
107              
108             sub create_contrib_md {
109 4     4 1 31 my $self = shift;
110 4         13 my $contrib_md_tmpl = shift;
111 4 50       19 croak('Unexpected argument(s)') if @_;
112 4 50       19 croak('Missing --module: no module specified') unless exists($self->{module});
113             my $contrib_md_tmpl_str = defined($contrib_md_tmpl) ?
114 4 100       20 do { local ( *ARGV, $/ ); @ARGV = ($contrib_md_tmpl); <> } : INTERNAL_CONTRIB_MD;
  1         11  
  1         4  
  1         156  
115 4         45 (my $mod_name = (split(/,/, $self->{module}))[0]) =~ s/::/-/g;
116 4         12 my $cpan_rt = "https://rt.cpan.org/NoAuth/ReportBug.html?Queue=$mod_name";
117 4 100       26 my $repo = $self->{prefix} . ($self->{uncapitalize} ? lc($mod_name) : $mod_name);
118 4         13 my $github_i = "https://github.com/$self->{login}/$repo/issues";
119 4 50       25 my $tmpl_obj = Text::Template->new(SOURCE => $contrib_md_tmpl_str, TYPE => 'STRING')
120             or croak("Couldn't construct template: $Text::Template::ERROR");
121              
122 4         560 my $tmpl_vars = {cpan_rt => $cpan_rt, github_i => $github_i};
123 4         10 @{$tmpl_vars}{qw(email full_name module)} = @{$self}{qw(email full_name module)};
  4         19  
  4         15  
124 4   33     16 my $contrib = $tmpl_obj->fill_in(HASH => $tmpl_vars)
125             // croak("Couldn't fill in template: $Text::Template::ERROR");
126 4         6198 open(my $fh, '>', catfile($self->{dir}, 'CONTRIBUTING.md'));
127 4         35 print $fh ($contrib, "\n");
128 4         226 close($fh);
129             }
130              
131              
132              
133             sub create_security_md {
134 4     4 1 20 my $self = shift;
135 4         105 my %args = (maintainer => sprintf("%s <%s>", @{$self}{qw(full_name email)}),
136             program => $self->{module},
137 4         11 @_);
138 4 100       31 if (!exists($args{url})) {
139 3         20 (my $m = $self->{module}) =~ s/::/-/g;
140 3 50       17 $m = lc($m) if $self->{uncapitalize};
141 3         14 $args{url} = "https://github.com/$self->{login}/$self->{prefix}${m}/blob/main/SECURITY.md";
142             }
143 4 50       27 delete @args{ grep { !defined $args{$_} || $args{$_} eq q{}} keys %args };
  18         99  
144 4         809 open(my $fh, '>', catfile($self->{dir}, 'SECURITY.md'));
145 4         94 print $fh (Software::Security::Policy::Individual->new(\%args)->fulltext);
146 4         37159 close($fh);
147             }
148              
149              
150             1; # End of Dist::PolicyFiles
151              
152              
153             __END__