MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / put_view_manifest

Method put_view_manifest

atomic-remote/src/http/upload.rs:144–200  ·  view source on GitHub ↗

Declare a view's identity and change log on the remote. POSTs the manifest text (header `name\tscope\tparent\tstate` plus the change log, one base32 hash per line). The server applies it declaratively: creates the view with the declared scope/parent if absent, fast-forwards its log, and verifies the resulting merkle equals the declared state. Every referenced change must already be on the server

(&self, view: &str, manifest_text: String)

Source from the content-addressed store, hash-verified

142 /// String-level like the rest of this client: serialization lives in
143 /// `atomic-repository`.
144 pub async fn put_view_manifest(&self, view: &str, manifest_text: String) -> RemoteResult<()> {
145 let url = format!("{}?view-manifest={}", self.base_url, view);
146 debug!(
147 "POST view-manifest: {} ({} bytes)",
148 url,
149 manifest_text.len()
150 );
151
152 let response = self
153 .client
154 .post(&url)
155 .header(CONTENT_TYPE, "text/plain")
156 .body(manifest_text)
157 .send()
158 .await
159 .map_err(|e| RemoteError::connection_failed(&url, e))?;
160
161 crate::check_min_version_header(response.headers());
162 let status = response.status();
163
164 match status {
165 StatusCode::OK => {
166 debug!("Successfully declared view manifest for {}", view);
167 Ok(())
168 }
169 StatusCode::NOT_FOUND => Err(RemoteError::repo_not_found(&url)),
170 StatusCode::CONFLICT => {
171 // Divergence / identity mismatch / state mismatch.
172 let msg = response.text().await.unwrap_or_default();
173 Err(RemoteError::protocol(msg))
174 }
175 StatusCode::UNAUTHORIZED | StatusCode::FORBIDDEN => {
176 let msg = response.text().await.unwrap_or_default();
177 Err(RemoteError::auth_failed(&url, msg))
178 }
179 StatusCode::BAD_REQUEST => {
180 let msg = response.text().await.unwrap_or_default();
181 // A missing change/dependency from the manifest apply names the
182 // offending hash(es); surface them instead of "0 dependencies",
183 // and fall back to the full server message when none parse.
184 if msg.contains("missing") && msg.contains("change") {
185 let hashes = extract_change_hashes(&msg);
186 if hashes.is_empty() {
187 Err(RemoteError::http(status.as_u16(), msg))
188 } else {
189 Err(RemoteError::missing_deps(hashes))
190 }
191 } else {
192 Err(RemoteError::http(status.as_u16(), msg))
193 }
194 }
195 _ => {
196 let msg = response.text().await.unwrap_or_default();
197 Err(RemoteError::http(status.as_u16(), msg))
198 }
199 }
200 }
201

Callers 1

run_asyncMethod · 0.80

Calls 8

check_min_version_headerFunction · 0.85
extract_change_hashesFunction · 0.85
postMethod · 0.80
textMethod · 0.80
headerMethod · 0.45
statusMethod · 0.45
containsMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected