Skip to content

Commit fd66b18

Browse files
authored
Merge pull request #9 from bnbong/dev
Fixing #6
2 parents 424c2bc + 1ba6149 commit fd66b18

File tree

5 files changed

+722
-59
lines changed

5 files changed

+722
-59
lines changed

.github/workflows/template-inspection.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ on:
1010
required: false
1111
default: ""
1212

13+
permissions:
14+
contents: read
15+
issues: write
16+
1317
jobs:
1418
inspect-templates:
1519
runs-on: ubuntu-latest
@@ -29,9 +33,20 @@ jobs:
2933
- name: Install dependencies
3034
run: pdm install -G dev
3135

36+
- name: Set up Docker Compose
37+
run: |
38+
if ! command -v docker-compose &> /dev/null; then
39+
echo "Installing Docker Compose..."
40+
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
41+
sudo chmod +x /usr/local/bin/docker-compose
42+
fi
43+
44+
docker --version
45+
docker-compose --version
46+
3247
- name: Run template inspection
3348
run: |
34-
pdm run python scripts/inspect-templates.py --templates "${{ github.event.inputs.templates }}" --output template_inspection_results.json
49+
pdm run python scripts/inspect-templates.py --templates "${{ github.event.inputs.templates }}" --output template_inspection_results.json --verbose
3550
3651
- name: Upload inspection results
3752
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ htmlcov/
1010
coverage.xml
1111
.coverage.*
1212
coverage/
13+
temp/
1314

1415
.pdm-python
1516
### VisualStudioCode template

src/fastapi_fastkit/backend/inspector.py

Lines changed: 128 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,24 @@ def _check_file_structure(self) -> bool:
219219

220220
for path in required_paths:
221221
if not (self.template_path / path).exists():
222-
self.errors.append(f"Missing required path: {path}")
222+
error_msg = f"Missing required path: {path}"
223+
self.errors.append(error_msg)
224+
debug_log(f"File structure check failed: {error_msg}", "error")
223225
return False
226+
227+
debug_log("File structure check passed", "info")
224228
return True
225229

226230
def _check_file_extensions(self) -> bool:
227231
"""Check all Python files have .py-tpl extension."""
228232
for path in self.template_path.rglob("*"):
229233
if path.is_file() and path.suffix == ".py":
230-
self.errors.append(f"Found .py file instead of .py-tpl: {path}")
234+
error_msg = f"Found .py file instead of .py-tpl: {path}"
235+
self.errors.append(error_msg)
236+
debug_log(f"File extension check failed: {error_msg}", "error")
231237
return False
238+
239+
debug_log("File extension check passed", "info")
232240
return True
233241

234242
def _check_dependencies(self) -> bool:
@@ -237,50 +245,73 @@ def _check_dependencies(self) -> bool:
237245
setup_path = self.template_path / "setup.py-tpl"
238246

239247
if not req_path.exists():
240-
self.errors.append("requirements.txt-tpl not found")
248+
error_msg = "requirements.txt-tpl not found"
249+
self.errors.append(error_msg)
250+
debug_log(f"Dependencies check failed: {error_msg}", "error")
241251
return False
242252
if not setup_path.exists():
243-
self.errors.append("setup.py-tpl not found")
253+
error_msg = "setup.py-tpl not found"
254+
self.errors.append(error_msg)
255+
debug_log(f"Dependencies check failed: {error_msg}", "error")
244256
return False
245257

246258
try:
247259
with open(req_path, encoding="utf-8") as f:
248260
deps = f.read().splitlines()
249261
package_names = [dep.split("==")[0] for dep in deps if dep]
262+
debug_log(f"Found dependencies: {package_names}", "debug")
250263
if "fastapi" not in package_names:
251-
self.errors.append(
252-
"FastAPI dependency not found in requirements.txt-tpl"
253-
)
264+
error_msg = "FastAPI dependency not found in requirements.txt-tpl"
265+
self.errors.append(error_msg)
266+
debug_log(f"Dependencies check failed: {error_msg}", "error")
254267
return False
255268
except (OSError, UnicodeDecodeError) as e:
256-
self.errors.append(f"Error reading requirements.txt-tpl: {e}")
269+
error_msg = f"Error reading requirements.txt-tpl: {e}"
270+
self.errors.append(error_msg)
271+
debug_log(f"Dependencies check failed: {error_msg}", "error")
257272
return False
273+
274+
debug_log("Dependencies check passed", "info")
258275
return True
259276

