meta-automata-nix / actions-batch

Time-sharing supercomputer built on GitHub Actions
https://blog.alexellis.io/github-actions-timesharing-supercomputer/
MIT License
1 stars 0 forks source link

Sweep: Make a build-a-py-binary-from-url.sh in /examples #33

Open ar4s-gh opened 1 month ago

ar4s-gh commented 1 month ago

Details

Steps for Converting a Python Project to an Executable Binary

1. Setup Environment

  1. Install Required Software:
    • Install Python
    • Install Git
    • Install PyInstaller
# Install Python and Git if not already installed
# For example, on Ubuntu:
sudo apt-get update
sudo apt-get install -y python3 python3-pip git

# Install PyInstaller
pip3 install pyinstaller
  1. Create a Working Directory:
mkdir /path/to/working/directory
cd /path/to/working/directory

2. Fetch the Project from GitHub

  1. Clone the Repository:
import subprocess
import os

def clone_repo(git_url, dest_dir):
    subprocess.run(["git", "clone", git_url, dest_dir])

git_url = "https://github.com/your-repo.git"  # This should be the input URL
dest_dir = "/path/to/working/directory/project"

clone_repo(git_url, dest_dir)

3. Setup the Project Environment

  1. Change Directory to the Project Directory:
os.chdir(dest_dir)
  1. Install Project Dependencies:

Check if the project has a requirements.txt or setup.py file. If these files are missing, attempt to create them from README.md. If README.md is also missing, create requirements.txt from the code repository.

import re

def create_requirements_from_readme(readme_file):
    with open(readme_file, 'r') as file:
        content = file.read()
    dependencies = re.findall(r'`pip install ([^`]+)`', content)
    with open("requirements.txt", 'w') as req_file:
        for dep in dependencies:
            req_file.write(dep.strip() + "\n")

def create_requirements_from_code(base_dir):
    requirements = set()
    for root, _, files in os.walk(base_dir):
        for file in files:
            if file.endswith(".py"):
                with open(os.path.join(root, file), 'r') as f:
                    content = f.read()
                imports = re.findall(r'^\s*import\s+(\S+)', content, re.MULTILINE) + re.findall(r'^\s*from\s+(\S+)', content, re.MULTILINE)
                requirements.update(imports)
    with open("requirements.txt", 'w') as req_file:
        for req in sorted(requirements):
            req_file.write(req.strip() + "\n")

def install_dependencies():
    if os.path.exists("requirements.txt"):
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])
    elif os.path.exists("setup.py"):
        subprocess.run(["pip3", "install", "."])
    elif os.path.exists("README.md"):
        create_requirements_from_readme("README.md")
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])
    else:
        create_requirements_from_code(".")
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])

install_dependencies()

4. Convert the Project

  1. Identify the Entry Point:

Determine the main script (entry point) of the project. This might require inspecting the project structure.

# Assuming the main script is named 'main.py'
main_script = "main.py"  # This might need to be dynamically determined
  1. Run PyInstaller:
def run_pyinstaller(main_script):
    subprocess.run(["pyinstaller", "--onefile", main_script])

run_pyinstaller(main_script)

5. Output the Binary

  1. Locate the Binary File:

The executable binary file will be located in the dist directory created by PyInstaller.

binary_path = os.path.join(dest_dir, "dist", os.path.splitext(main_script)[0])
  1. Provide the Downloadable Link:

If this is being run on a server, you can move the binary to a web-accessible directory or return the path to the binary.

# Example of moving the binary to a web-accessible directory
output_dir = "/path/to/output/directory"
subprocess.run(["mv", binary_path, output_dir])

download_link = os.path.join(output_dir, os.path.basename(binary_path))
print(f"Download link: {download_link}")

Full Script Example

Here is a complete example script that integrates all the steps:

import subprocess
import os
import re

def clone_repo(git_url, dest_dir):
    subprocess.run(["git", "clone", git_url, dest_dir])

def create_requirements_from_readme(readme_file):
    with open(readme_file, 'r') as file:
        content = file.read()
    dependencies = re.findall(r'`pip install ([^`]+)`', content)
    with open("requirements.txt", 'w') as req_file:
        for dep in dependencies:
            req_file.write(dep.strip() + "\n")

def create_requirements_from_code(base_dir):
    requirements = set()
    for root, _, files in os.walk(base_dir):
        for file in files:
            if file.endswith(".py"):
                with open(os.path.join(root, file), 'r') as f:
                    content = f.read()
                imports = re.findall(r'^\s*import\s+(\S+)', content, re.MULTILINE) + re.findall(r'^\s*from\s+(\S+)', content, re.MULTILINE)
                requirements.update(imports)
    with open("requirements.txt", 'w') as req_file:
        for req in sorted(requirements):
            req_file.write(req.strip() + "\n")

def install_dependencies():
    if os.path.exists("requirements.txt"):
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])
    elif os.path.exists("setup.py"):
        subprocess.run(["pip3", "install", "."])
    elif os.path.exists("README.md"):
        create_requirements_from_readme("README.md")
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])
    else:
        create_requirements_from_code(".")
        subprocess.run(["pip3", "install", "-r", "requirements.txt"])

def run_pyinstaller(main_script):
    subprocess.run(["pyinstaller", "--onefile", main_script])

def main(git_url, output_dir):
    dest_dir = "/path/to/working/directory/project"
    clone_repo(git_url, dest_dir)

    os.chdir(dest_dir)
    install_dependencies()

    # Assuming the main script is named 'main.py'
    main_script = "main.py"

    run_pyinstaller(main_script)

    binary_path = os.path.join(dest_dir, "dist", os.path.splitext(main_script)[0])
    subprocess.run(["mv", binary_path, output_dir])

    download_link = os.path.join(output_dir, os.path.basename(binary_path))
    print(f"Download link: {download_link}")

if __name__ == "__main__":
    git_url = input("Enter the GitHub repository URL: ")
    output_dir = "/path/to/output/directory"
    main(git_url, output_dir)

Instructions Recap

  1. Install Required Software

    • Install Python, Git, and PyInstaller.
  2. Create a Working Directory

    • Create and navigate to a working directory.
  3. Clone the Repository

    • Use the clone_repo function to clone the GitHub repository to the working directory.
  4. Change Directory

    • Navigate to the cloned repository directory.
  5. Install Project Dependencies

    • Use the install_dependencies function to handle dependencies:
      • Check for requirements.txt or setup.py.
      • If missing, try to create requirements.txt from README.md.
      • If README.md is missing, generate requirements.txt from the codebase.
  6. Identify the Entry Point

    • Determine the main script, assumed to be main.py.
  7. Run PyInstaller

    • Use the run_pyinstaller function to create an executable binary.
  8. Locate and Output the Binary

    • Move the binary to the output directory and provide the download link.

This comprehensive guide should enable an agent or LLM to successfully convert a Python project from a GitHub URL into an executable binary file.

Branch

No response

sweep-ai[bot] commented 1 month ago
Sweeping

0%
💎 Sweep Pro: You have unlimited Sweep issues

Actions


[!TIP] To recreate the pull request, edit the issue title or description.