Current section

Files

Jump to
electric mix.exs
Raw

mix.exs

defmodule Electric.MixProject do
use Mix.Project
@github_repo "https://github.com/electric-sql/electric"
# Application and Stack telemetry are enabled when Mix target is set to this value,
# e.g. via `MIX_TARGET=application` environment variable.
@telemetry_target :application
# make the metrics-enabled target available to the rest of the app
def telemetry_target, do: @telemetry_target
# Necessary boilerplate because opentelemetry doesn't mention opentelemetry_exporter in
# its list of dependency but actually expects it to be started before itself at runtime.
if Mix.target() == @telemetry_target do
@extra_telemetry_applications [:opentelemetry_exporter]
@telemetry_applications_in_release [
opentelemetry_exporter: :permanent,
opentelemetry: :temporary
]
else
@extra_telemetry_applications []
@telemetry_applications_in_release []
end
def project do
[
app: :electric,
version: version(),
elixir: "~> 1.17",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps(),
aliases: aliases(),
releases: [
electric: [
applications: @telemetry_applications_in_release,
include_executables_for: [:unix]
]
],
test_coverage: [
tool: ExCoveralls,
ignore_modules: [
Electric,
Electric.Telemetry,
Electric.Postgres.ReplicationClient.State,
~r/Electric.Postgres.LogicalReplication.Messages.*/,
~r/^Support.*/
]
],
dialyzer: [
plt_add_apps: [:mix, :ex_unit],
check_plt: true
],
description: description(),
package: package(),
docs: docs(),
source_url: "#{@github_repo}/tree/main/packages/sync-service",
homepage_url: "https://electric-sql.com"
]
end
def application do
[
extra_applications: [:logger, :runtime_tools] ++ @extra_telemetry_applications,
mod: {Electric.Application, []}
]
end
def cli do
[
preferred_envs: [
dialyzer: :test,
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.cobertura": :test,
"coveralls.lcov": :test
]
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp deps do
List.flatten([
[
{:backoff, "~> 1.1"},
{:bandit, "~> 1.6"},
{:dotenvy, "~> 1.1"},
{:ecto, "~> 3.12"},
{:esqlite, "~> 0.9.0"},
{:jason, "~> 1.4"},
{:nimble_options, "~> 1.1"},
{:nimble_pool, "~> 1.1"},
{:opentelemetry_telemetry, "~> 1.1"},
{:opentelemetry_semantic_conventions, "~> 1.27"},
{:pg_query_ex, "0.9.0"},
{:plug, "~> 1.17"},
{:postgrex, "~> 0.20"},
{:retry, "~> 0.19"},
{:remote_ip, "~> 1.2"},
{:req, "~> 0.5"},
{:stream_split, "~> 0.1"},
{:tz, "~> 0.28"}
],
dev_and_test_deps(),
telemetry_deps(Mix.target())
])
end
defp dev_and_test_deps do
[
{:dialyxir, "~> 1.4", only: [:test], runtime: false},
{:excoveralls, "~> 0.18", only: [:test], runtime: false},
{:junit_formatter, "~> 3.4", only: [:test], runtime: false},
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
{:stream_data, "~> 1.2", only: [:dev, :test]},
{:repatch, "~> 1.0", only: [:test]},
{:electric_client, path: "../elixir-client", only: [:test], runtime: false}
]
end
# Only include telemetry deps when building for the telemetry target.
# This avoids issues with hex.pm when the deps include path dependencies or overrides
# that would otherwise prevent package building.
defp telemetry_deps(@telemetry_target) do
[
{:electric_telemetry, path: "../electric-telemetry"},
{:opentelemetry, "~> 1.6"},
{:opentelemetry_exporter, "~> 1.10.0"},
# Pin protobuf to v0.13.x because starting with v0.14.0 it includes modules that conflict
# with those of Protox (which itself is brought in by pg_query_ex).
{:protobuf, "~> 0.13.0", override: true},
{:sentry, "~> 11.0"}
]
end
defp telemetry_deps(_), do: []
defp aliases do
[
start_dev: "cmd --cd dev docker compose up -d",
stop_dev: "cmd --cd dev docker compose down -v",
clean_persistent: "cmd rm -rf persistent",
reset: "do clean_persistent + stop_dev + start_dev"
]
end
defp version(default \\ "0.0.0") do
with :error <- version_from_env(),
:error <- version_from_package_json() do
default
end
end
defp version_from_env do
with {:ok, version} <- System.fetch_env("ELECTRIC_VERSION"),
trimmed = String.trim(version),
{:ok, _} <- Version.parse(trimmed) do
trimmed
end
end
defp version_from_package_json do
case File.read("./package.json") do
{:ok, binary} -> binary |> :json.decode() |> Map.fetch!("version")
{:error, _} -> :error
end
end
defp description do
"Postgres sync engine. Sync little subsets of your Postgres data into local apps and services. "
end
defp package do
[
licenses: ["Apache-2.0"],
links: %{
"Electric SQL" => "https://electric-sql.com",
"Github" => @github_repo
},
files: ~w(lib .formatter.exs mix.exs README.md CHANGELOG.md LICENSE package.json)
]
end
defp docs do
version = version("main")
tag = URI.encode("@core/sync-service@#{version}", &(&1 != ?@))
[
main: "readme",
extras: ["README.md"],
source_url_pattern: fn path, line ->
"#{@github_repo}/tree/#{tag}/packages/sync-service/#{path}#L#{line}"
end
]
end
end