Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f52e8788 authored by Ted Bauer's avatar Ted Bauer Committed by Gerrit Code Review
Browse files

Merge "Add filter by container to aflags" into main

parents 4a2c1b5c aeb96092
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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,
+135 −16
Original line number Diff line number Diff line
@@ -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 {
        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 {
        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 {
        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);
    }
}