blob: c4468b830b6cdc91f847f7353d6d2e02bca9c283 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::collections::HashMap;
use sdk_metadata::{HostTool, JsonObject, TargetArchitecture};
use crate::app::Result;
use crate::file_provider::{merge_files, FileProvider};
use crate::tarball::{InputTarball, OutputTarball, TarballContent};
impl FileProvider for HostTool {
fn get_common_files(&self) -> Vec<String> {
if let Some(files) = self.files.clone() {
return files;
}
Vec::new()
}
fn get_arch_files(&self) -> HashMap<TargetArchitecture, Vec<String>> {
if let Some(files) = self.target_files.clone() {
return files;
}
HashMap::new()
}
}
pub fn merge_host_tool<F: TarballContent>(
meta_path: &str, base: &impl InputTarball<F>, complement: &impl InputTarball<F>,
output: &mut impl OutputTarball<F>,
) -> Result<()> {
let base_meta: HostTool = base.get_metadata(meta_path)?;
let complement_meta: HostTool = complement.get_metadata(meta_path)?;
merge_files(&base_meta, base, &complement_meta, complement, output)?;
let mut meta = base_meta.clone();
if let Some(complement_target_files) = &complement_meta.target_files {
if let Some(meta_target_files) = &mut meta.target_files {
for (arch, files) in complement_target_files {
meta_target_files.insert(arch.clone(), files.to_vec());
}
} else {
meta.target_files = complement_meta.target_files.clone();
}
}
meta.validate()?;
output.write_json(meta_path, &meta)?;
Ok(())
}
#[cfg(test)]
mod tests {
use crate::testing::{MockInputTarball, MockOutputTarball};
use super::*;
#[test]
fn test_merge() {
let meta = "tools/foobar-meta.json";
let data = r#"
{
"name": "foobar",
"type": "host_tool",
"root": "tools",
"files": [
"tools/foobar"
]
}
"#;
let base = MockInputTarball::new();
base.add(meta, data);
base.add("tools/foobar", "I am a tool");
let complement = MockInputTarball::new();
complement.add(meta, data);
complement.add("tools/foobar", "I am a tool");
let mut output = MockOutputTarball::new();
merge_host_tool(meta, &base, &complement, &mut output).expect("Should not fail!");
output.assert_has_file(meta);
output.assert_has_file("tools/foobar");
}
#[test]
fn test_merge_multiple_architectures() {
let meta = "tools/foobar-meta.json";
let base_data = r#"
{
"name": "foobar",
"type": "host_tool",
"root": "tools",
"target_files": {
"x64": [
"tools/foobar_x64"
]
}
}
"#;
let complement_data = r#"
{
"name": "foobar",
"type": "host_tool",
"root": "tools",
"target_files": {
"arm64": [
"tools/foobar_arm64"
]
}
}
"#;
let base = MockInputTarball::new();
base.add(meta, base_data);
base.add("tools/foobar_x64", "I am a tool");
let complement = MockInputTarball::new();
complement.add(meta, complement_data);
complement.add("tools/foobar_arm64", "I am a tool too");
let mut output = MockOutputTarball::new();
merge_host_tool(meta, &base, &complement, &mut output).expect("Should not fail!");
output.assert_has_file(meta);
output.assert_has_file("tools/foobar_x64");
output.assert_has_file("tools/foobar_arm64");
let data = HostTool::new(output.get_content(meta).as_bytes()).unwrap();
assert!(data.target_files.is_some());
assert!(
data.target_files.unwrap().len() == 2,
"Invalid number of architectures"
);
}
}