From 3b3948bc9001ac8029cf26734e6722e15ab197f4 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sat, 9 Aug 2025 17:22:32 -0400 Subject: [PATCH 01/19] chore: bump burrito Bumping burrito to v1.4 supports a new URL scheme for the beam machine, which is the CDN that burrito pulls OTP builds from from darwin and linux --- .github/workflows/elixir.yml | 12 ++--- .github/workflows/release.yml | 6 +-- apps/expert/mix.exs | 2 +- apps/expert/mix.lock | 4 +- flake.lock | 86 ++++++++++++++++++----------------- flake.nix | 35 +++++++------- 6 files changed, 73 insertions(+), 72 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index de1ad022..bd438b6c 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -150,8 +150,8 @@ jobs: target: darwin_amd64 include: - - elixir: "1.15.8" - otp: "27" + - elixir: "1.17.3" + otp: "27.3.4.1" steps: - name: Checkout code @@ -165,8 +165,9 @@ jobs: - uses: mlugg/setup-zig@v2 with: - version: "0.14.0" + version: "0.14.1" + - uses: extractions/setup-just@v3 - name: Cache deps id: cache-deps uses: actions/cache@v4 @@ -180,10 +181,7 @@ jobs: ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}- - name: Build and release - env: - MIX_ENV: prod - BURRITO_TARGET: ${{ matrix.os.target }} - run: make build.engine && cd apps/expert && mix deps.get && mix release expert + run: just release-local test: runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4656f72..50d864fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,12 +40,12 @@ jobs: - uses: extractions/setup-just@v3 - uses: erlef/setup-beam@v1 with: - otp-version: "27.0" - elixir-version: "1.15.8-otp-25" + otp-version: "27.3.4.1" + elixir-version: "1.17.3" version-type: strict - uses: mlugg/setup-zig@v2 with: - version: "0.14.0" + version: "0.14.1" - uses: actions/checkout@v4 - run: just release-all env: diff --git a/apps/expert/mix.exs b/apps/expert/mix.exs index f0aaf49d..69c0de51 100644 --- a/apps/expert/mix.exs +++ b/apps/expert/mix.exs @@ -77,7 +77,7 @@ defmodule Expert.MixProject do defp deps do [ - {:burrito, "~> 1.3", only: [:dev, :prod]}, + {:burrito, "~> 1.4", only: [:dev, :prod]}, Mix.Credo.dependency(), Mix.Dialyzer.dependency(), # In practice Expert does not hardly depend on Engine, only on its compiled diff --git a/apps/expert/mix.lock b/apps/expert/mix.lock index 86a4ecea..869dbb95 100644 --- a/apps/expert/mix.lock +++ b/apps/expert/mix.lock @@ -1,7 +1,7 @@ %{ "benchee": {:hex, :benchee, "1.3.1", "c786e6a76321121a44229dde3988fc772bca73ea75170a73fd5f4ddf1af95ccf", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "76224c58ea1d0391c8309a8ecbfe27d71062878f59bd41a390266bf4ac1cc56d"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "burrito": {:hex, :burrito, "1.3.0", "4be8504185250756ff4a8770d0c0d91dbfe518d2faa5f1888f13b00540028c59", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:req, ">= 0.5.0", [hex: :req, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.2.0 or ~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "a53f6bc0644bfd998164d68714c9af04291c220f5f7d0c90cb9616780cc60165"}, + "burrito": {:hex, :burrito, "1.4.0", "f94fa1c3f174575bc4cad887a2940fd77469e1985c3a6633fcdcfa72f915caf2", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:req, ">= 0.5.0", [hex: :req, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.2.0 or ~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "0fa052e6f446cd3e5ff7e00813452b09eeadeddb5ec5174c2976eb0e4ad88765"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, @@ -23,7 +23,7 @@ "path_glob": {:hex, :path_glob, "0.2.0", "b9e34b5045cac5ecb76ef1aa55281a52bf603bf7009002085de40958064ca312", [:mix], [{:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "be2594cb4553169a1a189f95193d910115f64f15f0d689454bb4e8cfae2e7ebc"}, "recon": {:hex, :recon, "2.5.6", "9052588e83bfedfd9b72e1034532aee2a5369d9d9343b61aeb7fbce761010741", [:mix, :rebar3], [], "hexpm", "96c6799792d735cc0f0fd0f86267e9d351e63339cbe03df9d162010cefc26bb0"}, "refactorex": {:hex, :refactorex, "0.1.52", "22a69062c84e0f20a752d3d6580269c09c242645ee4f722f03d4270dd8cbf218", [:mix], [{:sourceror, "~> 1.7", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "4927fe6c3acd1f4695d6d3e443380167d61d004d507b1279c6084433900c94d0"}, - "req": {:hex, :req, "0.5.14", "521b449fa0bf275e6d034c05f29bec21789a0d6cd6f7a1c326c7bee642bf6e07", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b7b15692071d556c73432c7797aa7e96b51d1a2db76f746b976edef95c930021"}, + "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "schematic": {:hex, :schematic, "0.2.1", "0b091df94146fd15a0a343d1bd179a6c5a58562527746dadd09477311698dbb1", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0b255d65921e38006138201cd4263fd8bb807d9dfc511074615cd264a571b3b1"}, "snowflake": {:hex, :snowflake, "1.0.4", "8433b4e04fbed19272c55e1b7de0f7a1ee1230b3ae31a813b616fd6ef279e87a", [:mix], [], "hexpm", "badb07ebb089a5cff737738297513db3962760b10fe2b158ae3bebf0b4d5be13"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, diff --git a/flake.lock b/flake.lock index 66aafe4f..08730fa5 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,26 @@ { "nodes": { + "beam-flakes": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1754773944, + "narHash": "sha256-N7OHT0uUblt9XXqRXS18u74/AIo+dpXIRe7Y4Wr/7J8=", + "owner": "elixir-tools", + "repo": "nix-beam-flakes", + "rev": "ac950a8ca59a5f4c32fc0669637672f1e63573ec", + "type": "github" + }, + "original": { + "owner": "elixir-tools", + "repo": "nix-beam-flakes", + "type": "github" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -20,16 +41,18 @@ }, "nixpkgs": { "locked": { - "lastModified": 1749903597, - "narHash": "sha256-jp0D4vzBcRKwNZwfY4BcWHemLGUs4JrS3X9w5k/JYDA=", + "lastModified": 1748344075, + "narHash": "sha256-PsZAY3H0e/PBoDVn4fLwGEmeSwESj7SZPZ6CMfgbWFU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "41da1e3ea8e23e094e5e3eeb1e6b830468a7399e", + "rev": "e0042dedfbc9134ef973f64e5c7f56a38cc5cc97", "type": "github" }, "original": { - "id": "nixpkgs", - "type": "indirect" + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" } }, "nixpkgs-lib": { @@ -44,13 +67,26 @@ "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1749903597, + "narHash": "sha256-jp0D4vzBcRKwNZwfY4BcWHemLGUs4JrS3X9w5k/JYDA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "41da1e3ea8e23e094e5e3eeb1e6b830468a7399e", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, "root": { "inputs": { + "beam-flakes": "beam-flakes", "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs", - "systems": "systems", - "xzpkgs": "xzpkgs", - "zigpkgs": "zigpkgs" + "nixpkgs": "nixpkgs_2", + "systems": "systems" } }, "systems": { @@ -67,38 +103,6 @@ "repo": "default", "type": "github" } - }, - "xzpkgs": { - "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - } - }, - "zigpkgs": { - "locked": { - "lastModified": 1747426788, - "narHash": "sha256-N4cp0asTsJCnRMFZ/k19V9akkxb7J/opG+K+jU57JGc=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "12a55407652e04dcf2309436eb06fef0d3713ef3", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "rev": "12a55407652e04dcf2309436eb06fef0d3713ef3", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 4d36b230..076c1124 100644 --- a/flake.nix +++ b/flake.nix @@ -2,19 +2,20 @@ description = "Reimagined language server for Elixir"; inputs.nixpkgs.url = "flake:nixpkgs"; - inputs.zigpkgs.url = "github:nixos/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3"; - inputs.xzpkgs.url = "github:nixos/nixpkgs/18dd725c29603f582cf1900e0d25f9f1063dbf11"; + inputs.beam-flakes.url = "github:elixir-tools/nix-beam-flakes"; + inputs.beam-flakes.inputs.flake-parts.follows = "flake-parts"; + inputs.flake-parts.url = "github:hercules-ci/flake-parts"; inputs.systems.url = "github:nix-systems/default"; outputs = { self, systems, - zigpkgs, - xzpkgs, + beam-flakes, ... } @ inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} { + imports = [beam-flakes.flakeModule]; flake = { lib = { mkExpert = {erlang}: erlang.callPackage ./nix/expert.nix {}; @@ -23,14 +24,8 @@ systems = import systems; - perSystem = { - pkgs, - system, - ... - }: let + perSystem = {pkgs, ...}: let erlang = pkgs.beam.packages.erlang_25; - zpkgs = zigpkgs.legacyPackages.${system}; - xzpkgs' = xzpkgs.legacyPackages.${system}; expert = self.lib.mkExpert {inherit erlang;}; in { formatter = pkgs.alejandra; @@ -59,13 +54,17 @@ outputHash = pkgs.lib.fakeSha256; }); }; - - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - beam.packages.erlang_27.erlang - beam.packages.erlang_27.elixir_1_17 - zpkgs.zig_0_14 - xzpkgs'.xz + beamWorkspace = { + enable = true; + devShell.languageServers.elixir = false; + devShell.languageServers.erlang = false; + versions = { + elixir = "1.17.3"; + erlang = "27.3.4.1"; + }; + devShell.extraPackages = with pkgs; [ + zig + xz just _7zz ]; From e6ec2f392ac4150ee902efdb0d0ca996fa189e9b Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 10 Aug 2025 08:27:41 -0400 Subject: [PATCH 02/19] fixup! chore: bump burrito --- apps/forge/lib/forge/build.ex | 22 ---------------------- justfile | 15 ++++++++++++--- 2 files changed, 12 insertions(+), 25 deletions(-) delete mode 100644 apps/forge/lib/forge/build.ex diff --git a/apps/forge/lib/forge/build.ex b/apps/forge/lib/forge/build.ex deleted file mode 100644 index 34727750..00000000 --- a/apps/forge/lib/forge/build.ex +++ /dev/null @@ -1,22 +0,0 @@ -defmodule Mix.Tasks.Build do - use Mix.Task - - def run(_args) do - Mix.Task.run("compile", []) - - namespaced_dir = "_build/#{Mix.env()}_ns" - - # Remove the existing namespaced dir - File.rm_rf(namespaced_dir) - # Create our namespaced area - File.mkdir_p(namespaced_dir) - - # Move our build artifacts from safekeeping to the build area - File.cp_r!("_build/#{Mix.env()}", namespaced_dir) - - # Namespace the new code - Mix.Task.run(:namespace, [ - namespaced_dir - ]) - end -end diff --git a/justfile b/justfile index 2b8c48b7..94c8ca29 100644 --- a/justfile +++ b/justfile @@ -39,6 +39,7 @@ test project="all" *args="": [doc('Run a mix command in one or all projects. Use `just test` to run tests.')] mix cmd *project: #!/usr/bin/env bash + set -euxo pipefail if [ -n "{{ project }}" ]; then cd apps/{{ project }} @@ -63,10 +64,18 @@ lint *project: just mix dialyzer {{ project }} build-engine: - #!/usr/bin/env bash + #!/usr/bin/env bash + set -euxo pipefail + + cd apps/engine + MIX_ENV=dev mix compile + namespaced_dir=_build/dev_ns + rm -rf $namespaced_dir + mkdir -p $namespaced_dir + + cp -r _build/dev "$namespaced_dir" - cd apps/engine - mix build + MIX_ENV=dev mix namespace "$namespaced_dir" [doc('Build a release for the local system')] From 2e594ec9ce6592919b48e026473c423d6e422623 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 21:35:06 -0400 Subject: [PATCH 03/19] fixup! chore: bump burrito --- .github/workflows/{elixir.yml => ci.yml} | 137 +++++++++++------------ apps/forge/lib/forge/log_filter.ex | 11 +- apps/forge/mix.exs | 1 + justfile | 40 +++---- 4 files changed, 87 insertions(+), 102 deletions(-) rename .github/workflows/{elixir.yml => ci.yml} (57%) diff --git a/.github/workflows/elixir.yml b/.github/workflows/ci.yml similarity index 57% rename from .github/workflows/elixir.yml rename to .github/workflows/ci.yml index bd438b6c..ea078ad1 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/ci.yml @@ -1,23 +1,11 @@ name: Elixir CI -# Define workflow that runs when changes are pushed to the -# `main` branch or pushed to a PR branch that targets the `main` -# branch. Change the branch name if your project uses a -# different name for the main branch like "master" or "production". on: - push: - branches: ["main", "releases/**", "feat/**", "fix/**"] # adapt branch for project pull_request: - branches: ["main"] # adapt branch for project + push: + branches: main -# Sets the ENV `MIX_ENV` to `test` for running tests env: - MIX_ENV: test - # Default elixir and otp are the ones that we validate - # against. Formatting and types can change from version to version, - # so keeping credo, dialyzer and formatting checks in the matrix - # would create an impossible situation, as different versions would have - # different rules DEFAULT_ELIXIR: 1.15.8-otp-25 DEFAULT_OTP: 25.3.2.4 @@ -25,13 +13,21 @@ permissions: contents: read jobs: - static_analysis: + static-analysis: runs-on: ubuntu-latest name: Static analysis + + strategy: + matrix: + project: + - engine + - expert + - expert_credo + - forge steps: # Step: Setup Elixir + Erlang image as the base - - name: Set up Elixir - uses: erlef/setup-beam@v1 + - uses: extractions/setup-just@v3 + - uses: erlef/setup-beam@v1 with: otp-version: ${{ env.DEFAULT_OTP }} elixir-version: ${{ env.DEFAULT_ELIXIR }} @@ -47,41 +43,36 @@ jobs: uses: actions/cache@v4 with: path: | - apps/**/deps - apps/**/_build + apps/${{ matrix.project }}/deps + apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/**/mix.lock') }} + key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} restore-keys: | ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- - # Step: Download project dependencies. If unchanged, uses - # the cached version. - - name: Install and compile dependencies - run: | - make deps.poncho - make deps.compile.poncho + - name: Deps + run: just deps ${{ matrix.project }} - - name: Compile and don't let warnings through - run: make compile.poncho + - name: Compile + run: just compile ${{ matrix.project }} --warnings-as-errors - # Step: Check that the checked in code has already been formatted. - # This step fails if something was found unformatted. - # Customize this step as desired. - - name: Check Formatting - run: MIX_ENV=dev mix format --check-formatted + - name: Formatter + run: just mix ${{ matrix.project }} format --check-formatted - # Step: Run credo static code analysis - - name: Credo static analysis - run: make credo.check.poncho + - name: Credo + run: just mix ${{ matrix.project }} credo dialyzer: runs-on: ubuntu-latest - name: Run Dialyzer - env: - apps_mix_lock: ${{ format('{0}{1}', github.workspace, 'apps/**/mix.lock') }} - MIX_ENV: dev + name: Dialyzer + strategy: + matrix: + project: + - engine + - expert + - expert_credo + - forge steps: - # Step: Setup Elixir + Erlang image as the base. - name: Set up Elixir uses: erlef/setup-beam@v1 with: @@ -97,14 +88,12 @@ jobs: - name: Cache deps id: cache-deps uses: actions/cache@v4 - env: - cache-name: cache-elixir-deps-1 with: path: | - apps/**/deps - apps/**/_build + apps/${{ matrix.project }}/deps + apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/**/mix.lock') }} + key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{ matrix.project }}/mix.lock') }} restore-keys: | ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- @@ -113,28 +102,28 @@ jobs: id: cache-plt uses: actions/cache@v4 with: - path: "priv/plts" - key: expert-plts-2-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}-${{ hashFiles('apps/**/mix.lock' ) }}-${{ github.run_id }} + key: expert-plts-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}-${{ hashFiles('apps/${{ matrix.project }}/mix.lock' ) }} restore-keys: | - expert-plts-2-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}-${{ hashFiles('apps/**/mix.lock') }}- - expert-plts-2-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}- + expert-plts-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}-${{ hashFiles('apps/${{ matrix.project }}/mix.lock') }}- + expert-plts-${{ env.DEFAULT_OTP }}-${{ env.DEFAULT_ELIXIR }}- + path: "priv/plts" - - name: Install and compile dependencies - run: make deps.compile.poncho + - name: Deps + run: just deps ${{ matrix.project }} - name: Compile - run: make compile.all + run: just compile ${{ matrix.project }} --warnings-as-errors - - name: Maybe create plt files + - name: Create PLT if: steps.cache-plt.outputs.cache-hit != 'true' run: | mkdir -p priv/plts - make dialyzer.plt.all + just mix ${{ matrix.project }} dialyzer --plt - - name: Run dialyzer + - name: Dialyzer run: | - make compile.protocols.poncho - make dialyzer.all + just mix ${{ matrix.project }} compile.protocols --warnings-as-errors + just mix ${{ matrix.project }} dialyzer release-test: runs-on: ${{matrix.os.name}} @@ -157,6 +146,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - uses: extractions/setup-just@v3 - name: Set up Elixir uses: erlef/setup-beam@v1 with: @@ -167,7 +157,6 @@ jobs: with: version: "0.14.1" - - uses: extractions/setup-just@v3 - name: Cache deps id: cache-deps uses: actions/cache@v4 @@ -209,36 +198,40 @@ jobs: otp: "26" - elixir: "1.15.8" otp: "25" + + project: + - engine + - expert + - expert_credo + - forge steps: - # Step: Check out the code. - name: Checkout code uses: actions/checkout@v4 - # Step: Setup Elixir + Erlang image as the base. + - uses: extractions/setup-just@v3 - name: Set up Elixir uses: erlef/setup-beam@v1 with: otp-version: ${{matrix.otp}} elixir-version: ${{matrix.elixir}} - # Step: Define how to cache deps. Restores existing cache if present. - name: Cache deps id: cache-deps uses: actions/cache@v4 with: path: | - apps/**/deps - apps/**/_build + apps/${{ matrix.project }}/deps + apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('apps/**/mix.lock') }} + key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} restore-keys: | - ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}- + ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- + + - name: Deps + run: just deps ${{ matrix.project }} - # Step: Download project dependencies. If unchanged, uses - # the cached version. - - name: Install and compile the app - run: make compile.poncho + - name: Compile + run: just compile ${{ matrix.project }} --warnings-as-errors - # Step: Execute the tests. - name: Run tests - run: make test.all + run: just test ${{ matrix.project }} --warnings-as-errors diff --git a/apps/forge/lib/forge/log_filter.ex b/apps/forge/lib/forge/log_filter.ex index 1ad75b57..6efb9ef4 100644 --- a/apps/forge/lib/forge/log_filter.ex +++ b/apps/forge/lib/forge/log_filter.ex @@ -1,5 +1,5 @@ defmodule Forge.LogFilter do - def hook_into_logger() do + def hook_into_logger do :logger.add_primary_filter(:ignore_module_warnings, {&reject_module_warnings/2, []}) end @@ -14,9 +14,14 @@ defmodule Forge.LogFilter do |> action() %{msg: {format_string, format_data}} -> - format_string - |> :io.format(format_data) + {:ok, pid} = StringIO.open("log") + + :io.format(pid, format_string, format_data) + + pid + |> StringIO.flush() |> ensure_binary() + |> tap(fn _ -> StringIO.close(pid) end) |> action() _ -> diff --git a/apps/forge/mix.exs b/apps/forge/mix.exs index d6dc3c8f..89e901bd 100644 --- a/apps/forge/mix.exs +++ b/apps/forge/mix.exs @@ -38,6 +38,7 @@ defmodule Forge.MixProject do {:benchee, "~> 1.3", only: :test}, Mix.Credo.dependency(), Mix.Dialyzer.dependency(), + {:gen_lsp, "~> 0.11"}, {:snowflake, "~> 1.0"}, {:sourceror, "~> 1.9"}, {:stream_data, "~> 1.1", only: [:test], runtime: false}, diff --git a/justfile b/justfile index 94c8ca29..515a9b51 100644 --- a/justfile +++ b/justfile @@ -17,51 +17,37 @@ run project +ARGS: eval "{{ ARGS }}" [doc('Compile the given project.')] -compile project: (deps project) - cd apps/{{ project }} && mix compile +compile project *args="": (deps project) + cd apps/{{ project }} && mix compile {{ args }} [doc('Run tests in the given project')] test project="all" *args="": + @just mix {{ project }} test {{args}} + +[doc('Run a mix command in one or all projects. Use `just test` to run tests.')] +mix project="all" *args="": #!/usr/bin/env bash - set -euo pipefail + set -euxo pipefail case {{ project }} in all) for proj in {{ apps }}; do - (cd "apps/$proj" && mix test {{args}}) + (cd "apps/$proj" && mix {{args}}) done ;; *) - (cd "apps/{{ project }}" && mix test {{args}}) + (cd "apps/{{ project }}" && mix {{args}}) ;; esac -[doc('Run a mix command in one or all projects. Use `just test` to run tests.')] -mix cmd *project: - #!/usr/bin/env bash - set -euxo pipefail - - if [ -n "{{ project }}" ]; then - cd apps/{{ project }} - mix {{ cmd }} - else - for project in {{ apps }}; do - ( - cd apps/"$project" - - mix {{ cmd }} - ) - done - fi - [doc('Lint all projects or just a single project')] -lint *project: +lint *project="all": #!/usr/bin/env bash set -euxo pipefail - just mix "format --check-formatted" {{ project }} - just mix credo {{ project }} - just mix dialyzer {{ project }} + just mix {{ project }} format --check-formatted + just mix {{ project }} credo + just mix {{ project }} dialyzer build-engine: #!/usr/bin/env bash From 59be68b977325d30e7c00647c2ab0c8e66431d8c Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 21:41:33 -0400 Subject: [PATCH 04/19] fixup! chore: bump burrito --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea078ad1..7a662ad6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,6 +73,7 @@ jobs: - expert_credo - forge steps: + - uses: extractions/setup-just@v3 - name: Set up Elixir uses: erlef/setup-beam@v1 with: From a059b0a108f7316009052f94d58118c7ebdcd70f Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 21:43:44 -0400 Subject: [PATCH 05/19] fixup! chore: bump burrito --- .github/workflows/ci.yml | 3 --- apps/expert/mix.lock | 6 ------ apps/expert_credo/mix.lock | 4 ---- 3 files changed, 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a662ad6..96e32400 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -231,8 +231,5 @@ jobs: - name: Deps run: just deps ${{ matrix.project }} - - name: Compile - run: just compile ${{ matrix.project }} --warnings-as-errors - - name: Run tests run: just test ${{ matrix.project }} --warnings-as-errors diff --git a/apps/expert/mix.lock b/apps/expert/mix.lock index 869dbb95..714cc893 100644 --- a/apps/expert/mix.lock +++ b/apps/expert/mix.lock @@ -1,9 +1,7 @@ %{ - "benchee": {:hex, :benchee, "1.3.1", "c786e6a76321121a44229dde3988fc772bca73ea75170a73fd5f4ddf1af95ccf", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "76224c58ea1d0391c8309a8ecbfe27d71062878f59bd41a390266bf4ac1cc56d"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "burrito": {:hex, :burrito, "1.4.0", "f94fa1c3f174575bc4cad887a2940fd77469e1985c3a6633fcdcfa72f915caf2", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:req, ">= 0.5.0", [hex: :req, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.2.0 or ~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "0fa052e6f446cd3e5ff7e00813452b09eeadeddb5ec5174c2976eb0e4ad88765"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "e3ddc403554050221a2fd19a10a896fa7525bc02", [ref: "e3ddc403554050221a2fd19a10a896fa7525bc02"]}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, @@ -18,17 +16,13 @@ "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, - "observer_cli": {:hex, :observer_cli, "1.8.3", "866ee083eb3482d5f40d301c2ac7e1df0b6061d02ae771e164d71931d3c687c4", [:mix, :rebar3], [{:recon, "~> 2.5.6", [hex: :recon, repo: "hexpm", optional: false]}], "hexpm", "041c638d54cc8265e6e0472aec7c17a83bb2c4a02628ddedd9138747d9d0b8bf"}, "patch": {:hex, :patch, "0.15.0", "947dd6a8b24a2d2d1137721f20bb96a8feb4f83248e7b4ad88b4871d52807af5", [:mix], [], "hexpm", "e8dadf9b57b30e92f6b2b1ce2f7f57700d14c66d4ed56ee27777eb73fb77e58d"}, "path_glob": {:hex, :path_glob, "0.2.0", "b9e34b5045cac5ecb76ef1aa55281a52bf603bf7009002085de40958064ca312", [:mix], [{:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "be2594cb4553169a1a189f95193d910115f64f15f0d689454bb4e8cfae2e7ebc"}, - "recon": {:hex, :recon, "2.5.6", "9052588e83bfedfd9b72e1034532aee2a5369d9d9343b61aeb7fbce761010741", [:mix, :rebar3], [], "hexpm", "96c6799792d735cc0f0fd0f86267e9d351e63339cbe03df9d162010cefc26bb0"}, "refactorex": {:hex, :refactorex, "0.1.52", "22a69062c84e0f20a752d3d6580269c09c242645ee4f722f03d4270dd8cbf218", [:mix], [{:sourceror, "~> 1.7", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "4927fe6c3acd1f4695d6d3e443380167d61d004d507b1279c6084433900c94d0"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "schematic": {:hex, :schematic, "0.2.1", "0b091df94146fd15a0a343d1bd179a6c5a58562527746dadd09477311698dbb1", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0b255d65921e38006138201cd4263fd8bb807d9dfc511074615cd264a571b3b1"}, "snowflake": {:hex, :snowflake, "1.0.4", "8433b4e04fbed19272c55e1b7de0f7a1ee1230b3ae31a813b616fd6ef279e87a", [:mix], [], "hexpm", "badb07ebb089a5cff737738297513db3962760b10fe2b158ae3bebf0b4d5be13"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, - "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"}, } diff --git a/apps/expert_credo/mix.lock b/apps/expert_credo/mix.lock index f8481ac3..14fe5efb 100644 --- a/apps/expert_credo/mix.lock +++ b/apps/expert_credo/mix.lock @@ -1,8 +1,6 @@ %{ - "benchee": {:hex, :benchee, "1.3.1", "c786e6a76321121a44229dde3988fc772bca73ea75170a73fd5f4ddf1af95ccf", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "76224c58ea1d0391c8309a8ecbfe27d71062878f59bd41a390266bf4ac1cc56d"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, @@ -18,8 +16,6 @@ "schematic": {:hex, :schematic, "0.2.1", "0b091df94146fd15a0a343d1bd179a6c5a58562527746dadd09477311698dbb1", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0b255d65921e38006138201cd4263fd8bb807d9dfc511074615cd264a571b3b1"}, "snowflake": {:hex, :snowflake, "1.0.4", "8433b4e04fbed19272c55e1b7de0f7a1ee1230b3ae31a813b616fd6ef279e87a", [:mix], [], "hexpm", "badb07ebb089a5cff737738297513db3962760b10fe2b158ae3bebf0b4d5be13"}, "sourceror": {:hex, :sourceror, "1.9.0", "3bf5fe2d017aaabe3866d8a6da097dd7c331e0d2d54e59e21c2b066d47f1e08e", [:mix], [], "hexpm", "d20a9dd5efe162f0d75a307146faa2e17b823ea4f134f662358d70f0332fed82"}, - "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, - "stream_data": {:hex, :stream_data, "1.1.3", "15fdb14c64e84437901258bb56fc7d80aaf6ceaf85b9324f359e219241353bfb", [:mix], [], "hexpm", "859eb2be72d74be26c1c4f272905667672a52e44f743839c57c7ee73a1a66420"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"}, } From fe0a206dd28d7096dcac66e438973c0fac0b9e48 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 21:46:07 -0400 Subject: [PATCH 06/19] fixup! chore: bump burrito --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96e32400..8b596ed9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ permissions: jobs: static-analysis: runs-on: ubuntu-latest - name: Static analysis + name: Static analysis - ${{ matrix.project }} strategy: matrix: @@ -64,7 +64,7 @@ jobs: dialyzer: runs-on: ubuntu-latest - name: Dialyzer + name: Dialyzer - ${{ matrix.project }} strategy: matrix: project: @@ -175,7 +175,7 @@ jobs: test: runs-on: ubuntu-latest - name: Test on OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}} + name: Test ${{ matrix.project }} on OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}} strategy: # Specify the OTP and Elixir versions to use when building # and running the workflow steps. From f089b529feb8f0e86f5e6684da3daee96f98cb50 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 21:48:02 -0400 Subject: [PATCH 07/19] fixup! chore: bump burrito --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b596ed9..7216f150 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,9 +46,9 @@ jobs: apps/${{ matrix.project }}/deps apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} + key: ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} restore-keys: | - ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- + ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- - name: Deps run: just deps ${{ matrix.project }} @@ -94,9 +94,9 @@ jobs: apps/${{ matrix.project }}/deps apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{ matrix.project }}/mix.lock') }} + key: ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{ matrix.project }}/mix.lock') }} restore-keys: | - ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- + ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- # Step: Create dialyzer .plt files if they're not present - name: Cache dialyzer plt files @@ -224,9 +224,9 @@ jobs: apps/${{ matrix.project }}/deps apps/${{ matrix.project }}/_build - key: ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} + key: ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}-${{ hashFiles('apps/${{matrix.project}}/mix.lock') }} restore-keys: | - ${{ runner.os }}-mix-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- + ${{ runner.os }}-mix-${{ matrix.project }}-${{ env.DEFAULT_ELIXIR }}-${{ env.DEFAULT_OTP }}- - name: Deps run: just deps ${{ matrix.project }} From 819016e3ec4ea5b86a2c050de37f712715fc5a59 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 22:42:48 -0400 Subject: [PATCH 08/19] fixup! chore: bump burrito --- apps/engine/mix.exs | 2 +- apps/expert/mix.exs | 4 ++-- apps/expert/test/engine/code_intelligence/definition_test.exs | 2 +- .../completion/translations/module_or_behaviour_test.exs | 3 +-- apps/expert/test/{ => forge}/document_test.exs | 1 - apps/expert/test/support/test/completion_case.ex | 2 +- apps/expert_credo/mix.exs | 2 +- apps/forge/{test/support => lib}/test/code_mod_case.ex | 0 apps/forge/{test/support => lib}/test/code_sigil.ex | 0 apps/forge/{test/support => lib}/test/cursor_support.ex | 0 apps/forge/{test/support => lib}/test/detection_case.ex | 0 apps/forge/{test/support => lib}/test/detection_case/suite.ex | 0 apps/forge/{test/support => lib}/test/diagnostic_support.ex | 0 apps/forge/{test/support => lib}/test/document_support.ex | 0 apps/forge/{test/support => lib}/test/eventual_assertions.ex | 0 apps/forge/{test/support => lib}/test/fixtures.ex | 4 ++-- apps/forge/{test/support => lib}/test/position_support.ex | 0 apps/forge/{test/support => lib}/test/quiet.ex | 0 apps/forge/{test/support => lib}/test/range_support.ex | 0 apps/forge/{test/support => lib}/test/variations.ex | 0 20 files changed, 9 insertions(+), 11 deletions(-) rename apps/expert/test/{ => forge}/document_test.exs (99%) rename apps/forge/{test/support => lib}/test/code_mod_case.ex (100%) rename apps/forge/{test/support => lib}/test/code_sigil.ex (100%) rename apps/forge/{test/support => lib}/test/cursor_support.ex (100%) rename apps/forge/{test/support => lib}/test/detection_case.ex (100%) rename apps/forge/{test/support => lib}/test/detection_case/suite.ex (100%) rename apps/forge/{test/support => lib}/test/diagnostic_support.ex (100%) rename apps/forge/{test/support => lib}/test/document_support.ex (100%) rename apps/forge/{test/support => lib}/test/eventual_assertions.ex (100%) rename apps/forge/{test/support => lib}/test/fixtures.ex (82%) rename apps/forge/{test/support => lib}/test/position_support.ex (100%) rename apps/forge/{test/support => lib}/test/quiet.ex (100%) rename apps/forge/{test/support => lib}/test/range_support.ex (100%) rename apps/forge/{test/support => lib}/test/variations.ex (100%) diff --git a/apps/engine/mix.exs b/apps/engine/mix.exs index 7cf0b9d9..c2d96058 100644 --- a/apps/engine/mix.exs +++ b/apps/engine/mix.exs @@ -49,7 +49,7 @@ defmodule Engine.MixProject do Mix.Dialyzer.dependency(), {:elixir_sense, github: "elixir-lsp/elixir_sense", ref: "e3ddc403554050221a2fd19a10a896fa7525bc02"}, - {:forge, path: "../forge", env: Mix.env()}, + {:forge, path: "../forge"}, {:gen_lsp, "~> 0.11"}, {:patch, "~> 0.15", only: [:dev, :test], optional: true, runtime: false}, {:path_glob, "~> 0.2", optional: true}, diff --git a/apps/expert/mix.exs b/apps/expert/mix.exs index 69c0de51..9b4ed6de 100644 --- a/apps/expert/mix.exs +++ b/apps/expert/mix.exs @@ -83,8 +83,8 @@ defmodule Expert.MixProject do # In practice Expert does not hardly depend on Engine, only on its compiled # artifacts, but we need it as a test dependency to set up tests that # assume a roundtrip to a project node is made. - {:engine, path: "../engine", env: Mix.env(), only: [:test]}, - {:forge, path: "../forge", env: Mix.env()}, + {:engine, path: "../engine", only: [:test]}, + {:forge, path: "../forge" }, {:gen_lsp, "~> 0.11"}, {:jason, "~> 1.4"}, {:logger_file_backend, "~> 0.0", only: [:dev, :prod]}, diff --git a/apps/expert/test/engine/code_intelligence/definition_test.exs b/apps/expert/test/engine/code_intelligence/definition_test.exs index f2893f85..f0519ef9 100644 --- a/apps/expert/test/engine/code_intelligence/definition_test.exs +++ b/apps/expert/test/engine/code_intelligence/definition_test.exs @@ -1,4 +1,4 @@ -defmodule Engine.CodeIntelligence.DefinitionTest do +defmodule Expert.Engine.CodeIntelligence.DefinitionTest do alias Engine.Search alias Expert.EngineApi alias Expert.EngineNode diff --git a/apps/expert/test/expert/code_intelligence/completion/translations/module_or_behaviour_test.exs b/apps/expert/test/expert/code_intelligence/completion/translations/module_or_behaviour_test.exs index 4f795f33..f876e705 100644 --- a/apps/expert/test/expert/code_intelligence/completion/translations/module_or_behaviour_test.exs +++ b/apps/expert/test/expert/code_intelligence/completion/translations/module_or_behaviour_test.exs @@ -270,10 +270,9 @@ defmodule Expert.CodeIntelligence.Completion.Translations.ModuleOrBehaviourTest use En| ] - assert [ex_unit_completion, ex_unit_properties_completion] = complete(project, source) + assert [ex_unit_completion] = complete(project, source) assert apply_completion(ex_unit_completion) =~ "use ExUnit" - assert apply_completion(ex_unit_properties_completion) =~ "use ExUnitProperties" end end end diff --git a/apps/expert/test/document_test.exs b/apps/expert/test/forge/document_test.exs similarity index 99% rename from apps/expert/test/document_test.exs rename to apps/expert/test/forge/document_test.exs index 409dd58d..f7992dbd 100644 --- a/apps/expert/test/document_test.exs +++ b/apps/expert/test/forge/document_test.exs @@ -6,7 +6,6 @@ defmodule Forge.DocumentTest do alias GenLSP.Structures.TextEdit use ExUnit.Case - use ExUnitProperties import Forge.Document, except: [to_string: 1] diff --git a/apps/expert/test/support/test/completion_case.ex b/apps/expert/test/support/test/completion_case.ex index 2b313f1f..22c07a66 100644 --- a/apps/expert/test/support/test/completion_case.ex +++ b/apps/expert/test/support/test/completion_case.ex @@ -27,7 +27,7 @@ defmodule Expert.Test.Expert.CompletionCase do ]) EngineApi.schedule_compile(project, true) - assert_receive project_compiled(), 5000 + assert_receive project_compiled(), 20000 assert_receive project_index_ready(), 5000 {:ok, project: project} end diff --git a/apps/expert_credo/mix.exs b/apps/expert_credo/mix.exs index ff083867..2f23d93b 100644 --- a/apps/expert_credo/mix.exs +++ b/apps/expert_credo/mix.exs @@ -27,7 +27,7 @@ defmodule ExpertCredo.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:forge, path: "../forge", env: Mix.env()}, + {:forge, path: "../forge"}, {:credo, "> 0.0.0", only: [:dev, :test]}, Mix.Dialyzer.dependency(), {:jason, "> 0.0.0", optional: true}, diff --git a/apps/forge/test/support/test/code_mod_case.ex b/apps/forge/lib/test/code_mod_case.ex similarity index 100% rename from apps/forge/test/support/test/code_mod_case.ex rename to apps/forge/lib/test/code_mod_case.ex diff --git a/apps/forge/test/support/test/code_sigil.ex b/apps/forge/lib/test/code_sigil.ex similarity index 100% rename from apps/forge/test/support/test/code_sigil.ex rename to apps/forge/lib/test/code_sigil.ex diff --git a/apps/forge/test/support/test/cursor_support.ex b/apps/forge/lib/test/cursor_support.ex similarity index 100% rename from apps/forge/test/support/test/cursor_support.ex rename to apps/forge/lib/test/cursor_support.ex diff --git a/apps/forge/test/support/test/detection_case.ex b/apps/forge/lib/test/detection_case.ex similarity index 100% rename from apps/forge/test/support/test/detection_case.ex rename to apps/forge/lib/test/detection_case.ex diff --git a/apps/forge/test/support/test/detection_case/suite.ex b/apps/forge/lib/test/detection_case/suite.ex similarity index 100% rename from apps/forge/test/support/test/detection_case/suite.ex rename to apps/forge/lib/test/detection_case/suite.ex diff --git a/apps/forge/test/support/test/diagnostic_support.ex b/apps/forge/lib/test/diagnostic_support.ex similarity index 100% rename from apps/forge/test/support/test/diagnostic_support.ex rename to apps/forge/lib/test/diagnostic_support.ex diff --git a/apps/forge/test/support/test/document_support.ex b/apps/forge/lib/test/document_support.ex similarity index 100% rename from apps/forge/test/support/test/document_support.ex rename to apps/forge/lib/test/document_support.ex diff --git a/apps/forge/test/support/test/eventual_assertions.ex b/apps/forge/lib/test/eventual_assertions.ex similarity index 100% rename from apps/forge/test/support/test/eventual_assertions.ex rename to apps/forge/lib/test/eventual_assertions.ex diff --git a/apps/forge/test/support/test/fixtures.ex b/apps/forge/lib/test/fixtures.ex similarity index 82% rename from apps/forge/test/support/test/fixtures.ex rename to apps/forge/lib/test/fixtures.ex index edc98e5c..9a37b47b 100644 --- a/apps/forge/test/support/test/fixtures.ex +++ b/apps/forge/lib/test/fixtures.ex @@ -5,13 +5,13 @@ defmodule Forge.Test.Fixtures do use ExUnit.CaseTemplate def fixtures_path do - [__ENV__.file, "..", "..", "..", "fixtures"] + [__ENV__.file, "..", "..", "..", "test/fixtures"] |> Path.join() |> Path.expand() end def project(project_name) do - [Path.dirname(__ENV__.file), "..", "..", "fixtures", to_string(project_name)] + [Path.dirname(__ENV__.file), "..", "..", "test/fixtures", to_string(project_name)] |> Path.join() |> Path.expand() |> Forge.Document.Path.to_uri() diff --git a/apps/forge/test/support/test/position_support.ex b/apps/forge/lib/test/position_support.ex similarity index 100% rename from apps/forge/test/support/test/position_support.ex rename to apps/forge/lib/test/position_support.ex diff --git a/apps/forge/test/support/test/quiet.ex b/apps/forge/lib/test/quiet.ex similarity index 100% rename from apps/forge/test/support/test/quiet.ex rename to apps/forge/lib/test/quiet.ex diff --git a/apps/forge/test/support/test/range_support.ex b/apps/forge/lib/test/range_support.ex similarity index 100% rename from apps/forge/test/support/test/range_support.ex rename to apps/forge/lib/test/range_support.ex diff --git a/apps/forge/test/support/test/variations.ex b/apps/forge/lib/test/variations.ex similarity index 100% rename from apps/forge/test/support/test/variations.ex rename to apps/forge/lib/test/variations.ex From b94b9e467b37c4db938be40c4a81e636fccb125b Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 22:44:13 -0400 Subject: [PATCH 09/19] fixup! chore: bump burrito --- apps/expert/mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/expert/mix.exs b/apps/expert/mix.exs index 9b4ed6de..d0cfa286 100644 --- a/apps/expert/mix.exs +++ b/apps/expert/mix.exs @@ -84,7 +84,7 @@ defmodule Expert.MixProject do # artifacts, but we need it as a test dependency to set up tests that # assume a roundtrip to a project node is made. {:engine, path: "../engine", only: [:test]}, - {:forge, path: "../forge" }, + {:forge, path: "../forge"}, {:gen_lsp, "~> 0.11"}, {:jason, "~> 1.4"}, {:logger_file_backend, "~> 0.0", only: [:dev, :prod]}, From 90521afa92de30b2dcefd9d497c0257cf19da81d Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Wed, 13 Aug 2025 22:56:30 -0400 Subject: [PATCH 10/19] fixup! chore: bump burrito --- .formatter.exs | 5 - .github/matrix.json | 184 ++++++++++++++++++ .github/workflows/ci.yml | 41 ++-- .../test/support/test/completion_case.ex | 2 +- matrix.exs | 29 +++ 5 files changed, 227 insertions(+), 34 deletions(-) delete mode 100644 .formatter.exs create mode 100644 .github/matrix.json create mode 100644 matrix.exs diff --git a/.formatter.exs b/.formatter.exs deleted file mode 100644 index 90a08535..00000000 --- a/.formatter.exs +++ /dev/null @@ -1,5 +0,0 @@ -# Used by "mix format" -[ - inputs: ["mix.exs", "config/*.exs"], - subdirectories: ["apps/*"] -] diff --git a/.github/matrix.json b/.github/matrix.json new file mode 100644 index 00000000..98af2462 --- /dev/null +++ b/.github/matrix.json @@ -0,0 +1,184 @@ +{ + "include": [ + { + "otp": "27", + "elixir": "1.18.1", + "project": "engine" + }, + { + "otp": "26", + "elixir": "1.18.1", + "project": "engine" + }, + { + "otp": "27", + "elixir": "1.17", + "project": "engine" + }, + { + "otp": "26", + "elixir": "1.17", + "project": "engine" + }, + { + "otp": "25", + "elixir": "1.17", + "project": "engine" + }, + { + "otp": "26", + "elixir": "1.16", + "project": "engine" + }, + { + "otp": "25", + "elixir": "1.16", + "project": "engine" + }, + { + "otp": "26", + "elixir": "1.15.8", + "project": "engine" + }, + { + "otp": "25", + "elixir": "1.15.8", + "project": "engine" + }, + { + "otp": "27", + "elixir": "1.18.1", + "project": "expert" + }, + { + "otp": "26", + "elixir": "1.18.1", + "project": "expert" + }, + { + "otp": "27", + "elixir": "1.17", + "project": "expert" + }, + { + "otp": "26", + "elixir": "1.17", + "project": "expert" + }, + { + "otp": "25", + "elixir": "1.17", + "project": "expert" + }, + { + "otp": "26", + "elixir": "1.16", + "project": "expert" + }, + { + "otp": "25", + "elixir": "1.16", + "project": "expert" + }, + { + "otp": "26", + "elixir": "1.15.8", + "project": "expert" + }, + { + "otp": "25", + "elixir": "1.15.8", + "project": "expert" + }, + { + "otp": "27", + "elixir": "1.18.1", + "project": "expert_credo" + }, + { + "otp": "26", + "elixir": "1.18.1", + "project": "expert_credo" + }, + { + "otp": "27", + "elixir": "1.17", + "project": "expert_credo" + }, + { + "otp": "26", + "elixir": "1.17", + "project": "expert_credo" + }, + { + "otp": "25", + "elixir": "1.17", + "project": "expert_credo" + }, + { + "otp": "26", + "elixir": "1.16", + "project": "expert_credo" + }, + { + "otp": "25", + "elixir": "1.16", + "project": "expert_credo" + }, + { + "otp": "26", + "elixir": "1.15.8", + "project": "expert_credo" + }, + { + "otp": "25", + "elixir": "1.15.8", + "project": "expert_credo" + }, + { + "otp": "27", + "elixir": "1.18.1", + "project": "forge" + }, + { + "otp": "26", + "elixir": "1.18.1", + "project": "forge" + }, + { + "otp": "27", + "elixir": "1.17", + "project": "forge" + }, + { + "otp": "26", + "elixir": "1.17", + "project": "forge" + }, + { + "otp": "25", + "elixir": "1.17", + "project": "forge" + }, + { + "otp": "26", + "elixir": "1.16", + "project": "forge" + }, + { + "otp": "25", + "elixir": "1.16", + "project": "forge" + }, + { + "otp": "26", + "elixir": "1.15.8", + "project": "forge" + }, + { + "otp": "25", + "elixir": "1.15.8", + "project": "forge" + } + ] +} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7216f150..3444b212 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,38 +173,23 @@ jobs: - name: Build and release run: just release-local + prep-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout to repository + uses: actions/checkout@v4 + - name: Set matrix data + id: set-matrix + run: echo "matrix=$(jq -c . < .github/matrix.json)" >> $GITHUB_OUTPUT + test: runs-on: ubuntu-latest name: Test ${{ matrix.project }} on OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}} + needs: prep-matrix strategy: - # Specify the OTP and Elixir versions to use when building - # and running the workflow steps. - matrix: - include: - - elixir: "1.18.1" - otp: "27" - - elixir: "1.18.1" - otp: "26" - - elixir: "1.17" - otp: "27" - - elixir: "1.17" - otp: "26" - - elixir: "1.17" - otp: "25" - - elixir: "1.16" - otp: "26" - - elixir: "1.16" - otp: "25" - - elixir: "1.15.8" - otp: "26" - - elixir: "1.15.8" - otp: "25" - - project: - - engine - - expert - - expert_credo - - forge + matrix: ${{ fromJson(needs.prep-matrix.outputs.matrix) }} steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/apps/expert/test/support/test/completion_case.ex b/apps/expert/test/support/test/completion_case.ex index 22c07a66..2b313f1f 100644 --- a/apps/expert/test/support/test/completion_case.ex +++ b/apps/expert/test/support/test/completion_case.ex @@ -27,7 +27,7 @@ defmodule Expert.Test.Expert.CompletionCase do ]) EngineApi.schedule_compile(project, true) - assert_receive project_compiled(), 20000 + assert_receive project_compiled(), 5000 assert_receive project_index_ready(), 5000 {:ok, project: project} end diff --git a/matrix.exs b/matrix.exs new file mode 100644 index 00000000..b08a58a3 --- /dev/null +++ b/matrix.exs @@ -0,0 +1,29 @@ +Mix.install([:jason]) + +projects = [ + "engine", + "expert", + "expert_credo", + "forge" +] + +versions = [ + %{elixir: "1.18.1", otp: "27"}, + %{elixir: "1.18.1", otp: "26"}, + %{elixir: "1.17", otp: "27"}, + %{elixir: "1.17", otp: "26"}, + %{elixir: "1.17", otp: "25"}, + %{elixir: "1.16", otp: "26"}, + %{elixir: "1.16", otp: "25"}, + %{elixir: "1.15.8", otp: "26"}, + %{elixir: "1.15.8", otp: "25"} +] + +%{ + include: + for project <- projects, version <- versions do + Map.put(version, :project, project) + end +} +|> Jason.encode!(pretty: true) +|> then(&File.write!(".github/matrix.json", &1)) From 87050c1bdcd2f2e41bd7cb903f6a8df5bd90f3b4 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Fri, 15 Aug 2025 18:59:19 -0400 Subject: [PATCH 11/19] Update justfile Co-authored-by: Dorgan --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 515a9b51..c7a6aa7b 100644 --- a/justfile +++ b/justfile @@ -59,7 +59,7 @@ build-engine: rm -rf $namespaced_dir mkdir -p $namespaced_dir - cp -r _build/dev "$namespaced_dir" + cp -r _build/dev/ "$namespaced_dir" MIX_ENV=dev mix namespace "$namespaced_dir" From 679c7f9656e347daf530abdec9f6f60baed10c82 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sat, 16 Aug 2025 14:08:11 -0400 Subject: [PATCH 12/19] fixup! chore: bump burrito --- .dialyzer_ignore.exs | 0 apps/forge/lib/forge/document.ex | 2 +- apps/forge/lib/forge/document/position.ex | 4 ++++ apps/forge/lib/test/cursor_support.ex | 23 ++++++++++++------ apps/forge/lib/test/detection_case.ex | 3 +-- apps/forge/lib/test/range_support.ex | 29 ++++++++++------------- dialyzer.ignore-warnings | 2 ++ 7 files changed, 37 insertions(+), 26 deletions(-) delete mode 100644 .dialyzer_ignore.exs diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/forge/lib/forge/document.ex b/apps/forge/lib/forge/document.ex index 63da346c..4c1caa57 100644 --- a/apps/forge/lib/forge/document.ex +++ b/apps/forge/lib/forge/document.ex @@ -43,7 +43,7 @@ defmodule Forge.Document do Creates a new document from a uri or path, the source code as a binary and the vewrsion. """ - @spec new(Forge.path() | Forge.uri(), String.t(), version()) :: t + @spec new(Forge.path() | Forge.uri(), String.t(), version()) :: t() def new(maybe_uri, text, version, language_id \\ nil) do uri = DocumentPath.ensure_uri(maybe_uri) path = DocumentPath.from_uri(uri) diff --git a/apps/forge/lib/forge/document/position.ex b/apps/forge/lib/forge/document/position.ex index 562a39c7..4904a16e 100644 --- a/apps/forge/lib/forge/document/position.ex +++ b/apps/forge/lib/forge/document/position.ex @@ -71,6 +71,10 @@ defmodule Forge.Document.Position do end end + def new(_, _, _) do + :error + end + @doc """ Compares two positions. diff --git a/apps/forge/lib/test/cursor_support.ex b/apps/forge/lib/test/cursor_support.ex index ce9f5a4e..314d81c6 100644 --- a/apps/forge/lib/test/cursor_support.ex +++ b/apps/forge/lib/test/cursor_support.ex @@ -62,8 +62,12 @@ defmodule Forge.Test.CursorSupport do } """ - @spec pop_cursor(text :: String.t(), [opt]) :: {Position.t(), String.t() | Document.t()} - when opt: {:cursor, String.t()} | {:as, :text | :document} | {:document, String.t()} + @spec pop_cursor(text :: String.t(), [opt]) :: + {Position.t() | nil | :error, String.t() | Document.t()} + when opt: + {:cursor, String.t()} + | {:as, :text | :document} + | {:document, String.t()} def pop_cursor(text, opts \\ []) do as_document? = opts[:as] == :document or is_binary(opts[:document]) @@ -71,7 +75,11 @@ defmodule Forge.Test.CursorSupport do stripped_text = strip_cursor(text, Keyword.take(opts, [:cursor])) if as_document? do - uri = opts |> Keyword.get(:document, "file:///file.ex") |> Document.Path.ensure_uri() + uri = + opts + |> Keyword.get(:document, "file:///file.ex") + |> Document.Path.ensure_uri() + document = Document.new(uri, stripped_text, 0) position = position(document, position) {position, document} @@ -84,7 +92,7 @@ defmodule Forge.Test.CursorSupport do @doc """ Strips all instances of `cursor` from `text`. """ - @spec strip_cursor(text :: String.t(), cursor :: String.t()) :: String.t() + @spec strip_cursor(text :: String.t(), opts :: Keyword.t()) :: String.t() def strip_cursor(text, opts \\ []) do cursor = Keyword.get(opts, :cursor, @default_cursor) @@ -155,15 +163,16 @@ defmodule Forge.Test.CursorSupport do end end - defp position(%Document{} = document, {line, column}) do + defp position(%Document{} = document, {line, column}) + when is_number(line) and is_number(column) do Position.new(document, line, column) end defp position(%Document{}, nil), do: nil - defp position({line, column}) do + defp position({line, column}) when is_number(line) and is_number(column) do PositionSupport.position(line, column) end - defp position(nil), do: nil + defp position(_), do: nil end diff --git a/apps/forge/lib/test/detection_case.ex b/apps/forge/lib/test/detection_case.ex index e8551a7c..e4961813 100644 --- a/apps/forge/lib/test/detection_case.ex +++ b/apps/forge/lib/test/detection_case.ex @@ -143,8 +143,7 @@ defmodule Forge.Test.DetectionCase do |> position_stream() |> Enum.group_by(fn position -> Enum.find(ranges, &includes?(&1, position)) end) - for {range, positions} <- positions_by_range, - position <- positions do + for {range, positions} <- positions_by_range, position <- positions do try do if range do assert context.detected?(analysis, position) diff --git a/apps/forge/lib/test/range_support.ex b/apps/forge/lib/test/range_support.ex index f82cf162..9329c121 100644 --- a/apps/forge/lib/test/range_support.ex +++ b/apps/forge/lib/test/range_support.ex @@ -22,8 +22,19 @@ defmodule Forge.Test.RangeSupport do {Range.new(start_position, end_position), text} end - def pop_all_ranges(text) do - do_pop_all_ranges(text, []) + @spec pop_all_ranges(String.t(), list()) :: {list(), String.t()} + def pop_all_ranges(text, ranges \\ []) do + {start_position, text} = + CursorSupport.pop_cursor(text, cursor: @range_start_marker, default_to_end: false) + + {end_position, text} = + CursorSupport.pop_cursor(text, cursor: @range_end_marker, default_to_end: false) + + if start_position == nil or end_position == nil do + {Enum.reverse(ranges), text} + else + pop_all_ranges(text, [Range.new(start_position, end_position) | ranges]) + end end def decorate(%Document{} = document, %Range{} = range) do @@ -114,18 +125,4 @@ defmodule Forge.Test.RangeSupport do {leading, trailing} = String.split_at(text, character - 1) leading <> marker <> trailing end - - defp do_pop_all_ranges(text, ranges) do - {start_position, text} = - CursorSupport.pop_cursor(text, cursor: @range_start_marker, default_to_end: false) - - {end_position, text} = - CursorSupport.pop_cursor(text, cursor: @range_end_marker, default_to_end: false) - - if start_position == nil or end_position == nil do - {Enum.reverse(ranges), text} - else - do_pop_all_ranges(text, [Range.new(start_position, end_position) | ranges]) - end - end end diff --git a/dialyzer.ignore-warnings b/dialyzer.ignore-warnings index a1ceb788..ae03f018 100644 --- a/dialyzer.ignore-warnings +++ b/dialyzer.ignore-warnings @@ -1,2 +1,4 @@ src/ lib/elixir/lib/future/ +lib/test/detection_case.ex +lib/test/range_support.ex From 0c64aa3e6e60578fbbb9d2c382bbc8b17e9b0654 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:28:46 -0400 Subject: [PATCH 13/19] Trigger Build From 039713968ce8b8491614d63661894eceaab273c3 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:36:08 -0400 Subject: [PATCH 14/19] fixup! chore: bump burrito --- apps/expert/test/expert/project/node_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/expert/test/expert/project/node_test.exs b/apps/expert/test/expert/project/node_test.exs index 58f5d917..1d0bf196 100644 --- a/apps/expert/test/expert/project/node_test.exs +++ b/apps/expert/test/expert/project/node_test.exs @@ -20,7 +20,7 @@ defmodule Expert.Project.NodeTest do end test "the project should be compiled when the node starts" do - assert_receive project_compiled(), 750 + assert_receive project_compiled(), :timer.seconds(15) end test "remote control is started when the node starts", %{project: project} do From 1f85309e98b808777d22e2861b125d4971991de3 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:44:01 -0400 Subject: [PATCH 15/19] fixup! chore: bump burrito --- apps/expert/test/expert/engine_node_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/expert/test/expert/engine_node_test.exs b/apps/expert/test/expert/engine_node_test.exs index e45d5d81..2b645243 100644 --- a/apps/expert/test/expert/engine_node_test.exs +++ b/apps/expert/test/expert/engine_node_test.exs @@ -20,7 +20,7 @@ defmodule Expert.EngineNodeTest do assert project_alive? assert :ok = EngineNode.stop(project, 1500) - assert Process.whereis(EngineNode.name(project)) == nil + assert_eventually Process.whereis(EngineNode.name(project)) == nil, :timer.seconds(5) end test "it should be stopped atomically when the startup process is dead", %{project: project} do From 9b50acd0787c2f7a822b3a1c63a6a456489df052 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:48:34 -0400 Subject: [PATCH 16/19] fixup! chore: bump burrito --- apps/expert/test/engine/build_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/expert/test/engine/build_test.exs b/apps/expert/test/engine/build_test.exs index 36f3a5e8..ea7f74aa 100644 --- a/apps/expert/test/engine/build_test.exs +++ b/apps/expert/test/engine/build_test.exs @@ -97,7 +97,7 @@ defmodule Engine.BuildTest do {:ok, project} = with_project(:umbrella) EngineApi.schedule_compile(project, true) - assert_receive project_compiled(status: :success) + assert_receive project_compiled(status: :success), :timer.seconds(15) assert_receive project_diagnostics(diagnostics: []) assert_receive module_updated(name: Umbrella.First, functions: functions) From 06389e78f46cfe04eed70219c50178380addc824 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:49:59 -0400 Subject: [PATCH 17/19] fixup! chore: bump burrito --- matrix.exs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/matrix.exs b/matrix.exs index b08a58a3..b2a75ee4 100644 --- a/matrix.exs +++ b/matrix.exs @@ -7,15 +7,16 @@ projects = [ "forge" ] +# renable these once we make the repo public versions = [ - %{elixir: "1.18.1", otp: "27"}, - %{elixir: "1.18.1", otp: "26"}, - %{elixir: "1.17", otp: "27"}, - %{elixir: "1.17", otp: "26"}, - %{elixir: "1.17", otp: "25"}, - %{elixir: "1.16", otp: "26"}, - %{elixir: "1.16", otp: "25"}, - %{elixir: "1.15.8", otp: "26"}, + # %{elixir: "1.18.1", otp: "27"}, + # %{elixir: "1.18.1", otp: "26"}, + # %{elixir: "1.17", otp: "27"}, + # %{elixir: "1.17", otp: "26"}, + # %{elixir: "1.17", otp: "25"}, + # %{elixir: "1.16", otp: "26"}, + # %{elixir: "1.16", otp: "25"}, + # %{elixir: "1.15.8", otp: "26"}, %{elixir: "1.15.8", otp: "25"} ] From 9de74355fbc17b04697d98ba02b72128b5489651 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 16:50:39 -0400 Subject: [PATCH 18/19] fixup! chore: bump burrito --- .github/matrix.json | 160 -------------------------------------------- 1 file changed, 160 deletions(-) diff --git a/.github/matrix.json b/.github/matrix.json index 98af2462..9b5b61bb 100644 --- a/.github/matrix.json +++ b/.github/matrix.json @@ -1,180 +1,20 @@ { "include": [ - { - "otp": "27", - "elixir": "1.18.1", - "project": "engine" - }, - { - "otp": "26", - "elixir": "1.18.1", - "project": "engine" - }, - { - "otp": "27", - "elixir": "1.17", - "project": "engine" - }, - { - "otp": "26", - "elixir": "1.17", - "project": "engine" - }, - { - "otp": "25", - "elixir": "1.17", - "project": "engine" - }, - { - "otp": "26", - "elixir": "1.16", - "project": "engine" - }, - { - "otp": "25", - "elixir": "1.16", - "project": "engine" - }, - { - "otp": "26", - "elixir": "1.15.8", - "project": "engine" - }, { "otp": "25", "elixir": "1.15.8", "project": "engine" }, - { - "otp": "27", - "elixir": "1.18.1", - "project": "expert" - }, - { - "otp": "26", - "elixir": "1.18.1", - "project": "expert" - }, - { - "otp": "27", - "elixir": "1.17", - "project": "expert" - }, - { - "otp": "26", - "elixir": "1.17", - "project": "expert" - }, - { - "otp": "25", - "elixir": "1.17", - "project": "expert" - }, - { - "otp": "26", - "elixir": "1.16", - "project": "expert" - }, - { - "otp": "25", - "elixir": "1.16", - "project": "expert" - }, - { - "otp": "26", - "elixir": "1.15.8", - "project": "expert" - }, { "otp": "25", "elixir": "1.15.8", "project": "expert" }, - { - "otp": "27", - "elixir": "1.18.1", - "project": "expert_credo" - }, - { - "otp": "26", - "elixir": "1.18.1", - "project": "expert_credo" - }, - { - "otp": "27", - "elixir": "1.17", - "project": "expert_credo" - }, - { - "otp": "26", - "elixir": "1.17", - "project": "expert_credo" - }, - { - "otp": "25", - "elixir": "1.17", - "project": "expert_credo" - }, - { - "otp": "26", - "elixir": "1.16", - "project": "expert_credo" - }, - { - "otp": "25", - "elixir": "1.16", - "project": "expert_credo" - }, - { - "otp": "26", - "elixir": "1.15.8", - "project": "expert_credo" - }, { "otp": "25", "elixir": "1.15.8", "project": "expert_credo" }, - { - "otp": "27", - "elixir": "1.18.1", - "project": "forge" - }, - { - "otp": "26", - "elixir": "1.18.1", - "project": "forge" - }, - { - "otp": "27", - "elixir": "1.17", - "project": "forge" - }, - { - "otp": "26", - "elixir": "1.17", - "project": "forge" - }, - { - "otp": "25", - "elixir": "1.17", - "project": "forge" - }, - { - "otp": "26", - "elixir": "1.16", - "project": "forge" - }, - { - "otp": "25", - "elixir": "1.16", - "project": "forge" - }, - { - "otp": "26", - "elixir": "1.15.8", - "project": "forge" - }, { "otp": "25", "elixir": "1.15.8", From bed5fe9b8a932cbc23f8e9c04516b9181807280a Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 17 Aug 2025 17:10:05 -0400 Subject: [PATCH 19/19] fixup! chore: bump burrito --- justfile | 4 ++++ matrix.exs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index c7a6aa7b..75c2f616 100644 --- a/justfile +++ b/justfile @@ -93,5 +93,9 @@ release-plain: (compile "engine") cd apps/expert MIX_ENV=prod mix release plain --overwrite +[doc('Compiles .github/matrix.json')] +compile-ci-matrix: + elixir matrix.exs + default: release-local diff --git a/matrix.exs b/matrix.exs index b2a75ee4..7e7929ec 100644 --- a/matrix.exs +++ b/matrix.exs @@ -7,7 +7,7 @@ projects = [ "forge" ] -# renable these once we make the repo public +# TODO(#44): renable these once we make the repo public versions = [ # %{elixir: "1.18.1", otp: "27"}, # %{elixir: "1.18.1", otp: "26"},