blob: 44070387aad1f19d66792c5c59e02433813e9298 [file] [log] [blame]
#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from typing import Callable, List, Set
from gn_label import GnLabel
import dataclasses
import os
@dataclasses.dataclass(frozen=False)
class FileAccess:
"""Manages access to the real file system, while keeping track of depfiles."""
fuchsia_source_path_str: str
visited_files: Set[str] = dataclasses.field(default_factory=set)
def read_text(self, label: GnLabel) -> str:
"""Reads the file into a text string"""
GnLabel.check_type(label)
path = os.path.join(self.fuchsia_source_path_str, label.path_str)
self.visited_files.add(path)
with open(path) as f:
return f.read()
def file_exists(self, label: GnLabel) -> bool:
"""Whether the file exists and is not a directory"""
GnLabel.check_type(label)
path = os.path.join(self.fuchsia_source_path_str, label.path_str)
if os.path.isfile(path):
self.visited_files.add(path)
return True
return False
def directory_exists(self, label: GnLabel) -> bool:
"""Whether the directory exists and is indeed a directory"""
GnLabel.check_type(label)
path = os.path.join(self.fuchsia_source_path_str, label.path_str)
if os.path.isdir(path):
self.visited_files.add(path)
return True
return False
def search_directory(
self, label: GnLabel, path_predicate: Callable[[str], bool]
) -> List[GnLabel]:
"""Lists the files in a directory corresponding with `label` (including files in subdirs) matching `path_predicate`"""
GnLabel.check_type(label)
path = os.path.join(self.fuchsia_source_path_str, label.path_str)
self.visited_files.add(path)
output = []
for root, _, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
if path_predicate(file_path):
relative_to_label = os.path.relpath(
os.path.relpath(
file_path, self.fuchsia_source_path_str
),
label.path_str,
)
output.append(
label.create_child_from_str(relative_to_label)
)
return output
def write_depfile(self, dep_file_path: str, main_entry: str) -> None:
os.makedirs(os.path.dirname(dep_file_path), exist_ok=True)
with open(dep_file_path, "w") as dep_file:
dep_file.write(f"{main_entry}:\\\n")
dep_file.write(
"\\\n".join(sorted([f" {p}" for p in self.visited_files]))
)