Skip to content

Commit

Permalink
feat: add skip year option to composer (maennchen#114)
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Timmer <[email protected]>
Co-authored-by: Jonatan Männchen <[email protected]>
  • Loading branch information
3 people authored Feb 2, 2023
1 parent 7336e46 commit 708a688
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
39 changes: 31 additions & 8 deletions lib/crontab/cron_expression/composer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ defmodule Crontab.CronExpression.Composer do

alias Crontab.CronExpression

@type opts :: [
skip_year: boolean
]

@doc """
Generate from `%Crontab.CronExpression{}` to `* * * * * *`.
Available options:
- skip_year: boolean
If set to `true`, do not add the year to the expression.
This means that `%Crontab.CronExpression{}` will return `* * * * *`.
## Examples
iex> Crontab.CronExpression.Composer.compose %Crontab.CronExpression{}
Expand All @@ -19,27 +29,40 @@ defmodule Crontab.CronExpression.Composer do
iex> Crontab.CronExpression.Composer.compose %Crontab.CronExpression{reboot: true}
"@reboot"
iex> Crontab.CronExpression.Composer.compose(%Crontab.CronExpression{}, skip_year: true)
"* * * * *"
iex> Crontab.CronExpression.Composer.compose(%Crontab.CronExpression{minute: [9, {:-, 4, 6}, {:/, :*, 9}]}, skip_year: true)
"9,4-6,*/9 * * * *"
"""
@spec compose(CronExpression.t()) :: binary
def compose(%CronExpression{reboot: true}) do
@spec compose(CronExpression.t(), opts) :: binary
def compose(cron_expression, opts \\ [])

def compose(%CronExpression{reboot: true}, _) do
"@reboot"
end

def compose(cron_expression = %CronExpression{}) do
def compose(cron_expression = %CronExpression{}, opts) do
cron_expression
|> CronExpression.to_condition_list()
|> compose_interval
|> compose_interval(Map.new(opts))
|> Enum.join(" ")
end

@spec compose_interval(CronExpression.condition_list()) :: [binary]
defp compose_interval([{_, conditions} | tail]),
do: [
@spec compose_interval(CronExpression.condition_list(), map) :: [binary]
defp compose_interval([{:year, _} | tail], opts = %{skip_year: true}) do
compose_interval(tail, opts)
end

defp compose_interval([{_, conditions} | tail], opts) do
[
Enum.map_join(conditions, ",", fn condition -> compose_condition(condition) end)
| compose_interval(tail)
| compose_interval(tail, opts)
]
end

defp compose_interval([]), do: []
defp compose_interval([], _), do: []

@spec compose_condition(CronExpression.value()) :: binary
defp compose_condition(:*), do: "*"
Expand Down
15 changes: 15 additions & 0 deletions test/crontab/cron_expression/composer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,19 @@ defmodule Crontab.CronExpression.ComposerTest do
use ExUnit.Case, async: true

doctest Crontab.CronExpression.Composer

alias Crontab.CronExpression.Composer
alias Crontab.CronExpression.Parser

test "works" do
specific_cron = "*/15 9-17 5-19 2-8 SUN 2012-2015"
cron_expression = Parser.parse!(specific_cron)
assert "*/15 9-17 5-19 2-8 7 2012-2015" == Composer.compose(cron_expression)
end

test "works with skip year flag" do
specific_cron = "*/15 9-17 5-19 2-8 SUN 2012-2015"
cron_expression = Parser.parse!(specific_cron)
assert "*/15 9-17 5-19 2-8 7" == Composer.compose(cron_expression, %{skip_year: true})
end
end

0 comments on commit 708a688

Please sign in to comment.