• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! `aconfig-storage` is a debugging tool to parse storage files
18 
19 use aconfig_storage_file::{
20     list_flags, list_flags_with_info, read_file_to_bytes, AconfigStorageError, FlagInfoList,
21     FlagTable, FlagValueList, PackageTable, StorageFileType,
22 };
23 
24 use clap::{builder::ArgAction, Arg, Command};
25 
cli() -> Command26 fn cli() -> Command {
27     Command::new("aconfig-storage")
28         .subcommand_required(true)
29         .subcommand(
30             Command::new("print")
31                 .arg(Arg::new("file").long("file").required(true).action(ArgAction::Set))
32                 .arg(
33                     Arg::new("type")
34                         .long("type")
35                         .required(true)
36                         .value_parser(|s: &str| StorageFileType::try_from(s)),
37                 ),
38         )
39         .subcommand(
40             Command::new("list")
41                 .arg(
42                     Arg::new("package-map")
43                         .long("package-map")
44                         .required(true)
45                         .action(ArgAction::Set),
46                 )
47                 .arg(Arg::new("flag-map").long("flag-map").required(true).action(ArgAction::Set))
48                 .arg(Arg::new("flag-val").long("flag-val").required(true).action(ArgAction::Set))
49                 .arg(
50                     Arg::new("flag-info").long("flag-info").required(false).action(ArgAction::Set),
51                 ),
52         )
53 }
54 
print_storage_file( file_path: &str, file_type: &StorageFileType, ) -> Result<(), AconfigStorageError>55 fn print_storage_file(
56     file_path: &str,
57     file_type: &StorageFileType,
58 ) -> Result<(), AconfigStorageError> {
59     let bytes = read_file_to_bytes(file_path)?;
60     match file_type {
61         StorageFileType::PackageMap => {
62             let package_table = PackageTable::from_bytes(&bytes)?;
63             println!("{:?}", package_table);
64         }
65         StorageFileType::FlagMap => {
66             let flag_table = FlagTable::from_bytes(&bytes)?;
67             println!("{:?}", flag_table);
68         }
69         StorageFileType::FlagVal => {
70             let flag_value = FlagValueList::from_bytes(&bytes)?;
71             println!("{:?}", flag_value);
72         }
73         StorageFileType::FlagInfo => {
74             let flag_info = FlagInfoList::from_bytes(&bytes)?;
75             println!("{:?}", flag_info);
76         }
77     }
78     Ok(())
79 }
80 
main() -> Result<(), AconfigStorageError>81 fn main() -> Result<(), AconfigStorageError> {
82     let matches = cli().get_matches();
83     match matches.subcommand() {
84         Some(("print", sub_matches)) => {
85             let file_path = sub_matches.get_one::<String>("file").unwrap();
86             let file_type = sub_matches.get_one::<StorageFileType>("type").unwrap();
87             print_storage_file(file_path, file_type)?
88         }
89         Some(("list", sub_matches)) => {
90             let package_map = sub_matches.get_one::<String>("package-map").unwrap();
91             let flag_map = sub_matches.get_one::<String>("flag-map").unwrap();
92             let flag_val = sub_matches.get_one::<String>("flag-val").unwrap();
93             let flag_info = sub_matches.get_one::<String>("flag-info");
94             match flag_info {
95                 Some(info_file) => {
96                     let flags = list_flags_with_info(package_map, flag_map, flag_val, info_file)?;
97                     for flag in flags.iter() {
98                         println!(
99                             "{} {} {} {:?} IsReadWrite: {}, HasServerOverride: {}, HasLocalOverride: {}",
100                             flag.package_name, flag.flag_name, flag.flag_value, flag.value_type,
101                             flag.is_readwrite, flag.has_server_override, flag.has_local_override,
102                         );
103                     }
104                 }
105                 None => {
106                     let flags = list_flags(package_map, flag_map, flag_val)?;
107                     for flag in flags.iter() {
108                         println!(
109                             "{} {} {} {:?}",
110                             flag.package_name, flag.flag_name, flag.flag_value, flag.value_type,
111                         );
112                     }
113                 }
114             }
115         }
116         _ => unreachable!(),
117     }
118     Ok(())
119 }
120