Skip to content

Commit 2734de3

Browse files
committed
✨ Add support for .fastapicloudignore file
1 parent 70e068d commit 2734de3

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

src/fastapi_cloud_cli/commands/deploy.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ def _should_exclude_entry(path: Path) -> bool:
4949

5050
def archive(path: Path) -> Path:
5151
logger.debug("Starting archive creation for path: %s", path)
52-
files = rignore.walk(path, should_exclude_entry=_should_exclude_entry)
52+
files = rignore.walk(
53+
path,
54+
should_exclude_entry=_should_exclude_entry,
55+
additional_ignore_paths=[".fastapicloudignore"],
56+
)
5357

5458
temp_dir = tempfile.mkdtemp()
5559
logger.debug("Created temp directory: %s", temp_dir)

tests/test_archive.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import tarfile
2+
from pathlib import Path
3+
4+
from fastapi_cloud_cli.commands.deploy import archive
5+
6+
7+
def test_archive_creates_tar_file(tmp_path: Path) -> None:
8+
(tmp_path / "main.py").write_text("print('hello')")
9+
(tmp_path / "config.json").write_text('{"key": "value"}')
10+
(tmp_path / "subdir").mkdir()
11+
(tmp_path / "subdir" / "utils.py").write_text("def helper(): pass")
12+
13+
tar_path = archive(tmp_path)
14+
15+
assert tar_path.exists()
16+
assert tar_path.suffix == ".tar"
17+
assert tar_path.name.startswith("fastapi-cloud-deploy-")
18+
19+
20+
def test_archive_excludes_venv_and_similar_folders(tmp_path: Path) -> None:
21+
"""Should exclude .venv directory from archive."""
22+
# the only files we want to include
23+
(tmp_path / "main.py").write_text("print('hello')")
24+
(tmp_path / "static").mkdir()
25+
(tmp_path / "static" / "index.html").write_text("<html></html>")
26+
# virtualenv
27+
(tmp_path / ".venv").mkdir()
28+
(tmp_path / ".venv" / "lib").mkdir()
29+
(tmp_path / ".venv" / "lib" / "package.py").write_text("# package")
30+
# pycache
31+
(tmp_path / "__pycache__").mkdir()
32+
(tmp_path / "__pycache__" / "main.cpython-311.pyc").write_text("bytecode")
33+
# pyc files
34+
(tmp_path / "main.pyc").write_text("bytecode")
35+
# mypy/pytest
36+
(tmp_path / ".mypy_cache").mkdir()
37+
(tmp_path / ".mypy_cache" / "file.json").write_text("{}")
38+
(tmp_path / ".pytest_cache").mkdir()
39+
(tmp_path / ".pytest_cache" / "cache.db").write_text("data")
40+
41+
tar_path = archive(tmp_path)
42+
43+
with tarfile.open(tar_path, "r") as tar:
44+
names = tar.getnames()
45+
assert set(names) == {"main.py", "static/index.html"}
46+
47+
48+
def test_archive_preserves_relative_paths(tmp_path: Path) -> None:
49+
(tmp_path / "src").mkdir()
50+
(tmp_path / "src" / "app").mkdir()
51+
(tmp_path / "src" / "app" / "main.py").write_text("print('hello')")
52+
53+
tar_path = archive(tmp_path)
54+
55+
with tarfile.open(tar_path, "r") as tar:
56+
names = tar.getnames()
57+
assert names == ["src/app/main.py"]
58+
59+
60+
def test_archive_respects_fastapicloudignore(tmp_path: Path) -> None:
61+
"""Should exclude files specified in .fastapicloudignore."""
62+
# Create test files
63+
(tmp_path / "main.py").write_text("print('hello')")
64+
(tmp_path / "config.py").write_text("CONFIG = 'value'")
65+
(tmp_path / "secrets.env").write_text("SECRET_KEY=xyz")
66+
(tmp_path / "data").mkdir()
67+
(tmp_path / "data" / "file.txt").write_text("data")
68+
69+
# Create .fastapicloudignore file
70+
(tmp_path / ".fastapicloudignore").write_text("secrets.env\ndata/\n")
71+
72+
# Create archive
73+
tar_path = archive(tmp_path)
74+
75+
# Verify ignored files are excluded
76+
with tarfile.open(tar_path, "r") as tar:
77+
names = tar.getnames()
78+
assert set(names) == {
79+
"main.py",
80+
"config.py",
81+
}

0 commit comments

Comments
 (0)