From d576137b9f9c320890afeacb51b5b3a563643e45 Mon Sep 17 00:00:00 2001 From: ApurveKaranwal Date: Thu, 16 Oct 2025 23:22:11 +0530 Subject: [PATCH 1/2] Refactor: safer subprocess calls, install check, and fix output path --- script.py | 113 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 45 deletions(-) diff --git a/script.py b/script.py index a62c330..a8f16dc 100644 --- a/script.py +++ b/script.py @@ -1,56 +1,79 @@ -import os -import time +# Simple README to HTML converter +# Run like this: +# python script.py -i README.md -o output.html -t "My Project" +# Output will always go in the 'dist/' folder, so just pass a filename for -o -import argparse as parsing - - -parser = parsing.ArgumentParser( - description="ReadME.md to .html writer", - formatter_class=parsing.ArgumentDefaultsHelpFormatter, -) - -parser.add_argument( - "-i", - "--input", - action="store", - type=str, - required=True, - help="name of the input file eg. template.html", -) -parser.add_argument( - "-t", - "--title", - action="store", - type=str, - default="Progress", - help="title of the html page.", -) -parser.add_argument( - "-o", - "--output", - action="store", - type=str, - required=True, - help="the generated output file name , which is generated in dist folder. eg. template.html", -) +import argparse +import subprocess +import shutil +import sys +import time +from pathlib import Path +# ------------------------------ +# Parse command line arguments +# ------------------------------ +parser = argparse.ArgumentParser(description="Convert a README/Markdown file to HTML") +parser.add_argument("-i", "--input", required=True, help="Path to the input file, e.g., README.md") +parser.add_argument("-t", "--title", default="Progress", help="Title of the HTML page") +parser.add_argument("-o", "--output", required=True, help="Output filename (will be saved in dist/ folder), e.g., output.html") args = parser.parse_args() FILE_NAME = args.input TITLE = args.title -OUTPUT_NAME = args.output +OUTPUT_NAME = Path("dist") / Path(args.output).name # Only take filename, ignore any folder + +# Make sure output folder exists +OUTPUT_NAME.parent.mkdir(parents=True, exist_ok=True) + +# ------------------------------ +# Check input file exists +# ------------------------------ +if not Path(FILE_NAME).is_file(): + print(f"Error: The input file does not exist: {FILE_NAME}", file=sys.stderr) + sys.exit(1) + +# ------------------------------ +# Check if npx is installed +# ------------------------------ +if not shutil.which("npx"): + print("Error: 'npx' is not installed. Please install Node.js first: https://nodejs.org/", file=sys.stderr) + sys.exit(1) + +use_shell = sys.platform.startswith("win") # Needed for Windows +# ------------------------------ +# Install github-readme-to-html if missing +# ------------------------------ try: - os.system("npm install github-readme-to-html") -except: - print("NPM is not Installed") - print("Try : sudo apt install nodejs | sudo apt install npm ") + subprocess.run( + ["npx", "github-readme-to-html", "--version"], + check=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + shell=use_shell + ) +except subprocess.CalledProcessError: + print("Installing 'github-readme-to-html' globally via npm...") + try: + subprocess.run(["npm", "install", "-g", "github-readme-to-html"], check=True, shell=use_shell) + except subprocess.CalledProcessError as e: + print(f"Error: Failed to install 'github-readme-to-html' (exit code {e.returncode})", file=sys.stderr) + sys.exit(e.returncode) -time.sleep(5) -print("Wait While The File is Converting") -time.sleep(15) +# ------------------------------ +# Convert README/Markdown to HTML +# ------------------------------ +print("Converting file, please wait...") +time.sleep(1) try: - os.system(f"npx github-readme-to-html -i {FILE_NAME} -t {TITLE} -o {OUTPUT_NAME}") -except: - print("Please Check If file is exit") + subprocess.run( + ["npx", "github-readme-to-html", "-i", FILE_NAME, "-t", TITLE, "-o", str(OUTPUT_NAME.name)], + check=True, + shell=use_shell + ) + print(f"Conversion successful! HTML saved to: {OUTPUT_NAME}") +except subprocess.CalledProcessError as e: + print(f"Error: Conversion failed (exit code {e.returncode}). Please check your input file and command.", file=sys.stderr) + sys.exit(e.returncode) From 2c9d980a8aef91ad658eb2def9600de67bf0a488 Mon Sep 17 00:00:00 2001 From: ApurveKaranwal Date: Fri, 17 Oct 2025 20:06:43 +0530 Subject: [PATCH 2/2] Improve error handling, add Node.js check, auto .html extension, wrap in main() --- script.py | 128 +++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/script.py b/script.py index a8f16dc..a5dc1e5 100644 --- a/script.py +++ b/script.py @@ -10,70 +10,82 @@ import time from pathlib import Path -# ------------------------------ -# Parse command line arguments -# ------------------------------ -parser = argparse.ArgumentParser(description="Convert a README/Markdown file to HTML") -parser.add_argument("-i", "--input", required=True, help="Path to the input file, e.g., README.md") -parser.add_argument("-t", "--title", default="Progress", help="Title of the HTML page") -parser.add_argument("-o", "--output", required=True, help="Output filename (will be saved in dist/ folder), e.g., output.html") -args = parser.parse_args() +def main(): + + # Parse command line arguments + parser = argparse.ArgumentParser(description="Convert a README/Markdown file to HTML") + parser.add_argument("-i", "--input", required=True, help="Path to the input file, e.g., README.md") + parser.add_argument("-t", "--title", default="Progress", help="Title of the HTML page") + parser.add_argument("-o", "--output", required=True, help="Output filename (will be saved in dist/ folder), e.g., output.html") + args = parser.parse_args() -FILE_NAME = args.input -TITLE = args.title -OUTPUT_NAME = Path("dist") / Path(args.output).name # Only take filename, ignore any folder + FILE_NAME = args.input + TITLE = args.title + OUTPUT_NAME = Path("dist") / Path(args.output).name # Only take filename, ignore any folder -# Make sure output folder exists -OUTPUT_NAME.parent.mkdir(parents=True, exist_ok=True) + # Ensure output has .html extension + if not OUTPUT_NAME.suffix: + OUTPUT_NAME = OUTPUT_NAME.with_suffix(".html") -# ------------------------------ -# Check input file exists -# ------------------------------ -if not Path(FILE_NAME).is_file(): - print(f"Error: The input file does not exist: {FILE_NAME}", file=sys.stderr) - sys.exit(1) + # Make sure output folder exists + OUTPUT_NAME.parent.mkdir(parents=True, exist_ok=True) -# ------------------------------ -# Check if npx is installed -# ------------------------------ -if not shutil.which("npx"): - print("Error: 'npx' is not installed. Please install Node.js first: https://nodejs.org/", file=sys.stderr) - sys.exit(1) + # Check input file exists + if not Path(FILE_NAME).is_file(): + raise FileNotFoundError(f"The input file does not exist: {FILE_NAME}") -use_shell = sys.platform.startswith("win") # Needed for Windows -# ------------------------------ -# Install github-readme-to-html if missing -# ------------------------------ -try: - subprocess.run( - ["npx", "github-readme-to-html", "--version"], - check=True, - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - shell=use_shell - ) -except subprocess.CalledProcessError: - print("Installing 'github-readme-to-html' globally via npm...") + # Check if npx and node are installed + if not shutil.which("npx"): + raise EnvironmentError("`npx` is not installed. Please install Node.js first: https://nodejs.org/") + + if not shutil.which("node"): + raise EnvironmentError("`node` is not installed or not in PATH. Please install Node.js first: https://nodejs.org/") + + use_shell = sys.platform.startswith("win") # Needed for Windows + + + # Install github-readme-to-html if missing try: - subprocess.run(["npm", "install", "-g", "github-readme-to-html"], check=True, shell=use_shell) - except subprocess.CalledProcessError as e: - print(f"Error: Failed to install 'github-readme-to-html' (exit code {e.returncode})", file=sys.stderr) - sys.exit(e.returncode) + subprocess.run( + ["npx", "github-readme-to-html", "--version"], + check=True, + capture_output=True, + text=True, + shell=use_shell + ) + except subprocess.CalledProcessError: + print("Installing 'github-readme-to-html' globally via npm...") + try: + subprocess.run( + ["npm", "install", "-g", "github-readme-to-html"], + check=True, + capture_output=True, + text=True, + shell=use_shell + ) + except subprocess.CalledProcessError as e: + print(f"Error: {e.stderr}", file=sys.stderr) + raise RuntimeError(f"Failed to install 'github-readme-to-html' (exit code {e.returncode})") + + + # Convert README/Markdown to HTML + print("Converting file, please wait...") + time.sleep(1) -# ------------------------------ -# Convert README/Markdown to HTML -# ------------------------------ -print("Converting file, please wait...") -time.sleep(1) + try: + subprocess.run( + ["npx", "github-readme-to-html", "-i", FILE_NAME, "-t", TITLE, "-o", str(OUTPUT_NAME.name)], + check=True, + capture_output=True, + text=True, + shell=use_shell + ) + print(f"Conversion successful! HTML saved to: {OUTPUT_NAME}") + except subprocess.CalledProcessError as e: + print(f"Error: {e.stderr}", file=sys.stderr) + raise RuntimeError(f"Conversion failed (exit code {e.returncode}). Please check your input file and command.") from e -try: - subprocess.run( - ["npx", "github-readme-to-html", "-i", FILE_NAME, "-t", TITLE, "-o", str(OUTPUT_NAME.name)], - check=True, - shell=use_shell - ) - print(f"Conversion successful! HTML saved to: {OUTPUT_NAME}") -except subprocess.CalledProcessError as e: - print(f"Error: Conversion failed (exit code {e.returncode}). Please check your input file and command.", file=sys.stderr) - sys.exit(e.returncode) +# Entry point +if __name__ == "__main__": + main()