summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/manifest.rs26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/manifest.rs b/src/manifest.rs
index 3a34af7..bc09073 100644
--- a/src/manifest.rs
+++ b/src/manifest.rs
@@ -31,6 +31,7 @@ impl ArtifactManifest {
files.sort_by(|left, right| left.path.cmp(&right.path));
services.sort_by(|left, right| left.name.cmp(&right.name));
archive_members.sort_by(|left, right| left.path.cmp(&right.path));
+ validate_file_records(&files)?;
ensure_unique("package", packages.iter().map(|record| record.name.as_str()))?;
ensure_unique("file", files.iter().map(|record| record.path.as_str()))?;
ensure_unique("service", services.iter().map(|record| record.name.as_str()))?;
@@ -355,6 +356,31 @@ fn link_target(path: &Path) -> Result<String> {
Ok(value.to_owned())
}
+fn validate_file_records(records: &[FileRecord]) -> Result<()> {
+ for record in records {
+ match record.kind.as_str() {
+ "file" => {
+ if record.digest.as_deref().is_none_or(str::is_empty) {
+ bail!("regular file record requires a digest: {}", record.path);
+ }
+ if record.target.is_some() {
+ bail!("regular file record cannot carry a target: {}", record.path);
+ }
+ }
+ "symlink" | "hardlink" => {
+ if record.digest.is_some() {
+ bail!("{} record cannot carry a digest: {}", record.kind, record.path);
+ }
+ if record.target.as_deref().is_none_or(str::is_empty) {
+ bail!("{} record requires a target: {}", record.kind, record.path);
+ }
+ }
+ _ => bail!("unsupported file record kind {}: {}", record.kind, record.path),
+ }
+ }
+ Ok(())
+}
+
fn ensure_unique<'a>(kind: &str, keys: impl IntoIterator<Item = &'a str>) -> Result<()> {
let mut seen = HashSet::new();
for key in keys {