Compare commits

...

7 Commits

Author SHA1 Message Date
zvecr 8d6a53d792 Add userspace-setup subcommand 2024-11-14 21:04:48 +00:00
Nick Brassel 1e98a2e459 Broken CI. 2024-11-15 06:42:33 +11:00
Nick Brassel c53fb88479 Merge pull request #186 from qmk/found-repo-prompt 2024-11-15 06:14:09 +11:00
Nick Brassel fed1e39611 Merge pull request #168 from qmk/userspace1 2024-11-15 06:13:00 +11:00
zvecr ae45bdeb02 Update 'qmk env' 2024-10-27 05:00:54 +00:00
zvecr d20af71118 Automatically configure userspace at runtime 2024-10-27 05:00:54 +00:00
fauxpark 27a97e4ebf qmk setup: ask user what to do if repo already exists 2024-10-27 15:52:52 +11:00
7 changed files with 170 additions and 13 deletions
+1 -1
View File
@@ -74,7 +74,7 @@ jobs:
shell: msys2 {0} shell: msys2 {0}
run: | run: |
python3 -m build python3 -m build
python3 -m pip install dist/qmk-*.tar.gz python3 -m pip install --break-system-packages dist/qmk-*.tar.gz
- name: (MSYS2) Run qmk setup -y - name: (MSYS2) Run qmk setup -y
shell: msys2 {0} shell: msys2 {0}
run: qmk setup -y run: qmk setup -y
+51 -1
View File
@@ -1,8 +1,9 @@
"""Useful helper functions. """Useful helper functions.
""" """
import os import os
import json
from platformdirs import user_data_dir
from functools import lru_cache from functools import lru_cache
from importlib.util import find_spec
from pathlib import Path from pathlib import Path
from milc import cli from milc import cli
@@ -44,6 +45,10 @@ def find_qmk_firmware():
return path.resolve() return path.resolve()
return path return path
hidden_home = Path(user_data_dir('qmk_cli', 'QMK')) / 'qmk_firmware'
if hidden_home.exists():
return hidden_home
return Path.home() / 'qmk_firmware' return Path.home() / 'qmk_firmware'
@@ -58,3 +63,48 @@ def in_qmk_firmware():
# Move up a directory before the next iteration # Move up a directory before the next iteration
cur_dir = cur_dir / '..' cur_dir = cur_dir / '..'
cur_dir = cur_dir.resolve() cur_dir = cur_dir.resolve()
def is_qmk_userspace(qmk_userspace):
"""Returns True if the given Path() is a qmk_userspace clone.
"""
path = qmk_userspace / 'qmk.json'
if not path.exists():
return False
try:
return 'userspace_version' in json.loads(path.read_text(encoding="UTF-8"))
except json.decoder.JSONDecodeError as e:
return False
@lru_cache(maxsize=2)
def find_qmk_userspace():
"""Look for qmk_userspace in the usual places.
"""
if in_qmk_userspace():
return in_qmk_userspace()
if cli.config.user.overlay_dir:
return Path(cli.config.user.overlay_dir).expanduser().resolve()
if 'QMK_USERSPACE' in os.environ:
path = Path(os.environ['QMK_USERSPACE']).expanduser()
if path.exists():
return path.resolve()
return path
return Path.home() / 'qmk_userspace'
def in_qmk_userspace():
"""Returns the path to the qmk_userspace we are currently in, or None if we are not inside qmk_userspace.
"""
cur_dir = Path.cwd()
while len(cur_dir.parents) > 0:
if is_qmk_userspace(cur_dir):
return cur_dir
# Move up a directory before the next iteration
cur_dir = cur_dir / '..'
cur_dir = cur_dir.resolve()
+3 -1
View File
@@ -13,7 +13,7 @@ from traceback import print_exc
import milc import milc
from . import __version__ from . import __version__
from .helpers import find_qmk_firmware, is_qmk_firmware from .helpers import find_qmk_firmware, is_qmk_firmware, find_qmk_userspace, is_qmk_userspace
milc.cli.milc_options(version=__version__) milc.cli.milc_options(version=__version__)
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
@@ -59,7 +59,9 @@ def main():
exit(1) exit(1)
# Environment setup # Environment setup
qmk_userspace = find_qmk_userspace()
qmk_firmware = find_qmk_firmware() qmk_firmware = find_qmk_firmware()
os.environ['QMK_USERSPACE'] = str(qmk_userspace)
os.environ['QMK_HOME'] = str(qmk_firmware) os.environ['QMK_HOME'] = str(qmk_firmware)
os.environ['ORIG_CWD'] = os.getcwd() os.environ['ORIG_CWD'] = os.getcwd()
+1
View File
@@ -6,3 +6,4 @@ from . import clone # noqa
from . import console # noqa from . import console # noqa
from . import env # noqa from . import env # noqa
from . import setup # noqa from . import setup # noqa
from . import userspace # noqa
+4 -2
View File
@@ -4,16 +4,18 @@ import os
from pathlib import Path from pathlib import Path
from milc import cli from milc import cli
from qmk_cli.helpers import is_qmk_firmware from qmk_cli.helpers import is_qmk_firmware, is_qmk_userspace
@cli.argument('var', arg_only=True, default=None, nargs='?', help='Optional variable to query') @cli.argument('var', arg_only=True, default=None, nargs='?', help='Optional variable to query')
@cli.subcommand('Prints environment information.') @cli.subcommand('Prints environment information.')
def env(cli): def env(cli):
home = os.environ.get('QMK_HOME', "") home = os.environ.get('QMK_HOME', "")
userspace = os.environ.get('QMK_USERSPACE', "")
data = { data = {
'QMK_HOME': home, 'QMK_HOME': home,
'QMK_FIRMWARE': home if is_qmk_firmware(Path(home)) else "" 'QMK_FIRMWARE': home if is_qmk_firmware(Path(home)) else "",
'QMK_USERSPACE': userspace if is_qmk_userspace(Path(userspace)) else ""
} }
# Now munge the current cli config # Now munge the current cli config
+40 -8
View File
@@ -5,9 +5,10 @@ import shlex
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from shutil import rmtree
from milc import cli from milc import cli
from milc.questions import yesno from milc.questions import choice, question, yesno
from qmk_cli.git import git_clone from qmk_cli.git import git_clone
from qmk_cli.helpers import is_qmk_firmware from qmk_cli.helpers import is_qmk_firmware
@@ -43,6 +44,17 @@ def git_upstream(destination):
return False return False
def git_clone_fork(fork, branch, force=False):
if force:
rmtree(cli.args.home)
git_url = '/'.join((cli.args.baseurl, fork))
if git_clone(git_url, cli.args.home, branch):
git_upstream(cli.args.home)
else:
exit(1)
@cli.argument('-n', '--no', arg_only=True, action='store_true', help='Answer no to all questions') @cli.argument('-n', '--no', arg_only=True, action='store_true', help='Answer no to all questions')
@cli.argument('-y', '--yes', arg_only=True, action='store_true', help='Answer yes to all questions') @cli.argument('-y', '--yes', arg_only=True, action='store_true', help='Answer yes to all questions')
@cli.argument('--baseurl', arg_only=True, default=default_base, help='The URL all git operations start from. Default: %s' % default_base) @cli.argument('--baseurl', arg_only=True, default=default_base, help='The URL all git operations start from. Default: %s' % default_base)
@@ -61,9 +73,34 @@ def setup(cli):
cli.log.error("Can't use both --yes and --no at the same time.") cli.log.error("Can't use both --yes and --no at the same time.")
exit(1) exit(1)
# Check on qmk_firmware, and if it doesn't exist offer to check it out. # Check on qmk_firmware
# If it exists, ask the user what to do with it
# If it doesn't exist, offer to check it out
if is_qmk_firmware(cli.args.home): if is_qmk_firmware(cli.args.home):
cli.log.info('Found qmk_firmware at %s.', str(cli.args.home)) cli.log.info('Found qmk_firmware at %s.', str(cli.args.home))
found_prompt = "What do you want to do?"
found_options = [
f"Delete and reclone {cli.args.fork}",
"Delete and clone a different fork",
"Keep it and continue"
]
delete_confirm = "WARNING: This will delete your current qmk_firmware directory. Proceed?"
found_action = choice(found_prompt, options=found_options, default=2)
if found_action == f"Delete and reclone {cli.args.fork}":
if not yesno(delete_confirm, default=False):
exit(1)
git_clone_fork(cli.args.fork, cli.args.branch, force=True)
elif found_action == "Delete and clone a different fork":
fork_name = question("Enter the name of the fork:", default=cli.args.fork)
branch_name = question("Enter the branch name to clone:", default=cli.args.branch)
if not yesno(delete_confirm, default=False):
exit(1)
git_clone_fork(fork_name, branch_name, force=True)
# Exists (but not an empty dir) # Exists (but not an empty dir)
elif cli.args.home.exists() and any(cli.args.home.iterdir()): elif cli.args.home.exists() and any(cli.args.home.iterdir()):
@@ -78,12 +115,7 @@ def setup(cli):
else: else:
cli.log.error('Could not find qmk_firmware!') cli.log.error('Could not find qmk_firmware!')
if yesno(clone_prompt): if yesno(clone_prompt):
git_url = '/'.join((cli.args.baseurl, cli.args.fork)) git_clone_fork(cli.args.fork, cli.args.branch)
if git_clone(git_url, cli.args.home, cli.args.branch):
git_upstream(cli.args.home)
else:
exit(1)
else: else:
cli.log.warning('Not cloning qmk_firmware due to user input or --no flag.') cli.log.warning('Not cloning qmk_firmware due to user input or --no flag.')
+70
View File
@@ -0,0 +1,70 @@
"""Setup qmk_userspace on your computer.
"""
import os
import sys
from pathlib import Path
from platformdirs import user_data_dir
from milc import cli
from milc.questions import yesno
from qmk_cli.git import git_clone
from qmk_cli.helpers import find_qmk_firmware, is_qmk_firmware, is_qmk_userspace
default_base = 'https://github.com'
default_fork = 'qmk/qmk_userspace'
default_branch = 'main'
@cli.argument('-n', '--no', arg_only=True, action='store_true', help='Answer no to all questions')
@cli.argument('-y', '--yes', arg_only=True, action='store_true', help='Answer yes to all questions')
@cli.argument('--baseurl', arg_only=True, default=default_base, help='The URL all git operations start from. Default: %s' % default_base)
@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help='The branch to clone. Default: %s' % default_branch)
@cli.argument('-H', '--home', arg_only=True, default=Path(os.environ['QMK_USERSPACE']), type=Path, help='The location for qmk_userspace. Default: %s' % os.environ['QMK_HOME'])
@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help='The qmk_userspace fork to clone. Default: %s' % default_fork)
@cli.subcommand('Setup your computer for qmk_userspace.')
def userspace_setup(cli):
"""Guide the user through setting up their QMK environment.
"""
# Sanity checks
if cli.args.yes and cli.args.no:
cli.log.error("Can't use both --yes and --no at the same time.")
exit(1)
if is_qmk_userspace(cli.args.home):
cli.log.info(f'Found qmk_userspace at {cli.args.home}.')
else:
cli.log.error('Could not find qmk_userspace!')
if yesno('Would you like to clone qmk_userspace?'):
git_url = f'{cli.args.baseurl}/{cli.args.fork}'
if not git_clone(git_url, cli.args.home, cli.args.branch):
exit(1)
else:
cli.log.warning('Not cloning qmk_userspace due to user input or --no flag.')
qmk_firmware = find_qmk_firmware()
if is_qmk_firmware(qmk_firmware):
cli.log.info(f'Found qmk_firmware at {qmk_firmware}.')
else:
cli.log.error('Could not find qmk_firmware!')
if yesno('Would you like to clone qmk_firmware?'):
git_url = f'{cli.args.baseurl}/qmk/qmk_firmware'
hidden_home = Path(user_data_dir('qmk_cli', 'QMK')) / 'qmk_firmware'
if not git_clone(git_url, hidden_home, 'master'):
exit(1)
else:
cli.log.warning('Not cloning qmk_firmware due to user input or --no flag.')
# Run `qmk doctor` to check the rest of the environment out
if cli.args.home.exists():
color = '--color' if cli.config.general.color else '--no-color'
unicode = '--unicode' if cli.config.general.unicode else '--no-unicode'
doctor_command = [Path(sys.argv[0]).as_posix(), color, unicode, 'doctor']
if cli.args.no:
doctor_command.append('-n')
if cli.args.yes:
doctor_command.append('-y')
cli.run(doctor_command, stdin=None, capture_output=False, cwd=cli.args.home)