1#
2# Copyright (C) 2018 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
17import collections
18import logging
19import os
20import shutil
21
22
23class BuildInfo(dict):
24    """dict class for fetched device imgs, test suites, etc."""
25
26    def __init__(self):
27        super(BuildInfo, self).__init__()
28
29    def __setitem__(self, key, value):
30        """__setitem__ for BuildInfo dict.
31
32        Remove pre-fetched file which has the same use in HC
33        if the old one has different file name from the new one.
34
35        Args:
36            key: string, key for the path to the fetched file.
37            value: string, path to the newly fetched file.
38        """
39        if key in self and value != self[key]:
40            logging.info("Removing pre-fetched item: %s", self[key])
41            try:
42                if os.path.isfile(self[key]):
43                    os.remove(self[key])
44                elif os.path.isdir(self[key]):
45                    shutil.rmtree(self[key])
46                else:
47                    logging.error("%s is not found", self[key])
48            except OSError as e:
49                logging.error("ERROR: error on file remove %s", e)
50
51        super(BuildInfo, self).__setitem__(key, value)
52
53    def update(self, other=None, **kwargs):
54        """Overrides update() in order to call BuildInfo.__setitem__().
55
56        Args:
57            other: dict or iterable of key/value pairs. Update self
58                   using this argument
59            **kwargs: The optional attributes.
60        """
61        if other is not None:
62            for k, v in other.items() if isinstance(
63                    other, collections.Mapping) else other:
64                self[k] = v
65        for k, v in kwargs.items():
66            self[k] = v
67
68        dict_keys = self.keys()
69        for key in dict_keys:
70            if not os.path.exists(self[key]):
71                logging.info(
72                    "Removing path info %s from build info", self.pop(key))
73