Skip to content

Instantly share code, notes, and snippets.

@bukowa
Created February 13, 2023 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bukowa/9cfed701b1fc4dcdd753a8ec410157f0 to your computer and use it in GitHub Desktop.
Save bukowa/9cfed701b1fc4dcdd753a8ec410157f0 to your computer and use it in GitHub Desktop.
python makefile click autocomplete
import dataclasses
import selectors
import sys
import click
from colorama import Fore
@dataclasses.dataclass
class Command:
returncode: int = 0
stdout_lines: list[str] = dataclasses.field(default_factory=list)
stderr_lines: list[str] = dataclasses.field(default_factory=list)
@property
def stdout(self):
return "\n".join(self.stdout_lines)
@property
def stderr(self):
return "\n".join(self.stderr_lines)
def run(cmd, **kwargs):
from subprocess import Popen, PIPE
p = Popen(cmd, stdout=PIPE, stderr=PIPE, **kwargs)
sel = selectors.DefaultSelector()
sel.register(p.stdout, selectors.EVENT_READ)
sel.register(p.stderr, selectors.EVENT_READ)
stdout = []
stderr = []
def _run():
while True:
for key, _ in sel.select():
# noinspection PyUnresolvedReferences
data = key.fileobj.read1().decode()
if not data:
exit_code = p.poll()
return Command(
stdout_lines=stdout, stderr_lines=stderr, returncode=exit_code
)
if key.fileobj is p.stdout:
stdout.append(data)
sys.stdout.write("".join([Fore.GREEN, data]))
else:
stderr.append(data)
sys.stderr.write("".join([Fore.RED, data]))
return _run()
def ffast(cmd, **kwargs):
"""Run a command and exit on failure"""
command = run(cmd, **kwargs)
if command.returncode != 0:
print(Fore.RED, "Command failed")
sys.exit(command.returncode)
return command
@click.group()
def cli():
pass
@click.command("hello_world")
def hello_world():
"""Print hello world"""
r = run(["echo", "hello world"])
return r.returncode
cli.add_command(hello_world)
from setuptools import setup
setup(
name="my-app",
version="0.1.0",
py_modules=["Makefile"],
install_requires=[
"click==8.1.3",
"colorama==0.4.6",
],
entry_points={
"console_scripts": [
"makepy = Makefile:cli",
],
},
)
#!/bin/bash
set -e
# script to setup the virtual environment
# setup Makefile.py
pip install --no-cache-dir --editable .
# shellcheck disable=SC1090
source <(_MAKEPY_COMPLETE=zsh_source makepy)
set +e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment