wsb 0.275.7622

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
use super::*;
use crate::test_environment::Environment;

fn git(dir: &Path, args: &[&str]) {
    let output = crate::git_backend::git_command()
        .arg("-C")
        .arg(dir)
        .args(["-c", "user.name=t", "-c", "user.email=t@t"])
        .args(args)
        .output()
        .expect("git runs");
    assert!(output.status.success(), "git {args:?}: {}", String::from_utf8_lossy(&output.stderr));
}

/// TEST20116: a note made in a worktree is written into that worktree's
/// `.wsb/`, linked to what it is about — a file, the worktree, the project —
/// found again from anywhere in the workshop by any of them, and removed with
/// its links; outside a worktree wsb manages, nothing is written.
#[test]
fn test20116_a_note_is_written_where_it_is_made_and_found_by_what_it_is_about() {
    let prj = tempfile::tempdir().unwrap();
    let machine = tempfile::tempdir().unwrap();
    let root = crate::platform::canonicalize(prj.path()).unwrap();
    let _env = Environment::set(&[
        ("PRJ", &root.to_string_lossy()),
        (crate::daemon::MACHINE_DIR_ENV, &machine.path().to_string_lossy()),
    ]);
    let main = root.join("names/main-worktree");
    std::fs::create_dir_all(main.join("src")).unwrap();
    git(&main, &["init", "--quiet"]);
    git(&main, &["remote", "add", "origin", "git@github.com:owner/names.git"]);
    wsb_prj::settings::RepoSettings {
        name: "names".to_string(),
        alias: "names".to_string(),
        templates_root: ".".to_string(),
        version: wsb_prj::settings::VersionSettings::at_major(0),
    }
    .save(&main)
    .unwrap();
    std::fs::write(main.join("src/lib.rs"), "").unwrap();

    let about = Targets {
        files: vec![main.join("src/lib.rs")],
        worktree: true,
        project: true,
        ..Default::default()
    };
    let (note, written) =
        note_add(&main.join("src"), "Why the parser is lazy", "Because.", &about, "bench").unwrap();
    assert_eq!(written.len(), 4, "the note and a link per target: {written:?}");
    assert!(written.iter().all(|path| path.starts_with(main.join(".wsb"))), "{written:?}");
    assert_eq!(note.machine, "bench");

    let index = index().unwrap();
    for about in ["path:owner/names/src/lib.rs", "worktree:owner/names/main", "project:owner/names"] {
        let found = notes_about(&index, Some(&about.parse().unwrap()));
        assert_eq!(found.len(), 1, "the note is not found by {about}");
        assert_eq!(found[0].note.id, note.id);
    }
    assert!(notes_about(&index, Some(&"machine:bench".parse().unwrap())).is_empty());

    let (edited, _) = note_edit(&main, &note.id, None, Some("Because it must be.")).unwrap();
    assert_eq!((edited.title.as_str(), edited.body.as_str()), ("Why the parser is lazy", "Because it must be."));

    let removed = note_rm(&main, &note.id).unwrap();
    assert_eq!(removed.len(), 4, "the note and every link naming it: {removed:?}");
    assert!(index_is_empty(), "something of the note was left");

    let outside = tempfile::tempdir().unwrap();
    let refused = note_add(outside.path(), "t", "", &Targets::default(), "bench").unwrap_err();
    assert!(refused.to_string().contains("no worktree wsb manages"), "{refused}");
}

fn index_is_empty() -> bool {
    let index = index().unwrap();
    index.notes.is_empty() && index.links.is_empty() && index.problems.is_empty()
}