Reconstruct a view's manifest from a pulled [`SyncPack`]: find the view's ref target, then its view-snapshot object, and render the manifest text. Returns `None` when the pack carries no ref/snapshot for `name` (the remote view does not exist). This replaces the per-object `get_view_ref` + `get_object("views", …)` round-trips: a pull now reads the remote's view state from the single `/code` sync
(pack: &SyncPack, name: &str, url: &str)
| 61 | /// round-trips: a pull now reads the remote's view state from the single `/code` |
| 62 | /// sync response. |
| 63 | fn manifest_from_pack(pack: &SyncPack, name: &str, url: &str) -> CliResult<Option<ViewManifest>> { |
| 64 | let target = match pack.refs.iter().find(|r| r.name == name) { |
| 65 | Some(r) => r.new_target.clone(), |
| 66 | None => return Ok(None), |
| 67 | }; |
| 68 | let snapshot = pack |
| 69 | .objects |
| 70 | .iter() |
| 71 | .find(|o| o.family == ObjectFamily::View && o.key == target) |
| 72 | .and_then(|o| ViewSnapshot::from_bytes(&o.bytes)); |
| 73 | let snapshot = match snapshot { |
| 74 | Some(s) => s, |
| 75 | None => return Ok(None), |
| 76 | }; |
| 77 | let manifest = ViewManifest::parse(&snapshot.to_manifest_text(name)).map_err(|e| { |
| 78 | CliError::RemoteError { |
| 79 | message: format!("Corrupt manifest for view '{name}': {e}"), |
| 80 | url: Some(url.to_string()), |
| 81 | } |
| 82 | })?; |
| 83 | // O(1) producer-integrity cross-check: the snapshot's declared `own_set_id` |
| 84 | // must equal the order-invariant fold of its own change list. Content |
| 85 | // addressing guarantees the object's bytes, but not that a (buggy) producer |
| 86 | // minted a self-consistent set-id; this catches that cheaply. |
| 87 | let mut fold = SetId::ZERO; |
| 88 | for h in &manifest.changes { |
| 89 | fold = fold.add(h); |
| 90 | } |
| 91 | if fold.to_base32() != snapshot.own_set_id { |
| 92 | print_warning(&format!( |
| 93 | "Remote view '{name}' snapshot set-id disagrees with its change list; \ |
| 94 | the remote object may be inconsistent." |
| 95 | )); |
| 96 | } |
| 97 | Ok(Some(manifest)) |
| 98 | } |
| 99 | |
| 100 | /// Index a pack's objects of one family into `content key → bytes`. |
| 101 | fn pack_objects_by_key(pack: &SyncPack, family: ObjectFamily) -> HashMap<String, Vec<u8>> { |
no test coverage detected