aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/screen.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/access/screen.rs')
-rw-r--r--src/access/screen.rs44
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)?;