Merge "Add filter by container to aflags" into main am: f52e8788a2
am: 09fbb10fc4
Original change: https://android-review.googlesource.com/c/platform/build/+/3087903 Change-Id: Ief4f1bd2e94e07496400d3f0b7f7b60ed242b732 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
59198ca2d2
2 changed files with 136 additions and 18 deletions
|
@ -27,8 +27,7 @@ impl FlagSource for AconfigStorageSource {
|
|||
let container =
|
||||
file_info.container.ok_or(anyhow!("storage file is missing container"))?;
|
||||
|
||||
for listed_flag in
|
||||
aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
|
||||
for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
|
||||
{
|
||||
result.push(Flag {
|
||||
name: listed_flag.flag_name,
|
||||
|
|
|
@ -35,10 +35,14 @@ enum FlagPermission {
|
|||
|
||||
impl std::fmt::Display for FlagPermission {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", match &self {
|
||||
Self::ReadOnly => "read-only",
|
||||
Self::ReadWrite => "read-write",
|
||||
})
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match &self {
|
||||
Self::ReadOnly => "read-only",
|
||||
Self::ReadWrite => "read-write",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,10 +54,14 @@ enum ValuePickedFrom {
|
|||
|
||||
impl std::fmt::Display for ValuePickedFrom {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", match &self {
|
||||
Self::Default => "default",
|
||||
Self::Server => "server",
|
||||
})
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match &self {
|
||||
Self::Default => "default",
|
||||
Self::Server => "server",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,10 +85,14 @@ impl TryFrom<&str> for FlagValue {
|
|||
|
||||
impl std::fmt::Display for FlagValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", match &self {
|
||||
Self::Enabled => "enabled",
|
||||
Self::Disabled => "disabled",
|
||||
})
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match &self {
|
||||
Self::Enabled => "enabled",
|
||||
Self::Disabled => "disabled",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,6 +165,10 @@ enum Command {
|
|||
/// Read from the new flag storage.
|
||||
#[clap(long)]
|
||||
use_new_storage: bool,
|
||||
|
||||
/// Optionally filter by container name.
|
||||
#[clap(short = 'c', long = "container")]
|
||||
container: Option<String>,
|
||||
},
|
||||
|
||||
/// Enable an aconfig flag on this device, on the next boot.
|
||||
|
@ -176,6 +192,23 @@ struct PaddingInfo {
|
|||
longest_permission_col: usize,
|
||||
}
|
||||
|
||||
struct Filter {
|
||||
container: Option<String>,
|
||||
}
|
||||
|
||||
impl Filter {
|
||||
fn apply(&self, flags: &[Flag]) -> Vec<Flag> {
|
||||
flags
|
||||
.iter()
|
||||
.filter(|flag| match &self.container {
|
||||
Some(c) => flag.container == *c,
|
||||
None => true,
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn format_flag_row(flag: &Flag, info: &PaddingInfo) -> String {
|
||||
let full_name = flag.qualified_name();
|
||||
let p0 = info.longest_flag_col + 1;
|
||||
|
@ -215,11 +248,12 @@ fn set_flag(qualified_name: &str, value: &str) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn list(source_type: FlagSourceType) -> Result<String> {
|
||||
let flags = match source_type {
|
||||
fn list(source_type: FlagSourceType, container: Option<String>) -> Result<String> {
|
||||
let flags_unfiltered = match source_type {
|
||||
FlagSourceType::DeviceConfig => DeviceConfigSource::list_flags()?,
|
||||
FlagSourceType::AconfigStorage => AconfigStorageSource::list_flags()?,
|
||||
};
|
||||
let flags = (Filter { container }).apply(&flags_unfiltered);
|
||||
let padding_info = PaddingInfo {
|
||||
longest_flag_col: flags.iter().map(|f| f.qualified_name().len()).max().unwrap_or(0),
|
||||
longest_val_col: flags.iter().map(|f| f.value.to_string().len()).max().unwrap_or(0),
|
||||
|
@ -251,8 +285,12 @@ fn list(source_type: FlagSourceType) -> Result<String> {
|
|||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
let output = match cli.command {
|
||||
Command::List { use_new_storage: true } => list(FlagSourceType::AconfigStorage).map(Some),
|
||||
Command::List { use_new_storage: false } => list(FlagSourceType::DeviceConfig).map(Some),
|
||||
Command::List { use_new_storage: true, container } => {
|
||||
list(FlagSourceType::AconfigStorage, container).map(Some)
|
||||
}
|
||||
Command::List { use_new_storage: false, container } => {
|
||||
list(FlagSourceType::DeviceConfig, container).map(Some)
|
||||
}
|
||||
Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None),
|
||||
Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None),
|
||||
};
|
||||
|
@ -262,3 +300,84 @@ fn main() {
|
|||
Err(message) => println!("Error: {message}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_filter_container() {
|
||||
let flags = vec![
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test1".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "system".to_string(),
|
||||
},
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test2".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "not_system".to_string(),
|
||||
},
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test3".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "system".to_string(),
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!((Filter { container: Some("system".to_string()) }).apply(&flags).len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_no_container() {
|
||||
let flags = vec![
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test1".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "system".to_string(),
|
||||
},
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test2".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "not_system".to_string(),
|
||||
},
|
||||
Flag {
|
||||
namespace: "namespace".to_string(),
|
||||
name: "test3".to_string(),
|
||||
package: "package".to_string(),
|
||||
value: FlagValue::Disabled,
|
||||
staged_value: None,
|
||||
permission: FlagPermission::ReadWrite,
|
||||
value_picked_from: ValuePickedFrom::Default,
|
||||
container: "system".to_string(),
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!((Filter { container: None }).apply(&flags).len(), 3);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue