swh-graph-stdlib 13.0.0

Library of algorithms and data structures for swh-graph
Documentation
// Copyright (C) 2024-2026  The Software Heritage developers
// See the AUTHORS file at the top-level directory of this distribution
// License: GNU General Public License version 3, or any later version
// See top-level LICENSE file for more information

use anyhow::Result;

use swh_graph::graph_builder::GraphBuilder;
use swh_graph::swhid;
use swh_graph_stdlib::*;

mod data;

#[test]
fn test_find_head_rev() -> Result<()> {
    let mut builder = GraphBuilder::default();
    let snp0 = builder
        .node(swhid!(swh:1:snp:0000000000000000000000000000000000000000))?
        .done();
    let rev1 = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000001))?
        .done();
    let rev2 = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000002))?
        .done();
    let rev3 = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000003))?
        .done();
    builder.snp_arc(snp0, rev1, "refs/heads/bug");
    builder.snp_arc(snp0, rev2, "refs/heads/main");
    builder.snp_arc(snp0, rev3, "refs/heads/new-sux");
    let graph = builder.done()?;

    assert_eq!(vcs::find_head_rev(&graph, snp0)?, Some(rev2));
    Ok(())
}

#[test]
fn test_list_root_revisions() -> Result<()> {
    // Graph structure (arrows = rev->rev arcs, ie. "has parent"):
    //   a <- b <- d
    //        c <-
    //   e <- f
    //
    // Root revisions (no parent): a, c, e
    let mut builder = GraphBuilder::default();
    let a = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000010))?
        .done();
    let b = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000020))?
        .done();
    let c = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000030))?
        .done();
    let d = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000040))?
        .done();
    let e = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000050))?
        .done();
    let f = builder
        .node(swhid!(swh:1:rev:0000000000000000000000000000000000000060))?
        .done();
    // Non-rev node to check it's excluded
    let dir = builder
        .node(swhid!(swh:1:dir:0000000000000000000000000000000000000070))?
        .done();

    builder.arc(b, a);
    builder.arc(d, b);
    builder.arc(d, c);
    builder.arc(f, e);
    builder.arc(b, dir); // rev -> dir, ignored by the rev-only subgraph

    let graph = builder.done()?;
    let mut roots = vcs::list_root_revisions(&graph)?;
    roots.sort();

    assert_eq!(roots, vec![a, c, e]);

    Ok(())
}