diff --git a/.tool-versions b/.tool-versions index ba5d169..fd02f88 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,3 @@ elixir 1.19.0-rc.0-otp-27 erlang 27.3.4 +gleam 1.11.1 diff --git a/CLAUDE.md b/CLAUDE.md index 5e43864..8e4568e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +## Prerequisites + +Before setting up the project, ensure you have the following installed: +- Elixir 1.17+ +- Erlang/OTP +- PostgreSQL with PostGIS extension +- **Gleam** (required for Gleam modules) - Install from https://gleam.run/getting-started/installing/ + ## Project Overview This is an Elixir Phoenix LiveView application that serves as a real-time APRS (Automatic Packet Reporting System) tracker and visualizer. It connects to the APRS-IS network to receive live amateur radio packets and displays them on an interactive map interface. @@ -9,7 +17,8 @@ This is an Elixir Phoenix LiveView application that serves as a real-time APRS ( ## Development Commands ### Setup -- `mix setup` - Complete project setup (deps.get + ecto.setup) +- `mix archive.install hex mix_gleam --force` - Install mix_gleam archive (required first step) +- `mix setup` - Complete project setup (deps.get + ecto.setup + gleam compilation) - `mix deps.get` - Install dependencies - `mix ecto.setup` - Create database, run migrations, and seed data - `mix ecto.reset` - Drop and recreate database @@ -56,6 +65,7 @@ This is an Elixir Phoenix LiveView application that serves as a real-time APRS ( - Oban for background job processing - GenStage for packet processing pipelines - Tailwind CSS + ESBuild for frontend assets (no Node.js) +- Gleam for additional type-safe modules (requires mix_gleam archive) ## Test-Driven Development diff --git a/README.md b/README.md index c05bf38..5574aa1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ # Aprs +## Prerequisites + +Before setting up the project, ensure you have the following installed: +- Elixir 1.17+ +- Erlang/OTP +- PostgreSQL with PostGIS extension +- **Gleam** - Required for Gleam modules. Install from https://gleam.run/getting-started/installing/ + - If using asdf: `asdf install` (will use versions from .tool-versions) + +## Setup + To start your Phoenix server: - * Install dependencies with `mix deps.get` - * Create and migrate your database with `mix ecto.setup` + * First install the mix_gleam archive: + ```bash + mix archive.install hex mix_gleam --force + ``` + * Run the complete setup: + ```bash + mix setup + ``` * Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server` Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. diff --git a/lib/mix/tasks/setup_gleam.ex b/lib/mix/tasks/setup_gleam.ex new file mode 100644 index 0000000..7dd71a6 --- /dev/null +++ b/lib/mix/tasks/setup_gleam.ex @@ -0,0 +1,27 @@ +defmodule Mix.Tasks.SetupGleam do + use Mix.Task + + @shortdoc "Installs mix_gleam archive if not already installed" + + def run(_) do + if archive_installed?() do + Mix.shell().info("mix_gleam archive already installed") + else + Mix.shell().info("Installing mix_gleam archive...") + # Use System.cmd to avoid Mix dependency issues + {_, 0} = System.cmd("mix", ["archive.install", "hex", "mix_gleam", "--force"]) + end + end + + defp archive_installed? do + archives_path = Path.join([Mix.Utils.mix_home(), "archives"]) + + if File.exists?(archives_path) do + archives_path + |> File.ls!() + |> Enum.any?(&String.starts_with?(&1, "mix_gleam")) + else + false + end + end +end \ No newline at end of file diff --git a/mix.exs b/mix.exs index 30aabcb..dc9a44f 100644 --- a/mix.exs +++ b/mix.exs @@ -128,7 +128,7 @@ defmodule Aprsme.MixProject do # See the documentation for `Mix` for more info on aliases. defp aliases do [ - setup: ["deps.get", "ecto.setup", "gleam_compile"], + setup: ["setup_gleam", "deps.get", "ecto.setup", "gleam_compile"], compile: ["gleam_compile", "compile"], "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"],