Skip to content

Commit 113eecc

Browse files
authored
Merge pull request fastapi#41 from fastapilabs/09-18-_add_.fastapi_to_.gitignore_and_explain_what_the_folder_is
✨ Add .fastapi to .gitignore and explain what the folder is
2 parents fd912a1 + ad86491 commit 113eecc

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

src/fastapi_cli/utils/apps.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,40 @@ def get_app_config(path_to_deploy: Path) -> Optional[AppConfig]:
1818
return AppConfig.model_validate_json(config_path.read_text(encoding="utf-8"))
1919

2020

21+
README = """
22+
> Why do I have a folder named ".fastapi" in my project? 🤔
23+
The ".fastapi" folder is created when you link a directory to a FastAPI Cloud project.
24+
25+
> What does the "cloud.json" file contain?
26+
The "cloud.json" file contains:
27+
- The ID of the FastAPI app that you linked ("app_id")
28+
- The ID of the team your FastAPI Cloud project is owned by ("team_id")
29+
30+
> Should I commit the ".fastapi" folder?
31+
No, you should not commit the ".fastapi" folder to your version control system.
32+
On creation, it will be automatically added to your ".gitignore" file.
33+
"""
34+
35+
2136
def write_app_config(path_to_deploy: Path, app_config: AppConfig) -> None:
2237
config_path = path_to_deploy / ".fastapi/cloud.json"
38+
readme_path = path_to_deploy / ".fastapi/README.md"
2339
config_path.parent.mkdir(parents=True, exist_ok=True)
2440

2541
config_path.write_text(
2642
app_config.model_dump_json(),
2743
encoding="utf-8",
2844
)
45+
readme_path.write_text(README, encoding="utf-8")
46+
47+
git_ignore_path = path_to_deploy / ".gitignore"
48+
49+
if not git_ignore_path.exists():
50+
git_ignore_path.write_text(".fastapi\n", encoding="utf-8")
51+
else:
52+
git_ignore_content = git_ignore_path.read_text(encoding="utf-8")
53+
54+
if ".fastapi" not in git_ignore_content:
55+
git_ignore_path.write_text(
56+
f"{git_ignore_content}.fastapi\n", encoding="utf-8"
57+
)

tests/test_cli_deploy.py

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import pytest
88
import respx
9+
from click.testing import Result
910
from fastapi_cli.cli import app
1011
from fastapi_cli.config import settings
1112
from httpx import Response
@@ -449,10 +450,7 @@ def test_returns_error_when_team_not_found(
449450
assert result.exit_code == 1
450451

451452

452-
@pytest.mark.respx(base_url=settings.base_api_url)
453-
def test_can_skip_waiting(
454-
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
455-
) -> None:
453+
def _deploy_without_waiting(respx_mock: respx.MockRouter, tmp_path: Path) -> Result:
456454
steps = [ENTER, ENTER, ENTER, *"demo", ENTER]
457455

458456
team_data = _get_random_team()
@@ -499,8 +497,55 @@ def test_can_skip_waiting(
499497
with changing_dir(tmp_path), patch("click.getchar") as mock_getchar:
500498
mock_getchar.side_effect = steps
501499

502-
result = runner.invoke(app, ["deploy", "--no-wait"])
500+
return runner.invoke(app, ["deploy", "--no-wait"])
503501

504-
assert result.exit_code == 0
505502

506-
assert "Check the status of your deployment at" in result.output
503+
@pytest.mark.respx(base_url=settings.base_api_url)
504+
def test_can_skip_waiting(
505+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
506+
) -> None:
507+
result = _deploy_without_waiting(respx_mock, tmp_path)
508+
509+
assert result.exit_code == 0
510+
511+
assert "Check the status of your deployment at" in result.output
512+
513+
514+
@pytest.mark.respx(base_url=settings.base_api_url)
515+
def test_creates_config_folder_and_adds_it_to_gitignore(
516+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
517+
) -> None:
518+
git_ignore_path = tmp_path / ".gitignore"
519+
git_ignore_path.write_text(".venv\n")
520+
521+
_deploy_without_waiting(respx_mock, tmp_path)
522+
523+
assert (tmp_path / ".fastapi" / "cloud.json").exists()
524+
assert (tmp_path / ".fastapi" / "README.md").exists()
525+
526+
assert git_ignore_path.read_text() == ".venv\n.fastapi\n"
527+
528+
529+
@pytest.mark.respx(base_url=settings.base_api_url)
530+
def test_creates_config_folder_and_creates_git_ignore(
531+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
532+
) -> None:
533+
_deploy_without_waiting(respx_mock, tmp_path)
534+
535+
assert (tmp_path / ".fastapi" / "cloud.json").exists()
536+
assert (tmp_path / ".fastapi" / "README.md").exists()
537+
assert (tmp_path / ".gitignore").exists()
538+
539+
assert (tmp_path / ".gitignore").read_text() == ".fastapi\n"
540+
541+
542+
@pytest.mark.respx(base_url=settings.base_api_url)
543+
def test_does_not_duplicate_entry_in_git_ignore(
544+
logged_in_cli: None, tmp_path: Path, respx_mock: respx.MockRouter
545+
) -> None:
546+
git_ignore_path = tmp_path / ".gitignore"
547+
git_ignore_path.write_text(".fastapi\n")
548+
549+
_deploy_without_waiting(respx_mock, tmp_path)
550+
551+
assert git_ignore_path.read_text() == ".fastapi\n"

0 commit comments

Comments
 (0)