pub fn group(
paths: &[String],
vocabulary: &ScopeVocabulary,
derived: &[String],
) -> Vec<CommitGroup>Expand description
Group a set of paths into the commits the evidence supports.
The evidence is the scope vocabulary: paths the history scopes the same way are one commit. Paths the vocabulary knows nothing about are one further group rather than one group each, because the alternative — a commit per unrecognised file — is never what somebody wanted and is the failure that makes a planner untrustworthy on its first run in a new repository.
derived is the subset of paths this repository generates. Its presence collapses the
plan to one commit, and the reason is project.derived-files-regenerated: a generated
file is a projection of the whole tree, so only the last of several commits could carry a
current one and every earlier commit would be stale by construction — which the
derived-current hook then refuses, one commit at a time, after the split has already
been made. The planner found this on its first run against its own change set, where it
proposed putting twenty-three generated files in a commit of their own.
use majordomus_cli::commit::{plan::group, ScopeVocabulary};
let mut v = ScopeVocabulary::default();
v.learn("alpha", "src/alpha", 40);
v.learn("derive", "docs/generated", 180);
let paths: Vec<String> = vec!["src/alpha/a.rs".into(), "docs/generated/x.json".into()];
// without the derived-file rule the scopes alone would make two commits
assert_eq!(group(&paths, &v, &[]).len(), 2);
// with one of them generated, it is one, and the rationale names the rule that decided
let one = group(&paths, &v, &["docs/generated/x.json".into()]);
assert_eq!(one.len(), 1);
assert!(one[0].rationale.contains("derived-files-regenerated"), "{}", one[0].rationale);