diff options
Diffstat (limited to 'src/access')
| -rw-r--r-- | src/access/screen.rs | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/access/screen.rs b/src/access/screen.rs index 162528b..758c83b 100644 --- a/src/access/screen.rs +++ b/src/access/screen.rs @@ -288,7 +288,15 @@ pub(crate) fn apply( let decoded: Vec<crate::document::ExpandedChange> = ready.iter().map(|change| change.decode()).collect(); - let ops: Vec<Vec<Op>> = Inspector::new(doc).ops(&decoded); + // Without a policy here, nor one among these: none judged but an epoch's root, and + // nothing placed. A change writing the policy writes at its key. + let judging = super::policy::of(&*doc).enforced() + || crate::document::inspect::touch_key(&decoded, "policy"); + let ops: Vec<Vec<Op>> = if judging { + Inspector::new(doc).ops(&decoded) + } else { + vec![Vec::new(); decoded.len()] + }; let paths: Vec<BTreeSet<Path>> = ops .iter() .map(|ops| ops.iter().map(|op| op.path.clone()).collect()) @@ -431,26 +439,32 @@ pub(crate) fn apply( } } let seen_at: Vec<ChangeHash> = seen_at.into_iter().collect(); - let judged = rules::judge( - doc, - epoch, - &rules::Change { - hash, - deps: change.deps(), - seen: &seen_at, - committer, - user: user.as_deref(), - paths: &paths[index], - ops: &ops[index], - }, - ); + let root = change.deps().is_empty(); + let judged = if judging || root { + rules::judge( + doc, + epoch, + &rules::Change { + hash, + deps: change.deps(), + seen: &seen_at, + committer, + user: user.as_deref(), + paths: &paths[index], + ops: &ops[index], + }, + ) + } else { + Ok(()) + }; match judged { Ok(()) => { accepted.push(change.clone()); if let Some(committer) = committer { screened.taken_from.insert(committer.to_owned()); } - if relevant(&paths[index]) || reaches_signed(doc, &paths[index]) { + // A root too: whether another may be one is read in the document. + if root || relevant(&paths[index]) || reaches_signed(doc, &paths[index]) { // What rules read changed: in before the next is judged. screened.applied += accepted.len(); apply_taken(doc, std::mem::take(&mut accepted), log)?; |
