README.md

# OptimumCredo

Custom Credo checks for Elixir projects to enforce code quality and consistency patterns that reduce manual code review cycles.

## Features

This package provides custom Credo checks to automatically catch common code quality issues:

- **Readability checks** for better code organization and patterns
- **Type safety improvements** for better documentation and maintainability
- **Assertion pattern simplifications** for more idiomatic test code

## Installation

Add the `:optimum_credo` package to your `mix.exs` dependencies:

```elixir
def deps do
  [
    {:optimum_credo, "~> 0.1", only: [:dev, :test], runtime: false},
  ]
end
```

## Usage

Add the checks you want in your `.credo.exs` configuration file:

```elixir
%{
  configs: [
    %{
      name: "default",
      requires: ["./deps/optimum_credo/lib/**/*.ex"],
      checks: [
        # Existing Credo checks...

        # OptimumCredo checks
        {OptimumCredo.Check.Readability.ModuleOrganization, []},
        {OptimumCredo.Check.Readability.DocumentationFormatting, []},
        {OptimumCredo.Check.Readability.UnusedTypes, []},
        {OptimumCredo.Check.Readability.VerboseAssertions, []},
        {OptimumCredo.Check.Readability.ExtractableSpecTypes, []},
        {OptimumCredo.Check.Readability.PrivateFunctionSpecs, []},

        # Original checks
        {OptimumCredo.Check.Readability.DepsOrder, []},
        {OptimumCredo.Check.Readability.ImportOrder, []},
        {OptimumCredo.Check.Readability.TypespecOrder, []},
      ]
    }
  ]
}
```

Then you can run `mix credo` as usual.

## Available Checks

### Readability

#### ModuleOrganization

Enforces blank line separation between different statement types (`use`, `import`, `alias`, `require`).

**Bad:**

```elixir
defmodule MyModule do
  use Supervisor
  import Telemetry.Metrics
  alias MyApp.SomeModule
end
```

**Good:**

```elixir
defmodule MyModule do
  use Supervisor

  import Telemetry.Metrics

  alias MyApp.SomeModule
end
```

#### DocumentationFormatting

Ensures proper spacing in function documentation, specifically blank lines after section headers.

**Bad:**

```elixir
@doc """
Returns the index URL.

## Examples
iex> index_url()
"http://localhost:4000/index.md"
"""
```

**Good:**

```elixir
@doc """
Returns the index URL.

## Examples

iex> index_url()
"http://localhost:4000/index.md"
"""
```

#### UnusedTypes

Detects `@type` definitions that are never used in the module.

**Bad:**

```elixir
@type short_id :: String.t()  # Never used
@type conn :: Plug.Conn.t()

@spec index(conn()) :: conn()
def index(conn), do: conn
```

**Good:**

```elixir
@type conn :: Plug.Conn.t()

@spec index(conn()) :: conn()
def index(conn), do: conn
```

#### VerboseAssertions

Detects verbose assertion patterns that can be simplified to idiomatic Elixir.

**Bad:**

```elixir
assert drop.id != nil
assert user.name == nil
refute item.id != nil
```

**Good:**

```elixir
assert drop.id
refute user.name
refute item.id
```

#### ExtractableSpecTypes

Enforces extraction of common types in `@spec` declarations to semantic module-level type aliases.

**Bad:**

```elixir
@spec show(Plug.Conn.t(), map()) :: Plug.Conn.t()
@spec index(Plug.Conn.t()) :: Plug.Conn.t()
```

**Good:**

```elixir
@type conn :: Plug.Conn.t()
@type params :: map()

@spec show(conn(), params()) :: conn()
@spec index(conn()) :: conn()
```

#### PrivateFunctionSpecs

Detects `@spec` declarations for private functions, which should not have specs.

**Bad:**

```elixir
@spec lookup_cached_entries(list()) :: {:hit, content()} | :miss
defp lookup_cached_entries(ets_match_spec) do
  # ...
end
```

**Good:**

```elixir
defp lookup_cached_entries(ets_match_spec) do
  # ...
end
```

#### DepsOrder (Original)

Enforces alphabetical ordering of dependencies in `app_deps` and `optimum_deps` functions.

#### ImportOrder (Original)

Enforces alphabetical ordering of import statements.

#### TypespecOrder (Original)

Enforces alphabetical ordering of typespec definitions.

## Benefits

1. **Reduces Manual Review Cycles**: Catches trivial formatting issues automatically
2. **Enforces Team Standards**: Consistent code organization across projects
3. **Speeds Up Development**: Less back-and-forth on style issues
4. **Improves Type Safety**: Better documentation and semantic meaning through type aliases

## Testing

Run the test suite:

```bash
mix test
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for your changes
4. Ensure all tests pass
5. Submit a pull request

## License

This project is licensed under the MIT License.