Ejemplo n.º 1
0
Archivo: setup.py Proyecto: qmk/qmk_cli
def setup(cli):
    """Guide the user through setting up their QMK environment.
    """
    clone_prompt = 'Would you like to clone {fg_cyan}%s{fg_reset} to {fg_cyan}%s{fg_reset}?' % (
        cli.args.fork, shlex.quote(str(cli.args.home)))
    home_prompt = 'Would you like to set {fg_cyan}%s{fg_reset} as your QMK home?' % (
        shlex.quote(str(cli.args.home)), )

    # 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)

    # Check on qmk_firmware, and if it doesn't exist offer to check it out.
    if is_qmk_firmware(cli.args.home):
        cli.log.info('Found qmk_firmware at %s.', str(cli.args.home))

    elif cli.args.home.exists():
        path_str = str(cli.args.home)

        if cli.args.home.name != 'qmk_firmware':
            cli.log.warning(
                'Warning: %s does not end in "qmk_firmware". Did you mean to use "--home %s/qmk_firmware"?'
                % (path_str, path_str))

        cli.log.error("Path '%s' exists but is not a qmk_firmware clone!",
                      path_str)
        exit(1)

    else:
        cli.log.error('Could not find qmk_firmware!')
        if yesno(clone_prompt):
            git_url = '/'.join((cli.config.setup.baseurl, cli.args.fork))

            if git_clone(git_url, cli.args.home, cli.config.setup.branch):
                git_upstream(cli.args.home)
            else:
                exit(1)

    # Offer to set `user.qmk_home` for them.
    if str(cli.args.home) != os.environ['QMK_HOME'] and yesno(home_prompt):
        cli.config['user']['qmk_home'] = str(cli.args.home.absolute())
        cli.config_source['user']['qmk_home'] = 'config_file'
        cli.write_config_option('user', 'qmk_home')

    # Run `qmk doctor` to check the rest of the environment out
    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('--no')

    if cli.args.yes:
        doctor_command.append('--yes')

    cli.run(doctor_command, stdin=None, capture_output=False)
Ejemplo n.º 2
0
def setup(cli):
    """Guide the user through setting up their QMK environment.
    """
    clone_prompt = 'Would you like to clone {fg_cyan}%s{fg_reset} to {fg_cyan}%s{fg_reset}?' % (
        cli.args.fork, shlex.quote(str(cli.args.home)))
    home_prompt = 'Would you like to set {fg_cyan}%s{fg_reset} as your QMK home?' % (
        shlex.quote(str(cli.args.home)), )

    # 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)

    # Check on qmk_firmware, and if it doesn't exist offer to check it out.
    if (cli.args.home / 'Makefile').exists():
        cli.log.info('Found qmk_firmware at %s.', str(cli.args.home))
    else:
        cli.log.error('Could not find qmk_firmware!')
        if yesno(clone_prompt):
            git_url = '/'.join((cli.config.setup.baseurl, cli.args.fork))

            if git_clone(git_url, cli.args.home, cli.config.setup.branch):
                git_upstream(cli.args.home)
            else:
                exit(1)

    # Offer to set `user.qmk_home` for them.
    if cli.args.home != Path(os.environ['QMK_HOME']) and yesno(home_prompt):
        cli.config['user']['qmk_home'] = str(cli.args.home.absolute())
        cli.write_config_option('user', 'qmk_home')

    # Run `qmk_firmware/bin/qmk doctor` to check the rest of the environment out
    qmk_bin = cli.args.home / 'bin/qmk'
    doctor_cmd = [sys.executable, qmk_bin.as_posix(), 'doctor']

    if cli.args.yes:
        doctor_cmd.append('--yes')

    if cli.args.no:
        doctor_cmd.append('--no')

    subprocess.run(doctor_cmd)
Ejemplo n.º 3
0
def doctor(cli):
    """Basic QMK environment checks.

    This is currently very simple, it just checks that all the expected binaries are on your system.

    TODO(unclaimed):
        * [ ] Compile a trivial program with each compiler
    """
    cli.log.info('QMK Doctor is checking your environment.')

    status = os_tests()

    cli.log.info('QMK home: {fg_cyan}%s', QMK_FIRMWARE)

    # Make sure our QMK home is a Git repo
    git_ok = check_git_repo()

    if git_ok == CheckStatus.WARNING:
        cli.log.warning(
            "QMK home does not appear to be a Git repository! (no .git folder)"
        )
        status = CheckStatus.WARNING

    # Make sure the basic CLI tools we need are available and can be executed.
    bin_ok = check_binaries()

    if not bin_ok:
        if yesno('Would you like to install dependencies?', default=True):
            run(['util/qmk_install.sh'])
            bin_ok = check_binaries()

    if bin_ok:
        cli.log.info('All dependencies are installed.')
    else:
        status = CheckStatus.ERROR

    # Make sure the tools are at the correct version
    ver_ok = check_binary_versions()
    if CheckStatus.ERROR in ver_ok:
        status = CheckStatus.ERROR
    elif CheckStatus.WARNING in ver_ok and status == CheckStatus.OK:
        status = CheckStatus.WARNING

    # Check out the QMK submodules
    sub_ok = check_submodules()

    if sub_ok == CheckStatus.OK:
        cli.log.info('Submodules are up to date.')
    else:
        if yesno('Would you like to clone the submodules?', default=True):
            submodules.update()
            sub_ok = check_submodules()

        if sub_ok == CheckStatus.ERROR:
            status = CheckStatus.ERROR
        elif sub_ok == CheckStatus.WARNING and status == CheckStatus.OK:
            status = CheckStatus.WARNING

    # Report a summary of our findings to the user
    if status == CheckStatus.OK:
        cli.log.info('{fg_green}QMK is ready to go')
        return 0
    elif status == CheckStatus.WARNING:
        cli.log.info(
            '{fg_yellow}QMK is ready to go, but minor problems were found')
        return 1
    else:
        cli.log.info(
            '{fg_red}Major problems detected, please fix these problems before proceeding.'
        )
        cli.log.info(
            '{fg_blue}Check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/Uq7gcHh) for help.'
        )
        return 2
Ejemplo n.º 4
0
    print(
        f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}'
    )
    exit(127)

# Check to make sure we have all our dependencies
msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.'
args = sys.argv[1:]
while args and args[0][0] == '-':
    del args[0]

safe_command = args and args[0] in safe_commands

if not safe_command:
    if _broken_module_imports('requirements.txt'):
        if yesno('Would you like to install the required Python modules?'):
            _run_cmd(sys.executable, '-m', 'pip', 'install', '-r',
                     'requirements.txt')
        else:
            print()
            print(msg_install % (str(Path('requirements.txt').resolve()), ))
            print()
            exit(1)

    if cli.config.user.developer and _broken_module_imports(
            'requirements-dev.txt'):
        if yesno(
                'Would you like to install the required developer Python modules?'
        ):
            _run_cmd(sys.executable, '-m', 'pip', 'install', '-r',
                     'requirements-dev.txt')
Ejemplo n.º 5
0
def main():
    """Setup the environment before dispatching to the entrypoint.
    """
    # Warn if they use an outdated python version
    if sys.version_info < (3, 7):
        print(
            'Warning: Your Python version is out of date! Some subcommands may not work!'
        )
        print('Please upgrade to Python 3.7 or later.')

    if 'windows' in platform().lower():
        msystem = os.environ.get('MSYSTEM', '')

        if 'mingw64' not in sys.executable or 'MINGW64' not in msystem:
            print('ERROR: It seems you are not using the MINGW64 terminal.')
            print(
                'Please close this terminal and open a new MSYS2 MinGW 64-bit terminal.'
            )
            print('Python: %s, MSYSTEM: %s' % (sys.executable, msystem))
            exit(1)

    # Environment setup
    import qmk_cli
    milc.cli.version = qmk_cli.__version__
    qmk_firmware = find_qmk_firmware()
    os.environ['QMK_HOME'] = str(qmk_firmware)
    os.environ['ORIG_CWD'] = os.getcwd()

    import qmk_cli.subcommands

    # Check out and initialize the qmk_firmware environment
    if is_qmk_firmware(qmk_firmware):
        # All subcommands are run relative to the qmk_firmware root to make it easier to use the right copy of qmk_firmware.
        os.chdir(str(qmk_firmware))

        # Check to make sure we have all the requirements
        broken_modules, broken_dev_modules = broken_module_imports()
        msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.'

        if broken_modules:
            if yesno('Would you like to install the required Python modules?'):
                run_cmd(sys.executable, '-m', 'pip', 'install', '-r',
                        'requirements.txt')
            else:
                print()
                print(msg_install %
                      (os.environ['QMK_HOME'] + '/requirements.txt', ))
                print()
                exit(1)

        if broken_dev_modules:
            if yesno(
                    'Would you like to install the required developer Python modules?'
            ):
                run_cmd(sys.executable, '-m', 'pip', 'install', '-r',
                        'requirements.txt')
            else:
                print()
                print(msg_install %
                      (os.environ['QMK_HOME'] + '/requirements-dev.txt', ))
                print(
                    'You can also turn off developer mode: qmk config user.developer=None'
                )
                print()
                exit(1)

        # Environment looks good, include the qmk_firmware subcommands
        sys.path.append(str(qmk_firmware / 'lib/python'))

        try:
            import qmk.cli  # noqa

        except ImportError as e:
            if qmk_firmware.name != 'qmk_firmware':
                print(
                    'Warning: %s does not end in "qmk_firmware". Do you need to set QMK_HOME to "%s/qmk_firmware"?'
                    % (qmk_firmware, qmk_firmware))

            print('Error: %s: %s', (e.__class__.__name__, e))
            print_exc()
            sys.exit(1)

    # Call the entrypoint
    return_code = milc.cli()

    if return_code is False:
        exit(1)

    elif return_code is not True and isinstance(return_code, int):
        if return_code < 0 or return_code > 255:
            milc.cli.log.error('Invalid return_code: %d', return_code)
            exit(255)

        exit(return_code)

    exit(0)
