]> gitweb.factorcode.org Git - factor.git/commitdiff
crontab: adding "~" randomization
authorJohn Benediktsson <mrjbq7@gmail.com>
Sat, 2 Dec 2023 23:29:49 +0000 (15:29 -0800)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sat, 2 Dec 2023 23:29:49 +0000 (15:29 -0800)
from the manpage for crontab(5)

> Randomization of the execution time within a range can be
> used.  A random number within a range specified as two numbers
> separated with a tilde is picked.  The specified range is
> inclusive.  For example, 6~15 for a 'minutes' entry picks a
> random minute within 6 to 15 range.  The random number is
> picked when crontab file is parsed.  The first number must be
> less than or equal to the second one. You might omit one or
> both of the numbers specifying the range.  For example, ~ for
> a 'minutes' entry picks a random minute within 0 to 59 range.

extra/crontab/crontab.factor

index 08164ddef004b3bbcf795420b2e170f22b0ec8db..66521a5d7002c666fd3d481a11179bbbf679a4b1 100644 (file)
@@ -5,17 +5,22 @@ USING: accessors arrays ascii assocs assocs.extras calendar
 calendar.english calendar.format calendar.parser
 calendar.private circular combinators combinators.short-circuit
 io kernel literals math math.order math.parser prettyprint
-ranges sequences sets sorting splitting ;
+random ranges sequences sets sorting splitting ;
 
 IN: crontab
 
 ERROR: invalid-cronentry value ;
 
+TUPLE: cronentry minutes hours days months days-of-week command ;
+
+<PRIVATE
+
 :: parse-value ( value quot: ( value -- value' ) seq -- value )
     value {
         { [ CHAR: , over member? ] [
             "," split [ quot seq parse-value ] map concat ] }
         { [ dup "*" = ] [ drop seq ] }
+        { [ dup "~" = ] [ drop seq random 1array ] }
         { [ CHAR: / over member? ] [
             "/" split1 [
                 quot seq parse-value
@@ -24,6 +29,8 @@ ERROR: invalid-cronentry value ;
             ] dip string>number <range> swap nths ] }
         { [ CHAR: - over member? ] [
             "-" split1 quot bi@ [a..b] ] }
+        { [ CHAR: ~ over member? ] [
+            "~" split1 quot bi@ [a..b] random 1array ] }
         [ quot call 1array ]
     } cond members sort ; inline recursive
 
@@ -37,8 +44,6 @@ ERROR: invalid-cronentry value ;
         >lower $[ month-abbreviations [ >lower ] map ] index
     ] ?unless ;
 
-TUPLE: cronentry minutes hours days months days-of-week command ;
-
 CONSTANT: aliases H{
     { "@yearly"   "0 0 1 1 *" }
     { "@annually" "0 0 1 1 *" }
@@ -62,6 +67,8 @@ CONSTANT: aliases H{
         [ hours>> [ 0 23 between? ] all? ]
     } 1&& [ invalid-cronentry ] unless ;
 
+PRIVATE>
+
 : parse-cronentry ( entry -- cronentry )
     " " split1 [ aliases ?at drop ] dip " " glue
     " " split1 " " split1 " " split1 " " split1 " " split1 {