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   1325 use 5.010001;
  2         4  
3 2     2   6 use warnings;
  2         2  
  2         61  
4 2     2   5 use strict;
  2         2  
  2         46  
5 2     2   1029 use utf8;
  2         16  
  2         9  
6              
7             our $VERSION = 'v2.3.7';
8              
9 2     2   69 use FindBin;
  2         3  
  2         100  
10 2     2   759 use lib "$FindBin::Bin/../lib/perl5";
  2         942  
  2         11  
11 2     2   580 use Narada;
  2         3  
  2         43  
12 2     2   397 use Narada::Config qw( get_config set_config );
  2         3  
  2         10  
13 2     2   578 use Path::Tiny;
  2         2  
  2         1364  
14              
15              
16             main(@ARGV) if !caller;
17              
18              
19 2     2   50 sub err { die "narada-setup-cron: @_\n" }
20              
21             sub main {
22 14 100 100 14   9357 die "Usage: narada-setup-cron [--clean]\n"
      66        
23             if (@_ > 1)
24             || (@_ == 1 && $_[0] ne '--clean');
25              
26 10 100       20 if (@_) {
27 4         22 path('var/use/cron')->remove;
28 4         305 del_cron();
29             }
30             else {
31 6 100       61 if (Narada::detect() eq 'narada') {
32 4         9 path('var/use/cron')->touch;
33             }
34 6         481 my $c = path('config/crontab');
35 6 100       107 my @configs = map {m{\Aconfig/(.*)}ms} grep {$_->is_file}
  6         84  
  7         299  
36             $c->is_dir ? $c->children : $c;
37 6 100       103 if (!@configs) {
38 2         6 del_cron();
39             }
40             else {
41 4         7 my $crontab = join "\n", map { get_config($_) } @configs;
  6         248  
42 4         1969 $crontab = process($crontab);
43 4         28 set_cron($crontab);
44             }
45             }
46              
47 10         78 return;
48             }
49              
50             sub get_project_dir {
51 82     82   137006 chomp (my $project_dir = `pwd`);
52 82 100       735 $project_dir !~ /\n/xms or err 'Project directory must not contain \\n';
53 80         683 return $project_dir;
54             }
55              
56             sub process {
57 6     6   894 my ($crontab) = @_;
58 6         13 my $project_dir = get_project_dir();
59 6         20 $project_dir = quotemeta $project_dir;
60 6         75 $project_dir =~ s{\\([/,._-])}{$1}xmsg; # unquote safe chars for readability
61 6         107 $crontab =~ s/^(\s*(?!\#)(?:\S+\s+){5})/${1}cd $project_dir || exit; /xmsg;
62 6         26 return $crontab;
63             }
64              
65             sub get_markers {
66 68     68   104 my $project_dir = get_project_dir();
67 68         177 my $start = "# ENTER Narada: $project_dir";
68 68         155 my $end = "# LEAVE Narada: $project_dir";
69 68         623 my $re = qr/^\Q$start\E\n.*?^\Q$end\E(?:\n|\z)/xms;
70 68         292 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   39241 my ($s) = @_;
94 180 100       600 if ($s =~ /[^\n]\z/xms) {
95 68         102 $s .= "\n";
96             }
97 180         462 return $s;
98             }
99              
100             sub set_cron {
101 60     60   185 my ($crontab) = @_;
102 60         76 $crontab = force_last_cr($crontab);
103              
104 60         94 my $user_crontab = get_user_crontab();
105 60         145 my ($re, $start, $end) = get_markers();
106 60 100       459 if ($user_crontab !~ /$re/xms) {
107 30         75 $user_crontab = force_last_cr($user_crontab);
108 30         62 $user_crontab .= "$start\n$end\n";
109             }
110              
111 60         555 $user_crontab =~ s/$re/$start\n$crontab$end\n/xms;
112 60         294 set_user_crontab($user_crontab);
113 60         278 return;
114             }
115              
116             sub del_cron {
117 6     6   3050 my $user_crontab = get_user_crontab();
118 6         28 my ($re) = get_markers();
119 6         54 $user_crontab =~ s/$re//xms;
120 6         35 set_user_crontab($user_crontab);
121 6         28 return;
122             }
123              
124              
125             1; # Magic true value required at end of module
126             __END__