Packages
ex_tempo
1.1.1
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.0
1.3.1
1.3.0
1.2.0
1.1.1
1.1.0
1.0.0
0.21.0
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.1
0.4.0
0.3.0
0.2.0
Time as an interval, not an instant — ISO 8601 / IXDTF date, time, interval, duration, recurrence, set-algebra, scheduling, and constraint-network library for Elixir. Calendar- and timezone-aware.
Current section
Files
Jump to
Current section
Files
mix.exs
defmodule Tempo.MixProject do
use Mix.Project
# OTP 26 is not supported. The tokenizer is compiled with the Erlang optimiser
# disabled (the `@compile` flags in the tokenizer modules roughly halve build
# time), and OTP 26's compiler miscompiles that unoptimised binary-matching
# path — it crashes at runtime with a bogus multi-terabyte allocation. Fail
# fast here with a clear message rather than let a consumer hit the crash.
if String.to_integer(System.otp_release()) < 27 do
Mix.raise(
"ex_tempo requires Erlang/OTP 27 or later — OTP #{System.otp_release()} detected. " <>
"See the README for details."
)
end
@version "1.1.1"
def project do
[
app: :ex_tempo,
version: @version,
name: "Tempo",
source_url: "https://github.com/elixir-tempo/tempo",
docs: docs(),
deps: deps(),
description: description(),
package: package(),
elixir: "~> 1.17",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
# Excluded from coverage:
# * `~r/Error$/` — exception structs, whose uncovered lines are
# `message/1` formatting on rare error paths, not logic.
# * the tokenizer grammar modules — their functions are NimbleParsec
# combinator builders that run at *compile* time to assemble the
# parser, so runtime line-coverage cannot see them execute.
test_coverage: [
ignore_modules: [
~r/Error$/,
Tempo.Iso8601.Tokenizer.Numbers,
Tempo.Iso8601.Tokenizer.Grammar,
Tempo.Iso8601.Tokenizer.Helpers
]
],
dialyzer: [
flags: [
:error_handling,
:unknown,
:underspecs,
:extra_return,
:missing_return
]
]
]
end
def description do
"Time as an interval, not an instant — ISO 8601 / IXDTF date, time, " <>
"interval, duration, recurrence, set-algebra, scheduling, and " <>
"constraint-network library for Elixir. Calendar- and timezone-aware."
end
def package do
[
maintainers: ["Kip Cole"],
licenses: ["Apache-2.0"],
links: links(),
files: [
"lib",
"mix.exs",
"README*",
"CHANGELOG*",
"LICENSE*",
"assets/logo.png"
]
]
end
def links do
%{
"GitHub" => "https://github.com/elixir-tempo/tempo",
"Readme" => "https://github.com/elixir-tempo/tempo/blob/v#{@version}/README.md",
"Changelog" => "https://github.com/elixir-tempo/tempo/blob/v#{@version}/CHANGELOG.md"
}
end
def docs do
[
source_ref: "v#{@version}",
main: "readme",
logo: "assets/logo.png",
# Copy the project's `assets/` directory into the generated
# docs' `assets/` subdirectory so images referenced from README
# (and guides) resolve. Without this, ``
# renders as a broken image in local `mix docs` output and on
# hexdocs.pm.
assets: %{"assets" => "assets"},
extras:
[
"README.md",
"LICENSE.md",
"CHANGELOG.md"
] ++ Path.wildcard("guides/*.md") ++ Path.wildcard("livebooks/*.livemd"),
formatters: ["html", "markdown"],
groups_for_modules: groups_for_modules(),
groups_for_extras: groups_for_extras(),
skip_undefined_reference_warnings_on:
[
"CHANGELOG.md"
] ++ Path.wildcard("guides/*.md") ++ Path.wildcard("livebooks/*.livemd")
]
end
def groups_for_modules do
[
Core: ~r/^Tempo(?:\.(Interval|IntervalSet|Duration|Set))?$/,
"Clock and current time": ~r/^Tempo\.Clock(\.|$)/,
"Set algebra and comparison": ~r/^Tempo\.(Operations|Compare|Math|Select|Territory)$/,
"Recurrence (RRULE)": ~r/^Tempo\.RRule(\.|$)/,
"iCalendar integration": ~r/^Tempo\.ICal(\.|$)/,
# `Tempo.Range` is the ISO 8601-2 set-member range element, not a
# core algebra type — see its moduledoc.
"ISO 8601 and IXDTF": ~r/^Tempo\.Iso8601(\.|$)|^Tempo\.Range$/,
Enumeration: ~r/^Tempo\.Enumeration$|^Enumerable\.Tempo/,
"Explanation and inspection":
~r/^Tempo\.(Explain|Explanation|Inspect|Format|Sigil|Validation)$/,
Exceptions: ~r/^Tempo\.\w+Error$/
]
end
defp groups_for_extras do
[
Tutorial: [
"guides/tutorial-booking-availability.md"
],
Livebooks: [
"livebooks/getting-started.livemd",
"livebooks/scheduling-workbook.livemd",
"livebooks/uncertain-dates-workbook.livemd"
],
Cookbooks: [
"guides/cookbook.md",
"guides/scheduling.md",
"guides/workdays-and-weekends.md",
"guides/holidays.md"
],
Guides: [
"guides/when-to-use-tempo.md",
"guides/ai-assistance.md",
"guides/interop.md",
"guides/set-operations.md",
"guides/uncertain-dates.md",
"guides/enumeration-semantics.md",
"guides/pattern-matching-with-sigils.md",
"guides/ical-integration.md",
"guides/chronological-networks.md",
"guides/falsehoods.md"
],
Reference: [
"guides/iso8601-conformance.md",
"guides/rfc5545_rrule_conformance.md",
"guides/shared-ast-iso8601-and-rrule.md"
],
Foundations: [
"guides/temporal-formalisms.md",
"guides/custom-calendars.md"
]
]
end
def application do
[
extra_applications: [:logger, :localize]
]
end
defp deps do
[
{:nimble_parsec, "~> 1.0"},
{:calendrical, "~> 1.0"},
{:astro, "~> 2.4"},
{:localize, "~> 1.0"},
{:ical, "~> 2.0 or ~> 3.0", optional: true},
{:ex_doc, "~> 0.38", only: [:dev, :test, :release], optional: true, runtime: false},
{:benchee, "~> 1.3", only: :dev, runtime: false},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:stream_data, "~> 1.0", only: [:dev, :test], runtime: false},
# Tempo is time zone database agnostic: it works against the
# `Calendar.TimeZoneDatabase` behaviour and consumers configure
# their own implementation (`:tz`, `:tzdata`, `:time_zone_info`,
# `:zoneinfo`) — see `Tempo.TimeZoneDatabase`. `tz` is used
# locally for dev and test.
{:tz, "~> 0.28", only: [:dev, :test]}
] ++ maybe_json_polyfill()
end
defp maybe_json_polyfill do
if Code.ensure_loaded?(:json) do
[]
else
[{:json_polyfill, "~> 0.2 or ~> 1.0"}]
end
end
defp elixirc_paths(:test), do: ["lib", "mix", "test", "test/support"]
defp elixirc_paths(:dev), do: ["lib", "mix", "bench"]
defp elixirc_paths(_), do: ["lib"]
end