Ejemplo n.º 6
0
def doctor(cli):
    """Basic QMK environment checks.

    This is currently very simple, it just checks that all the expected binaries are on your system.

    TODO(unclaimed):
        * [ ] Compile a trivial program with each compiler
    """
    cli.log.info('QMK Doctor is checking your environment.')
    status = CheckStatus.OK

    # Determine our OS and run platform specific tests
    platform_id = platform.platform().lower()

    if 'darwin' in platform_id or 'macos' in platform_id:
        status = os_test_macos()
    elif 'linux' in platform_id:
        status = os_test_linux()
    elif 'windows' in platform_id:
        status = os_test_windows()
    else:
        cli.log.warning('Unsupported OS detected: %s', platform_id)
        status = CheckStatus.WARNING

    cli.log.info('QMK home: {fg_cyan}%s', QMK_FIRMWARE)

    # Make sure the basic CLI tools we need are available and can be executed.
    bin_ok = check_binaries()

    if not bin_ok:
        if yesno('Would you like to install dependencies?', default=True):
            run(['util/qmk_install.sh'])
            bin_ok = check_binaries()

    if bin_ok:
        cli.log.info('All dependencies are installed.')
    else:
        status = CheckStatus.ERROR

    # Make sure the tools are at the correct version
    ver_ok = []
    for check in (check_arm_gcc_version, check_avr_gcc_version, check_avrdude_version, check_dfu_util_version, check_dfu_programmer_version):
        ver_ok.append(check())

    if CheckStatus.ERROR in ver_ok:
        status = CheckStatus.ERROR
    elif CheckStatus.WARNING in ver_ok and status == CheckStatus.OK:
        status = CheckStatus.WARNING

    # Check out the QMK submodules
    sub_ok = check_submodules()

    if sub_ok == CheckStatus.OK:
        cli.log.info('Submodules are up to date.')
    else:
        if yesno('Would you like to clone the submodules?', default=True):
            submodules.update()
            sub_ok = check_submodules()

        if CheckStatus.ERROR in sub_ok:
            status = CheckStatus.ERROR
        elif CheckStatus.WARNING in sub_ok and status == CheckStatus.OK:
            status = CheckStatus.WARNING

    # Report a summary of our findings to the user
    if status == CheckStatus.OK:
        cli.log.info('{fg_green}QMK is ready to go')
        return 0
    elif status == CheckStatus.WARNING:
        cli.log.info('{fg_yellow}QMK is ready to go, but minor problems were found')
        return 1
    else:
        cli.log.info('{fg_red}Major problems detected, please fix these problems before proceeding.')
        cli.log.info('{fg_blue}Check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/Uq7gcHh) for help.')
        return 2
Ejemplo n.º 7
0
def _yesno(*args):
    """Wrapper to only prompt if interactive
    """
    return sys.stdout.isatty() and yesno(*args)