Merge "Restructure aconfig repo to be a cargo workspace with many crates" into main
This commit is contained in:
commit
9f34a48141
51 changed files with 205 additions and 156 deletions
|
@ -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"
|
||||
]
|
||||
|
|
|
@ -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: "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,
|
||||
},
|
||||
}
|
||||
|
||||
// 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 {
|
18
tools/aconfig/aconfig/Cargo.toml
Normal file
18
tools/aconfig/aconfig/Cargo.toml
Normal file
|
@ -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" }
|
|
@ -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<I>(
|
||||
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#"
|
|
@ -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<I>(
|
||||
package: &str,
|
|
@ -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<String> {
|
||||
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() {
|
|
@ -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<I>(
|
||||
package: &str,
|
|
@ -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<Vec<ProtoParsedFlags>> =
|
||||
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<Box<DumpPredicate>> = 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());
|
|
@ -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<Box<DumpPredicate>> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::protos::ProtoParsedFlags;
|
||||
use aconfig_protos::ProtoParsedFlags;
|
||||
use crate::test::parse_test_flags;
|
||||
use protobuf::Message;
|
||||
|
|
@ -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::<protos::ProtoFlagPermission>(sub_matches, "default-permission")?;
|
||||
get_required_arg::<aconfig_protos::ProtoFlagPermission>(sub_matches, "default-permission")?;
|
||||
let output = commands::parse_flags(
|
||||
package,
|
||||
container,
|
|
@ -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};
|
||||
|
|
@ -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()
|
||||
}
|
|
@ -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<String> {
|
62
tools/aconfig/aconfig_protos/Android.bp
Normal file
62
tools/aconfig/aconfig_protos/Android.bp
Normal file
|
@ -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",
|
||||
]
|
||||
}
|
17
tools/aconfig/aconfig_protos/Cargo.toml
Normal file
17
tools/aconfig/aconfig_protos/Cargo.toml
Normal file
|
@ -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"
|
|
@ -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<T>(s: &str) -> Result<T>
|
||||
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<ProtoFlagDeclarations> {
|
||||
|
@ -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"
|
||||
);
|
||||
}
|
15
tools/aconfig/printflags/Cargo.toml
Normal file
15
tools/aconfig/printflags/Cargo.toml
Normal file
|
@ -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" }
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue