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

View file

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

View file

@ -9,6 +9,8 @@ import shutil
import fnmatch import fnmatch
import platform import platform
import logging import logging
import tempfile
from typing import Optional from typing import Optional
from cutekit import const from cutekit import const
@ -125,11 +127,18 @@ def wget(url: str, path: Optional[str] = None) -> str:
return path return path
def exec(*args: str): def exec(*args: str, quiet: bool = False) -> bool:
logger.info(f"Executing {args}") logger.info(f"Executing {args}")
try: 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: except FileNotFoundError:
raise RuntimeError(f"{args[0]}: Command not found") 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) 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] = {} LATEST_CACHE: dict[str, str] = {}

View file

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