Packages

Zero-dependency bootstrap archive for SvEx projects.

Current section

Files

Jump to
sv_ex_new mix.exs
Raw

mix.exs

defmodule SvExNew.MixProject do
use Mix.Project
# `.version` is the single source of truth, spelled the way the parent repo
# spells its own. This archive's version is INDEPENDENT of sv_ex's: the two
# ship as separate packages on separate cadences, and the root
# `scripts/bump_version.exs` bumps THIS file only for commits that touch a path
# under `installer/sv_ex_new/`. A commit confined to the hex package leaves it
# alone, so the two numbers accumulate at their own rates and are meant to.
#
# Resolved against __DIR__, never a bare ".version". A relative read resolves
# against the CURRENT WORKING DIRECTORY, which is this project's root only by
# convention — it is not when the root suite shells in from one directory up,
# which is exactly how this project is built and tested.
@version_path Path.join(__DIR__, ".version")
@external_resource @version_path
@version @version_path |> File.read!() |> String.trim()
# Hex REFUSES to build without `links` -- "Missing metadata fields: links" --
# so this is not optional metadata.
#
# It points at the PARENT repository, not at an `sv_ex_new` repository of its
# own: this directory is a nested build target inside sv_ex, not a separate
# checkout. Two hex packages, one repository -- README.md, "One project, two
# outputs": "no second product, no second repository and no second roadmap".
# The project this was ported from split the two across repositories and had
# to gitignore one inside the other; that is the arrangement being dropped,
# not copied.
@source_url "https://github.com/wimwian-org/sv_ex"
@description "Zero-dependency bootstrap archive for SvEx projects."
def project do
[
app: :sv_ex_new,
version: @version,
elixir: "~> 1.20",
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
description: @description,
package: package(),
test_coverage: [tool: ExCoveralls],
dialyzer: [plt_add_apps: [:mix]],
docs: [main: "readme", extras: ["README.md"]]
]
end
def cli do
[preferred_envs: [coveralls: :test, "coveralls.json": :test]]
end
# Deliberately empty, so the shipped .app declares exactly
# [:kernel, :stdlib, :elixir] — the archive's zero-dependency claim, asserted
# by the root suite's archive_test.exs.
#
# `extra_applications: [:eex]` would be the intuitive addition, because the
# generators this task delegates to (`mix new`, `mix phx.new`) render their
# templates through EEx. It is not needed and is not harmless: it appends
# :eex to `applications` and breaks that assertion. `extra_applications`
# governs release inclusion and application start order, NOT code-path
# availability — :eex ships with Elixir and its ebin is already on the path
# for any in-process `Mix.Task.run/2`.
def application, do: []
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# `files` is spelled out only because `.version` is not one of hex's defaults,
# and mix.exs reads it at build time — a package without it builds here and
# fails to compile for the consumer. Everything else in the list is what the
# default would have included anyway.
#
defp package do
[
description: @description,
licenses: ["MIT"],
links: %{"GitHub" => @source_url},
files: ~w(.version lib mix.exs README.md .formatter.exs)
]
end
# RULE: every dep MUST carry an `only:` that EXCLUDES :prod.
#
# `runtime: false` is NOT the discriminator — {:jason, "~> 1.4",
# runtime: false} with no `only:` still emits a full entry in the package's
# `requirements`, and this archive's whole point is having none.
#
# A dep with `only: [:dev, :test]` and the default `runtime: true` also leaks
# into the shipped .app's `applications` list while shipping zero BEAMs —
# which is why the tooling deps below carry `runtime: false` as well.
defp deps do
[
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
{:doctor, "~> 0.21", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.34", only: :dev, runtime: false},
{:excoveralls, "~> 0.18", only: :test, runtime: false},
{:ex_machina, "~> 2.8", only: :test, runtime: false},
{:faker, "~> 0.18", only: :test, runtime: false}
]
end
end