diff --git a/tools/aconfig/Cargo.toml b/tools/aconfig/Cargo.toml index 7b58e94631..8d93261934 100644 --- a/tools/aconfig/Cargo.toml +++ b/tools/aconfig/Cargo.toml @@ -1,22 +1,7 @@ -[package] -name = "aconfig" -version = "0.1.0" -edition = "2021" -build = "build.rs" +[workspace] -[features] -default = ["cargo"] -cargo = [] - -[dependencies] -anyhow = "1.0.69" -clap = { version = "4.1.8", features = ["derive"] } -itertools = "0.10.5" -paste = "1.0.11" -protobuf = "3.2.0" -serde = { version = "1.0.152", features = ["derive"] } -serde_json = "1.0.93" -tinytemplate = "1.2.1" - -[build-dependencies] -protobuf-codegen = "3.2.0" +members = [ + "aconfig", + "aconfig_protos", + "printflags" +] diff --git a/tools/aconfig/Android.bp b/tools/aconfig/aconfig/Android.bp similarity index 85% rename from tools/aconfig/Android.bp rename to tools/aconfig/aconfig/Android.bp index 0f9561de3d..3be456c97f 100644 --- a/tools/aconfig/Android.bp +++ b/tools/aconfig/aconfig/Android.bp @@ -2,51 +2,6 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } -// proto libraries for consumers of `aconfig dump --format=protobuf` output - -java_library { - name: "libaconfig_java_proto_lite", - host_supported: true, - srcs: ["protos/aconfig.proto"], - static_libs: ["libprotobuf-java-lite"], - proto: { - type: "lite", - }, - sdk_version: "current", - min_sdk_version: "34", - apex_available: [ - "com.android.configinfrastructure", - "//apex_available:platform", - ] -} - -java_library_host { - name: "libaconfig_java_proto_full", - srcs: ["protos/aconfig.proto"], - static_libs: ["libprotobuf-java-full"], - proto: { - type: "full", - }, -} - -python_library_host { - name: "libaconfig_python_proto", - srcs: ["protos/aconfig.proto"], - proto: { - canonical_path_from_root: false, - }, -} - -// host binary: aconfig - -rust_protobuf { - name: "libaconfig_protos", - protos: ["protos/aconfig.proto"], - crate_name: "aconfig_protos", - source_stem: "aconfig_protos", - host_supported: true, -} - rust_defaults { name: "aconfig.defaults", edition: "2021", @@ -63,9 +18,6 @@ rust_defaults { "libserde_json", "libtinytemplate", ], - proc_macros: [ - "libpaste", - ] } rust_binary_host { diff --git a/tools/aconfig/aconfig/Cargo.toml b/tools/aconfig/aconfig/Cargo.toml new file mode 100644 index 0000000000..01ad8c6760 --- /dev/null +++ b/tools/aconfig/aconfig/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "aconfig" +version = "0.1.0" +edition = "2021" + +[features] +default = ["cargo"] +cargo = [] + +[dependencies] +anyhow = "1.0.69" +clap = { version = "4.1.8", features = ["derive"] } +itertools = "0.10.5" +protobuf = "3.2.0" +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" +tinytemplate = "1.2.1" +aconfig_protos = { path = "../aconfig_protos" } diff --git a/tools/aconfig/src/codegen/cpp.rs b/tools/aconfig/aconfig/src/codegen/cpp.rs similarity index 99% rename from tools/aconfig/src/codegen/cpp.rs rename to tools/aconfig/aconfig/src/codegen/cpp.rs index 1279d8e7fa..cd71b10d52 100644 --- a/tools/aconfig/src/codegen/cpp.rs +++ b/tools/aconfig/aconfig/src/codegen/cpp.rs @@ -19,10 +19,11 @@ use serde::Serialize; use std::path::PathBuf; use tinytemplate::TinyTemplate; +use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; + use crate::codegen; use crate::codegen::CodegenMode; use crate::commands::OutputFile; -use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; pub fn generate_cpp_code( package: &str, @@ -136,7 +137,7 @@ fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) #[cfg(test)] mod tests { use super::*; - use crate::protos::ProtoParsedFlags; + use aconfig_protos::ProtoParsedFlags; use std::collections::HashMap; const EXPORTED_PROD_HEADER_EXPECTED: &str = r#" diff --git a/tools/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs similarity index 99% rename from tools/aconfig/src/codegen/java.rs rename to tools/aconfig/aconfig/src/codegen/java.rs index 78e892b479..7ce1d51a4a 100644 --- a/tools/aconfig/src/codegen/java.rs +++ b/tools/aconfig/aconfig/src/codegen/java.rs @@ -20,10 +20,11 @@ use std::collections::{BTreeMap, BTreeSet}; use std::path::PathBuf; use tinytemplate::TinyTemplate; +use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; + use crate::codegen; use crate::codegen::CodegenMode; use crate::commands::OutputFile; -use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; pub fn generate_java_code( package: &str, diff --git a/tools/aconfig/src/codegen/mod.rs b/tools/aconfig/aconfig/src/codegen/mod.rs similarity index 86% rename from tools/aconfig/src/codegen/mod.rs rename to tools/aconfig/aconfig/src/codegen/mod.rs index 64ffa8b379..7b2336f987 100644 --- a/tools/aconfig/src/codegen/mod.rs +++ b/tools/aconfig/aconfig/src/codegen/mod.rs @@ -20,32 +20,7 @@ pub mod rust; use anyhow::{ensure, Result}; use clap::ValueEnum; - -pub fn is_valid_name_ident(s: &str) -> bool { - // Identifiers must match [a-z][a-z0-9_]*, except consecutive underscores are not allowed - if s.contains("__") { - return false; - } - let mut chars = s.chars(); - let Some(first) = chars.next() else { - return false; - }; - if !first.is_ascii_lowercase() { - return false; - } - chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_') -} - -pub fn is_valid_package_ident(s: &str) -> bool { - if !s.contains('.') { - return false; - } - s.split('.').all(is_valid_name_ident) -} - -pub fn is_valid_container_ident(s: &str) -> bool { - s.split('.').all(is_valid_name_ident) -} +use aconfig_protos::{is_valid_name_ident, is_valid_package_ident}; pub fn create_device_config_ident(package: &str, flag_name: &str) -> Result { ensure!(is_valid_package_ident(package), "bad package"); @@ -75,6 +50,7 @@ impl std::fmt::Display for CodegenMode { #[cfg(test)] mod tests { use super::*; + use aconfig_protos::is_valid_container_ident; #[test] fn test_is_valid_name_ident() { diff --git a/tools/aconfig/src/codegen/rust.rs b/tools/aconfig/aconfig/src/codegen/rust.rs similarity index 99% rename from tools/aconfig/src/codegen/rust.rs rename to tools/aconfig/aconfig/src/codegen/rust.rs index 8a88ffecc7..33c3d37633 100644 --- a/tools/aconfig/src/codegen/rust.rs +++ b/tools/aconfig/aconfig/src/codegen/rust.rs @@ -18,10 +18,11 @@ use anyhow::Result; use serde::Serialize; use tinytemplate::TinyTemplate; +use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; + use crate::codegen; use crate::codegen::CodegenMode; use crate::commands::OutputFile; -use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag}; pub fn generate_rust_code( package: &str, diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs similarity index 96% rename from tools/aconfig/src/commands.rs rename to tools/aconfig/aconfig/src/commands.rs index a35ad08730..93bc436fd8 100644 --- a/tools/aconfig/src/commands.rs +++ b/tools/aconfig/aconfig/src/commands.rs @@ -26,7 +26,7 @@ use crate::codegen::java::generate_java_code; use crate::codegen::rust::generate_rust_code; use crate::codegen::CodegenMode; use crate::dump::{DumpFormat, DumpPredicate}; -use crate::protos::{ +use aconfig_protos::{ ParsedFlagExt, ProtoFlagMetadata, ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag, ProtoParsedFlags, ProtoTracepoint, }; @@ -44,7 +44,7 @@ impl Input { self.reader .read_to_end(&mut buffer) .with_context(|| format!("failed to read {}", self.source))?; - crate::protos::parsed_flags::try_from_binary_proto(&buffer) + aconfig_protos::parsed_flags::try_from_binary_proto(&buffer) .with_context(|| self.error_context()) } @@ -77,7 +77,7 @@ pub fn parse_flags( .read_to_string(&mut contents) .with_context(|| format!("failed to read {}", input.source))?; - let flag_declarations = crate::protos::flag_declarations::try_from_text_proto(&contents) + let flag_declarations = aconfig_protos::flag_declarations::try_from_text_proto(&contents) .with_context(|| input.error_context())?; ensure!( package == flag_declarations.package(), @@ -96,7 +96,7 @@ pub fn parse_flags( ); } for mut flag_declaration in flag_declarations.flag.into_iter() { - crate::protos::flag_declaration::verify_fields(&flag_declaration) + aconfig_protos::flag_declaration::verify_fields(&flag_declaration) .with_context(|| input.error_context())?; // create ParsedFlag using FlagDeclaration and default values @@ -130,7 +130,7 @@ pub fn parse_flags( parsed_flag.metadata = Some(metadata).into(); // verify ParsedFlag looks reasonable - crate::protos::parsed_flag::verify_fields(&parsed_flag)?; + aconfig_protos::parsed_flag::verify_fields(&parsed_flag)?; // verify ParsedFlag can be added ensure!( @@ -151,10 +151,10 @@ pub fn parse_flags( .reader .read_to_string(&mut contents) .with_context(|| format!("failed to read {}", input.source))?; - let flag_values = crate::protos::flag_values::try_from_text_proto(&contents) + let flag_values = aconfig_protos::flag_values::try_from_text_proto(&contents) .with_context(|| input.error_context())?; for flag_value in flag_values.flag_value.into_iter() { - crate::protos::flag_value::verify_fields(&flag_value) + aconfig_protos::flag_value::verify_fields(&flag_value) .with_context(|| input.error_context())?; let Some(parsed_flag) = parsed_flags @@ -184,8 +184,8 @@ pub fn parse_flags( } // Create a sorted parsed_flags - crate::protos::parsed_flags::sort_parsed_flags(&mut parsed_flags); - crate::protos::parsed_flags::verify_fields(&parsed_flags)?; + aconfig_protos::parsed_flags::sort_parsed_flags(&mut parsed_flags); + aconfig_protos::parsed_flags::verify_fields(&parsed_flags)?; let mut output = Vec::new(); parsed_flags.write_to_vec(&mut output)?; Ok(output) @@ -287,7 +287,7 @@ pub fn dump_parsed_flags( let individually_parsed_flags: Result> = input.iter_mut().map(|i| i.try_parse_flags()).collect(); let parsed_flags: ProtoParsedFlags = - crate::protos::parsed_flags::merge(individually_parsed_flags?, dedup)?; + aconfig_protos::parsed_flags::merge(individually_parsed_flags?, dedup)?; let filters: Vec> = if filters.is_empty() { vec![Box::new(|_| true)] } else { @@ -386,16 +386,16 @@ where #[cfg(test)] mod tests { use super::*; - use crate::protos::ProtoFlagPurpose; + use aconfig_protos::ProtoFlagPurpose; #[test] fn test_parse_flags() { let parsed_flags = crate::test::parse_test_flags(); // calls parse_flags - crate::protos::parsed_flags::verify_fields(&parsed_flags).unwrap(); + aconfig_protos::parsed_flags::verify_fields(&parsed_flags).unwrap(); let enabled_ro = parsed_flags.parsed_flag.iter().find(|pf| pf.name() == "enabled_ro").unwrap(); - assert!(crate::protos::parsed_flag::verify_fields(enabled_ro).is_ok()); + assert!(aconfig_protos::parsed_flag::verify_fields(enabled_ro).is_ok()); assert_eq!("com.android.aconfig.test", enabled_ro.package()); assert_eq!("enabled_ro", enabled_ro.name()); assert_eq!("This flag is ENABLED + READ_ONLY", enabled_ro.description()); @@ -462,7 +462,7 @@ mod tests { ) .unwrap(); let parsed_flags = - crate::protos::parsed_flags::try_from_binary_proto(&flags_bytes).unwrap(); + aconfig_protos::parsed_flags::try_from_binary_proto(&flags_bytes).unwrap(); assert_eq!(1, parsed_flags.parsed_flag.len()); let parsed_flag = parsed_flags.parsed_flag.first().unwrap(); assert_eq!(ProtoFlagState::DISABLED, parsed_flag.state()); @@ -602,7 +602,7 @@ mod tests { ) .unwrap(); let parsed_flags = - crate::protos::parsed_flags::try_from_binary_proto(&flags_bytes).unwrap(); + aconfig_protos::parsed_flags::try_from_binary_proto(&flags_bytes).unwrap(); assert_eq!(1, parsed_flags.parsed_flag.len()); let parsed_flag = parsed_flags.parsed_flag.first().unwrap(); assert_eq!(ProtoFlagPurpose::PURPOSE_FEATURE, parsed_flag.metadata.purpose()); diff --git a/tools/aconfig/src/dump.rs b/tools/aconfig/aconfig/src/dump.rs similarity index 99% rename from tools/aconfig/src/dump.rs rename to tools/aconfig/aconfig/src/dump.rs index 37368eec1a..12352f99f8 100644 --- a/tools/aconfig/src/dump.rs +++ b/tools/aconfig/aconfig/src/dump.rs @@ -14,10 +14,10 @@ * limitations under the License. */ -use crate::protos::{ +use aconfig_protos::{ ParsedFlagExt, ProtoFlagMetadata, ProtoFlagPermission, ProtoFlagState, ProtoTracepoint, }; -use crate::protos::{ProtoParsedFlag, ProtoParsedFlags}; +use aconfig_protos::{ProtoParsedFlag, ProtoParsedFlags}; use anyhow::{anyhow, bail, Context, Result}; use protobuf::Message; @@ -197,7 +197,7 @@ fn create_filter_predicate_single(filter: &str) -> Result> { #[cfg(test)] mod tests { use super::*; - use crate::protos::ProtoParsedFlags; + use aconfig_protos::ProtoParsedFlags; use crate::test::parse_test_flags; use protobuf::Message; diff --git a/tools/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs similarity index 97% rename from tools/aconfig/src/main.rs rename to tools/aconfig/aconfig/src/main.rs index 120e98caa7..30a7e9db92 100644 --- a/tools/aconfig/src/main.rs +++ b/tools/aconfig/aconfig/src/main.rs @@ -27,7 +27,6 @@ use std::path::{Path, PathBuf}; mod codegen; mod commands; mod dump; -mod protos; mod storage; use codegen::CodegenMode; @@ -57,8 +56,8 @@ fn cli() -> Command { .arg( Arg::new("default-permission") .long("default-permission") - .value_parser(protos::flag_permission::parse_from_str) - .default_value(protos::flag_permission::to_string( + .value_parser(aconfig_protos::flag_permission::parse_from_str) + .default_value(aconfig_protos::flag_permission::to_string( &commands::DEFAULT_FLAG_PERMISSION, )), ) @@ -215,7 +214,7 @@ fn main() -> Result<()> { let declarations = open_zero_or_more_files(sub_matches, "declarations")?; let values = open_zero_or_more_files(sub_matches, "values")?; let default_permission = - get_required_arg::(sub_matches, "default-permission")?; + get_required_arg::(sub_matches, "default-permission")?; let output = commands::parse_flags( package, container, diff --git a/tools/aconfig/src/storage/flag_table.rs b/tools/aconfig/aconfig/src/storage/flag_table.rs similarity index 100% rename from tools/aconfig/src/storage/flag_table.rs rename to tools/aconfig/aconfig/src/storage/flag_table.rs diff --git a/tools/aconfig/src/storage/flag_value.rs b/tools/aconfig/aconfig/src/storage/flag_value.rs similarity index 99% rename from tools/aconfig/src/storage/flag_value.rs rename to tools/aconfig/aconfig/src/storage/flag_value.rs index 45f5ec0c08..3c5bb17384 100644 --- a/tools/aconfig/src/storage/flag_value.rs +++ b/tools/aconfig/aconfig/src/storage/flag_value.rs @@ -15,7 +15,7 @@ */ use crate::commands::assign_flag_ids; -use crate::protos::ProtoFlagState; +use aconfig_protos::ProtoFlagState; use crate::storage::{self, FlagPackage}; use anyhow::{anyhow, Result}; diff --git a/tools/aconfig/src/storage/mod.rs b/tools/aconfig/aconfig/src/storage/mod.rs similarity index 98% rename from tools/aconfig/src/storage/mod.rs rename to tools/aconfig/aconfig/src/storage/mod.rs index b4a8b5e5aa..4f2dc81a03 100644 --- a/tools/aconfig/src/storage/mod.rs +++ b/tools/aconfig/aconfig/src/storage/mod.rs @@ -22,7 +22,7 @@ use anyhow::{anyhow, Result}; use std::collections::{hash_map::DefaultHasher, HashMap, HashSet}; use std::hash::{Hash, Hasher}; -use crate::protos::{ProtoParsedFlag, ProtoParsedFlags}; +use aconfig_protos::{ProtoParsedFlag, ProtoParsedFlags}; use crate::storage::{ flag_table::FlagTable, flag_value::FlagValueList, package_table::PackageTable, }; @@ -221,7 +221,7 @@ mod tests { crate::commands::DEFAULT_FLAG_PERMISSION, ) .unwrap(); - crate::protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() + aconfig_protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() }) .collect() } diff --git a/tools/aconfig/src/storage/package_table.rs b/tools/aconfig/aconfig/src/storage/package_table.rs similarity index 100% rename from tools/aconfig/src/storage/package_table.rs rename to tools/aconfig/aconfig/src/storage/package_table.rs diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/aconfig/src/test.rs similarity index 97% rename from tools/aconfig/src/test.rs rename to tools/aconfig/aconfig/src/test.rs index cbb95b8ef0..7b5318d2e0 100644 --- a/tools/aconfig/src/test.rs +++ b/tools/aconfig/aconfig/src/test.rs @@ -17,7 +17,7 @@ #[cfg(test)] pub mod test_utils { use crate::commands::Input; - use crate::protos::ProtoParsedFlags; + use aconfig_protos::ProtoParsedFlags; use itertools; pub const TEST_PACKAGE: &str = "com.android.aconfig.test"; @@ -265,7 +265,7 @@ parsed_flag { crate::commands::DEFAULT_FLAG_PERMISSION, ) .unwrap(); - crate::protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() + aconfig_protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() } pub fn parse_test_flags() -> ProtoParsedFlags { @@ -289,7 +289,7 @@ parsed_flag { crate::commands::DEFAULT_FLAG_PERMISSION, ) .unwrap(); - crate::protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() + aconfig_protos::parsed_flags::try_from_binary_proto(&bytes).unwrap() } pub fn first_significant_code_diff(a: &str, b: &str) -> Option { diff --git a/tools/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template similarity index 100% rename from tools/aconfig/templates/FakeFeatureFlagsImpl.java.template rename to tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template diff --git a/tools/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template similarity index 100% rename from tools/aconfig/templates/FeatureFlags.java.template rename to tools/aconfig/aconfig/templates/FeatureFlags.java.template diff --git a/tools/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template similarity index 100% rename from tools/aconfig/templates/FeatureFlagsImpl.java.template rename to tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template diff --git a/tools/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template similarity index 100% rename from tools/aconfig/templates/Flags.java.template rename to tools/aconfig/aconfig/templates/Flags.java.template diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/aconfig/templates/cpp_exported_header.template similarity index 100% rename from tools/aconfig/templates/cpp_exported_header.template rename to tools/aconfig/aconfig/templates/cpp_exported_header.template diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/aconfig/templates/cpp_source_file.template similarity index 100% rename from tools/aconfig/templates/cpp_source_file.template rename to tools/aconfig/aconfig/templates/cpp_source_file.template diff --git a/tools/aconfig/templates/rust.template b/tools/aconfig/aconfig/templates/rust.template similarity index 100% rename from tools/aconfig/templates/rust.template rename to tools/aconfig/aconfig/templates/rust.template diff --git a/tools/aconfig/templates/rust_test.template b/tools/aconfig/aconfig/templates/rust_test.template similarity index 100% rename from tools/aconfig/templates/rust_test.template rename to tools/aconfig/aconfig/templates/rust_test.template diff --git a/tools/aconfig/tests/AconfigHostTest.java b/tools/aconfig/aconfig/tests/AconfigHostTest.java similarity index 100% rename from tools/aconfig/tests/AconfigHostTest.java rename to tools/aconfig/aconfig/tests/AconfigHostTest.java diff --git a/tools/aconfig/tests/AconfigTest.java b/tools/aconfig/aconfig/tests/AconfigTest.java similarity index 100% rename from tools/aconfig/tests/AconfigTest.java rename to tools/aconfig/aconfig/tests/AconfigTest.java diff --git a/tools/aconfig/tests/AndroidManifest.xml b/tools/aconfig/aconfig/tests/AndroidManifest.xml similarity index 100% rename from tools/aconfig/tests/AndroidManifest.xml rename to tools/aconfig/aconfig/tests/AndroidManifest.xml diff --git a/tools/aconfig/tests/aconfig_exported_mode_test.cpp b/tools/aconfig/aconfig/tests/aconfig_exported_mode_test.cpp similarity index 100% rename from tools/aconfig/tests/aconfig_exported_mode_test.cpp rename to tools/aconfig/aconfig/tests/aconfig_exported_mode_test.cpp diff --git a/tools/aconfig/tests/aconfig_exported_mode_test.rs b/tools/aconfig/aconfig/tests/aconfig_exported_mode_test.rs similarity index 100% rename from tools/aconfig/tests/aconfig_exported_mode_test.rs rename to tools/aconfig/aconfig/tests/aconfig_exported_mode_test.rs diff --git a/tools/aconfig/tests/aconfig_force_read_only_mode_test.cpp b/tools/aconfig/aconfig/tests/aconfig_force_read_only_mode_test.cpp similarity index 100% rename from tools/aconfig/tests/aconfig_force_read_only_mode_test.cpp rename to tools/aconfig/aconfig/tests/aconfig_force_read_only_mode_test.cpp diff --git a/tools/aconfig/tests/aconfig_force_read_only_mode_test.rs b/tools/aconfig/aconfig/tests/aconfig_force_read_only_mode_test.rs similarity index 100% rename from tools/aconfig/tests/aconfig_force_read_only_mode_test.rs rename to tools/aconfig/aconfig/tests/aconfig_force_read_only_mode_test.rs diff --git a/tools/aconfig/tests/aconfig_prod_mode_test.rs b/tools/aconfig/aconfig/tests/aconfig_prod_mode_test.rs similarity index 100% rename from tools/aconfig/tests/aconfig_prod_mode_test.rs rename to tools/aconfig/aconfig/tests/aconfig_prod_mode_test.rs diff --git a/tools/aconfig/tests/aconfig_test.cpp b/tools/aconfig/aconfig/tests/aconfig_test.cpp similarity index 100% rename from tools/aconfig/tests/aconfig_test.cpp rename to tools/aconfig/aconfig/tests/aconfig_test.cpp diff --git a/tools/aconfig/tests/aconfig_test_mode_test.rs b/tools/aconfig/aconfig/tests/aconfig_test_mode_test.rs similarity index 100% rename from tools/aconfig/tests/aconfig_test_mode_test.rs rename to tools/aconfig/aconfig/tests/aconfig_test_mode_test.rs diff --git a/tools/aconfig/tests/aconfig_test_test_variant.cpp b/tools/aconfig/aconfig/tests/aconfig_test_test_variant.cpp similarity index 100% rename from tools/aconfig/tests/aconfig_test_test_variant.cpp rename to tools/aconfig/aconfig/tests/aconfig_test_test_variant.cpp diff --git a/tools/aconfig/tests/first.values b/tools/aconfig/aconfig/tests/first.values similarity index 100% rename from tools/aconfig/tests/first.values rename to tools/aconfig/aconfig/tests/first.values diff --git a/tools/aconfig/tests/read_only_test.aconfig b/tools/aconfig/aconfig/tests/read_only_test.aconfig similarity index 100% rename from tools/aconfig/tests/read_only_test.aconfig rename to tools/aconfig/aconfig/tests/read_only_test.aconfig diff --git a/tools/aconfig/tests/read_only_test.values b/tools/aconfig/aconfig/tests/read_only_test.values similarity index 100% rename from tools/aconfig/tests/read_only_test.values rename to tools/aconfig/aconfig/tests/read_only_test.values diff --git a/tools/aconfig/tests/second.values b/tools/aconfig/aconfig/tests/second.values similarity index 100% rename from tools/aconfig/tests/second.values rename to tools/aconfig/aconfig/tests/second.values diff --git a/tools/aconfig/tests/storage_test_1.aconfig b/tools/aconfig/aconfig/tests/storage_test_1.aconfig similarity index 100% rename from tools/aconfig/tests/storage_test_1.aconfig rename to tools/aconfig/aconfig/tests/storage_test_1.aconfig diff --git a/tools/aconfig/tests/storage_test_2.aconfig b/tools/aconfig/aconfig/tests/storage_test_2.aconfig similarity index 100% rename from tools/aconfig/tests/storage_test_2.aconfig rename to tools/aconfig/aconfig/tests/storage_test_2.aconfig diff --git a/tools/aconfig/tests/storage_test_4.aconfig b/tools/aconfig/aconfig/tests/storage_test_4.aconfig similarity index 100% rename from tools/aconfig/tests/storage_test_4.aconfig rename to tools/aconfig/aconfig/tests/storage_test_4.aconfig diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/aconfig/tests/test.aconfig similarity index 100% rename from tools/aconfig/tests/test.aconfig rename to tools/aconfig/aconfig/tests/test.aconfig diff --git a/tools/aconfig/tests/test_exported.aconfig b/tools/aconfig/aconfig/tests/test_exported.aconfig similarity index 100% rename from tools/aconfig/tests/test_exported.aconfig rename to tools/aconfig/aconfig/tests/test_exported.aconfig diff --git a/tools/aconfig/tests/test_force_read_only.aconfig b/tools/aconfig/aconfig/tests/test_force_read_only.aconfig similarity index 100% rename from tools/aconfig/tests/test_force_read_only.aconfig rename to tools/aconfig/aconfig/tests/test_force_read_only.aconfig diff --git a/tools/aconfig/aconfig_protos/Android.bp b/tools/aconfig/aconfig_protos/Android.bp new file mode 100644 index 0000000000..1cc4e419e2 --- /dev/null +++ b/tools/aconfig/aconfig_protos/Android.bp @@ -0,0 +1,62 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +// proto libraries for consumers of `aconfig dump --format=protobuf` output + +java_library { + name: "libaconfig_java_proto_lite", + host_supported: true, + srcs: ["protos/aconfig.proto"], + static_libs: ["libprotobuf-java-lite"], + proto: { + type: "lite", + }, + sdk_version: "current", + min_sdk_version: "UpsideDownCake", + apex_available: [ + "com.android.configinfrastructure", + "//apex_available:platform", + ] +} + +java_library_host { + name: "libaconfig_java_proto_full", + srcs: ["protos/aconfig.proto"], + static_libs: ["libprotobuf-java-full"], + proto: { + type: "full", + }, +} + +python_library_host { + name: "libaconfig_python_proto", + srcs: ["protos/aconfig.proto"], + proto: { + canonical_path_from_root: false, + }, +} + +rust_protobuf { + name: "libaconfig_rust_proto", + protos: ["protos/aconfig.proto"], + crate_name: "aconfig_rust_proto", + source_stem: "aconfig_rust_proto", + host_supported: true, +} + +rust_library { + name: "libaconfig_protos", + srcs: ["src/lib.rs"], + crate_name: "aconfig_protos", + host_supported: true, + lints: "none", + rustlibs: [ + "libaconfig_rust_proto", + "libanyhow", + "libprotobuf", + ], + proc_macros: [ + "libpaste", + ] +} diff --git a/tools/aconfig/aconfig_protos/Cargo.toml b/tools/aconfig/aconfig_protos/Cargo.toml new file mode 100644 index 0000000000..114cf80612 --- /dev/null +++ b/tools/aconfig/aconfig_protos/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aconfig_protos" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[features] +default = ["cargo"] +cargo = [] + +[dependencies] +anyhow = "1.0.69" +paste = "1.0.11" +protobuf = "3.2.0" + +[build-dependencies] +protobuf-codegen = "3.2.0" diff --git a/tools/aconfig/build.rs b/tools/aconfig/aconfig_protos/build.rs similarity index 100% rename from tools/aconfig/build.rs rename to tools/aconfig/aconfig_protos/build.rs diff --git a/tools/aconfig/protos/aconfig.proto b/tools/aconfig/aconfig_protos/protos/aconfig.proto similarity index 100% rename from tools/aconfig/protos/aconfig.proto rename to tools/aconfig/aconfig_protos/protos/aconfig.proto diff --git a/tools/aconfig/src/protos.rs b/tools/aconfig/aconfig_protos/src/lib.rs similarity index 92% rename from tools/aconfig/src/protos.rs rename to tools/aconfig/aconfig_protos/src/lib.rs index 2684d20278..f0d27d6d47 100644 --- a/tools/aconfig/src/protos.rs +++ b/tools/aconfig/aconfig_protos/src/lib.rs @@ -29,17 +29,17 @@ // ---- When building with the Android tool-chain ---- #[cfg(not(feature = "cargo"))] mod auto_generated { - pub use aconfig_protos::aconfig::flag_metadata::Flag_purpose as ProtoFlagPurpose; - pub use aconfig_protos::aconfig::Flag_declaration as ProtoFlagDeclaration; - pub use aconfig_protos::aconfig::Flag_declarations as ProtoFlagDeclarations; - pub use aconfig_protos::aconfig::Flag_metadata as ProtoFlagMetadata; - pub use aconfig_protos::aconfig::Flag_permission as ProtoFlagPermission; - pub use aconfig_protos::aconfig::Flag_state as ProtoFlagState; - pub use aconfig_protos::aconfig::Flag_value as ProtoFlagValue; - pub use aconfig_protos::aconfig::Flag_values as ProtoFlagValues; - pub use aconfig_protos::aconfig::Parsed_flag as ProtoParsedFlag; - pub use aconfig_protos::aconfig::Parsed_flags as ProtoParsedFlags; - pub use aconfig_protos::aconfig::Tracepoint as ProtoTracepoint; + pub use aconfig_rust_proto::aconfig::flag_metadata::Flag_purpose as ProtoFlagPurpose; + pub use aconfig_rust_proto::aconfig::Flag_declaration as ProtoFlagDeclaration; + pub use aconfig_rust_proto::aconfig::Flag_declarations as ProtoFlagDeclarations; + pub use aconfig_rust_proto::aconfig::Flag_metadata as ProtoFlagMetadata; + pub use aconfig_rust_proto::aconfig::Flag_permission as ProtoFlagPermission; + pub use aconfig_rust_proto::aconfig::Flag_state as ProtoFlagState; + pub use aconfig_rust_proto::aconfig::Flag_value as ProtoFlagValue; + pub use aconfig_rust_proto::aconfig::Flag_values as ProtoFlagValues; + pub use aconfig_rust_proto::aconfig::Parsed_flag as ProtoParsedFlag; + pub use aconfig_rust_proto::aconfig::Parsed_flags as ProtoParsedFlags; + pub use aconfig_rust_proto::aconfig::Tracepoint as ProtoTracepoint; } // ---- When building with cargo ---- @@ -68,6 +68,32 @@ pub use auto_generated::*; use anyhow::Result; use paste::paste; +pub fn is_valid_name_ident(s: &str) -> bool { + // Identifiers must match [a-z][a-z0-9_]*, except consecutive underscores are not allowed + if s.contains("__") { + return false; + } + let mut chars = s.chars(); + let Some(first) = chars.next() else { + return false; + }; + if !first.is_ascii_lowercase() { + return false; + } + chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_') +} + +pub fn is_valid_package_ident(s: &str) -> bool { + if !s.contains('.') { + return false; + } + s.split('.').all(is_valid_name_ident) +} + +pub fn is_valid_container_ident(s: &str) -> bool { + s.split('.').all(is_valid_name_ident) +} + fn try_from_text_proto(s: &str) -> Result where T: protobuf::MessageFull, @@ -87,14 +113,13 @@ macro_rules! ensure_required_fields { pub mod flag_declaration { use super::*; - use crate::codegen; use anyhow::ensure; pub fn verify_fields(pdf: &ProtoFlagDeclaration) -> Result<()> { ensure_required_fields!("flag declaration", pdf, "name", "namespace", "description"); - ensure!(codegen::is_valid_name_ident(pdf.name()), "bad flag declaration: bad name"); - ensure!(codegen::is_valid_name_ident(pdf.namespace()), "bad flag declaration: bad name"); + ensure!(is_valid_name_ident(pdf.name()), "bad flag declaration: bad name"); + ensure!(is_valid_name_ident(pdf.namespace()), "bad flag declaration: bad name"); ensure!(!pdf.description().is_empty(), "bad flag declaration: empty description"); ensure!(pdf.bug.len() == 1, "bad flag declaration: exactly one bug required"); @@ -104,7 +129,6 @@ pub mod flag_declaration { pub mod flag_declarations { use super::*; - use crate::codegen; use anyhow::ensure; pub fn try_from_text_proto(s: &str) -> Result { @@ -118,11 +142,11 @@ pub mod flag_declarations { // TODO(b/312769710): Make the container field required. ensure!( - codegen::is_valid_package_ident(pdf.package()), + is_valid_package_ident(pdf.package()), "bad flag declarations: bad package" ); ensure!( - !pdf.has_container() || codegen::is_valid_container_ident(pdf.container()), + !pdf.has_container() || is_valid_container_ident(pdf.container()), "bad flag declarations: bad container" ); for flag_declaration in pdf.flag.iter() { @@ -135,14 +159,13 @@ pub mod flag_declarations { pub mod flag_value { use super::*; - use crate::codegen; use anyhow::ensure; pub fn verify_fields(fv: &ProtoFlagValue) -> Result<()> { ensure_required_fields!("flag value", fv, "package", "name", "state", "permission"); - ensure!(codegen::is_valid_package_ident(fv.package()), "bad flag value: bad package"); - ensure!(codegen::is_valid_name_ident(fv.name()), "bad flag value: bad name"); + ensure!(is_valid_package_ident(fv.package()), "bad flag value: bad package"); + ensure!(is_valid_name_ident(fv.name()), "bad flag value: bad name"); Ok(()) } @@ -200,7 +223,6 @@ pub mod tracepoint { pub mod parsed_flag { use super::*; - use crate::codegen; use anyhow::ensure; pub fn verify_fields(pf: &ProtoParsedFlag) -> Result<()> { @@ -215,13 +237,13 @@ pub mod parsed_flag { "permission" ); - ensure!(codegen::is_valid_package_ident(pf.package()), "bad parsed flag: bad package"); + ensure!(is_valid_package_ident(pf.package()), "bad parsed flag: bad package"); ensure!( - !pf.has_container() || codegen::is_valid_container_ident(pf.container()), + !pf.has_container() || is_valid_container_ident(pf.container()), "bad parsed flag: bad container" ); - ensure!(codegen::is_valid_name_ident(pf.name()), "bad parsed flag: bad name"); - ensure!(codegen::is_valid_name_ident(pf.namespace()), "bad parsed flag: bad namespace"); + ensure!(is_valid_name_ident(pf.name()), "bad parsed flag: bad name"); + ensure!(is_valid_name_ident(pf.namespace()), "bad parsed flag: bad namespace"); ensure!(!pf.description().is_empty(), "bad parsed flag: empty description"); ensure!(!pf.trace.is_empty(), "bad parsed flag: empty trace"); for tp in pf.trace.iter() { @@ -261,7 +283,7 @@ pub mod parsed_flags { } pub fn verify_fields(pf: &ProtoParsedFlags) -> Result<()> { - use crate::protos::parsed_flag::path_to_declaration; + use crate::parsed_flag::path_to_declaration; let mut previous: Option<&ProtoParsedFlag> = None; for parsed_flag in pf.parsed_flag.iter() { @@ -848,7 +870,7 @@ parsed_flag { let parsed_flags = try_from_binary_proto_from_text_proto(text_proto).unwrap(); let parsed_flag = &parsed_flags.parsed_flag[0]; assert_eq!( - crate::protos::parsed_flag::path_to_declaration(parsed_flag), + crate::parsed_flag::path_to_declaration(parsed_flag), "flags.declarations" ); } diff --git a/tools/aconfig/printflags/Cargo.toml b/tools/aconfig/printflags/Cargo.toml new file mode 100644 index 0000000000..7313f5d044 --- /dev/null +++ b/tools/aconfig/printflags/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "printflags" +version = "0.1.0" +edition = "2021" + +[features] +default = ["cargo"] +cargo = [] + +[dependencies] +anyhow = "1.0.69" +paste = "1.0.11" +protobuf = "3.2.0" +regex = "1.10.3" +aconfig_protos = { path = "../aconfig_protos" } diff --git a/tools/aconfig/printflags/src/main.rs b/tools/aconfig/printflags/src/main.rs index ae9b83aae6..7fcde61273 100644 --- a/tools/aconfig/printflags/src/main.rs +++ b/tools/aconfig/printflags/src/main.rs @@ -16,8 +16,8 @@ //! `printflags` is a device binary to print feature flags. -use aconfig_protos::aconfig::Flag_state as State; -use aconfig_protos::aconfig::Parsed_flags as ProtoParsedFlags; +use aconfig_protos::ProtoFlagState as State; +use aconfig_protos::ProtoParsedFlags as ProtoParsedFlags; use anyhow::{bail, Context, Result}; use regex::Regex; use std::collections::BTreeMap;