Restructure aconfig repo to be a cargo workspace with many crates

This is cherry pick of aosp/2924191 to avoid merge conflict in git main

Previously, aconfig repo is the root directory of aconfig binary crate,
but it also hosts printflags crate inside, and there is no cargo support
for printflags binary crate. In addition, with more aconfig development,
more crates are being added to this repo. Thus this repo should be
configured as a Cargo workspace with multiple crates rather than a
single crate.

Note the top level Cargo.toml file specifies the crates this workspace
carries:
(1) aconfig_protos: the proto library crate that will be used by many other
crates such as aconfig binary crate and printflags binary crate
(2) aconfig: the aconfig binary crate
(3) printflags: the printflags binary crate

(1) aconfig_protos crate setup:

Inside aconfig_protos dir we set up the aconfig_protos crate, the
previously src/proto.rs is now aconfig_protos/src/lib.rs, the build.rs
is carried over to this crate.

(2) aconfig binary crate setup:

Notice its Cargo.toml file claims package dependency on aconfig_protos
crate. It no longer carries proto related module and build.rs file.

(3) printflags binary crate setup:

Similary, notice that in its Cargo.toml file, it claims package
dependency on aconfig_protos crate.

With this setup, we can Cargo build/test each crate individually when
inside a specific crate dir. But we can also run Cargo build/test at
repo root level, which will build/test all the crates in this workplace.

This is the structuring cl. The next cl is to move storage modules into
its own library crate. This storage file library crate will be used by
both aconfig binary crate as well as flag read library crate (to be
created as another new crate here).

Bug: b/321984352
Test: top and individual crate dir level Cargo build/test, m each
individual targets

Ignore-AOSP-First: cherrypick to git main to resolve merge conflict
Change-Id: I75833f4997f7ee554ff6c1557df9ac87f62b2732
This commit is contained in:
Dennis Shen
2024-01-23 18:01:52 +00:00
parent 75bd81de17
commit c77c6612e7
51 changed files with 205 additions and 156 deletions

View File

@@ -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"
]

View File

@@ -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 {

View 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" }

View File

@@ -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#"

View File

@@ -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,

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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());

View File

@@ -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;

View File

@@ -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,

View File

@@ -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};

View File

@@ -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()
}

View File

@@ -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> {

View 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",
]
}

View 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"

View File

@@ -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"
);
}

View 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" }

View File

@@ -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;