From d397703b6374c65803ca6c61b1fa6949da949eb0 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:48:00 -0300 Subject: [PATCH 1/4] use Tower.Igniter.configure_reporter --- lib/mix/tasks/tower_bugsnag.install.ex | 140 +----------------- mix.exs | 6 +- mix.lock | 4 +- test/mix/tasks/tower_bugsnag.install_test.exs | 3 +- 4 files changed, 17 insertions(+), 136 deletions(-) diff --git a/lib/mix/tasks/tower_bugsnag.install.ex b/lib/mix/tasks/tower_bugsnag.install.ex index 595d668..283dc3e 100644 --- a/lib/mix/tasks/tower_bugsnag.install.ex +++ b/lib/mix/tasks/tower_bugsnag.install.ex @@ -1,4 +1,6 @@ -if Code.ensure_loaded?(Igniter) && Code.ensure_loaded?(Tower.Igniter) do +if Code.ensure_loaded?(Igniter) and + Code.ensure_loaded?(Tower.Igniter) and + function_exported?(Tower.Igniter, :configure_reporter, 4) do defmodule Mix.Tasks.TowerBugsnag.Install do @example "mix igniter.install tower_bugsnag" @@ -15,145 +17,19 @@ if Code.ensure_loaded?(Igniter) && Code.ensure_loaded?(Tower.Igniter) do use Igniter.Mix.Task - import Tower.Igniter - - @default_runtime_config """ - import Config - - if config_env() == :prod do - config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") - end - """ - - @prod_config_patterns [ - """ - if config_env() == :prod do - __cursor__() - end - """, - """ - if :prod == config_env() do - __cursor__() - end - """ - ] - - @bugsnag_config_code """ - config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") - """ - @impl Igniter.Mix.Task def info(_argv, _composing_task) do - %Igniter.Mix.Task.Info{ - group: :tower, - adds_deps: [], - installs: [], - example: @example, - only: nil, - positional: [], - composes: [], - schema: [], - defaults: [], - aliases: [], - required: [] - } + %Igniter.Mix.Task.Info{group: :tower, example: @example} end @impl Igniter.Mix.Task def igniter(igniter) do igniter - |> add_reporter_to_config(TowerBugsnag) - |> configure_runtime() - end - - defp configure_runtime(igniter) do - if runtime_config_exists?(igniter) do - igniter - else - add_runtime_config(igniter) - end - end - - defp runtime_config_exists?(igniter) do - Igniter.Project.Config.configures_key?(igniter, "runtime.exs", :tower_bugsnag, [ - :api_key - ]) - end - - defp add_runtime_config(igniter) do - Igniter.create_or_update_elixir_file( - igniter, - "config/runtime.exs", - @default_runtime_config, - &update_runtime_config/1 - ) - end - - defp update_runtime_config(zipper) do - if Igniter.Project.Config.configures_key?(zipper, :tower_bugsnag, :api_key) do - {:ok, zipper} - else - add_config_to_prod_block(zipper) - end - end - - defp add_config_to_prod_block(zipper) do - zipper - |> Igniter.Code.Common.move_to_cursor_match_in_scope(@prod_config_patterns) - |> case do - {:ok, zipper} -> - handle_existing_prod_block(zipper) - - :error -> - add_prod_block_with_config(zipper) - end - end - - defp handle_existing_prod_block(zipper) do - if Igniter.Project.Config.configures_key?(zipper, :tower_bugsnag, :api_key) do - {:ok, zipper} - else - update_existing_config_or_add_new(zipper) - end - end - - defp update_existing_config_or_add_new(zipper) do - case find_existing_bugsnag_config(zipper) do - {:ok, _zipper} -> - update_existing_bugsnag_config(zipper) - - _ -> - Igniter.Code.Common.add_code(zipper, @bugsnag_config_code) - end - end - - defp find_existing_bugsnag_config(zipper) do - Igniter.Code.Function.move_to_function_call_in_current_scope( - zipper, - :=, - 2, - fn call -> - Igniter.Code.Function.argument_equals?(call, 0, :tower_bugsnag) - end - ) - end - - defp update_existing_bugsnag_config(zipper) do - zipper - |> Igniter.Project.Config.modify_config_code( - [:api_key], + |> Tower.Igniter.configure_reporter( + TowerBugsnag, :tower_bugsnag, - Sourceror.parse_string!(~s[System.get_env("BUGSNAG_API_KEY")]) + api_key: ~s[System.get_env("BUGSNAG_API_KEY")] ) - |> then(&{:ok, &1}) - end - - defp add_prod_block_with_config(zipper) do - Igniter.Code.Common.add_code(zipper, """ - if config_env() == :prod do - #{@bugsnag_config_code} - end - """) end end else @@ -177,7 +53,7 @@ else @impl Mix.Task def run(_argv) do Mix.shell().error(""" - The task 'tower_bugsnag.install' requires igniter and tower > 0.8.3. Please install igniter or update tower and try again. + The task 'tower_bugsnag.install' requires igniter and tower >= 0.8.4. Please install igniter or update tower and try again. For more information, see: https://hexdocs.pm/igniter/readme.html#installation """) diff --git a/mix.exs b/mix.exs index 1ad9912..c30e6c3 100644 --- a/mix.exs +++ b/mix.exs @@ -43,7 +43,11 @@ defmodule TowerBugsnag.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:tower, "~> 0.7.1 or ~> 0.8.0"}, + { + :tower, + "~> 0.7.1 or ~> 0.8.0", + github: "mimiquate/tower", branch: "tower-igniter-add-reporter-config" + }, # Optional {:igniter, "~> 0.6", optional: true}, diff --git a/mix.lock b/mix.lock index 046a6b1..2f247c4 100644 --- a/mix.lock +++ b/mix.lock @@ -31,8 +31,8 @@ "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, - "thousand_island": {:hex, :thousand_island, "1.4.0", "7189aa9046cb4dc50e5d1d515cd4be6e1c34b6755b2becee624784ab8b07b4df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "686ff52b9e4cf1e16d2bd8ba83360f2357ac6ca304250702ecc3b40000f04015"}, - "tower": {:hex, :tower, "0.8.3", "853c26b390e14dbb6d39022a5fe526a35a8a8732f4ed53d91cc0e053cda344da", [:mix], [{:bandit, "~> 1.6", [hex: :bandit, repo: "hexpm", optional: true]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}, {:uuid_v7, "~> 0.6.0", [hex: :uuid_v7, repo: "hexpm", optional: false]}], "hexpm", "e8af9b32d2d2b1b0ec79a066a0939f57b59e88eaefde47a13f708596fd6ef9fa"}, + "thousand_island": {:hex, :thousand_island, "1.4.1", "8df065e627407e281f7935da5ad0f3842d10eb721afa92e760b720d71e2e37aa", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "204a8640e5d2818589b87286ae66160978628d7edf6095181cbe0440765fb6c1"}, + "tower": {:git, "https://github.com/mimiquate/tower.git", "1f4dbe3e1a2c6c445a9b685e02ec3a40c2639f44", [branch: "tower-igniter-add-reporter-config"]}, "uuid_v7": {:hex, :uuid_v7, "0.6.0", "1d65727ade8ca619ed40fdef90c4186b50c84657d2b412f7cb79777ab2d47559", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1dc401134e61da847a7b2a3b28d2593893f457b9f2704893b1ba3ff7946ce91f"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, } diff --git a/test/mix/tasks/tower_bugsnag.install_test.exs b/test/mix/tasks/tower_bugsnag.install_test.exs index ea2e25e..1cc6e06 100644 --- a/test/mix/tasks/tower_bugsnag.install_test.exs +++ b/test/mix/tasks/tower_bugsnag.install_test.exs @@ -19,7 +19,8 @@ if Code.ensure_loaded?(Tower.Igniter) do import Config if config_env() == :prod do - config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") + config :tower_bugsnag, + api_key: System.get_env("BUGSNAG_API_KEY") end """ ) From 46a28a5055bbbca0f908a16b60d8ede38e8e7a75 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:50:10 -0300 Subject: [PATCH 2/4] bump tower --- lib/mix/tasks/tower_bugsnag.install.ex | 6 +++--- mix.lock | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/mix/tasks/tower_bugsnag.install.ex b/lib/mix/tasks/tower_bugsnag.install.ex index 283dc3e..3026e0d 100644 --- a/lib/mix/tasks/tower_bugsnag.install.ex +++ b/lib/mix/tasks/tower_bugsnag.install.ex @@ -1,6 +1,6 @@ if Code.ensure_loaded?(Igniter) and Code.ensure_loaded?(Tower.Igniter) and - function_exported?(Tower.Igniter, :configure_reporter, 4) do + function_exported?(Tower.Igniter, :runtime_configure_reporter, 3) do defmodule Mix.Tasks.TowerBugsnag.Install do @example "mix igniter.install tower_bugsnag" @@ -25,8 +25,8 @@ if Code.ensure_loaded?(Igniter) and @impl Igniter.Mix.Task def igniter(igniter) do igniter - |> Tower.Igniter.configure_reporter( - TowerBugsnag, + |> Tower.Igniter.reporters_list_append(TowerBugsnag) + |> Tower.Igniter.runtime_configure_reporter( :tower_bugsnag, api_key: ~s[System.get_env("BUGSNAG_API_KEY")] ) diff --git a/mix.lock b/mix.lock index 2f247c4..d9627c7 100644 --- a/mix.lock +++ b/mix.lock @@ -32,7 +32,7 @@ "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, "thousand_island": {:hex, :thousand_island, "1.4.1", "8df065e627407e281f7935da5ad0f3842d10eb721afa92e760b720d71e2e37aa", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "204a8640e5d2818589b87286ae66160978628d7edf6095181cbe0440765fb6c1"}, - "tower": {:git, "https://github.com/mimiquate/tower.git", "1f4dbe3e1a2c6c445a9b685e02ec3a40c2639f44", [branch: "tower-igniter-add-reporter-config"]}, + "tower": {:git, "https://github.com/mimiquate/tower.git", "b32d28a661d109cc896cc55ae0c91829a969cba1", [branch: "tower-igniter-add-reporter-config"]}, "uuid_v7": {:hex, :uuid_v7, "0.6.0", "1d65727ade8ca619ed40fdef90c4186b50c84657d2b412f7cb79777ab2d47559", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1dc401134e61da847a7b2a3b28d2593893f457b9f2704893b1ba3ff7946ce91f"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, } From 3528fca7d61e9d5ec977bae6be6d6acfcfe7410c Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:57:40 -0300 Subject: [PATCH 3/4] test: just test idempotence and from scratch here - other cases in tower --- test/mix/tasks/tower_bugsnag.install_test.exs | 96 ------------------- 1 file changed, 96 deletions(-) diff --git a/test/mix/tasks/tower_bugsnag.install_test.exs b/test/mix/tasks/tower_bugsnag.install_test.exs index 1cc6e06..6807f0e 100644 --- a/test/mix/tasks/tower_bugsnag.install_test.exs +++ b/test/mix/tasks/tower_bugsnag.install_test.exs @@ -26,102 +26,6 @@ if Code.ensure_loaded?(Tower.Igniter) do ) end - test "modifies existing tower configs if available" do - test_project( - files: %{ - "config/config.exs" => """ - import Config - - config :tower, reporters: [TowerEmail] - """, - "config/runtime.exs" => """ - import Config - """ - } - ) - |> Igniter.compose_task("tower_bugsnag.install", []) - |> assert_has_patch( - "config/config.exs", - """ - |import Config - | - - |config :tower, reporters: [TowerEmail] - + |config :tower, reporters: [TowerEmail, TowerBugsnag] - """ - ) - |> assert_has_patch( - "config/runtime.exs", - """ - |import Config - | - + |if config_env() == :prod do - + | config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") - + |end - + | - """ - ) - end - - test "modifies existing tower configs if config_env() == :prod block exists" do - test_project( - files: %{ - "config/config.exs" => """ - import Config - - config :tower, reporters: [TowerEmail] - """, - "config/runtime.exs" => """ - import Config - - if config_env() == :prod do - IO.puts("hello") - end - """ - } - ) - |> Igniter.compose_task("tower_bugsnag.install", []) - |> assert_has_patch( - "config/config.exs", - """ - |import Config - | - - |config :tower, reporters: [TowerEmail] - + |config :tower, reporters: [TowerEmail, TowerBugsnag] - """ - ) - |> assert_has_patch( - "config/runtime.exs", - """ - |if config_env() == :prod do - | IO.puts("hello") - + | config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") - |end - | - """ - ) - end - - test "does not modify existing tower_bugsnag configs if config_env() == :prod block exists" do - test_project( - files: %{ - "config/config.exs" => """ - import Config - - config :tower, reporters: [TowerEmail, TowerBugsnag] - """, - "config/runtime.exs" => """ - import Config - - if config_env() == :prod do - config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") - end - """ - } - ) - |> Igniter.compose_task("tower_bugsnag.install", []) - |> assert_unchanged() - end - test "is idempotent" do test_project() |> Igniter.compose_task("tower_bugsnag.install", []) From aa320185215bbd0e9f190d78a31c2f9ca0c667c9 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Tue, 23 Sep 2025 10:59:51 -0300 Subject: [PATCH 4/4] bump tower --- lib/mix/tasks/tower_bugsnag.install.ex | 2 +- mix.exs | 6 +----- mix.lock | 2 +- test/mix/tasks/tower_bugsnag.install_test.exs | 6 +----- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/mix/tasks/tower_bugsnag.install.ex b/lib/mix/tasks/tower_bugsnag.install.ex index 3026e0d..7743b1f 100644 --- a/lib/mix/tasks/tower_bugsnag.install.ex +++ b/lib/mix/tasks/tower_bugsnag.install.ex @@ -28,7 +28,7 @@ if Code.ensure_loaded?(Igniter) and |> Tower.Igniter.reporters_list_append(TowerBugsnag) |> Tower.Igniter.runtime_configure_reporter( :tower_bugsnag, - api_key: ~s[System.get_env("BUGSNAG_API_KEY")] + api_key: {:code, Sourceror.parse_string!(~s[System.get_env("BUGSNAG_API_KEY")])} ) end end diff --git a/mix.exs b/mix.exs index c30e6c3..9436557 100644 --- a/mix.exs +++ b/mix.exs @@ -43,11 +43,7 @@ defmodule TowerBugsnag.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - { - :tower, - "~> 0.7.1 or ~> 0.8.0", - github: "mimiquate/tower", branch: "tower-igniter-add-reporter-config" - }, + {:tower, "~> 0.7.1 or ~> 0.8.0", github: "mimiquate/tower"}, # Optional {:igniter, "~> 0.6", optional: true}, diff --git a/mix.lock b/mix.lock index 739b14a..7cde764 100644 --- a/mix.lock +++ b/mix.lock @@ -32,7 +32,7 @@ "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, "thousand_island": {:hex, :thousand_island, "1.4.1", "8df065e627407e281f7935da5ad0f3842d10eb721afa92e760b720d71e2e37aa", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "204a8640e5d2818589b87286ae66160978628d7edf6095181cbe0440765fb6c1"}, - "tower": {:git, "https://github.com/mimiquate/tower.git", "b32d28a661d109cc896cc55ae0c91829a969cba1", [branch: "tower-igniter-add-reporter-config"]}, + "tower": {:git, "https://github.com/mimiquate/tower.git", "a10c670fc96fc120822b3a8cc9fdb6f28b200c84", []}, "uuid_v7": {:hex, :uuid_v7, "0.6.0", "1d65727ade8ca619ed40fdef90c4186b50c84657d2b412f7cb79777ab2d47559", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1dc401134e61da847a7b2a3b28d2593893f457b9f2704893b1ba3ff7946ce91f"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, } diff --git a/test/mix/tasks/tower_bugsnag.install_test.exs b/test/mix/tasks/tower_bugsnag.install_test.exs index 6807f0e..063967a 100644 --- a/test/mix/tasks/tower_bugsnag.install_test.exs +++ b/test/mix/tasks/tower_bugsnag.install_test.exs @@ -17,11 +17,7 @@ if Code.ensure_loaded?(Tower.Igniter) do "config/runtime.exs", """ import Config - - if config_env() == :prod do - config :tower_bugsnag, - api_key: System.get_env("BUGSNAG_API_KEY") - end + config :tower_bugsnag, api_key: System.get_env("BUGSNAG_API_KEY") """ ) end