Packages

Custom Credo checks for common Elixir/Phoenix anti-patterns and CWE Top 25 security vulnerabilities. Provides 58 comprehensive checks in total.

Current section

Files

Jump to
Raw

mix.exs

defmodule OeditusCredo.MixProject do
use Mix.Project
@version "0.11.2"
@source_url "https://github.com/Oeditus/oeditus_credo"
@homepage_url "https://oeditus.com"
def project do
[
app: :oeditus_credo,
version: @version,
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps(),
description: description(),
package: package(),
docs: docs(),
aliases: aliases(),
escript: escript(),
test_coverage: [tool: ExCoveralls],
dialyzer: [
plt_add_apps: [:mix, :credo],
plt_core_path: "priv/plts",
plt_file: {:no_warn, "priv/plts/dialyzer.plt"}
],
name: "OeditusCredo",
source_url: @source_url,
homepage_url: @homepage_url
]
end
def application do
[
# :tools provides :cover, used by the ChangeRiskAntiPatterns check to read
# persisted coverage data.
extra_applications: [:logger, :tools]
]
end
defp escript do
[
main_module: OeditusCredo.Escript,
name: "oeditus_credo",
embed_elixir: true,
app: nil
]
end
def cli do
[
preferred_envs: [
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.json": :test
]
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp deps do
[
# Core dependency
{:credo, "~> 1.7"},
# Optional: type-aware checks (Elixir 1.20+)
{:typle, "~> 0.3", optional: true},
# Development and documentation
{:ex_doc, "~> 0.31", only: :dev, runtime: false},
{:excoveralls, "~> 0.18", only: :test, runtime: false},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}
]
end
defp aliases do
[
quality: ["format", "credo --strict", "dialyzer"],
"quality.ci": [
"format --check-formatted",
"credo --strict",
"dialyzer"
]
]
end
defp description do
"""
Custom Credo checks for common Elixir/Phoenix anti-patterns and
CWE Top 25 security vulnerabilities.
Provides 58 comprehensive checks in total.
"""
end
defp package do
[
name: "oeditus_credo",
files: ~w(
lib
.formatter.exs
mix.exs
README.md
STANDALONE.md
LICENSE
NOTICE.md
CHANGELOG.md
),
licenses: ["MIT"],
maintainers: ["Oeditus Team"],
links: %{
"GitHub" => @source_url,
"Homepage" => @homepage_url,
"Changelog" => "#{@source_url}/blob/main/CHANGELOG.md",
"Documentation" => "https://hexdocs.pm/oeditus_credo"
}
]
end
defp docs do
[
main: "readme",
logo: "stuff/img/logo-oeditus-credo-48x48.png",
assets: %{"stuff/img" => "assets"},
extras: extras(),
extra_section: "GUIDES",
source_url: @source_url,
source_ref: "v#{@version}",
homepage_url: @homepage_url,
formatters: ["html", "epub"],
groups_for_modules: groups_for_modules(),
nest_modules_by_prefix: [
OeditusCredo.Check.Warning,
OeditusCredo.Check.Security,
OeditusCredo.Check.Refactoring,
OeditusCredo.Check.Readability
],
before_closing_body_tag: &before_closing_body_tag/1,
authors: ["Oeditus Team"],
canonical: "https://hexdocs.pm/oeditus_credo",
skip_undefined_reference_warnings_on: ["CHANGELOG.md"]
]
end
defp extras do
[
"README.md",
"QUICKSTART.md": [title: "Quick Start"],
"STANDALONE.md": [title: "Standalone Usage"],
LICENSE: [title: "License"],
"CHANGELOG.md": [title: "Changelog"],
"stuff/docs/Automated Detection of Common Elixir Phoenix Mistakes.md": [
filename: "automated_detection",
title: "Automated Detection"
]
]
end
defp groups_for_modules do
[
"Error Handling": [
OeditusCredo.Check.Warning.MissingErrorHandling,
OeditusCredo.Check.Warning.SilentErrorCase,
OeditusCredo.Check.Warning.SwallowingException
],
"Database & Performance": [
OeditusCredo.Check.Warning.InefficientFilter,
OeditusCredo.Check.Warning.NPlusOneQuery,
OeditusCredo.Check.Warning.MissingPreload
],
"LiveView & Concurrency": [
OeditusCredo.Check.Warning.UnmanagedTask,
OeditusCredo.Check.Warning.SyncOverAsync,
OeditusCredo.Check.Warning.MissingHandleAsync,
OeditusCredo.Check.Warning.MissingThrottle,
OeditusCredo.Check.Warning.InlineJavascript
],
Readability: [
OeditusCredo.Check.Readability.UnnecessaryInterpolatingSigil
],
"Code Quality": [
OeditusCredo.Check.Warning.DirectStructUpdate,
OeditusCredo.Check.Warning.CallbackHell,
OeditusCredo.Check.Warning.BlockingInPlug,
OeditusCredo.Check.Warning.UnsafeMapAccess
],
"Code Organization & Idiomatic Refactoring": [
OeditusCredo.Check.Refactoring.AvoidSinglePipe,
OeditusCredo.Check.Refactoring.AvoidUnawaitedTaskAsync,
OeditusCredo.Check.Refactoring.PreferCasePatternMatching,
OeditusCredo.Check.Refactoring.PreferDestructuring,
OeditusCredo.Check.Refactoring.PreferDotAccessForStructs,
OeditusCredo.Check.Refactoring.PreferForComprehensionOverFilterMap,
OeditusCredo.Check.Refactoring.PreferFunctionCapture,
OeditusCredo.Check.Refactoring.PreferInplaceBinaryMatching,
OeditusCredo.Check.Refactoring.PreferInplaceListMatching,
OeditusCredo.Check.Refactoring.PreferInplaceMapMatching,
OeditusCredo.Check.Refactoring.PreferListPrepend,
OeditusCredo.Check.Refactoring.PreferMapMerge,
OeditusCredo.Check.Refactoring.PreferMultiHeadForNil,
OeditusCredo.Check.Refactoring.PreferMultiHeadFunction,
OeditusCredo.Check.Refactoring.PreferPatternMatchingForEmptiness,
OeditusCredo.Check.Refactoring.PreferPipelineOperator,
OeditusCredo.Check.Refactoring.PreferShortFieldAccessCapture,
OeditusCredo.Check.Refactoring.PreferStringBoundariesOverRegex,
OeditusCredo.Check.Refactoring.PreferTaggedTuplesForErrors,
OeditusCredo.Check.Refactoring.PreferWithClause
],
"Refactoring Suggestions": [
OeditusCredo.Check.Refactoring.SuggestFSM,
OeditusCredo.Check.Refactoring.ChangeRiskAntiPatterns
],
"Telemetry & Observability": [
OeditusCredo.Check.Warning.TelemetryInRecursiveFunction,
OeditusCredo.Check.Warning.MissingTelemetryInAuthPlug,
OeditusCredo.Check.Warning.MissingTelemetryForExternalHttp
],
"Security - Injection": [
OeditusCredo.Check.Security.SQLInjection,
OeditusCredo.Check.Security.OSCommandInjection,
OeditusCredo.Check.Security.CodeInjection,
OeditusCredo.Check.Security.XSSVulnerability
],
"Security - Authentication & Authorization": [
OeditusCredo.Check.Security.MissingAuthentication,
OeditusCredo.Check.Security.MissingAuthorization,
OeditusCredo.Check.Security.IncorrectAuthorization,
OeditusCredo.Check.Security.InsecureDirectObjectReference
],
"Security - Data Protection": [
OeditusCredo.Check.Security.SensitiveDataExposure,
OeditusCredo.Check.Security.HardcodedCredentials,
OeditusCredo.Check.Security.UnsafeDeserialization
],
"Security - Input & File Handling": [
OeditusCredo.Check.Security.ImproperInputValidation,
OeditusCredo.Check.Security.PathTraversal,
OeditusCredo.Check.Security.UnrestrictedFileUpload
],
"Security - Web": [
OeditusCredo.Check.Security.MissingCSRFProtection,
OeditusCredo.Check.Security.SSRFVulnerability
],
"Security - Race Conditions": [
OeditusCredo.Check.Security.TOCTOU
]
]
end
defp before_closing_body_tag(:html) do
"""
<script>
// Add search keyboard shortcut
document.addEventListener("keydown", function(e) {
if (e.key === "/" && !e.ctrlKey && !e.metaKey) {
e.preventDefault();
document.querySelector(".search-input")?.focus();
}
});
</script>
"""
end
defp before_closing_body_tag(_), do: ""
end