diff options
author | 2025-03-18 23:12:26 +0000 | |
---|---|---|
committer | 2025-03-19 16:04:15 +0000 | |
commit | a524ed61e9b8bf128aed29b7cdf7e0032aaf9ae2 (patch) | |
tree | c0fcda3fc3641a5e772d92250b328ae003323ea4 | |
parent | 30f05352c3e6f4333c77d4af66c253572d3ea6c9 (diff) |
convert_finalized_flags takes extra flags in extended file
This change enables convert_finalized_flags to take extra flags in
extended files. This is required since there are flags set true, and
exported when V releases, but not recorded in the finalization files.
Test: m finalized_flags_record
Bug: 336800305
Change-Id: I6a0a5dda1e17886dcf570710ac8b577ea4a6a41c
4 files changed, 102 insertions, 20 deletions
diff --git a/tools/aconfig/convert_finalized_flags/Android.bp b/tools/aconfig/convert_finalized_flags/Android.bp index 5b3956062f..9ace80597a 100644 --- a/tools/aconfig/convert_finalized_flags/Android.bp +++ b/tools/aconfig/convert_finalized_flags/Android.bp @@ -50,7 +50,11 @@ genrule { srcs: [ "//prebuilts/sdk:finalized-api-flags", ], + tool_files: ["extended_flags_list_35.txt"], out: ["finalized_flags_record.json"], tools: ["convert_finalized_flags"], - cmd: "args=\"\" && for f in $(locations //prebuilts/sdk:finalized-api-flags); do args=\"$$args --flag_file_path $$f\"; done && $(location convert_finalized_flags) $$args > $(out)", + cmd: "args=\"\" && " + + "for f in $(locations //prebuilts/sdk:finalized-api-flags); " + + " do args=\"$$args --flag_file_path $$f\"; done && " + + "$(location convert_finalized_flags) $$args --extended-flag-file-path $(location extended_flags_list_35.txt) > $(out)", } diff --git a/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt b/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tools/aconfig/convert_finalized_flags/extended_flags_list_35.txt diff --git a/tools/aconfig/convert_finalized_flags/src/lib.rs b/tools/aconfig/convert_finalized_flags/src/lib.rs index 10faa39893..d79c509e8f 100644 --- a/tools/aconfig/convert_finalized_flags/src/lib.rs +++ b/tools/aconfig/convert_finalized_flags/src/lib.rs @@ -39,6 +39,9 @@ pub struct FinalizedFlag { #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct ApiLevel(pub i32); +/// API level of the extended flags file of version 35 +pub const EXTENDED_FLAGS_35_APILEVEL: ApiLevel = ApiLevel(35); + /// Contains all flags finalized for a given API level. #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct FinalizedFlagMap(HashMap<ApiLevel, HashSet<FinalizedFlag>>); @@ -78,6 +81,8 @@ impl FinalizedFlagMap { } } +const EXTENDED_FLAGS_LIST_35: &str = "extended_flags_list_35.txt"; + /// Converts a string to an int. Will parse to int even if the string is "X.0". /// Returns error for "X.1". fn str_to_api_level(numeric_string: &str) -> Result<ApiLevel> { @@ -117,28 +122,47 @@ pub fn read_files_to_map_using_path(flag_files: Vec<String>) -> Result<Finalized continue; }; - let file = fs::File::open(flag_file)?; - let reader = io::BufReader::new(file); - - for qualified_flag_name in reader.lines() { - // Split the qualified flag name into package and flag name: - // com.my.package.name.my_flag_name -> ['com.my.package.name', 'my_flag_name']. - let mut flag: Vec<String> = - qualified_flag_name?.rsplitn(2, '.').map(|s| s.to_string()).collect(); + let file = fs::File::open(&flag_file)?; - if flag.len() != 2 { - continue; - } + io::BufReader::new(file).lines().for_each(|flag| { + let flag = + flag.unwrap_or_else(|_| panic!("Failed to read line from file {}", flag_file)); + let finalized_flag = build_finalized_flag(&flag) + .unwrap_or_else(|_| panic!("cannot build finalized flag {}", flag)); + data_map.insert_if_new(api_level, finalized_flag); + }); + } - let package_name = flag.pop().ok_or(anyhow!("Missing flag package."))?; - let flag_name = flag.pop().ok_or(anyhow!("Missing flag name."))?; + Ok(data_map) +} - // Only add the flag if it wasn't added in a prior file. - data_map.insert_if_new(api_level, FinalizedFlag { flag_name, package_name }); - } +/// Read the qualified flag names into a FinalizedFlag set +pub fn read_extend_file_to_map_using_path(extened_file: String) -> Result<HashSet<FinalizedFlag>> { + let (_, file_name) = + extened_file.rsplit_once('/').ok_or(anyhow!("Invalid file: '{}'", extened_file))?; + if file_name != EXTENDED_FLAGS_LIST_35 { + return Err(anyhow!("Provided incorrect file, must be {}", EXTENDED_FLAGS_LIST_35)); } + let file = fs::File::open(extened_file)?; + let extended_flags = io::BufReader::new(file) + .lines() + .map(|flag| { + let flag = flag.expect("Failed to read line from extended file"); + build_finalized_flag(&flag) + .unwrap_or_else(|_| panic!("cannot build finalized flag {}", flag)) + }) + .collect::<HashSet<FinalizedFlag>>(); + Ok(extended_flags) +} - Ok(data_map) +fn build_finalized_flag(qualified_flag_name: &String) -> Result<FinalizedFlag> { + // Split the qualified flag name into package and flag name: + // com.my.package.name.my_flag_name -> ('com.my.package.name', 'my_flag_name') + let (package_name, flag_name) = qualified_flag_name + .rsplit_once('.') + .ok_or(anyhow!("Invalid qualified flag name format: '{}'", qualified_flag_name))?; + + Ok(FinalizedFlag { flag_name: flag_name.to_string(), package_name: package_name.to_string() }) } #[cfg(test)] @@ -392,4 +416,49 @@ mod tests { assert_eq!(map.get_finalized_level(&flags[0]).unwrap(), l35); assert_eq!(map.get_finalized_level(&flags[1]).unwrap(), l36); } + + #[test] + fn test_read_flag_from_extended_file() { + let flags = create_test_flags(); + + // Create the file <temp_dir>/35/extended_flags_list_35.txt + let temp_dir = tempdir().unwrap(); + let mut file_path = temp_dir.path().to_path_buf(); + file_path.push("35"); + fs::create_dir_all(&file_path).unwrap(); + file_path.push(EXTENDED_FLAGS_LIST_35); + let mut file = File::create(&file_path).unwrap(); + + // Write all flags to the file. + add_flags_to_file(&mut file, &[flags[0].clone(), flags[1].clone()]); + + let flags_set = + read_extend_file_to_map_using_path(file_path.to_string_lossy().to_string()).unwrap(); + assert_eq!(flags_set.len(), 2); + assert!(flags_set.contains(&flags[0])); + assert!(flags_set.contains(&flags[1])); + } + + #[test] + fn test_read_flag_from_wrong_extended_file_err() { + let flags = create_test_flags(); + + // Create the file <temp_dir>/35/extended_flags_list.txt + let temp_dir = tempdir().unwrap(); + let mut file_path = temp_dir.path().to_path_buf(); + file_path.push("35"); + fs::create_dir_all(&file_path).unwrap(); + file_path.push("extended_flags_list.txt"); + let mut file = File::create(&file_path).unwrap(); + + // Write all flags to the file. + add_flags_to_file(&mut file, &[flags[0].clone(), flags[1].clone()]); + + let err = read_extend_file_to_map_using_path(file_path.to_string_lossy().to_string()) + .unwrap_err(); + assert_eq!( + format!("{:?}", err), + "Provided incorrect file, must be extended_flags_list_35.txt" + ); + } } diff --git a/tools/aconfig/convert_finalized_flags/src/main.rs b/tools/aconfig/convert_finalized_flags/src/main.rs index 38300f6776..605e964d7e 100644 --- a/tools/aconfig/convert_finalized_flags/src/main.rs +++ b/tools/aconfig/convert_finalized_flags/src/main.rs @@ -23,7 +23,9 @@ use anyhow::Result; use clap::Parser; -use convert_finalized_flags::read_files_to_map_using_path; +use convert_finalized_flags::{ + read_extend_file_to_map_using_path, read_files_to_map_using_path, EXTENDED_FLAGS_35_APILEVEL, +}; const ABOUT_TEXT: &str = "Tool for processing finalized-flags.txt files. @@ -45,11 +47,18 @@ struct Cli { /// Flags files. #[arg(long = "flag_file_path")] flag_file_path: Vec<String>, + + #[arg(long)] + extended_flag_file_path: String, } fn main() -> Result<()> { let cli = Cli::parse(); - let finalized_flags_map = read_files_to_map_using_path(cli.flag_file_path)?; + let mut finalized_flags_map = read_files_to_map_using_path(cli.flag_file_path)?; + let extended_flag_set = read_extend_file_to_map_using_path(cli.extended_flag_file_path)?; + for flag in extended_flag_set { + finalized_flags_map.insert_if_new(EXTENDED_FLAGS_35_APILEVEL, flag); + } let json_str = serde_json::to_string(&finalized_flags_map)?; println!("{}", json_str); |