diff --git a/.credo.exs b/.credo.exs index ac6338c2..0c05f788 100644 --- a/.credo.exs +++ b/.credo.exs @@ -118,7 +118,9 @@ # ## Refactoring Opportunities # - {Credo.Check.Refactor.Apply, []}, + # Disabled: We intentionally use apply/3 for optional dev-only dependencies + # to avoid compile-time warnings in production builds + # {Credo.Check.Refactor.Apply, []}, {Credo.Check.Refactor.CondStatements, []}, {Credo.Check.Refactor.CyclomaticComplexity, []}, {Credo.Check.Refactor.FilterCount, []}, diff --git a/config/runtime.exs b/config/runtime.exs index d46e8f79..47654c5a 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -92,18 +92,27 @@ if config_env() == :prod do false end - config :libcluster, - topologies: [ - k8s: [ - strategy: Cluster.Strategy.Kubernetes.DNS, - config: [ - service: "towerops-headless", - application_name: "towerops", - namespace: "towerops", - polling_interval: 10_000 + # Only enable libcluster in Kubernetes deployments + # Kubernetes automatically sets KUBERNETES_SERVICE_HOST env var + libcluster_topologies = + if System.get_env("KUBERNETES_SERVICE_HOST") do + [ + k8s: [ + strategy: Cluster.Strategy.Kubernetes.DNS, + config: [ + service: "towerops-headless", + application_name: "towerops", + namespace: "towerops", + polling_interval: 10_000 + ] ] ] - ] + else + # No clustering for non-K8s deployments (Dokku, single-node, etc.) + [] + end + + config :libcluster, topologies: libcluster_topologies # Configure Swoosh to use Req for API requests config :swoosh, :api_client, Swoosh.ApiClient.Req diff --git a/lib/towerops/application.ex b/lib/towerops/application.ex index 26b096eb..64e95638 100644 --- a/lib/towerops/application.ex +++ b/lib/towerops/application.ex @@ -224,9 +224,9 @@ defmodule Towerops.Application do # Register file logger backend for development (only available in :dev environment) defp register_file_logger do - if Code.ensure_loaded?(LoggerBackends) do - # Add the backend with a unique identifier - LoggerBackends.add({LoggerFileBackend, :file_log}) + if Code.ensure_loaded?(LoggerBackends) and Code.ensure_loaded?(LoggerFileBackend) do + # Add the backend with a unique identifier (using apply to avoid compile-time warnings) + apply(LoggerBackends, :add, [{LoggerFileBackend, :file_log}]) # Configure the backend with path and level Logger.configure_backend({LoggerFileBackend, :file_log}, @@ -234,7 +234,7 @@ defmodule Towerops.Application do level: :debug ) else - Logger.warning("LoggerBackends not available - file logging disabled") + Logger.debug("LoggerBackends not available - file logging disabled (dev-only feature)") end end diff --git a/lib/towerops/profiles/profile_watcher.ex b/lib/towerops/profiles/profile_watcher.ex index 485400ec..a0308c20 100644 --- a/lib/towerops/profiles/profile_watcher.ex +++ b/lib/towerops/profiles/profile_watcher.ex @@ -28,16 +28,16 @@ defmodule Towerops.Profiles.ProfileWatcher do # Get the absolute path to the profiles directory profiles_path = Path.join(Application.app_dir(:towerops), @profiles_dir) - # Start watching the profiles directory for changes - {:ok, watcher_pid} = FileSystem.start_link(dirs: [profiles_path]) - FileSystem.subscribe(watcher_pid) + # Start watching the profiles directory for changes (using apply to avoid compile-time warnings) + {:ok, watcher_pid} = apply(FileSystem, :start_link, [[dirs: [profiles_path]]]) + apply(FileSystem, :subscribe, [watcher_pid]) Logger.info("ProfileWatcher: Started watching #{profiles_path}") {:ok, %{watcher_pid: watcher_pid, profiles_path: profiles_path}} else # In production, FileSystem is not available - Logger.debug("ProfileWatcher: FileSystem not available, running in no-op mode") + Logger.debug("ProfileWatcher: FileSystem not available, running in no-op mode (dev-only feature)") {:ok, %{}} end end