Build-time generation of the compiled holiday data.
Downloads a pinned date-holidays
bundle and compiles every territory to one nested priv/holidays/<CC>.etf —
the country's holidays plus each state's and region's own holidays and the
rule keys they override, which Tempo.Holidays.Data merges at load time (so
the country's holidays are not duplicated into every state). The version is
pinned exactly (not a range), so a build is reproducible: the same input
yields the same output, and the data need not be vendored in git.
ensure_built/0 runs from the :holidays Mix compiler and is a no-op once
the current pinned data is in place, in the current data format — so warm
builds, and every consumer build (where the etf ships in the package), do no
network I/O, while a change to the serialised structs regenerates it.
build/1 forces a fresh download and is what mix tempo.holidays.update runs.
Each rule is read with Tempo.DateRule as it is built, to leave out one it
does not read, and reading a rule can work out a date: an equinox needs
Astro's ephemeris, and a date of another calendar needs Calendrical. So
build/1 starts Tempo's applications (:ex_tempo, which starts Astro
before Calendrical) before it reads, as the :holidays compiler runs
before anything is started.
This module is Mix-only: it runs at the maintainer's build time, never at a consumer's runtime.
Summary
Types
Why the data could not be built: a version that is not three numbers, a directory that could not be made, a bundle that could not be downloaded, or an application that could not be started.
Functions
Downloads a date-holidays release's bundle of holiday data and writes every territory's data from it, whatever is already on disk.
The directory the package's own data is written to: its priv/holidays.
Builds the package's own data unless it is already built from the pinned
release, as the :holidays compiler asks at each compilation.
Compile one territory's holidays from an already-decoded bundle.
An error build/1 returns, in words.
The date-holidays release the package's own data is built from.
The URL of the bundle of holiday data of the pinned date-holidays release.
The URL of the bundle of holiday data of a date-holidays release.
Types
@type error() :: {:invalid_version, term()} | {:directory, Path.t(), File.posix()} | {:download_failed, String.t(), term()} | {atom(), term()}
Why the data could not be built: a version that is not three numbers, a directory that could not be made, a bundle that could not be downloaded, or an application that could not be started.
Functions
@spec build(keyword()) :: {:ok, non_neg_integer(), [String.t()]} | {:error, error()}
Downloads a date-holidays release's bundle of holiday data and writes every territory's data from it, whatever is already on disk.
Arguments
optionsis a keyword list of options.
Options
:versionis the date-holidays release, three numbers such as"3.38.0". The default ispinned_version/0.:directoryis where the data is written. The default isdefault_directory/0.:languageis the ISO 639-1 code of the holidays' names. The default is"en".
Returns
{:ok, territory_count, unsupported}, whereunsupportedlists the rules of the releaseTempo.DateRuledoes not read, whose holidays are left out of the data, or{:error, reason}:{:invalid_version, version},{:directory, directory, posix},{:download_failed, url, reason}, or an application that cannot be started.message/1says each in words.
@spec default_directory() :: String.t()
The directory the package's own data is written to: its priv/holidays.
Returns
- The directory, a path.
Examples
iex> Path.basename(Tempo.Holidays.Build.default_directory())
"holidays"
@spec ensure_built() :: :noop | :ok | {:error, error()}
Builds the package's own data unless it is already built from the pinned
release, as the :holidays compiler asks at each compilation.
Returns
:noopwhere the data is in place: on a warm build, and on every build of an application where the data ships in the package, so neither touches the network, or:okwhere it was built, or{:error, reason}asbuild/1returns it.
@spec holidays_from_bundle(map(), String.t(), String.t()) :: [ Tempo.Holidays.Holiday.t() ]
Compile one territory's holidays from an already-decoded bundle.
Pure — no network or filesystem — so the compile step is testable on its
own. Returns [] for a territory the bundle does not carry.
Arguments
bundleis the decodedholidays.jsonmap.codeis the territory's CLDR/IANA code as a string, such as"US".languageis the ISO 639-1 code for name selection.
Returns
- A list of
Tempo.Holidays.Holiday.t/0.
An error build/1 returns, in words.
Arguments
reasonis the reason of an{:error, reason}frombuild/1orensure_built/0.
Returns
- The message, a string.
Examples
iex> Tempo.Holidays.Build.message({:directory, "/x", :enotdir})
"could not make /x: not a directory"
@spec pinned_version() :: String.t()
The date-holidays release the package's own data is built from.
Returns
- The release, a version string.
Examples
iex> Tempo.Holidays.Build.pinned_version()
"3.38.0"
@spec source_url() :: String.t()
The URL of the bundle of holiday data of the pinned date-holidays release.
Returns
- The URL, a string.
Examples
iex> Tempo.Holidays.Build.source_url()
"https://cdn.jsdelivr.net/npm/date-holidays@3.38.0/data/holidays.json"
The URL of the bundle of holiday data of a date-holidays release.
Arguments
versionis a date-holidays release, such as"3.37.0".
Returns
- The URL, a string.
Examples
iex> Tempo.Holidays.Build.source_url("3.37.0")
"https://cdn.jsdelivr.net/npm/date-holidays@3.37.0/data/holidays.json"