Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
zackees committed Mar 24, 2024
1 parent f20e771 commit 9c3c071
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[MESSAGES CONTROL]
disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,line-too-long,raise-missing-from,too-few-public-methods,too-many-return-statements
disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,line-too-long,raise-missing-from,too-few-public-methods,too-many-return-statements,duplicate-code
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ Run `./lint.sh` to find linting errors using `pylint`, `flake8` and `mypy`.

# Releases

* 1.0.5: You may now omit the `--os` parameter and compile against the current system.
* 1.0.4: Fix
* 1.0.3: Native windows compile is available if the host is also windows.
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ license = { text = "BSD 3-Clause License" }
classifiers = ["Programming Language :: Python :: 3"]
dependencies = [
"docker-run-cmd~=1.0.10",
"isolated-environment"
"isolated-environment",
"pytest-xdist"
]
# Change this with the version number bump.
version = "1.0.4"
Expand Down
37 changes: 25 additions & 12 deletions src/python_compile/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@
import argparse
import os
import sys
from dataclasses import dataclass
from pathlib import Path

from docker_run_cmd.api import docker_run

from python_compile.native_build import run_native_build


@dataclass
class Args:
app_py: Path
requirements: Path | None = None
os: str | None = None


HERE = Path(__file__).parent
ASSETS = HERE / "assets"

Expand All @@ -30,6 +39,7 @@ def parse_args() -> argparse.Namespace:
type=str,
help="Which os to use",
choices=DOCKER_FILE_MAP.keys(),
required=False,
)
parser.add_argument(
"--platform",
Expand All @@ -51,14 +61,10 @@ def parse_args() -> argparse.Namespace:
return parser.parse_args()


def main() -> int:
def run(args: Args) -> int:
"""Main entry point for the template_python_cmd package."""
args = parse_args()
os_system = args.os
if not os_system:
print("You must provide an os")
return 1
app_py = args.input
app_py = args.app_py
requirements_txt = args.requirements
if os_system == "windows":
if os.name != "nt":
Expand All @@ -67,19 +73,17 @@ def main() -> int:
return 1
rtn = run_native_build(app_py=app_py, requirements_txt=requirements_txt)
return rtn
if os_system == "native":
run_native_build(app_py=app_py, requirements_txt=requirements_txt)
if os_system is None or os_system == "native":
rtn = run_native_build(app_py=app_py, requirements_txt=requirements_txt)
return rtn

dockerpath: Path | None = DOCKER_FILE_MAP.get(os_system)
if dockerpath is None:
print(f"OS {os_system} is not supported")
return 1
assert dockerpath.exists(), f"dockerpath {dockerpath} does not exist"
py_path = args.input
py_path = Path(py_path).as_posix()

assert py_path, "You must provide a python path"
py_path = args.app_py
assert Path(py_path).as_posix(), "You must provide a python path"

extra_files: dict[Path, Path] = {}
if args.requirements:
Expand All @@ -95,6 +99,15 @@ def main() -> int:
return 0


def main() -> int:
cli_args = parse_args()
os_system = cli_args.os
app_py = cli_args.input
requirements_txt = cli_args.requirements
args = Args(app_py=app_py, requirements=requirements_txt, os=os_system)
return run(args)


if __name__ == "__main__":
sys.argv.append("--os")
sys.argv.append("debian")
Expand Down
30 changes: 22 additions & 8 deletions src/python_compile/native_build.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import os
import shutil
import subprocess
import sys
import tempfile
import warnings
from atexit import register
from pathlib import Path

from isolated_environment import IsolatedEnvironment, Requirements
Expand Down Expand Up @@ -42,19 +46,29 @@ def generate_cmd_list(app_py: Path) -> list[str]:
return cmd_list


def run_native_build(app_py: Path, requirements_txt: Path) -> int:
"""Run the native windows build."""
def clean_dir(path: str) -> None:
"""Clean the directory."""
try:
shutil.rmtree(path, ignore_errors=True)
except Exception as e: # pylint: disable=broad-except
warnings.warn(f"Failed to clean directory: {path} with error: {e}")


def run_native_build(app_py: Path, requirements_txt: Path | None) -> int:
"""Run the native windows build."""
print("Running native build")
with tempfile.TemporaryDirectory() as tmp_dir:
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmp_dir:
print(f"Creating temporary directory: {tmp_dir}")
full_tmp_path = os.path.abspath(tmp_dir)
register(clean_dir, full_tmp_path)
env_path = Path(tmp_dir) / "nuitka_venv"
iso_env = IsolatedEnvironment(env_path, REQS)
subprocess.run(
["pip", "install", "-r", requirements_txt],
env=iso_env.environment(),
check=True,
)
if requirements_txt:
subprocess.run(
["pip", "install", "-r", requirements_txt],
env=iso_env.environment(),
check=True,
)
cmd_list: list[str] = generate_cmd_list(app_py)
subprocess.run(
cmd_list,
Expand Down
2 changes: 1 addition & 1 deletion test
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
set -e
. ./activate.sh
echo "Running unittests"
python -m unittest discover -s tests -p "*test*.py"
pytest -n auto -v tests
29 changes: 0 additions & 29 deletions tests/test_cli.py

This file was deleted.

46 changes: 46 additions & 0 deletions tests/test_cli_native.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Unit test file.
"""

import os
import subprocess
import sys
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory

HERE = Path(__file__).parent
PROJECT_ROOT = HERE.parent
DEMO_PY = PROJECT_ROOT / "src/python_compile/assets/demo_http_server.py"


class CliNativetester(unittest.TestCase):
"""Main tester class."""

def test_cli(self) -> None:
"""Test command line interface (CLI)."""
with TemporaryDirectory() as tmp_dir:
os.chdir(tmp_dir)
try:
cmd_list = [
"python-compile",
"--input",
str(DEMO_PY),
]
cmd_str = subprocess.list2cmdline(cmd_list)
print(f"Running: {cmd_str}")
rtn = os.system(" ".join(cmd_list))
self.assertEqual(0, rtn)
expected_path_gz: Path = Path("demo_http_server.bin.gz")
self.assertTrue(expected_path_gz.exists())
if sys.platform == "win32":
expected_path = Path("demo_http_server.exe")
else:
expected_path = Path("demo_http_server.bin")
self.assertTrue(expected_path.exists())
finally:
os.chdir(PROJECT_ROOT)


if __name__ == "__main__":
unittest.main()
41 changes: 41 additions & 0 deletions tests/test_debian.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Unit test file.
"""

import os
import subprocess
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory


class NativeTester(unittest.TestCase):
"""Main tester class."""

def test_compile(self) -> None:
"""Test command line interface (CLI)."""
with TemporaryDirectory() as tmp_dir:
prev_dir = os.getcwd()
os.chdir(tmp_dir)
try:
cmd_list = [
"python-compile",
"--input",
"src/python_compile/assets/demo_http_server.py",
"--os",
"debian",
]
cmd_str = subprocess.list2cmdline(cmd_list)
print(f"Running: {cmd_str}")
rtn = os.system(" ".join(cmd_list))
self.assertEqual(0, rtn)
expected_path_gz: Path = Path("demo_http_server.bin.gz")
self.assertTrue(expected_path_gz.exists())
expected_path = Path("demo_http_server.bin")
self.assertTrue(expected_path.exists())
finally:
os.chdir(prev_dir)


if __name__ == "__main__":
unittest.main()
45 changes: 45 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
Unit test file.
"""

import os
import sys
import unittest
from pathlib import Path
from pprint import pprint
from tempfile import TemporaryDirectory

from python_compile.cli import Args, run

HERE = Path(__file__).parent
PROJECT_ROOT = HERE.parent
DEMO_PY = PROJECT_ROOT / "src/python_compile/assets/demo_http_server.py"


class MainTester(unittest.TestCase):
"""Main tester class."""

def test_run_main(self) -> None:
"""Test command line interface (CLI)."""
with TemporaryDirectory(ignore_cleanup_errors=True) as tmp_dir:
prev_dir = os.getcwd()
os.chdir(tmp_dir)
if sys.platform == "win32":
expected_path = "demo_http_server.exe"
else:
expected_path = "demo_http_server.bin"
try:
args = Args(app_py=DEMO_PY)
rtn = run(args)
self.assertEqual(0, rtn)
files = os.listdir(tmp_dir)
pprint(files)
self.assertTrue(
expected_path in files, f"{expected_path} not found in {files}"
)
finally:
os.chdir(prev_dir)


if __name__ == "__main__":
unittest.main()
43 changes: 43 additions & 0 deletions tests/test_native.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Unit test file.
"""

import os
import subprocess
import sys
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory


class NativeTester(unittest.TestCase):
"""Main tester class."""

def test_compile(self) -> None:
"""Test command line interface (CLI)."""
with TemporaryDirectory() as tmp_dir:
prev_dir = os.getcwd()
os.chdir(tmp_dir)
try:
cmd_list = [
"python-compile",
"--input",
"src/python_compile/assets/demo_http_server.py",
]
cmd_str = subprocess.list2cmdline(cmd_list)
print(f"Running: {cmd_str}")
rtn = os.system(" ".join(cmd_list))
self.assertEqual(0, rtn)
expected_path_gz: Path = Path("demo_http_server.bin.gz")
self.assertTrue(expected_path_gz.exists())
if sys.platform == "win32":
expected_path = Path("demo_http_server.exe")
else:
expected_path = Path("demo_http_server.bin")
self.assertTrue(expected_path.exists())
finally:
os.chdir(prev_dir)


if __name__ == "__main__":
unittest.main()

0 comments on commit 9c3c071

Please sign in to comment.