feat: Make the init command more friendly.

This commit is contained in:
Sleepy Monax 2023-06-09 18:23:17 +02:00 committed by Sleepy Monax
parent 224a2fdd28
commit aea0678f65
5 changed files with 80 additions and 44 deletions

View file

@ -20,7 +20,7 @@ class Args:
del self.opts[key]
return result
def consumeOpt(self, key: str, default: Value) -> Value:
def consumeOpt(self, key: str, default: Value = False) -> Value:
if key in self.opts:
result = self.opts[key]
del self.opts[key]
@ -34,9 +34,9 @@ class Args:
return result
return None
def consumeArg(self) -> Optional[str]:
def consumeArg(self, default: Optional[str] = None) -> Optional[str]:
if len(self.args) == 0:
return None
return default
first = self.args[0]
del self.args[0]

View file

@ -1,6 +1,5 @@
import os
import logging
import tempfile
import requests
import sys
@ -220,8 +219,7 @@ def grabExtern(extern: dict[str, Extern]):
continue
print(f"Installing {extSpec}-{ext.tag} from {ext.git}...")
shell.popen("git", "clone", "--depth", "1", "--branch",
ext.tag, ext.git, extPath)
git.Repo.clone_from(ext.git, extPath, branch=ext.tag, depth=1)
if os.path.exists(os.path.join(extPath, "project.json")):
grabExtern(context.loadProject(extPath).extern)
@ -238,13 +236,11 @@ cmds += [Cmd("i", "install", "Install all the external packages", installCmd)]
def initCmd(args: Args):
repo = args.consumeOpt('repo', const.DEFAULT_REPO_TEMPLATES)
list = args.consumeOpt('list')
template = args.consumeArg()
if template is None:
raise RuntimeError("No template was provided")
repo = const.DEFAULT_REPO_TEMPLATES if not "repo" in args.opts else args.opts["repo"]
list = "list" in args.opts
name = args.consumeArg()
logger.info("Fetching registry...")
r = requests.get(
@ -257,20 +253,35 @@ def initCmd(args: Args):
registry = r.json()
if list:
print('\n'.join(
f"* {entry['id']} - {entry['description']}" for entry in registry))
else:
template_match: Callable[[Json], str] = lambda t: t['id'] == template
if not any(filter(template_match, registry)):
raise RuntimeError(f"Unknown template {template}")
logger.info("Fetching registry...")
r = requests.get(
f'https://raw.githubusercontent.com/{repo}/main/registry.json')
with tempfile.TemporaryDirectory() as tmp:
shell.exec(*["git", "clone", "-n", "--depth=1",
"--filter=tree:0", f"https://github.com/{repo}", tmp, "-q"])
shell.exec(*["git", "-C", tmp, "sparse-checkout",
"set", "--no-cone", template, "-q"])
shell.exec(*["git", "-C", tmp, "checkout", "-q"])
shell.mv(os.path.join(tmp, template), os.path.join(".", template))
if r.status_code != 200:
raise RuntimeError('Failed to fetch registry')
print('\n'.join(
f"* {entry['id']} - {entry['description']}" for entry in json.loads(r.text)))
return
if not template:
raise RuntimeError('Template not specified')
if not name:
raise RuntimeError('Name not specified')
if os.path.exists(name):
raise RuntimeError(f"Directory {name} already exists")
print(f"Creating project {name} from template {template}...")
shell.cloneDir(f"https://github.com/{repo}", template, name)
print(f"Project {name} created\n")
print("We suggest that you begin by typing:")
print(f" {vt100.GREEN}cd {name}{vt100.RESET}")
print(f" {vt100.GREEN}cutekit install{vt100.BRIGHT_BLACK} # Install external packages{vt100.RESET}")
print(
f" {vt100.GREEN}cutekit build{vt100.BRIGHT_BLACK} # Build the project{vt100.RESET}")
cmds += [Cmd("I", "init", "Initialize a new project", initCmd)]

View file

@ -9,6 +9,8 @@ import shutil
import fnmatch
import platform
import logging
import tempfile
from typing import Optional
from cutekit import const
@ -125,11 +127,18 @@ def wget(url: str, path: Optional[str] = None) -> str:
return path
def exec(*args: str):
def exec(*args: str, quiet: bool = False) -> bool:
logger.info(f"Executing {args}")
try:
proc = subprocess.run(args)
proc = subprocess.run(
args, stdout=sys.stdout if not quiet else subprocess.PIPE, stderr=sys.stderr if not quiet else subprocess.PIPE)
if proc.stdout:
logger.info(proc.stdout.decode('utf-8'))
if proc.stderr:
logger.error(proc.stderr.decode('utf-8'))
except FileNotFoundError:
raise RuntimeError(f"{args[0]}: Command not found")
@ -192,6 +201,19 @@ def cpTree(src: str, dst: str):
shutil.copytree(src, dst, dirs_exist_ok=True)
def cloneDir(url: str, path: str, dest: str) -> str:
with tempfile.TemporaryDirectory() as tmp:
mkdir(tmp)
exec(*["git", "clone", "-n", "--depth=1",
"--filter=tree:0", url, tmp, "-q"], quiet=True)
exec(*["git", "-C", tmp, "sparse-checkout",
"set", "--no-cone", path, "-q"], quiet=True)
exec(*["git", "-C", tmp, "checkout", "-q", "--no-progress"], quiet=True)
mv(os.path.join(tmp, path), dest)
return dest
LATEST_CACHE: dict[str, str] = {}

View file

@ -1,19 +1,22 @@
BLACK = "\033[0;30m"
RED = "\033[0;31m"
GREEN = "\033[0;32m"
BROWN = "\033[0;33m"
BLUE = "\033[0;34m"
PURPLE = "\033[0;35m"
CYAN = "\033[0;36m"
LIGHT_GRAY = "\033[0;37m"
DARK_GRAY = "\033[1;30m"
LIGHT_RED = "\033[1;31m"
LIGHT_GREEN = "\033[1;32m"
YELLOW = "\033[1;33m"
LIGHT_BLUE = "\033[1;34m"
LIGHT_PURPLE = "\033[1;35m"
LIGHT_CYAN = "\033[1;36m"
LIGHT_WHITE = "\033[1;37m"
BLACK = "\033[30m"
RED = "\033[31m"
GREEN = "\033[32m"
BROWN = "\033[33m"
BLUE = "\033[34m"
PURPLE = "\033[35m"
CYAN = "\033[36m"
WHITE = "\033[37m"
BRIGHT_BLACK = "\033[90m"
BRIGHT_RED = "\033[91m"
BRIGHT_GREEN = "\033[92m"
BRIGHT_BROWN = "\033[93m"
BRIGHT_BLUE = "\033[94m"
BRIGHT_PURPLE = "\033[95m"
BRIGHT_CYAN = "\033[96m"
BRIGHT_WHITE = "\033[97m"
BOLD = "\033[1m"
FAINT = "\033[2m"
ITALIC = "\033[3m"
@ -25,7 +28,7 @@ RESET = "\033[0m"
def title(text: str):
print(f"{LIGHT_WHITE}{text}{RESET}:")
print(f"{BOLD}{text}{RESET}:")
def wordwrap(text: str, width: int = 60, newline: str = "\n") -> str: