README.md

# PubGrub in Gleam

This repository is a Gleam port of the PubGrub version solving algorithm.
PubGrub finds a set of package versions that satisfy all constraints and, when
it cannot, produces a human-readable explanation for the conflict.

## Features

- Generic solver over package and version types.
- Deterministic resolution with explicit version ordering.
- Range operations (union, intersection, complement).
- Conflict reporting with a derivation tree.

## Getting started

Add this project as a dependency (local path or git) and use the public API in
`src/pubgrub.gleam`.

The solver requires a `compare` function for versions and a dependency provider.
An offline provider is included for tests and simple uses.

### Minimal example

```gleam
import gleam/dict
import gleam/order
import pubgrub
import pubgrub/version
import version_ranges as ranges

pub fn example() {
  let compare = version.compare

  let provider =
    pubgrub.offline_new()
    |> pubgrub.offline_add_dependencies("root", version.new(1, 0, 0), [
      #("foo", ranges.between(compare, version.new(1, 0, 0), version.new(2, 0, 0))),
    ])
    |> pubgrub.offline_add_dependencies("foo", version.new(1, 0, 0), [])

  let dp = pubgrub.offline_provider(provider, compare)
  let result = pubgrub.resolve(dp, "root", version.new(1, 0, 0))

  result
  |> case {
    Ok(solution) -> solution
    Error(err) -> {
      panic as "no solution"
    }
  }
}
```

## Integration specs

The integration tests demonstrate a tiny, readable spec format:

```
[package-a:1.0.0]
package-b = '2.0.0'

[package-b:2.0.0]
package-c = '>= 1.0.0 and < 2.0.0'
```

See `test/integration_resolution_test.gleam` for more examples and the parser.

## Ranges and comparisons

Ranges are created with an explicit compare function:

```gleam
let range = ranges.between(version.compare, version.new(1, 0, 0), version.new(2, 0, 0))
```

This lets you use semantic versions or simple integers:

```gleam
fn int_compare(a: Int, b: Int) -> order.Order {
  case a < b { True -> order.Lt False -> case a > b { True -> order.Gt False -> order.Eq } }
}
```

## Testing

Run:

```
gleam test
```

## License

Mozilla Public License 2.0