Packages

Renderer-neutral documentation extraction, site projection, and publication for Elixir

Current section

Files

Jump to
doc_shell mix.exs
Raw

mix.exs

defmodule DocShell.MixProject do
  use Mix.Project

  @version "0.5.0"
  @source_url "https://github.com/futhr/doc_shell"

  def project do
    [
      app: :doc_shell,
      name: "DocShell",
      version: @version,
      elixir: "~> 1.17",
      elixirc_paths: elixirc_paths(Mix.env()),
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      aliases: aliases(),
      description: description(),
      package: package(),
      source_url: @source_url,
      homepage_url: @source_url,
      docs: docs(),
      test_coverage: test_coverage(),
      dialyzer: dialyzer()
    ]
  end

  def application do
    [extra_applications: [:crypto, :logger]]
  end

  def cli do
    [
      preferred_envs: [
        check: :dev,
        ci: :test,
        coveralls: :test,
        "coveralls.detail": :test,
        "coveralls.html": :test,
        "coveralls.json": :test,
        "test.cover": :test,
        "test.cover.html": :test,
        "test.watch": :test
      ]
    ]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp test_coverage do
    [tool: ExCoveralls]
  end

  defp dialyzer do
    [
      # Test fixtures implement the optional AshOaskit adapter and are included
      # in the test analysis even though those dependencies are runtime-false.
      plt_add_apps: [
        :ash,
        :ash_oaskit,
        :ex_unit,
        :mix,
        :open_api_spex,
        :spark,
        :splode
      ],
      plt_local_path: "priv/plts",
      plt_core_path: "priv/plts",
      flags: [:error_handling, :unknown],
      ignore_warnings: ".dialyzer_ignore.exs"
    ]
  end

  defp deps do
    optional_integrations(Mix.env()) ++
      [
        {:jason, "~> 1.4"},
        {:open_api_spex, "~> 3.22.4", only: :test, runtime: false},
        {:earmark_parser, "~> 1.4"},
        {:yaml_elixir, "~> 2.11"},
        {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
        {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
        {:doctor, "~> 0.21", only: [:dev, :test], runtime: false},
        {:doctest_formatter, "~> 0.4", only: [:dev, :test], runtime: false},
        {:ex_check, "~> 0.17", only: :dev, runtime: false},
        {:excoveralls, "~> 0.18", only: :test},
        {:mix_audit, "~> 2.1", only: [:dev, :test], runtime: false},
        {:mix_test_watch, "~> 1.2", only: [:dev, :test], runtime: false},
        {:stream_data, "~> 1.0", only: [:dev, :test]},
        {:benchee, "~> 1.3", only: :dev, runtime: false},
        {:benchee_markdown, "~> 0.3", only: :dev, runtime: false},
        {:ex_doc, "~> 0.40", only: :dev, runtime: false},
        {:git_ops, "~> 2.6", only: :dev}
      ]
  end

  # Plug needs dependency ordering for conditional web compilation. AshOaskit
  # is a development fixture: its adapter resolves the host's library at runtime.
  # The isolated compile gate removes both integrations.
  defp optional_integrations(:no_optional), do: []

  defp optional_integrations(_) do
    [
      # Exercise both supported AshOaskit minor lines without imposing its
      # dependency tree on consumers of the runtime adapter.
      {:ash_oaskit, "~> 0.3 or ~> 0.4.1", only: [:dev, :test], runtime: false},
      {:plug, "~> 1.16", optional: true}
    ]
  end

  defp aliases do
    [
      # Setup
      setup: ["deps.get", "deps.compile", "compile"],

      # Testing
      "test.watch": ["test.watch --stale"],
      "test.cover": ["coveralls"],
      "test.cover.html": ["coveralls.html"],

      # Quality
      lint: ["format --check-formatted", "credo --strict", "dialyzer"],
      ci: ["setup", "lint", "test.cover"],

      # Benchmarks
      bench: ["bench.all"],
      "bench.all": [
        "bench.ast",
        "bench.presentation",
        "bench.json",
        "bench.serving",
        "bench.collection",
        "bench.site"
      ],
      "bench.ast": ["run bench/ast.exs"],
      "bench.presentation": ["run bench/presentation.exs"],
      "bench.json": ["run bench/json.exs"],
      "bench.serving": ["run bench/serving.exs"],
      "bench.collection": ["run bench/collection.exs"],
      "bench.site": ["run bench/site.exs"],

      # Release
      release: ["git_ops.release"]
    ]
  end

  defp description do
    "Renderer-neutral documentation extraction, site projection, and publication for Elixir"
  end

  defp package do
    [
      files: ~w(
        lib
        priv/contracts
        docs/specs
        docs/plans
        notebooks
        bench/output
        .formatter.exs
        mix.exs
        README.md
        CHANGELOG.md
        LICENSE.md
        CONTRIBUTING.md
        usage-rules.md
      ),
      maintainers: ["Tobias Bohwalli <hi@futhr.io>"],
      licenses: ["MIT"],
      links: %{
        "GitHub" => @source_url,
        "Issues" => "#{@source_url}/issues",
        "Changelog" => "#{@source_url}/blob/v#{@version}/CHANGELOG.md"
      }
    ]
  end

  defp docs do
    [
      main: "readme",
      extras: [
        "README.md": [title: "Overview"],
        "docs/specs/DSH.01-documentation-sites.md": [title: "Collection and site specification"],
        "docs/plans/documentation-sites.md": [title: "Implementation status"],
        "CHANGELOG.md": [title: "Changelog"],
        "notebooks/build-pipeline.livemd": [title: "The Build Pipeline"],
        "notebooks/openapi-adapters.livemd": [title: "OpenAPI Adapters"],
        "notebooks/artifact-contract.livemd": [title: "Artifact Contract"],
        "notebooks/serving-artifacts.livemd": [title: "Serving Artifacts"],
        "notebooks/site-publication.livemd": [title: "Publish a Portable Site"],
        "bench/output/ast.md": [title: "Markdown Parsing"],
        "bench/output/presentation.md": [title: "Presentation Projection"],
        "bench/output/json.md": [title: "Term Coercion"],
        "bench/output/artifact.md": [title: "Artifact Round Trip"],
        "bench/output/collection.md": [title: "Collection Preparation and Import"],
        "bench/output/site.md": [title: "Site Projection and Export"],
        "CONTRIBUTING.md": [title: "Contributing"],
        "LICENSE.md": [title: "License"],
        "usage-rules.md": [title: "Usage Rules (LLM)"]
      ],
      groups_for_extras: [
        Tutorials: ~r/notebooks\//,
        Performance: ~r/bench\/output\//,
        Reference: ~r/CHANGELOG|CONTRIBUTING|usage-rules|LICENSE/
      ],
      groups_for_modules: [
        Core: [
          DocShell,
          DocShell.Build,
          DocShell.Config,
          DocShell.Artifact,
          DocShell.Artifact.Transaction
        ],
        Extraction: [
          DocShell.Ast,
          DocShell.Generate.ExDoc,
          DocShell.Generate.Guides,
          DocShell.Generate.Livebooks,
          DocShell.Generate.Collector,
          DocShell.Generate.Collection,
          DocShell.Generate.Cohort
        ],
        Changelog: [
          DocShell.Generate.Changelog,
          DocShell.Generate.Changelog.Source,
          DocShell.Generate.Changelog.Sources.MarkdownFile
        ],
        OpenAPI: [
          DocShell.Generate.OpenApi,
          DocShell.Generate.OpenApi.Adapter,
          DocShell.Generate.OpenApi.Adapters.AshOaskit,
          DocShell.Generate.OpenApi.Adapters.OpenApiSpex,
          DocShell.Generate.OpenApi.Adapters.RawJson
        ],
        Presentation: [
          DocShell.Presentation.Source,
          DocShell.Presentation.StaticGenerator,
          DocShell.Presentation.GraphProjector,
          DocShell.Presentation.NavigationItem,
          DocShell.Presentation.SearchEntry,
          DocShell.Presentation.Backlink
        ],
        "Site Publication": [
          DocShell.Presentation.SiteSource,
          DocShell.Presentation.SiteSource.Default,
          DocShell.Presentation.SiteProjector,
          DocShell.Presentation.Site,
          DocShell.Presentation.Page,
          DocShell.Presentation.Breadcrumb,
          DocShell.Presentation.Heading,
          DocShell.Presentation.Link,
          DocShell.Presentation.SiteSearchEntry,
          DocShell.Presentation.SearchAdapter,
          DocShell.Presentation.SearchAdapter.Output,
          DocShell.Presentation.SearchAdapter.JSON,
          DocShell.Presentation.StaticExporter,
          DocShell.Presentation.Limits
        ],
        "Renderer Contracts": [
          DocShell.Presentation.Renderer,
          DocShell.Presentation.Renderer.Capabilities,
          DocShell.Presentation.Renderer.Capability,
          DocShell.Presentation.Renderer.CapabilityRequirement,
          DocShell.Presentation.Renderer.Context,
          DocShell.Presentation.Asset,
          DocShell.Presentation.Conformance,
          DocShell.Presentation.Conformance.Surface
        ],
        "Web Serving": [
          DocShell.Web.Cache,
          DocShell.Web.Plug,
          DocShell.Web.Controller,
          DocShell.Web.Response
        ],
        Support: [
          DocShell.Json
        ]
      ],
      source_ref: "v#{@version}",
      source_url: @source_url,

      # ex_doc's defaults, named so a future edit has to be deliberate:
      # dropping "markdown" also drops llms.txt and the per-module .md files
      formatters: ["html", "markdown", "epub"]
    ]
  end
end