Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
KMSCAKKSCFKA AKFACAMADCAS
brew
Commits
30297582
Unverified
Commit
30297582
authored
Nov 21, 2021
by
Sean Molenaar
Browse files
service: add basic cron support
parent
e482a9f0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Library/Homebrew/service.rb
View file @
30297582
...
...
@@ -145,10 +145,8 @@ module Homebrew
case
T
.
unsafe
(
value
)
when
nil
@run_type
when
:immediate
,
:interval
when
:immediate
,
:interval
,
:cron
@run_type
=
value
when
:cron
raise
TypeError
,
"Service#run_type does not support cron"
when
Symbol
raise
TypeError
,
"Service#run_type allows: '
#{
RUN_TYPE_IMMEDIATE
}
'/'
#{
RUN_TYPE_INTERVAL
}
'/'
#{
RUN_TYPE_CRON
}
'"
else
...
...
@@ -168,6 +166,64 @@ module Homebrew
end
end
sig
{
params
(
value:
T
.
nilable
(
String
)).
returns
(
T
.
nilable
(
Hash
))
}
def
cron
(
value
=
nil
)
case
T
.
unsafe
(
value
)
when
nil
@cron
when
String
@cron
=
parse_cron
(
T
.
must
(
value
))
else
raise
TypeError
,
"Service#cron expects a String"
end
end
sig
{
returns
(
T
::
Hash
[
Symbol
,
T
.
any
(
Integer
,
String
)])
}
def
default_cron_values
{
Month
:
"*"
,
Day
:
"*"
,
Weekday
:
"*"
,
Hour
:
"*"
,
Minute
:
"*"
,
}
end
sig
{
params
(
cron_statement:
String
).
returns
(
T
::
Hash
[
Symbol
,
T
.
any
(
Integer
,
String
)])
}
def
parse_cron
(
cron_statement
)
parsed
=
default_cron_values
case
cron_statement
when
"@hourly"
parsed
[
:Minute
]
=
0
when
"@daily"
parsed
[
:Minute
]
=
0
parsed
[
:Hour
]
=
0
when
"@weekly"
parsed
[
:Minute
]
=
0
parsed
[
:Hour
]
=
0
parsed
[
:Weekday
]
=
0
when
"@monthly"
parsed
[
:Minute
]
=
0
parsed
[
:Hour
]
=
0
parsed
[
:Day
]
=
1
when
"@yearly"
,
"@annually"
parsed
[
:Minute
]
=
0
parsed
[
:Hour
]
=
0
parsed
[
:Day
]
=
1
parsed
[
:Month
]
=
1
else
cron_parts
=
cron_statement
.
split
raise
TypeError
,
"Service#parse_cron expects a valid cron syntax"
if
cron_parts
.
length
!=
5
[
:Minute
,
:Hour
,
:Day
,
:Month
,
:Weekday
].
each_with_index
do
|
selector
,
index
|
parsed
[
selector
]
=
Integer
(
cron_parts
.
fetch
(
index
))
if
cron_parts
.
fetch
(
index
)
!=
"*"
end
end
parsed
end
sig
{
params
(
variables:
T
::
Hash
[
String
,
String
]).
returns
(
T
.
nilable
(
T
::
Hash
[
String
,
String
]))
}
def
environment_variables
(
variables
=
{})
case
T
.
unsafe
(
variables
)
...
...
@@ -246,6 +302,10 @@ module Homebrew
base
[
:StandardErrorPath
]
=
@error_log_path
if
@error_log_path
.
present?
base
[
:EnvironmentVariables
]
=
@environment_variables
unless
@environment_variables
.
empty?
if
@cron
.
present?
&&
@run_type
==
RUN_TYPE_CRON
base
[
:StartCalendarInterval
]
=
@cron
.
reject
{
|
_
,
value
|
value
==
"*"
}
end
base
.
to_plist
end
...
...
@@ -295,9 +355,15 @@ module Homebrew
instance_eval
(
&
@service_block
)
options
=
[]
options
<<
"Persistent=true
=
"
if
@run_type
==
RUN_TYPE_CRON
options
<<
"Persistent=true"
if
@run_type
==
RUN_TYPE_CRON
options
<<
"OnUnitActiveSec=
#{
@interval
}
"
if
@run_type
==
RUN_TYPE_INTERVAL
if
@run_type
==
RUN_TYPE_CRON
minutes
=
@cron
[
:Minute
]
==
"*"
?
"*"
:
format
(
"%02d"
,
@cron
[
:Minute
])
hours
=
@cron
[
:Hour
]
==
"*"
?
"*"
:
format
(
"%02d"
,
@cron
[
:Hour
])
options
<<
"OnCalendar=
#{
@cron
[
:Weekday
]
}
-*-
#{
@cron
[
:Month
]
}
-
#{
@cron
[
:Day
]
}
#{
hours
}
:
#{
minutes
}
:00"
end
timer
+
options
.
join
(
"
\n
"
)
end
end
...
...
Library/Homebrew/test/service_spec.rb
View file @
30297582
...
...
@@ -32,16 +32,20 @@ describe Homebrew::Service do
end
end
describe
"#
run
_type"
do
it
"throws for
cron
type"
do
describe
"#
process
_type"
do
it
"throws for
unexpected
type"
do
f
.
class
.
service
do
run
opt_bin
/
"beanstalkd"
run
_type
:c
ron
process
_type
:c
ow
end
expect
{
f
.
service
.
manual_command
}.
to
raise_error
TypeError
,
"Service#run_type does not support cron"
expect
{
f
.
service
.
manual_command
}.
to
raise_error
TypeError
,
"Service#process_type allows: 'background'/'standard'/'interactive'/'adaptive'"
end
end
describe
"#run_type"
do
it
"throws for unexpected type"
do
f
.
class
.
service
do
run
opt_bin
/
"beanstalkd"
...
...
@@ -206,6 +210,40 @@ describe Homebrew::Service do
EOS
expect
(
plist
).
to
eq
(
plist_expect
)
end
it
"returns valid cron plist"
do
f
.
class
.
service
do
run
opt_bin
/
"beanstalkd"
run_type
:cron
cron
"@daily"
end
plist
=
f
.
service
.
to_plist
plist_expect
=
<<~
EOS
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
\t
<key>Label</key>
\t
<string>homebrew.mxcl.formula_name</string>
\t
<key>ProgramArguments</key>
\t
<array>
\t\t
<string>
#{
HOMEBREW_PREFIX
}
/opt/formula_name/bin/beanstalkd</string>
\t
</array>
\t
<key>RunAtLoad</key>
\t
<false/>
\t
<key>StartCalendarInterval</key>
\t
<dict>
\t\t
<key>Hour</key>
\t\t
<integer>0</integer>
\t\t
<key>Minute</key>
\t\t
<integer>0</integer>
\t
</dict>
</dict>
</plist>
EOS
expect
(
plist
).
to
eq
(
plist_expect
)
end
end
describe
"#to_systemd_unit"
do
...
...
@@ -314,6 +352,53 @@ describe Homebrew::Service do
EOS
expect
(
unit
).
to
eq
(
unit_expect
)
end
it
"throws on incomplete cron"
do
f
.
class
.
service
do
run
opt_bin
/
"beanstalkd"
run_type
:cron
cron
"1 2 3 4"
end
expect
{
f
.
service
.
to_systemd_timer
}.
to
raise_error
TypeError
,
"Service#parse_cron expects a valid cron syntax"
end
it
"returns valid cron timers"
do
styles
=
{
"@hourly"
:
"*-*-*-* *:00:00"
,
"@daily"
:
"*-*-*-* 00:00:00"
,
"@weekly"
:
"0-*-*-* 00:00:00"
,
"@monthly"
:
"*-*-*-1 00:00:00"
,
"@yearly"
:
"*-*-1-1 00:00:00"
,
"@annually"
:
"*-*-1-1 00:00:00"
,
"5 5 5 5 5"
:
"5-*-5-5 05:05:00"
,
}
styles
.
each
do
|
cron
,
calendar
|
f
.
class
.
service
do
run
opt_bin
/
"beanstalkd"
run_type
:cron
cron
cron
.
to_s
end
unit
=
f
.
service
.
to_systemd_timer
unit_expect
=
<<~
EOS
[Unit]
Description=Homebrew generated timer for formula_name
[Install]
WantedBy=timers.target
[Timer]
Unit=homebrew.formula_name
Persistent=true
OnCalendar=
#{
calendar
}
EOS
expect
(
unit
).
to
eq
(
unit_expect
.
chomp
)
end
end
end
describe
"#timed?"
do
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment