moondepsolve

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

    semver
    dependency-resolver
    package-manager
    solver
    contest
    Download zip
    Version
    0.4.0
    License
    Apache-2.0
    Last updated
    14 hours ago
    Downloads
    9

    #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.

    #Install and Migrate to v0.4.0

    The maintained module is now python123-ops/moondepsolve, matching the current Mooncakes account. The earlier python123/moondepsolve@0.3.1 package remains available under its original owner; it cannot be updated using the current account. Version 0.4.0 carries the maintenance fixes from 0.3.2 into the new namespace.

    moon add python123-ops/moondepsolve@0.4.0

    Replace the old module path in your package imports:

    import {
    "python123-ops/moondepsolve",
    }

    The package alias remains @moondepsolve, so API calls keep the same names. Existing users should remove the old python123/moondepsolve dependency after replacing its imports. The earlier GitHub releases and competition documents retain their original namespace as historical records.

    #Maintenance Included

    • Updated for MoonBit 0.10.19+97801ee1b (2026-10-30) and moonbitlang/async@0.22.7.
    • Made the existing equality methods explicit to keep strict compiler checks passing.
    • Fixed numeric overflow, leading zeroes, malformed prerelease identifiers, large numeric prerelease ordering, and exact requirements containing x in prerelease names.
    • Added range-bound overflow checks and regression tests. All four stable backends pass: 35 tests each on Wasm, Wasm GC, and JavaScript, and 39 on native.
    • Added a cross-platform CLI check for four byte-for-byte outputs and three failure cases; CI runs on Linux and Windows with a pinned toolchain.
    • Reduced the Mooncakes archive to source, tests, examples, metadata, and license notices through .moonignore.

    #v0.3 Features

    • 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

    Use MoonBit 0.10.19+97801ee1b or a compatible newer toolchain. The pinned version is tested in CI; older toolchains may not understand the updated async dependency's package configuration.

    Default backend:

    python scripts/check_contributor_identity.py --ref HEAD moon info moon fmt --check moon check --deny-warn moon test --target all --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 python scripts/check_cli.py

    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.

    #Version and Requirement Syntax

    Versions use major.minor.patch with an optional -prerelease. Core components range from 0 to 2147483647 and reject leading zeroes. Prerelease identifiers follow the SemVer identifier and precedence rules; numeric prerelease identifiers can exceed the core component limit. Build metadata (+build) is not supported by the current Version type.

    Requirements support exact versions, ^major.minor.patch, ~major.minor.patch, space-separated comparators, and patch wildcards such as 1.2.x, 1.2.X, or 1.2.*. A generated upper bound must fit the core component range. Matching applies the comparators directly, including to prereleases; it does not add npm-style prerelease exclusion. OR expressions, hyphen ranges, and bare * are not supported.

    #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

    • This maintenance release is maintained on GitHub. GitLink retains the earlier competition history.
    • CI runs contributor identity checks, interface drift checks, formatting, diagnostics, all stable backend tests, native file CLI regressions, and package validation on Linux and Windows.
    • 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 and API documentation: python123-ops/moondepsolve@0.4.0. Publication status and downloadable archives are tracked in the GitHub release.

    #License

    MoonDepSolve is released under the Apache License 2.0.

    Comparator

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

    Comparator::equal

    fn Comparator::equal(Comparator, Comparator) -> Bool

    Comparator::not_equal

    fn Comparator::not_equal(x : Comparator, y : Comparator) -> Bool

    CompareOp

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

    CompareOp::equal

    fn CompareOp::equal(CompareOp, CompareOp) -> Bool

    CompareOp::not_equal

    fn CompareOp::not_equal(x : CompareOp, y : CompareOp) -> Bool

    ConflictKind

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

    ConflictKind::equal

    ConflictKind::not_equal

    fn ConflictKind::not_equal(x : ConflictKind, y : ConflictKind) -> Bool

    ConflictReport

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

    ConflictReport::equal

    ConflictReport::not_equal

    fn ConflictReport::not_equal(x : ConflictReport, y : ConflictReport) -> Bool

    DepError

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

    DepError::equal

    fn DepError::equal(DepError, DepError) -> Bool

    DepError::not_equal

    fn DepError::not_equal(x : DepError, y : DepError) -> Bool

    Dependency

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

    Dependency::equal

    fn Dependency::equal(Dependency, Dependency) -> Bool

    Dependency::not_equal

    fn Dependency::not_equal(x : Dependency, y : Dependency) -> Bool

    DependencyEdge

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

    DependencyEdge::equal

    DependencyEdge::not_equal

    fn DependencyEdge::not_equal(x : DependencyEdge, y : DependencyEdge) -> Bool

    DependencyGraph

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

    DependencyGraph::equal

    DependencyGraph::not_equal

    fn DependencyGraph::not_equal(x : DependencyGraph, y : DependencyGraph) -> Bool

    GraphNode

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

    GraphNode::equal

    fn GraphNode::equal(GraphNode, GraphNode) -> Bool

    GraphNode::not_equal

    fn GraphNode::not_equal(x : GraphNode, y : GraphNode) -> Bool

    PackageVersion

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

    PackageVersion::equal

    PackageVersion::not_equal

    fn PackageVersion::not_equal(x : PackageVersion, y : PackageVersion) -> Bool

    Registry

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

    Registry::equal

    fn Registry::equal(Registry, Registry) -> Bool

    Registry::not_equal

    fn Registry::not_equal(x : Registry, y : Registry) -> Bool

    Resolution

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

    Resolution::equal

    fn Resolution::equal(Resolution, Resolution) -> Bool

    Resolution::not_equal

    fn Resolution::not_equal(x : Resolution, y : Resolution) -> Bool

    UpgradeChange

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

    UpgradeChange::equal

    UpgradeChange::not_equal

    fn UpgradeChange::not_equal(x : UpgradeChange, y : UpgradeChange) -> Bool

    UpgradeChangeKind

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

    UpgradeChangeKind::equal

    UpgradeChangeKind::not_equal

    fn UpgradeChangeKind::not_equal(x : UpgradeChangeKind, y : UpgradeChangeKind) -> Bool

    UpgradeError

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

    UpgradeError::equal

    UpgradeError::not_equal

    fn UpgradeError::not_equal(x : UpgradeError, y : UpgradeError) -> Bool

    UpgradeOptions

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

    UpgradeOptions::equal

    UpgradeOptions::not_equal

    fn UpgradeOptions::not_equal(x : UpgradeOptions, y : UpgradeOptions) -> Bool

    UpgradePlan

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

    UpgradePlan::equal

    fn UpgradePlan::equal(UpgradePlan, UpgradePlan) -> Bool

    UpgradePlan::not_equal

    fn UpgradePlan::not_equal(x : UpgradePlan, y : UpgradePlan) -> Bool

    UpgradeStrategy

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

    UpgradeStrategy::equal

    UpgradeStrategy::not_equal

    fn UpgradeStrategy::not_equal(x : UpgradeStrategy, y : UpgradeStrategy) -> Bool

    Version

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

    Version::equal

    fn Version::equal(Version, Version) -> Bool

    Version::not_equal

    fn Version::not_equal(x : Version, y : Version) -> Bool

    VersionReq

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

    VersionReq::equal

    fn VersionReq::equal(VersionReq, VersionReq) -> Bool

    VersionReq::not_equal

    fn VersionReq::not_equal(x : VersionReq, y : VersionReq) -> Bool

    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 issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io