예제 #1
0
def cmd_doc(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Generate local project documentation."""
    if not _verify_executable_exists(ctx, 'sphinx-build'):
        return 1

    if args.doxygen:
        if not _verify_executable_exists(ctx, 'doxygen'):
            return 1

        doxygen_args: List[str] = [ctx.path_for_program('doxygen'),
                                   os.path.join(ctx.calendon_home(), 'Doxyfile')]
        doxygen_exit_code: int = run_program(doxygen_args, cwd=(ctx.calendon_home()))
        if doxygen_exit_code != 0:
            return doxygen_exit_code

    source_dir: str = os.path.join(ctx.sphinx_dir(), 'source')
    build_dir: str = 'build'
    sphinx_args: List[str] = [ctx.path_for_program('sphinx-build'),
                              '-M', 'html', source_dir, build_dir]
    sphinx_exit_code: int = run_program(sphinx_args, cwd=ctx.sphinx_dir())
    if sphinx_exit_code != 0:
        return sphinx_exit_code

    if args.no_open:
        return sphinx_exit_code

    index: str = os.path.join(ctx.sphinx_dir(), 'build', 'html', 'index.html')
    return mp.open_file(index)
예제 #2
0
def cmd_pycheck(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Run all the checks on Python source."""
    if not _verify_executable_exists(ctx, 'localpython3'):
        return 1

    if not _verify_venv_dir_exists(ctx.venv_dir()):
        return 1

    python_path = ctx.path_for_program('localpython3')
    checks = [['mypy'],
              ['pylint'],
              ['pycodestyle', '--max-line-length=120', '--show-source',
               '--statistics', '--count', '--ignore=E731'],
              ['pydocstyle', '--ignore=D100,D102,D103,D104,D200,D203,D204,D212,D401'],
              ]

    failures = 0
    for program in checks:
        cmd_line = [python_path, '-m']
        cmd_line.extend(program)
        cmd_line.extend(py_files())
        if run_program(cmd_line, cwd=ctx.py_dir()) != 0:
            failures += 1
            if args.incremental:
                return failures

    return failures
예제 #3
0
def _verify_executable_exists(ctx: ProjectContext, alias: Optional[str]) -> bool:
    """Return true if an alias maps to a file in a context and provide user messaging."""
    if alias is None:
        print('Cannot find an executable for a null alias.')
        return False

    if not ctx.has_registered_program(alias):
        print(f'No alias exists for {alias}')
        recommended: Optional[str] = mp.recommended_executable(mp.root_to_executable(alias))
        if recommended is not None:
            choice: str = input(f'Use recommended path for alias "{alias}": {recommended} (saves in .crank) [y/N]? ')
            if choice == 'y':
                print(f'Setting alias {alias} -> {recommended}')
                if ctx.register_program(alias, recommended):
                    ctx.save()
                    return True

        print('Use `crank register ALIAS PATH` to register a program for use.')
        print('Example: crank register cmake "C:/Program Files/CMake/bin/cmake.exe"')
        return False
    program_path = ctx.path_for_program(alias)
    if not os.path.isfile(program_path):
        print(f'Executable path for {alias} does not exist at {program_path}')
        return False
    return True
예제 #4
0
def cmd_gen(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Runs the generator to make build files like Visual Studio solutions."""
    if not _verify_executable_exists(ctx, 'cmake'):
        return 1

    if ctx.compiler() is not None and not _verify_executable_exists(ctx, ctx.compiler()):
        return 1

    build_dir = ctx.build_dir()
    if os.path.isfile(build_dir):
        print(f'Build directory {build_dir} exists as something other than a directory')
        return 1
    if os.path.isdir(build_dir):
        if args.force:
            if args.dry_run:
                print(f'Would have removed previously existing directory {build_dir}')
            else:
                shutil.rmtree(build_dir)
        else:
            print(f'{build_dir} exists.  Use --force to wipe and recreate the build dir.')
            return 1

    if args.dry_run:
        print(f'Would have created {build_dir}')
    else:
        print(f'Creating build directory {build_dir}')
        os.mkdir(build_dir)

    cmake_path: str = ctx.path_for_program('cmake')
    cmake_args = [cmake_path, '..']
    if args.enable_ccache:
        cmake_args.append('-DCN_ENABLE_CCACHE=1')

    compiler = ctx.compiler()
    if compiler is not None:
        compiler = ctx.path_for_program(compiler)
    cmake_args.extend(generator_settings_for_compiler(cmake_path, compiler))

    if args.dry_run:
        print(f'Would have run {cmake_args} in {build_dir}')
        return 0

    return run_program(cmake_args, cwd=build_dir)
예제 #5
0
def cmd_pysetup(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Creates a virtual environment for helper module installs."""
    if not _verify_executable_exists(ctx, 'python3'):
        return 1

    if os.path.isfile(ctx.venv_dir()):
        print(f'Cannot create venv, {ctx.venv_dir()} is a file.')
        return 1

    if os.path.isdir(ctx.venv_dir()) and args.clean:
        shutil.rmtree(ctx.venv_dir())

    if not os.path.isdir(ctx.venv_dir()):
        venv_args = [(ctx.path_for_program('python3')), '-m', 'venv', ctx.venv_dir()]
        venv_setup = run_program(venv_args, cwd=ctx.calendon_home())
        if venv_setup != 0:
            print(f'Could not create virtual environment at {ctx.venv_dir()}')
            return venv_setup
        ctx.register_program('localpython3', os.path.join(ctx.venv_bin_dir(),
                                                          mp.root_to_executable('python')),
                             override=True)

    pip_upgrade_result = run_program(
        [(ctx.path_for_program('localpython3')), '-m', 'pip', 'install',
         '--upgrade', 'pip', 'setuptools', 'wheel'], cwd=ctx.calendon_home())
    if pip_upgrade_result != 0:
        print('Could not upgrade pip.')

    requirements_file = os.path.join(ctx.py_dir(), 'requirements.txt')
    if os.path.isfile(requirements_file):
        pip_install_args = [ctx.path_for_program('localpython3'), '-m', 'pip', 'install', '-r', requirements_file]
    else:
        required_dev_packages = ['mypy', 'pylint', 'pydocstyle', 'pycodestyle', 'bandit', 'colorama']
        required_dev_packages.extend(['sphinx', 'sphinx_rtd_theme', 'breathe'])
        pip_install_args = [ctx.path_for_program('localpython3'), '-m', 'pip', 'install']
        pip_install_args.extend(required_dev_packages)

    sphinx_build_path: str = os.path.join(ctx.venv_bin_dir(), mp.root_to_executable('sphinx-build'))
    ctx.register_program('sphinx-build', sphinx_build_path, override=True)
    return run_program(pip_install_args, cwd=ctx.calendon_home())
예제 #6
0
def cmd_build(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Build using the current project configuration."""
    if not _verify_executable_exists(ctx, 'cmake'):
        return 1

    if not _verify_build_dir_exists(ctx.build_dir()):
        return 1

    cmake_args = [ctx.path_for_program('cmake'), '--build', '.',
                  '--parallel', str(multiprocessing.cpu_count()),
                  '--config', ctx.build_config()]

    if args.dry_run:
        print(f'Would have run {cmake_args} in {ctx.build_dir()}')
        return 0

    return run_program(cmake_args, cwd=(ctx.build_dir()))
예제 #7
0
def cmd_check(ctx: ProjectContext, args: argparse.Namespace) -> int:
    """Runs tests."""
    if not _verify_executable_exists(ctx, 'cmake'):
        return 1

    if not _verify_build_dir_exists(ctx.build_dir()):
        return 1

    check_target: str = 'check'
    if args.iterate:
        check_target += '-iterate'

    cmake_args = [ctx.path_for_program('cmake'), '--build', '.',
                  '--target', check_target,
                  '--config', ctx.build_config()]
    if args.dry_run:
        print(f'Would have run {cmake_args} in {ctx.build_dir()}')
        return 0
    else:
        return run_program(cmake_args, cwd=(ctx.build_dir()))