xref: /aosp_15_r20/external/toolchain-utils/cros_utils/file_utils.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1# -*- coding: utf-8 -*-
2# Copyright 2019 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Utilities for operations on files."""
7
8
9import errno
10import os
11import shutil
12
13from cros_utils import command_executer
14
15
16class FileUtils(object):
17    """Utilities for operations on files."""
18
19    _instance = None
20    DRY_RUN = False
21
22    @classmethod
23    def Configure(cls, dry_run):
24        cls.DRY_RUN = dry_run
25
26    def __new__(cls, *args, **kwargs):
27        if not cls._instance:
28            if cls.DRY_RUN:
29                cls._instance = super(FileUtils, cls).__new__(
30                    MockFileUtils, *args, **kwargs
31                )
32            else:
33                cls._instance = super(FileUtils, cls).__new__(
34                    cls, *args, **kwargs
35                )
36        return cls._instance
37
38    def Md5File(self, filename, log_level="verbose", _block_size=2 ** 10):
39        command = "md5sum %s" % filename
40        ce = command_executer.GetCommandExecuter(log_level=log_level)
41        ret, out, _ = ce.RunCommandWOutput(command)
42        if ret:
43            raise RuntimeError("Could not run md5sum on: %s" % filename)
44
45        return out.strip().split()[0]
46
47    def CanonicalizeChromeOSRoot(self, chromeos_root):
48        chromeos_root = os.path.expanduser(chromeos_root)
49        if os.path.isdir(os.path.join(chromeos_root, "chromite")):
50            return chromeos_root
51        else:
52            return None
53
54    def ChromeOSRootFromImage(self, chromeos_image):
55        chromeos_root = os.path.join(
56            os.path.dirname(chromeos_image), "../../../../.."
57        )
58        return self.CanonicalizeChromeOSRoot(chromeos_root)
59
60    def MkDirP(self, path):
61        try:
62            os.makedirs(path)
63        except OSError as exc:
64            if exc.errno == errno.EEXIST:
65                pass
66            else:
67                raise
68
69    def RmDir(self, path):
70        shutil.rmtree(path, ignore_errors=True)
71
72    def WriteFile(self, path, contents):
73        with open(path, "w", encoding="utf-8") as f:
74            f.write(contents)
75
76
77class MockFileUtils(FileUtils):
78    """Mock class for file utilities."""
79
80    def Md5File(self, filename, log_level="verbose", _block_size=2 ** 10):
81        return "d41d8cd98f00b204e9800998ecf8427e"
82
83    def CanonicalizeChromeOSRoot(self, chromeos_root):
84        return "/tmp/chromeos_root"
85
86    def ChromeOSRootFromImage(self, chromeos_image):
87        return "/tmp/chromeos_root"
88
89    def RmDir(self, path):
90        pass
91
92    def MkDirP(self, path):
93        pass
94
95    def WriteFile(self, path, contents):
96        pass
97