1# 2# Copyright (C) 2022 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 16import json 17import os 18 19_VALID_KEYS = set(("version", "domain_data")) 20 21 22class DescribeError(Exception): 23 """Parsing errors.""" 24 25 def __init__(self, tree, reason): 26 super().__init__(tree, reason) 27 self.tree = tree 28 self.reason = reason 29 30 def __str__(self): 31 return self.reason 32 33 34def interrogate_tree(_tree_key, inner_tree, _cookie): 35 """Interrogate the inner tree.""" 36 query = dict(build_domains=[inner_tree.build_domains]) 37 os.makedirs(os.path.dirname(inner_tree.out.tree_query()), exist_ok=True) 38 with open(inner_tree.out.tree_query(), 'w', encoding="iso-8859-1") as f: 39 f.write(json.dumps(query)) 40 inner_tree.invoke([ 41 "describe", "--input_json", 42 inner_tree.out.tree_query(base=inner_tree.out.Base.INNER), 43 "--output_json", 44 inner_tree.out.tree_info_file(base=inner_tree.out.Base.INNER) 45 ]) 46 47 try: 48 with open(inner_tree.out.tree_info_file(), encoding='iso-8859-1') as f: 49 info_json = json.load(f) 50 except FileNotFoundError as e: 51 raise DescribeError(inner_tree, "No return from interrogate.") from e 52 except json.decoder.JSONDecodeError as e: 53 raise DescribeError( 54 inner_tree, f"Failed to parse interrogate response: {e}") from e 55 56 if not isinstance(info_json, dict): 57 raise DescribeError(inner_tree, "Malformed describe response") 58 if set(info_json.keys()) - _VALID_KEYS: 59 raise DescribeError(inner_tree, 60 "Invalid keyname in describe response.") 61 # Make sure that fields are initialized, so that we can just access them. 62 if info_json.setdefault("version", 0): 63 raise DescribeError(inner_tree, 64 f"Invalid version: {info_json['version']}") 65 info_json.setdefault("domain_data", []) 66 67 return info_json 68