diff --git a/.gitignore b/.gitignore index 5fc555a..62c2163 100644 --- a/.gitignore +++ b/.gitignore @@ -162,3 +162,4 @@ cython_debug/ requirements-frozen.txt !/tests/fixtures/files/requirements-frozen.txt /docker-run-* +/report.html diff --git a/report_footer.html b/report_footer.html new file mode 100644 index 0000000..ed8075e --- /dev/null +++ b/report_footer.html @@ -0,0 +1,30 @@ + + + + + + diff --git a/report_header.html b/report_header.html new file mode 100644 index 0000000..ab40925 --- /dev/null +++ b/report_header.html @@ -0,0 +1,49 @@ + + + + + + Dependency Checker + + + + + + +
+
+
+
+

Dependency Checker Report

+
+ + +
+
+
+
+
+
+
diff --git a/src/main.py b/src/main.py index d6e81bd..aadd3be 100644 --- a/src/main.py +++ b/src/main.py @@ -11,8 +11,10 @@ from src.managers.repository import RepositoryManager from src.parsers.text import TextParser from src.parsers.toml import TomlParser +from src.reporters.html import HTMLReporter console = Console() +reporter = HTMLReporter() @click.command() @@ -21,7 +23,13 @@ prompt="Repository URL", help="The URL of the repository to clone.", ) -def start(repo_url): +@click.option( + "--report", + "-r", + is_flag=True, + help="Generate a printable report.", +) +def start(repo_url, report): console.clear() console.print("Welcome to the Dependency Checker.", style="bright_white") console.print( @@ -130,6 +138,17 @@ def start(repo_url): table.add_row("Docker Image", repository_manager.docker_image) console.print(table) + if report: + reporter.add_info_data( + { + "Repository URL": repository_manager.repo_url, + "Branch Name": repository_manager.get_branch(), + "Dockerfile Path": repository_manager.dockerfile_path, + "Poetry Version": repository_manager.poetry_version, + "Docker Image": repository_manager.docker_image, + } + ) + console.print("Analyzing the dependencies ...", style="cyan1") # process the requirements-frozen.txt file as a FrozenParser object @@ -191,6 +210,16 @@ def start(repo_url): table.add_row(name, frozen_version, latest_version, status, style=style) + if report: + reporter.add_production_data( + { + "Package": name, + "Installed Version": frozen_version, + "Latest Version": latest_version, + "Status": status, + } + ) + console.print(table) # development dependencies @@ -234,4 +263,17 @@ def start(repo_url): table.add_row(name, frozen_version, latest_version, status, style=style) + if report: + reporter.add_development_data( + { + "Package": name, + "Installed Version": frozen_version, + "Latest Version": latest_version, + "Status": status, + } + ) + console.print(table) + + if report: + reporter.write_report() diff --git a/src/reporters/html.py b/src/reporters/html.py new file mode 100644 index 0000000..70b993c --- /dev/null +++ b/src/reporters/html.py @@ -0,0 +1,88 @@ +from dataclasses import dataclass + + +@dataclass +class HTMLReporter: + report_header: str = "" + report_footer: str = "" + + report_info_section: str = "" + report_production_section: str = "" + report_development_section: str = "" + + def __post_init__(self): + with open("report_header.html") as f: + self.report_header = f.read() + + with open("report_footer.html") as f: + self.report_footer = f.read() + + self.info_data = {} + self.production_data = [] + self.development_data = [] + + self.report = "" + + def add_info_data(self, data: dict) -> None: + self.info_data = data + + def add_production_data(self, data: dict) -> None: + self.production_data.append(data) + + def add_development_data(self, data: dict) -> None: + self.development_data.append(data) + + def write_report(self): + self.report += self.report_header + + info_section = "

Info

\n" + info_section += "\n" + for key, value in self.info_data.items(): + info_section += f"" + info_section += "
{key}{value}
" + self.report += "
" + info_section + "
" + + self.report += "
" + + production_section = "

Production Dependencies

" + production_section += "" + production_section += ( + "" + ) + for data in self.production_data: + status_class = "pico-color-red-500" + if data["Status"] == "Check": + status_class = "pico-color-cyan-500" + elif data["Status"] == "Outdated": + status_class = "pico-color-orange-500" + elif data["Status"] == "OK": + status_class = "pico-color-green-500" + production_section += f"" # noqa + production_section += "
PackageInstalled VersionLatest VersionStatus
{data['Package']}{data['Installed Version']}{data['Latest Version']}{data['Status']}
" + self.report += "
" + production_section + "
" + + self.report += "
" + + development_section = "

Development Dependencies

" + development_section += "" + development_section += ( + "" + ) + for data in self.development_data: + status_class = "pico-color-red-500" + if data["Status"] == "Check": + status_class = "pico-color-cyan-500" + elif data["Status"] == "Outdated": + status_class = "pico-color-orange-500" + elif data["Status"] == "OK": + status_class = "pico-color-green-500" + development_section += f"" # noqa + development_section += "
PackageInstalled VersionLatest VersionStatus
{data['Package']}{data['Installed Version']}{data['Latest Version']}{data['Status']}
" + self.report += "
" + development_section + "
" + + self.report += "
" + + self.report += self.report_footer + + with open("report.html", "w") as f: + f.write(self.report)