moondepsolve

A MoonBit semantic version, version range, and dependency resolution library for package ecosystem tooling.

semver
dependency-resolver
package-manager
solver
contest
moon add python123/moondepsolve@0.3.1
Download zip
Author
Version
0.3.1
License
Apache-2.0
Last updated
last month
Downloads
18

Dependencies

README

#MoonDepSolve

CI License Release

MoonDepSolve is a MoonBit library and native CLI for semantic versions, deterministic dependency resolution, lock output, dependency graphs, conflict reports, and exact upgrade planning.

#What It Solves

MoonBit ecosystem tools need a small, reviewable dependency core: parse versions, match version ranges, choose compatible package versions, explain conflicts, and write stable lock output. MoonDepSolve keeps that boundary narrow so it can be reused by package managers, build tools, dependency audits, and release automation.

#v0.3 Highlights

  • HighestCompatible chooses the highest compatible package set through the existing resolver.
  • MinimalChange searches bounded candidate states, first minimizing changed packages and then preferring higher versions for deterministic ties.
  • UpgradePlan reports stable add, remove, upgrade, and downgrade changes with the target Resolution.
  • The native CLI reads registry and lock files, then emits lock output, a text dependency graph, or Graphviz DOT.
  • Four example-driven CLI checks compare real file outputs byte for byte.

v0.3 is additive. Existing v0.1/v0.2 APIs for version parsing, requirement matching, resolution, lock output, dependency graphs, and conflict reports remain available.

#Quick Verification

Default backend:

python scripts/check_contributor_identity.py --ref HEAD moon info moon fmt --check moon check --deny-warn moon test --deny-warn moon run cmd/main --deny-warn

Native CLI path, on a machine with a C compiler:

moon check --target native --deny-warn moon test --target native --deny-warn sh scripts/demo-v0.3.sh

ConflictReport.package_name replaces the earlier package field so OSC2026 quality gates can run with --deny-warn and no reserved-keyword suppression. Formatted reports still print package: ... for stable CLI output.

#File CLI

Registry rows use name version | dependency:requirement:

app 1.1.0 | core:^1.1.0, logging:1.0.x core 1.2.0 logging 1.0.0

Resolve and print a lock:

moon run cmd/cli --target native -- \ resolve \ --registry examples/registry.txt \ --root 'app:^1.0.0' \ --format lock

Plan from an existing lock:

moon run cmd/cli --target native -- \ plan \ --registry examples/registry.txt \ --lock examples/current.lock \ --root 'app:^1.0.0' \ --strategy minimal \ --max-states 100000

Expected minimal-change output starts with:

strategy: minimal-change changes: 0 target lock: # MoonDepSolve lock app 1.0.0 core 1.0.0 logging 1.0.0

Use --strategy highest to generate a highest-compatible upgrade plan. --max-states must be positive; if the bound is exhausted, MoonDepSolve returns SearchLimitExceeded instead of pretending it found an optimum.

#Library API

CapabilityPublic API
Versionsparse_version, format_version, compare_version
Requirementsparse_req, matches
Resolutionresolve
Registry and lockparse_registry, format_lock, parse_lock
Base errorsformat_error
Dependency graphbuild_dependency_graph, format_graph_text, format_graph_dot
Conflict reportbuild_conflict_report, format_conflict_report
Upgrade planningdefault_upgrade_options, plan_upgrade, format_upgrade_plan, format_upgrade_error

Exact signatures are tracked in pkg.generated.mbti.

#Project Evidence

  • GitHub and GitLink master are kept at the same commit.
  • CI runs contributor identity checks, interface drift checks, formatting, diagnostics, default tests, native tests, and file CLI regressions.
  • The OSC2026 materials are in docs/competition, including the one-page proposal PDF, demo script, release notes, and acceptance checklist.
  • License and dependency notices are in LICENSE and THIRD_PARTY_NOTICES.md.

Mooncakes package: python123/moondepsolve version 0.3.0 is published. Version 0.3.1 packages and validates locally; final Mooncakes publication requires logging in as the module owner python123.

#License

MoonDepSolve is released under the Apache License 2.0.

#
Comparator

pub(all) struct Comparator {
op : CompareOp
version : Version
} derive(Eq)

#
CompareOp

pub(all) enum CompareOp {
Eq
Gt
Gte
Lt
Lte
} derive(Eq)

#
ConflictKind