260277
def _check_fastapi_implementation(self) -> bool:
261278
"""Check if the template has a proper FastAPI server implementation."""
262279
try:
263280
core_modules = find_template_core_modules(self.temp_dir)
281+
debug_log(f"Found core modules: {core_modules}", "debug")
264282

265283
if not core_modules["main"]:
266-
self.errors.append("main.py not found in template")
284+
error_msg = "main.py not found in template"
285+
self.errors.append(error_msg)
286+
debug_log(f"FastAPI implementation check failed: {error_msg}", "error")
267287
return False
268288

269289
with open(core_modules["main"], encoding="utf-8") as f:
270290
content = f.read()
271291
if "FastAPI" not in content or "app" not in content:
272-
self.errors.append("FastAPI app creation not found in main.py")
292+
error_msg = "FastAPI app creation not found in main.py"
293+
self.errors.append(error_msg)
294+
debug_log(
295+
f"FastAPI implementation check failed: {error_msg}", "error"
296+
)
297+
debug_log(f"main.py content preview: {content[:200]}...", "debug")
273298
return False
274299
except (OSError, UnicodeDecodeError) as e:
275-
self.errors.append(f"Error checking FastAPI implementation: {e}")
300+
error_msg = f"Error checking FastAPI implementation: {e}"
301+
self.errors.append(error_msg)
302+
debug_log(f"FastAPI implementation check failed: {error_msg}", "error")
276303
return False
304+
305+
debug_log("FastAPI implementation check passed", "info")
277306
return True
278307

279308
def _test_template(self) -> bool:
280309
"""Run tests on the template using appropriate strategy based on configuration."""
281310
test_dir = os.path.join(self.temp_dir, "tests")
282311
if not os.path.exists(test_dir):
283-
self.warnings.append("No tests directory found")
312+
warning_msg = "No tests directory found"
313+
self.warnings.append(warning_msg)
314+
debug_log(f"Template warning: {warning_msg}", "warning")
284315
return True
285316

286317
# Determine test strategy based on template configuration
@@ -295,9 +326,9 @@ def _test_with_docker_strategy(self) -> bool:
295326

296327
if not docker_available:
297328
debug_log("Docker not available, trying fallback strategy", "warning")
298-
self.warnings.append(
299-
"Docker not available, using fallback testing strategy"
300-
)
329+
warning_msg = "Docker not available, using fallback testing strategy"
330+
self.warnings.append(warning_msg)
331+
debug_log(f"Template warning: {warning_msg}", "warning")
301332
return self._test_with_fallback_strategy()
302333

303334
try:
@@ -374,7 +405,13 @@ def _test_with_standard_strategy(self) -> bool:
374405
result = self._run_pytest_directly(venv_path)
375406

376407
if result.returncode != 0:
377-
self.errors.append(f"Tests failed: {result.stderr}")
408+
error_msg = f"Tests failed with return code {result.returncode}\n"
409+
if result.stderr:
410+
error_msg += f"STDERR:\n{result.stderr}\n"
411+
if result.stdout:
412+
error_msg += f"STDOUT:\n{result.stdout}\n"
413+
self.errors.append(error_msg)
414+
debug_log(f"Standard strategy tests failed: {error_msg}", "error")
378415
return False
379416

380417
debug_log("All tests passed successfully", "info")
@@ -549,13 +586,23 @@ def _test_with_fallback_strategy(self) -> bool:
549586
result = self._run_pytest_with_env(venv_path, env, fallback_config)
550587

551588
if result.returncode != 0:
552-
self.errors.append(f"Fallback tests failed: {result.stderr}")
589+
error_msg = (
590+
f"Fallback tests failed with return code {result.returncode}\n"
591+
)
592+
if result.stderr:
593+
error_msg += f"STDERR:\n{result.stderr}\n"
594+
if result.stdout:
595+
error_msg += f"STDOUT:\n{result.stdout}\n"
596+
self.errors.append(error_msg)
597+
debug_log(f"Fallback strategy tests failed: {error_msg}", "error")
553598
return False
554599

555600
debug_log("Fallback tests passed successfully", "info")
556-
self.warnings.append(
601+
warning_msg = (
557602
"Tests passed using fallback strategy (SQLite instead of PostgreSQL)"
558603
)
604+
self.warnings.append(warning_msg)
605+
debug_log(f"Template warning: {warning_msg}", "warning")
559606
return True
560607

561608
except Exception as e:
@@ -799,7 +846,15 @@ def _run_docker_tests(self, compose_file: str) -> bool:
799846
)
800847

