Skip to content

Commit 1d7538f

Browse files
committed
rename
1 parent ee21bc7 commit 1d7538f

2 files changed

Lines changed: 179 additions & 0 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) 2025, Salesforce, Inc.
2+
# SPDX-License-Identifier: Apache-2
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.
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Copyright (c) 2025, Salesforce, Inc.
2+
# SPDX-License-Identifier: Apache-2
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+
from __future__ import annotations
16+
17+
import os
18+
from pathlib import Path
19+
from typing import Optional
20+
21+
from datacustomcode.file.base import BaseDataAccessLayer
22+
23+
24+
class FileReaderError(Exception):
25+
"""Base exception for file reader operations."""
26+
27+
28+
class FileNotFoundError(FileReaderError):
29+
"""Raised when a file cannot be found."""
30+
31+
32+
class DefaultFindFilePath(BaseDataAccessLayer):
33+
"""Base class for finding file path
34+
35+
This class provides a framework for finding files from various locations
36+
with configurable search strategies and error handling.
37+
"""
38+
39+
# Default configuration values
40+
DEFAULT_CODE_PACKAGE = "payload"
41+
DEFAULT_FILE_FOLDER = "files"
42+
DEFAULT_CONFIG_FILE = "config.json"
43+
44+
def __init__(
45+
self,
46+
code_package: Optional[str] = None,
47+
file_folder: Optional[str] = None,
48+
config_file: Optional[str] = None,
49+
):
50+
"""Initialize the file reader with configuration.
51+
52+
Args:
53+
code_package: The default code package directory to search
54+
file_folder: The folder containing files relative to the code package
55+
config_file: The configuration file to use for path resolution
56+
"""
57+
self.code_package = code_package or self.DEFAULT_CODE_PACKAGE
58+
self.file_folder = file_folder or self.DEFAULT_FILE_FOLDER
59+
self.config_file = config_file or self.DEFAULT_CONFIG_FILE
60+
61+
def find_file_path(self, file_name: str) -> Path:
62+
"""Find a file path.
63+
64+
Args:
65+
file_name: The name of the file to open
66+
67+
Returns:
68+
A file path
69+
70+
Raises:
71+
FileNotFoundError: If the file cannot be found
72+
"""
73+
if not file_name:
74+
raise ValueError("file_name cannot be empty")
75+
76+
file_path = self._resolve_file_path(file_name)
77+
78+
if not file_path:
79+
raise FileNotFoundError(
80+
f"File '{file_name}' not found in any search location"
81+
)
82+
83+
return file_path
84+
85+
def _resolve_file_path(self, file_name: str) -> Path:
86+
"""Resolve the full path to a file.
87+
88+
Args:
89+
file_name: The name of the file to resolve
90+
91+
Returns:
92+
The full path to the file
93+
"""
94+
# First try the default code package location
95+
if self._code_package_exists():
96+
file_path = self._get_code_package_file_path(file_name)
97+
if file_path.exists():
98+
return file_path
99+
100+
# Fall back to config.json-based location
101+
config_path = self._find_config_file()
102+
if config_path:
103+
file_path = self._get_config_based_file_path(file_name, config_path)
104+
if file_path.exists():
105+
return file_path
106+
107+
# Return the file name as a Path if not found in any location
108+
return Path(file_name)
109+
110+
def _code_package_exists(self) -> bool:
111+
"""Check if the default code package directory exists.
112+
113+
Returns:
114+
True if the code package directory exists
115+
"""
116+
return os.path.exists(self.code_package)
117+
118+
def _get_code_package_file_path(self, file_name: str) -> Path:
119+
"""Get the file path relative to the code package.
120+
121+
Args:
122+
file_name: The name of the file
123+
124+
Returns:
125+
The full path to the file
126+
"""
127+
relative_path = f"{self.code_package}/{self.file_folder}/{file_name}"
128+
return Path(relative_path)
129+
# return Path.cwd().joinpath(relative_path)
130+
131+
def _find_config_file(self) -> Optional[Path]:
132+
"""Find the configuration file in the current directory tree.
133+
134+
Returns:
135+
The path to the config file, or None if not found
136+
"""
137+
return self._find_file_in_tree(self.config_file, Path.cwd())
138+
139+
def _get_config_based_file_path(self, file_name: str, config_path: Path) -> Path:
140+
"""Get the file path relative to the config file location.
141+
142+
Args:
143+
file_name: The name of the file
144+
config_path: The path to the config file
145+
146+
Returns:
147+
The full path to the file
148+
"""
149+
relative_path = f"{self.file_folder}/{file_name}"
150+
return Path(relative_path)
151+
# return config_path.parent.joinpath(relative_path)
152+
153+
def _find_file_in_tree(self, filename: str, search_path: Path) -> Optional[Path]:
154+
"""Find a file within a directory tree.
155+
156+
Args:
157+
filename: The name of the file to find
158+
search_path: The root directory to search from
159+
160+
Returns:
161+
The full path to the file, or None if not found
162+
"""
163+
for file_path in search_path.rglob(filename):
164+
return file_path
165+
return None

0 commit comments

Comments
 (0)