pub(all) enum ConflictKind {
MissingPackage
NoMatchingVersion
SelectedVersionConflict
} derive(Eq)

#
ConflictReport

pub(all) struct ConflictReport {
kind : ConflictKind
package_name : String
requirement : String?
selected_version : String?
dependency_path : String?
available_versions : Array[Version]
} derive(Eq)

#
DepError

pub(all) enum DepError {
InvalidVersion(String, String)
InvalidReq(String, String)
PackageNotFound(String)
NoMatchingVersion(String, String)
VersionConflict(String, String, String, String)
} derive(Eq)

#
Dependency

pub(all) struct Dependency {
name : String
req : VersionReq
} derive(Eq)

#
DependencyEdge

pub(all) struct DependencyEdge {
from : GraphNode
to : GraphNode
requirement : String
} derive(Eq)

#
DependencyGraph

pub(all) struct DependencyGraph {
nodes : Array[GraphNode]
edges : Array[DependencyEdge]
} derive(Eq)

#
GraphNode

pub(all) enum GraphNode {
Root
Package(String, Version)
Unresolved(String)
} derive(Eq)

#
PackageVersion

pub(all) struct PackageVersion {
name : String
version : Version
dependencies : Array[Dependency]
} derive(Eq)

#
Registry

pub(all) struct Registry {
packages : Array[PackageVersion]
} derive(Eq)

#
Resolution

pub(all) struct Resolution {
packages : Array[PackageVersion]
} derive(Eq)

#
UpgradeChange

pub(all) struct UpgradeChange {
kind : UpgradeChangeKind
package_name : String
from_version : Version?
to_version : Version?
} derive(Eq)

#
UpgradeChangeKind

pub(all) enum UpgradeChangeKind {
Add
Remove
Upgrade
Downgrade
} derive(Eq)

#
UpgradeError

pub(all) enum UpgradeError {
DependencyFailure(DepError)
InvalidSearchLimit(Int)
SearchLimitExceeded(Int)
} derive(Eq)

#
UpgradeOptions

pub(all) struct UpgradeOptions {
strategy : UpgradeStrategy
max_states : Int
} derive(Eq)

#
UpgradePlan

pub(all) struct UpgradePlan {
strategy : UpgradeStrategy
resolution : Resolution
changes : Array[UpgradeChange]
} derive(Eq)

#
UpgradeStrategy

pub(all) enum UpgradeStrategy {
HighestCompatible
MinimalChange
} derive(Eq)

#
Version

pub(all) struct Version {
major : Int
minor : Int
patch : Int
prerelease : String?
} derive(Eq)

#
VersionReq

pub(all) struct VersionReq {
raw : String
comparators : Array[Comparator]
} derive(Eq)

#
build_conflict_report

fn build_conflict_report(error : DepError, registry : Registry) -> ConflictReport?

#
build_dependency_graph

fn build_dependency_graph(root : Array[Dependency], resolution : Resolution) -> DependencyGraph

#
compare_version

fn compare_version(left : Version, right : Version) -> Int

#
default_upgrade_options

fn default_upgrade_options(strategy : UpgradeStrategy) -> UpgradeOptions

#
format_conflict_report

fn format_conflict_report(report : ConflictReport) -> String

#
format_error

fn format_error(err : DepError) -> String

#
format_graph_dot

fn format_graph_dot(graph : DependencyGraph) -> String

#
format_graph_text

fn format_graph_text(graph : DependencyGraph) -> String

#
format_lock

fn format_lock(resolution : Resolution) -> String

#
format_upgrade_error

fn format_upgrade_error(error : UpgradeError) -> String

#
format_upgrade_plan

fn format_upgrade_plan(plan : UpgradePlan) -> String

#
format_version

fn format_version(version : Version) -> String

#
matches

fn matches(version : Version, req : VersionReq) -> Bool

#
parse_lock

fn parse_lock(input : String) -> Result[Resolution, DepError]

#
parse_registry

fn parse_registry(input : String) -> Result[Registry, DepError]

#
parse_req

fn parse_req(input : String) -> Result[VersionReq, DepError]

#
parse_version

fn parse_version(input : String) -> Result[Version, DepError]

#
plan_upgrade

fn plan_upgrade(root : Array[Dependency], current : Resolution, registry : Registry, options : UpgradeOptions) -> Result[UpgradePlan, UpgradeError]

#
resolve

fn resolve(root : Array[Dependency], registry : Registry) -> Result[Resolution, DepError]

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io