801848
if result.returncode != 0:
802-
self.errors.append(f"Docker tests failed: {result.stderr}")
849+
error_msg = (
850+
f"Docker tests failed with return code {result.returncode}\n"
851+
)
852+
if result.stderr:
853+
error_msg += f"STDERR:\n{result.stderr}\n"
854+
if result.stdout:
855+
error_msg += f"STDOUT:\n{result.stdout}\n"
856+
self.errors.append(error_msg)
857+
debug_log(f"Docker strategy tests failed: {error_msg}", "error")
803858
return False
804859

805860
debug_log("Docker tests passed successfully", "info")
@@ -868,7 +923,15 @@ def _run_docker_exec_tests(self, compose_file: str) -> bool:
868923
)
869924

870925
if result.returncode != 0:
871-
self.errors.append(f"Docker exec tests failed: {result.stderr}")
926+
error_msg = (
927+
f"Docker exec tests failed with return code {result.returncode}\n"
928+
)
929+
if result.stderr:
930+
error_msg += f"STDERR:\n{result.stderr}\n"
931+
if result.stdout:
932+
error_msg += f"STDOUT:\n{result.stdout}\n"
933+
self.errors.append(error_msg)
934+
debug_log(f"Docker exec strategy tests failed: {error_msg}", "error")
872935
debug_log(f"Docker exec test stderr: {result.stderr}", "error")
873936
debug_log(f"Docker exec test stdout: {result.stdout}", "info")
874937
return False
@@ -904,11 +967,38 @@ def get_report(self) -> Dict[str, Any]:
904967
905968
:return: Dictionary containing inspection results
906969
"""
970+
is_valid = len(self.errors) == 0
971+
template_name = self.template_path.name
972+
973+
# Log final inspection results
974+
if is_valid:
975+
debug_log(
976+
f"Template inspection completed successfully for {template_name}",
977+
"info",
978+
)
979+
if self.warnings:
980+
debug_log(
981+
f"Template {template_name} has {len(self.warnings)} warnings: {self.warnings}",
982+
"warning",
983+
)
984+
else:
985+
debug_log(
986+
f"Template inspection failed for {template_name} with {len(self.errors)} errors",
987+
"error",
988+
)
989+
for i, error in enumerate(self.errors, 1):
990+
debug_log(f"Error {i}: {error}", "error")
991+
if self.warnings:
992+
debug_log(
993+
f"Template {template_name} also has {len(self.warnings)} warnings: {self.warnings}",
994+
"warning",
995+
)
996+
907997
return {
908998
"template_path": str(self.template_path),
909999
"errors": self.errors,
9101000
"warnings": self.warnings,
911-
"is_valid": len(self.errors) == 0,
1001+
"is_valid": is_valid,
9121002
}
9131003

9141004

@@ -919,21 +1009,38 @@ def inspect_fastapi_template(template_path: str) -> Dict[str, Any]:
9191009
:param template_path: Path to the template to inspect
9201010
:return: Inspection report dictionary
9211011
"""
1012+
template_name = Path(template_path).name
1013+
debug_log(
1014+
f"Starting template inspection for {template_name} at {template_path}", "info"
1015+
)
1016+
9221017
with TemplateInspector(template_path) as inspector:
9231018
is_valid = inspector.inspect_template()
9241019
report = inspector.get_report()
9251020

9261021
if is_valid:
9271022
print_success(f"Template {template_path} is valid!")
1023+
debug_log(
1024+
f"Template inspection completed successfully for {template_name}",
1025+
"info",
1026+
)
9281027
else:
9291028
print_error(f"Template {template_path} validation failed")
1029+
debug_log(f"Template inspection failed for {template_name}", "error")
9301030
for error in inspector.errors:
9311031
print_error(f" - {error}")
9321032

9331033
if inspector.warnings:
1034+
debug_log(
1035+
f"Template inspection for {template_name} has warnings", "warning"
1036+
)
9341037
for warning in inspector.warnings:
9351038
print_warning(f" - {warning}")
9361039

1040+
debug_log(
1041+
f"Template inspection completed for {template_name}. Valid: {is_valid}, Errors: {len(inspector.errors)}, Warnings: {len(inspector.warnings)}",
1042+
"info",
1043+
)
9371044
return report
9381045

9391046

0 commit comments

Comments
 (0)