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   431330 use 5.014;
  5         23  
4 5     5   64 use strict;
  5         14  
  5         178  
5 5     5   23 use warnings;
  5         21  
  5         361  
6              
7 5     5   32 use feature ':5.10';
  5         7  
  5         5057  
8              
9             our $VERSION = '0.05';
10              
11              
12 5     5   42 use Carp;
  5         10  
  5         411  
13 5     5   32 use File::Basename;
  5         8  
  5         522  
14 5     5   2651 use File::Spec::Functions;
  5         5089  
  5         506  
15              
16 5     5   3050 use Software::Security::Policy::Individual;
  5         247455  
  5         263  
17 5     5   73 use Text::Template;
  5         12  
  5         441  
18 5     5   3309 use GitHub::Config::SSH::UserData qw(get_user_data_from_ssh_cfg);
  5         159805  
  5         574  
19              
20              
21 5     5   55 use constant INTERNAL_CONTRIB_MD => <<'EOT';
  5         12  
  5         8995  
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 592623 my $class = shift;
71 17         296 my %args = (dir => '.', prefix => q{}, @_);
72 17         68 state $allowed = {map {$_ => undef} qw(dir
  28         66  
73             email
74             full_name
75             login
76             module
77             prefix
78             uncapitalize)};
79 17         87 $args{uncapitalize} = !!$args{uncapitalize};
80 17         77 foreach my $arg (keys(%args)) {
81 83 100       340 croak("$arg: unsupported argument") if !exists($allowed->{$arg});
82 82 100       515 croak("$arg: value is not a scalar") if ref($args{$arg});
83             }
84 14         49 delete @args{ grep { !defined $args{$_} } keys %args };
  75         187  
85 14 100       48 do {croak("$_: missing mandatory argument") if !exists($args{$_})} for (qw(login module));
  26         481  
86 11         34 my $self = bless(\%args, $class);
87 11 100 100     79 if (!(exists($self->{email}) && exists($self->{full_name}))) {
88 8         52 my $udata = get_user_data_from_ssh_cfg($self->{login});
89             $self->{email} //= $udata->{email2} // $udata->{email}
90 6   66     11927 // die("Could not determine email address"); # Should never happen.
      50        
      66        
91             $self->{full_name} //= $udata->{full_name}
92 6   50     43 // die("Could not determine user's full name"); # Should never happen.
      66        
93             }
94 9         38 return $self;
95             }
96              
97              
98 2     2 1 2618 sub dir {$_[0]->{dir}}
99 5     5 1 3649 sub email {$_[0]->{email}}
100 5     5 1 1083 sub full_name {$_[0]->{full_name}}
101 1     1 1 1117 sub login {$_[0]->{login}}
102 1     1 1 1109 sub module {$_[0]->{module}}
103 2     2 1 1111 sub prefix {$_[0]->{prefix}}
104 3     3 1 1417 sub uncapitalize {$_[0]->{uncapitalize}}
105              
106              
107              
108             sub create_contrib_md {
109 4     4 1 31 my $self = shift;
110 4         11 my $contrib_md_tmpl = shift;
111 4 50       18 croak('Unexpected argument(s)') if @_;
112 4 50       18 croak('Missing --module: no module specified') unless exists($self->{module});
113             my $contrib_md_tmpl_str = defined($contrib_md_tmpl) ?
114 4 100       16 do { local ( *ARGV, $/ ); @ARGV = ($contrib_md_tmpl); <> } : INTERNAL_CONTRIB_MD;
  1         12  
  1         4  
  1         140  
115 4         43 (my $mod_name = (split(/,/, $self->{module}))[0]) =~ s/::/-/g;
116 4         10 my $cpan_rt = "https://rt.cpan.org/NoAuth/ReportBug.html?Queue=$mod_name";
117 4 100       24 my $repo = $self->{prefix} . ($self->{uncapitalize} ? lc($mod_name) : $mod_name);
118 4         14 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         540 my $tmpl_vars = {cpan_rt => $cpan_rt, github_i => $github_i};
123 4         49 @{$tmpl_vars}{qw(email full_name module)} = @{$self}{qw(email full_name module)};
  4         15  
  4         18  
124 4   33     21 my $contrib = $tmpl_obj->fill_in(HASH => $tmpl_vars)
125             // croak("Couldn't fill in template: $Text::Template::ERROR");
126 4         6103 open(my $fh, '>', catfile($self->{dir}, 'CONTRIBUTING.md'));
127 4         34 print $fh ($contrib, "\n");
128 4         234 close($fh);
129             }
130              
131              
132              
133             sub create_security_md {
134 4     4 1 20 my $self = shift;
135 4         58 my %args = (maintainer => sprintf("%s <%s>", @{$self}{qw(full_name email)}),
136             program => $self->{module},
137 4         10 @_);
138 4 100       24 if (!exists($args{url})) {
139 3         28 (my $m = $self->{module}) =~ s/::/-/g;
140 3 50       14 $m = lc($m) if $self->{uncapitalize};
141 3         11 $args{url} = "https://github.com/$self->{login}/$self->{prefix}${m}/blob/main/SECURITY.md";
142             }
143 4 50       16 delete @args{ grep { !defined $args{$_} || $args{$_} eq q{}} keys %args };
  18         112  
144 4         806 open(my $fh, '>', catfile($self->{dir}, 'SECURITY.md'));
145 4         80 print $fh (Software::Security::Policy::Individual->new(\%args)->fulltext);
146 4         33729 close($fh);
147             }
148              
149              
150             1; # End of Dist::PolicyFiles
151              
152              
153             __END__