Files
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

226 lines
7.2 KiB
Python

# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
from mirage.commands.builtin.find_helper import find as _find_impl
from mirage.types import FileStat, FileType
from mirage.utils.filetype import guess_type
def _norm(path):
return "/" + path.strip("/")
def _write(backend, path, data):
store = backend.accessor.store
store.files[_norm(path)] = data
def _mkdir(backend, path):
store = backend.accessor.store
store.dirs.add(_norm(path))
def _sync_readdir(store, path):
p = _norm(path)
if p not in store.dirs:
raise FileNotFoundError(p)
prefix = p.rstrip("/") + "/"
seen = set()
for key in list(store.files) + list(store.dirs):
if key == p:
continue
if key.startswith(prefix):
remainder = key[len(prefix):]
child = remainder.split("/")[0]
if child:
seen.add(prefix + child)
return sorted(seen)
def _sync_stat(store, path):
p = _norm(path)
if p in store.dirs:
return FileStat(
name=p.rsplit("/", 1)[-1] or "/",
size=None,
modified=store.modified.get(p),
type=FileType.DIRECTORY,
)
if p in store.files:
data = store.files[p]
return FileStat(
name=p.rsplit("/", 1)[-1],
size=len(data),
modified=store.modified.get(p),
type=guess_type(p),
)
raise FileNotFoundError(p)
def find(backend, path, **kwargs):
store = backend.accessor.store
return _find_impl(lambda p: _sync_readdir(store, p),
lambda p: _sync_stat(store, p), path, **kwargs)
class TestDefault:
def test_all_files_recursively(self, backend):
_write(backend, "/tmp/a.txt", b"hello")
_write(backend, "/tmp/b.txt", b"world")
result = find(backend, "/tmp")
assert sorted(result) == ["/tmp/a.txt", "/tmp/b.txt"]
def test_includes_subdirectories(self, backend):
_mkdir(backend, "/tmp/sub")
_write(backend, "/tmp/sub/c.txt", b"nested")
result = find(backend, "/tmp")
assert "/tmp/sub" in result
assert "/tmp/sub/c.txt" in result
def test_empty_dir(self, backend):
result = find(backend, "/tmp")
assert result == []
class TestName:
def test_glob_pattern(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
_write(backend, "/tmp/b.py", b"bbb")
_write(backend, "/tmp/c.txt", b"ccc")
result = find(backend, "/tmp", name="*.txt")
assert sorted(result) == ["/tmp/a.txt", "/tmp/c.txt"]
def test_exact_name(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
_write(backend, "/tmp/b.txt", b"bbb")
result = find(backend, "/tmp", name="a.txt")
assert result == ["/tmp/a.txt"]
class TestTypeDirectory:
def test_type_directory(self, backend):
_mkdir(backend, "/tmp/sub")
_write(backend, "/tmp/file.txt", b"data")
result = find(backend, "/tmp", type=FileType.DIRECTORY)
assert result == ["/tmp/sub"]
def test_type_directory_nested(self, backend):
_mkdir(backend, "/tmp/a")
_mkdir(backend, "/tmp/a/b")
_write(backend, "/tmp/a/b/f.txt", b"x")
result = find(backend, "/tmp", type=FileType.DIRECTORY)
assert sorted(result) == ["/tmp/a", "/tmp/a/b"]
class TestTypeFile:
def test_type_file(self, backend):
_mkdir(backend, "/tmp/sub")
_write(backend, "/tmp/file.txt", b"data")
_write(backend, "/tmp/sub/nested.py", b"code")
result = find(backend, "/tmp", type="file")
assert sorted(result) == ["/tmp/file.txt", "/tmp/sub/nested.py"]
class TestSize:
def test_min_size(self, backend):
_write(backend, "/tmp/small.txt", b"hi")
_write(backend, "/tmp/big.txt", b"a" * 100)
result = find(backend, "/tmp", min_size=50)
assert result == ["/tmp/big.txt"]
def test_max_size(self, backend):
_write(backend, "/tmp/small.txt", b"hi")
_write(backend, "/tmp/big.txt", b"a" * 100)
result = find(backend, "/tmp", max_size=50)
assert result == ["/tmp/small.txt"]
def test_size_range(self, backend):
_write(backend, "/tmp/tiny.txt", b"x")
_write(backend, "/tmp/mid.txt", b"a" * 50)
_write(backend, "/tmp/huge.txt", b"a" * 200)
result = find(backend, "/tmp", min_size=10, max_size=100)
assert result == ["/tmp/mid.txt"]
class TestMaxdepth:
def test_depth_zero(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
result = find(backend, "/tmp", maxdepth=0)
assert result == ["/tmp/a.txt"]
def test_depth_limits_recursion(self, backend):
_mkdir(backend, "/tmp/d1")
_mkdir(backend, "/tmp/d1/d2")
_write(backend, "/tmp/a.txt", b"a")
_write(backend, "/tmp/d1/b.txt", b"b")
_write(backend, "/tmp/d1/d2/c.txt", b"c")
result = find(backend, "/tmp", maxdepth=1)
assert "/tmp/a.txt" in result
assert "/tmp/d1" in result
assert "/tmp/d1/b.txt" in result
assert "/tmp/d1/d2/c.txt" not in result
class TestNameExclude:
def test_exclude_pattern(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
_write(backend, "/tmp/b.pyc", b"bbb")
_write(backend, "/tmp/c.txt", b"ccc")
result = find(backend, "/tmp", name_exclude="*.pyc")
assert sorted(result) == ["/tmp/a.txt", "/tmp/c.txt"]
def test_exclude_with_name(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
_write(backend, "/tmp/b.txt", b"bbb")
_write(backend, "/tmp/c.py", b"ccc")
result = find(backend, "/tmp", name="*.txt", name_exclude="b*")
assert result == ["/tmp/a.txt"]
class TestOrNames:
def test_or_names(self, backend):
_write(backend, "/tmp/a.txt", b"aaa")
_write(backend, "/tmp/b.py", b"bbb")
_write(backend, "/tmp/c.md", b"ccc")
result = find(backend, "/tmp", or_names=["*.txt", "*.py"])
assert sorted(result) == ["/tmp/a.txt", "/tmp/b.py"]
class TestMixed:
def test_name_and_min_size(self, backend):
_write(backend, "/tmp/small.txt", b"hi")
_write(backend, "/tmp/big.txt", b"a" * 100)
_write(backend, "/tmp/big.py", b"a" * 100)
result = find(backend, "/tmp", name="*.txt", min_size=50)
assert result == ["/tmp/big.txt"]
class TestWarnings:
def test_warnings_on_missing_path(self, backend):
warnings = []
result = find(backend, "/nonexistent", warnings=warnings)
assert result == []
assert len(warnings) == 1
assert "/nonexistent" in warnings[0]