File Coverage

blib/script/narada-setup-cron
Criterion Covered Total %
statement 77 88 87.5
branch 16 24 66.6
condition 5 6 83.3
subroutine 17 19 89.4
pod n/a
total 115 137 83.9


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2 2     2   1467 use 5.010001;
  2         5  
3 2     2   8 use warnings;
  2         2  
  2         75  
4 2     2   6 use strict;
  2         2  
  2         38  
5 2     2   1349 use utf8;
  2         19  
  2         12  
6              
7             our $VERSION = 'v2.3.6';
8              
9 2     2   99 use FindBin;
  2         2  
  2         112  
10 2     2   880 use lib "$FindBin::Bin/../lib/perl5";
  2         1166  
  2         12  
11 2     2   703 use Narada;
  2         4  
  2         59  
12 2     2   499 use Narada::Config qw( get_config set_config );
  2         3  
  2         12  
13 2     2   586 use Path::Tiny;
  2         2  
  2         1639  
14              
15              
16             main(@ARGV) if !caller;
17              
18              
19 2     2   76 sub err { die "narada-setup-cron: @_\n" }
20              
21             sub main {
22 14 100 100 14   11151 die "Usage: narada-setup-cron [--clean]\n"
      66        
23             if (@_ > 1)
24             || (@_ == 1 && $_[0] ne '--clean');
25              
26 10 100       23 if (@_) {
27 4         14 path('var/use/cron')->remove;
28 4         332 del_cron();
29             }
30             else {
31 6 100       26 if (Narada::detect() eq 'narada') {
32 4         12 path('var/use/cron')->touch;
33             }
34 6         545 my $c = path('config/crontab');
35 6 100       128 my @configs = map {m{\Aconfig/(.*)}ms} grep {$_->is_file}
  6         114  
  7         361  
36             $c->is_dir ? $c->children : $c;
37 6 100       120 if (!@configs) {
38 2         6 del_cron();
39             }
40             else {
41 4         7 my $crontab = join "\n", map { get_config($_) } @configs;
  6         270  
42 4         2454 $crontab = process($crontab);
43 4         43 set_cron($crontab);
44             }
45             }
46              
47 10         95 return;
48             }
49              
50             sub get_project_dir {
51 82     82   163782 chomp (my $project_dir = `pwd`);
52 82 100       809 $project_dir !~ /\n/xms or err 'Project directory must not contain \\n';
53 80         868 return $project_dir;
54             }
55              
56             sub process {
57 6     6   1242 my ($crontab) = @_;
58 6         13 my $project_dir = get_project_dir();
59 6         24 $project_dir = quotemeta $project_dir;
60 6         98 $project_dir =~ s{\\([/,._-])}{$1}xmsg; # unquote safe chars for readability
61 6         125 $crontab =~ s/^(\s*(?!\#)(?:\S+\s+){5})/${1}cd $project_dir || exit; /xmsg;
62 6         34 return $crontab;
63             }
64              
65             sub get_markers {
66 68     68   116 my $project_dir = get_project_dir();
67 68         227 my $start = "# ENTER Narada: $project_dir";
68 68         173 my $end = "# LEAVE Narada: $project_dir";
69 68         893 my $re = qr/^\Q$start\E\n.*?^\Q$end\E(?:\n|\z)/xms;
70 68         271 return ($re, $start, $end);
71             }
72              
73             sub get_user_crontab {
74 0     0   0 local $/ = undef;
75             # WORKAROUND If user has no crontab then `crontab -l` output string
76             # "no crontab for USERNAME". So we've to use `crontab -e`
77             # instead, to get empty output in this case.
78 0 0       0 open my $cron, q{-|}, 'VISUAL=cat EDITOR=cat crontab -e' or err "crontab -e: $!";
79 0         0 my $crontab = <$cron>;
80 0 0       0 close $cron or err "crontab -e: $!";
81 0         0 return $crontab;
82             }
83              
84             sub set_user_crontab {
85 0     0   0 my ($crontab) = @_;
86 0 0       0 open my $cron, q{|-}, 'crontab -' or err "crontab -e: $!";
87 0         0 print {$cron} $crontab;
  0         0  
88 0 0       0 close $cron or err "crontab -e: $!";
89 0         0 return;
90             }
91              
92             sub force_last_cr {
93 180     180   47363 my ($s) = @_;
94 180 100       711 if ($s =~ /[^\n]\z/xms) {
95 68         107 $s .= "\n";
96             }
97 180         446 return $s;
98             }
99              
100             sub set_cron {
101 60     60   208 my ($crontab) = @_;
102 60         80 $crontab = force_last_cr($crontab);
103              
104 60         111 my $user_crontab = get_user_crontab();
105 60         194 my ($re, $start, $end) = get_markers();
106 60 100       538 if ($user_crontab !~ /$re/xms) {
107 30         71 $user_crontab = force_last_cr($user_crontab);
108 30         86 $user_crontab .= "$start\n$end\n";
109             }
110              
111 60         686 $user_crontab =~ s/$re/$start\n$crontab$end\n/xms;
112 60         412 set_user_crontab($user_crontab);
113 60         353 return;
114             }
115              
116             sub del_cron {
117 6     6   4202 my $user_crontab = get_user_crontab();
118 6         27 my ($re) = get_markers();
119 6         69 $user_crontab =~ s/$re//xms;
120 6         50 set_user_crontab($user_crontab);
121 6         40 return;
122             }
123              
124              
125             1; # Magic true value required at end of module
126             __END__