File Coverage

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


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2 2     2   1318 use 5.010001;
  2         7  
3 2     2   12 use warnings;
  2         4  
  2         57  
4 2     2   10 use strict;
  2         3  
  2         32  
5 2     2   1046 use utf8;
  2         26  
  2         9  
6              
7             our $VERSION = 'v2.3.8';
8              
9 2     2   81 use FindBin;
  2         4  
  2         99  
10 2     2   11 use lib "$FindBin::Bin/../lib/perl5";
  2         3  
  2         13  
11 2     2   692 use Narada;
  2         4  
  2         52  
12 2     2   426 use Narada::Config qw( get_config set_config );
  2         4  
  2         9  
13 2     2   693 use Path::Tiny;
  2         2  
  2         1726  
14              
15              
16             main(@ARGV) if !caller;
17              
18              
19 2     2   226 sub err { die "narada-setup-cron: @_\n" }
20              
21             sub main {
22 14 100 100 14   13942 die "Usage: narada-setup-cron [--clean]\n"
      100        
23             if (@_ > 1)
24             || (@_ == 1 && $_[0] ne '--clean');
25              
26 10 100       30 if (@_) {
27 4         13 path('var/use/cron')->remove;
28 4         398 del_cron();
29             }
30             else {
31 6 100       28 if (Narada::detect() eq 'narada') {
32 4         13 path('var/use/cron')->touch;
33             }
34 6         759 my $c = path('config/crontab');
35 6 100       190 my @configs = map {m{\Aconfig/(.*)}ms} grep {$_->is_file}
  6         128  
  7         537  
36             $c->is_dir ? $c->children : $c;
37 6 100       173 if (!@configs) {
38 2         6 del_cron();
39             }
40             else {
41 4         9 my $crontab = join "\n", map { get_config($_) } @configs;
  6         500  
42 4         2500 $crontab = process($crontab);
43 4         78 set_cron($crontab);
44             }
45             }
46              
47 10         187 return;
48             }
49              
50             sub get_project_dir {
51 82     82   254761 chomp (my $project_dir = `pwd`);
52 82 100       2277 $project_dir !~ /\n/xms or err 'Project directory must not contain \\n';
53 80         2436 return $project_dir;
54             }
55              
56             sub process {
57 6     6   3151 my ($crontab) = @_;
58 6         23 my $project_dir = get_project_dir();
59 6         50 $project_dir = quotemeta $project_dir;
60 6         201 $project_dir =~ s{\\([/,._-])}{$1}xmsg; # unquote safe chars for readability
61 6         237 $crontab =~ s/^(\s*(?!\#)(?:\S+\s+){5})/${1}cd $project_dir || exit; /xmsg;
62 6         86 return $crontab;
63             }
64              
65             sub get_markers {
66 68     68   263 my $project_dir = get_project_dir();
67 68         645 my $start = "# ENTER Narada: $project_dir";
68 68         469 my $end = "# LEAVE Narada: $project_dir";
69 68         1955 my $re = qr/^\Q$start\E\n.*?^\Q$end\E(?:\n|\z)/xms;
70 68         541 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   108625 my ($s) = @_;
94 180 100       1230 if ($s =~ /[^\n]\z/xms) {
95 68         375 $s .= "\n";
96             }
97 180         840 return $s;
98             }
99              
100             sub set_cron {
101 60     60   389 my ($crontab) = @_;
102 60         141 $crontab = force_last_cr($crontab);
103              
104 60         324 my $user_crontab = get_user_crontab();
105 60         345 my ($re, $start, $end) = get_markers();
106 60 100       1151 if ($user_crontab !~ /$re/xms) {
107 30         193 $user_crontab = force_last_cr($user_crontab);
108 30         163 $user_crontab .= "$start\n$end\n";
109             }
110              
111 60         1223 $user_crontab =~ s/$re/$start\n$crontab$end\n/xms;
112 60         1206 set_user_crontab($user_crontab);
113 60         878 return;
114             }
115              
116             sub del_cron {
117 6     6   7816 my $user_crontab = get_user_crontab();
118 6         53 my ($re) = get_markers();
119 6         131 $user_crontab =~ s/$re//xms;
120 6         130 set_user_crontab($user_crontab);
121 6         83 return;
122             }
123              
124              
125             1; # Magic true value required at end of module
126             __END__