blob: 532ee089e0e16d669a7241984770d499afdc6ca1 [file] [log] [blame]
// Copyright 2022 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 crate::{BUILD_INFO_PROTOCOL, ELF_TEST_RUNNER_SHARD};
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum Warning {
/// Users must declare any capabilities that are provided by the component
DeclareExpose,
/// Users might want to use gtest/gunit/rust/gotest but we don't yet support them
ElfTestRunnerUsed,
/// CMX had includes that we naively converted to .cml
IncludesRenamed,
/// Component retrieved build info through directory API and must switch to protocol.
BuildInfoImpl,
/// Component asks for hub feature
UsesHub,
/// Child needs an additional GN target added to package, possibly capabilities routed to it
ChildNeedsGnTargetAndRouting { child: String, gn_target: String },
/// Component must be added to the storage index
StorageIndex,
/// Test will require a mock for config-data
ConfigDataInTest,
/// Component uses device directories but we can't translate them perfectly
DeviceDirectoryBestEffort,
/// Test asks for a protocol that's unavailable to hermetic & system tests
TestWithUnavailableProtocol(String),
}
const EXPOSE_WARNING: &str = r#"
// WARNING: Components must declare capabilities they provide to parents.
// Either delete or uncomment and populate these lines:
//
// capabilities: [
// "fuchsia.example.Protocol",
// ],
// expose: [
// {
// protocol: [ "fuchsia.example.Protocol" ],
// from: "self",
// },
// ],"#;
const ELF_TEST_RUNNER_WARNING: &str = r#"
// NOTE: You may want to choose a test runner that understands your language's tests. See
// https://fuchsia.dev/fuchsia-src/development/testing/components/test_runner_framework?hl=en#inventory_of_test_runners
// for details.
"#;
const INCLUDE_RENAME_WARNING: &str = r#"
// WARNING: These includes have been mechanically renamed from .cmx to .cml, it's possible
// that some of them do not yet have CML equivalents. Check with authors of the v1 shards
// if you get build errors using this manifest."#;
const BUILD_INFO_WARNING: &str = r#"
// WARNING: Build info is delivered differently in v1 & v2. See
// https://fuchsia.dev/fuchsia-src/development/components/v2/migration/features#build-info."#;
const HUB_WARNING: &str = r#"
// WARNING: Event streams replace the hub for testing in v2. For more information:
// https://fuchsia.dev/fuchsia-src/development/components/v2/migration/features#events"#;
const STORAGE_INDEX_WARNING: &str = r#"
// NOTE: Using persistent storage requires updating the storage index. For more details:
// https://fuchsia.dev/fuchsia-src/development/components/v2/migration/features#update_component_storage_index"#;
const CONFIG_DATA_TEST_WARNING: &str = r#"
// NOTE: config-data in tests requires specifying the package:
// https://fuchsia.dev/fuchsia-src/development/components/v2/migration/features?hl=en#configuration_data_in_tests
"#;
const DEVICE_DIRECTORY_WARNING: &str = r#"
// WARNING: Device directories are converted as best-effort and may need either different rights or
// a different directory name to function in v2."#;
const UNAVAILABLE_TEST_PROTOCOL_WARNING: &str = r#"
// WARNING: This protocol is not normally available to tests, you may need to add it to the
// system test realm or add a mock/fake implementation as a child.
"#;
impl Warning {
pub fn apply(&self, lines: &mut Vec<String>) {
match self {
Warning::DeclareExpose => {
let use_or_end_idx =
lines.iter().position(|l| l == " use: [").unwrap_or_else(|| {
lines.iter().position(|l| l == "}").expect(
"generated manifests all have a closing brace on their own line",
)
});
lines.insert(use_or_end_idx, EXPOSE_WARNING.to_string());
}
Warning::ElfTestRunnerUsed => {
let runner_shard_idx = lines
.iter()
.position(|l| l.contains(ELF_TEST_RUNNER_SHARD))
.expect("files with the elf test runner warning must include the shard");
lines.insert(runner_shard_idx, ELF_TEST_RUNNER_WARNING.to_string());
}
Warning::IncludesRenamed => {
let includes_idx = lines
.iter()
.position(|l| l.starts_with(" include: ["))
.expect("files with include conversion warnings must have an include block");
lines.insert(includes_idx, INCLUDE_RENAME_WARNING.to_string());
}
Warning::BuildInfoImpl => {
let build_info_proto_idx = lines
.iter()
.position(|l| l.contains(BUILD_INFO_PROTOCOL))
.expect("files with build info warning list the build info protocol");
lines.insert(build_info_proto_idx, BUILD_INFO_WARNING.to_string());
}
Warning::UsesHub => {
let opening_brace_idx = lines
.iter()
.position(|l| l == "{")
.expect("all files have an opening brace on its own line");
lines.insert(opening_brace_idx, HUB_WARNING.to_string());
}
Warning::StorageIndex => {
let storage_idx = lines
.iter()
.position(|l| l.contains("storage: \"data\","))
.expect("files with storage index warnings have a persistent data directory");
lines.insert(storage_idx, STORAGE_INDEX_WARNING.to_string());
}
Warning::ChildNeedsGnTargetAndRouting { child, gn_target } => {
let child_name_idx = lines
.iter()
.position(|l| l.contains("name: ") && l.contains(&*child))
.expect("child warnings are only emitted for children we have");
lines.insert(
child_name_idx,
format!(
r#"
// WARNING: This child must be packaged with your component. The package should depend on:
// {}
// Note that you may need to route additional capabilities to this child."#,
gn_target
),
);
}
Warning::ConfigDataInTest => {
let config_data_idx = lines
.iter()
.position(|l| l.contains("config-data"))
.expect("config-data warnings are only emitted for cml's with the use");
lines.insert(config_data_idx, CONFIG_DATA_TEST_WARNING.to_string());
}
Warning::DeviceDirectoryBestEffort => {
let dev_idx = lines
.iter()
.position(|l| l.contains("directory: \"dev-"))
.expect("device dir warnings are only emitted for cml's with devices");
lines.insert(dev_idx, DEVICE_DIRECTORY_WARNING.to_string());
}
Warning::TestWithUnavailableProtocol(protocol) => {
let proto_idx = lines
.iter()
.position(|l| l.contains(&*protocol))
.expect("uses must have protocol listed if we're warning about it");
lines.insert(proto_idx, UNAVAILABLE_TEST_PROTOCOL_WARNING.to_string());
}
}
}
}