示例#1
0
def main():
    parser = OptionParser()

    parser.add_option(
        "--verbose",
        action="store_true",
        dest="verbose",
        default=False,
        help="""Show what it is doing. Default is %default.""",
    )

    parser.add_option(
        "--write",
        "-w",
        action="store_true",
        dest="write",
        default=False,
        help="""Write changes to the files. Default is %default.""",
    )

    options, positional_args = parser.parse_args()

    if not positional_args:
        positional_args = [
            "bin",
            "nuitka",
            "rpm",
            "misc",
            "tests/*/run_all.py",
            "*.rst",
        ]
        goHome()

    my_print("Working on:", positional_args)

    positional_args = sum(
        (resolveShellPatternToFilenames(positional_arg)
         for positional_arg in positional_args),
        [],
    )

    filenames = list(
        scanTargets(
            positional_args,
            suffixes=(".py", ".scons", ".rst", ".txt", ".j2", ".md", ".c",
                      ".h"),
        ))
    if not filenames:
        sys.exit("No files found.")

    result = runCodespell(filenames=filenames,
                          verbose=options.verbose,
                          write=options.write)

    if result:
        my_print("OK.")
    else:
        sys.exit(
            "\nError, please correct the spelling problems found or extend 'misc/codespell-ignore.txt' if applicable."
        )
示例#2
0
文件: __main__.py 项目: psydox/Nuitka
def main():
    parser = OptionParser()

    _options, positional_args = parser.parse_args()

    if not positional_args:
        positional_args = ["nuitka/plugins/standard/*.yml"]

    my_print("Working on:", positional_args)

    positional_args = sum(
        (resolveShellPatternToFilenames(positional_arg)
         for positional_arg in positional_args),
        [],
    )

    goHome()

    filenames = list(scanTargets(
        positional_args,
        suffixes=(".yaml", ),
    ))
    if not filenames:
        sys.exit("No files found.")

    for filename in filenames:
        checkYamllint(filename)
def main():
    parser = OptionParser()

    parser.add_option(
        "--verbose",
        action="store_true",
        dest="verbose",
        default=False,
        help="""Default is %default.""",
    )

    parser.add_option(
        "--from-commit",
        action="store_true",
        dest="from_commit",
        default=False,
        help=
        """From commit hook, do not descend into directories. Default is %default.""",
    )

    parser.add_option(
        "--abort-on-parsing-error",
        action="store_true",
        dest="abort",
        default=False,
        help="""Stop if an error occurs, or continue. Default is %default.""",
    )

    options, positional_args = parser.parse_args()

    if options.from_commit:
        assert not positional_args
        for desc in getStagedFileChangeDesc():
            autoformat(desc["src_path"], git_stage=desc, abort=options.abort)
    else:
        if not positional_args:
            positional_args = [
                "bin", "nuitka", "setup.py", "tests/*/run_all.py"
            ]

        my_print("Working on:", positional_args)

        positional_args = sum(
            (resolveShellPatternToFilenames(positional_arg)
             for positional_arg in positional_args),
            [],
        )

        filenames = list(
            scanTargets(
                positional_args,
                (".py", ".scons", ".rst", ".txt", ".j2", ".md", ".c", ".h"),
            ))
        if not filenames:
            sys.exit("No files found.")

        for filename in filenames:
            autoformat(filename, git_stage=False, abort=options.abort)
示例#4
0
def _addIncludedDataFilesFromFileOptions():
    for pattern, src, dest, arg in getShallIncludeDataFiles():
        filenames = resolveShellPatternToFilenames(pattern)

        if not filenames:
            options_logger.warning(
                "No matching data file to be included for '%s'." % pattern)

        for filename in filenames:
            file_reason = "specified data file '%s' on command line" % arg

            if src is None:
                rel_path = dest

                if rel_path.endswith(("/", os.path.sep)):
                    rel_path = os.path.join(rel_path,
                                            os.path.basename(filename))
            else:
                rel_path = os.path.join(dest, relpath(filename, src))

            yield makeIncludedDataFile(filename,
                                       rel_path,
                                       file_reason,
                                       tracer=options_logger,
                                       tags="user")

    for src, dest in getShallIncludeDataDirs():
        filenames = getFileList(src)

        if not filenames:
            options_logger.warning("No files in directory '%s.'" % src)

        for filename in filenames:
            relative_filename = relpath(filename, src)

            file_reason = "specified data dir %r on command line" % src

            rel_path = os.path.join(dest, relative_filename)

            yield makeIncludedDataFile(filename,
                                       rel_path,
                                       file_reason,
                                       tracer=options_logger,
                                       tags="user")
示例#5
0
def copyDataFiles(dist_dir):
    """Copy the data files needed for standalone distribution.

    Args:
        dist_dir: The distribution folder under creation
    Notes:
        This is for data files only, not DLLs or even extension modules,
        those must be registered as entry points, and would not go through
        necessary handling if provided like this.
    """

    # Many details to deal with, pylint: disable=too-many-branches,too-many-locals

    for pattern, dest, arg in Options.getShallIncludeDataFiles():
        filenames = resolveShellPatternToFilenames(pattern)

        if not filenames:
            inclusion_logger.warning("No match data file to be included: %r" %
                                     pattern)

        for filename in filenames:
            file_reason = "specified data file %r on command line" % arg

            rel_path = dest

            if rel_path.endswith(("/", os.path.sep)):
                rel_path = os.path.join(rel_path, os.path.basename(filename))

            _handleDataFile(
                dist_dir,
                inclusion_logger,
                makeIncludedDataFile(filename, rel_path, file_reason),
            )

    for src, dest in Options.getShallIncludeDataDirs():
        filenames = getFileList(src)

        if not filenames:
            inclusion_logger.warning("No files in directory" % src)

        for filename in filenames:
            relative_filename = relpath(filename, src)

            file_reason = "specified data dir %r on command line" % src

            rel_path = os.path.join(dest, relative_filename)

            _handleDataFile(
                dist_dir,
                inclusion_logger,
                makeIncludedDataFile(filename, rel_path, file_reason),
            )

    # Cyclic dependency
    from nuitka import ModuleRegistry

    for module in ModuleRegistry.getDoneModules():
        for plugin, included_datafile in Plugins.considerDataFiles(module):
            _handleDataFile(dist_dir=dist_dir,
                            tracer=plugin,
                            included_datafile=included_datafile)

    for module in ModuleRegistry.getDoneModules():
        if module.isCompiledPythonPackage(
        ) or module.isUncompiledPythonPackage():
            package_name = module.getFullName()

            match, reason = package_name.matchesToShellPatterns(
                patterns=Options.getShallIncludePackageData())

            if match:
                package_directory = module.getCompileTimeDirectory()

                pkg_filenames = getFileList(
                    package_directory,
                    ignore_dirs=("__pycache__", ),
                    ignore_suffixes=(".py", ".pyw", ".pyc", ".pyo", ".dll") +
                    getSharedLibrarySuffixes(),
                )

                if pkg_filenames:
                    file_reason = "package '%s' %s" % (package_name, reason)

                    for pkg_filename in pkg_filenames:
                        rel_path = os.path.join(
                            package_name.asPath(),
                            os.path.relpath(pkg_filename, package_directory),
                        )

                        _handleDataFile(
                            dist_dir,
                            inclusion_logger,
                            makeIncludedDataFile(pkg_filename, rel_path,
                                                 file_reason),
                        )
示例#6
0
    def considerDataFiles(self, module):
        # Many cases to deal with, pylint: disable=too-many-branches

        module_name = module.getFullName()
        module_folder = module.getCompileTimeDirectory()

        config = self.config.get(module_name)

        if config:
            target_dir = config.get("dest_path")

            # Default to near module or inside package folder.
            if target_dir is None:
                if (
                    module.isCompiledPythonPackage()
                    or module.isUncompiledPythonPackage()
                ):
                    target_dir = module_name.asPath()
                else:
                    package_name = module_name.getPackageName()

                    if package_name is not None:
                        target_dir = module_name.getPackageName().asPath()
                    else:
                        target_dir = "."

            patterns = config.get("patterns")
            if patterns is not None:
                if type(patterns) is not list or not patterns:
                    self.sysexit(
                        "Error, requiring list below 'pattern' entry for '%s' entry."
                        % module_name
                    )

                # TODO: Pattern should be data file kind potentially.
                for pattern in patterns:
                    pattern = os.path.join(module_folder, pattern)

                    for filename in resolveShellPatternToFilenames(pattern):
                        yield makeIncludedDataFile(
                            source_path=filename,
                            dest_path=os.path.normpath(
                                os.path.join(target_dir, os.path.basename(filename))
                            ),
                            reason="package data for %r" % module_name.asString(),
                        )

            empty_dirs = config.get("empty_dirs")
            if empty_dirs is not None:
                if type(empty_dirs) is not list or not empty_dirs:
                    self.sysexit(
                        "Error, requiring list below 'empty_dirs' entry for '%s' entry."
                        % module_name
                    )

                yield makeIncludedEmptyDirectories(
                    source_path=target_dir,
                    dest_paths=tuple(
                        os.path.join(target_dir, empty_dir) for empty_dir in empty_dirs
                    ),
                    reason="empty dir needed for %r" % module_name.asString(),
                )

            empty_dir_structures = config.get("empty_dir_structures")
            if empty_dir_structures is not None:
                if type(empty_dir_structures) is not list or not empty_dir_structures:
                    self.sysexit(
                        "Error, requiring list below 'empty_dirs_structure' entry for '%s' entry."
                        % module_name
                    )

                # TODO: This ignored dest_path, which is unused, but not consistent.
                yield _getSubDirectoryFolders(module, empty_dir_structures)

            dirs = config.get("dirs")
            if dirs is not None:
                if type(dirs) is not list or not dirs:
                    self.sysexit(
                        "Error, requiring list below 'empty_dirs_structure' entry for '%s' entry."
                        % module_name
                    )

                for data_dir in dirs:
                    source_path = os.path.join(module_folder, data_dir)

                    if os.path.isdir(source_path):
                        yield makeIncludedDataDirectory(
                            source_path=source_path,
                            dest_path=os.path.join(target_dir, data_dir),
                            reason="package data directory for %r"
                            % module_name.asString(),
                        )
示例#7
0
def main():
    setup(go_main=False)

    # So PyLint finds nuitka package.
    addPYTHONPATH(getHomePath())
    setupPATH()

    parser = OptionParser()

    parser.add_option(
        "--diff",
        action="store_true",
        dest="diff",
        default=False,
        help="""\
Analyse the changed files in git. Default is %default.""",
    )

    parser.add_option(
        "--show-todos",
        "--todos",
        action="store_true",
        dest="todos",
        default=False,
        help="""\
Show TODO items. Default is %default.""",
    )

    parser.add_option(
        "--verbose",
        action="store_true",
        dest="verbose",
        default=False,
        help="""\
Be verbose in output. Default is %default.""",
    )

    parser.add_option(
        "--one-by-one",
        action="store_true",
        dest="one_by_one",
        default=False,
        help="""\
Check files one by one. Default is %default.""",
    )

    parser.add_option(
        "--not-installed-is-no-error",
        action="store_true",
        dest="not_installed_is_no_error",
        default=False,
        help="""\
Insist on PyLint to be installed. Default is %default.""",
    )

    options, positional_args = parser.parse_args()

    if options.not_installed_is_no_error and not hasModule("pylint"):
        print("PyLint is not installed for this interpreter version: SKIPPED")
        sys.exit(0)

    if positional_args:
        if options.diff:
            sys.exit("Error, no filenames argument allowed in git diff mode.")
    else:
        goHome()

        if options.diff:
            positional_args = [
                filename for filename in getModifiedPaths()
                if isPythonFile(filename)
            ]
        else:
            positional_args = [
                "bin", "nuitka", "setup.py", "tests/*/run_all.py"
            ]

    positional_args = sum(
        (resolveShellPatternToFilenames(positional_arg)
         for positional_arg in positional_args),
        [],
    )

    if not positional_args:
        sys.exit("No files found.")

    print("Working on:", positional_args)

    ignore_list = []

    # Avoid checking the Python2 runner along with the one for Python3, it has name collisions.
    if python_version >= 0x300:
        ignore_list.append("nuitka")

    filenames = list(
        scanTargets(positional_args,
                    suffixes=(".py", ".scons"),
                    ignore_list=ignore_list))
    PyLint.executePyLint(
        filenames=filenames,
        show_todos=options.todos,
        verbose=options.verbose,
        one_by_one=options.one_by_one,
    )

    if not filenames:
        sys.exit("No files found.")

    sys.exit(PyLint.our_exit_code)
示例#8
0
def main():
    # Complex stuff, pylint: disable=too-many-statements

    # Make sure error messages are in English.
    os.environ["LANG"] = "C"

    parser = OptionParser()

    parser.add_option(
        "--no-pbuilder-update",
        action="store_false",
        dest="update_pbuilder",
        default=True,
        help="""\
Update the pbuilder chroot before building. Default %default.""",
    )

    options, positional_args = parser.parse_args()

    assert len(positional_args) == 1, positional_args
    codename = positional_args[0]

    nuitka_version = getNuitkaVersion()

    branch_name = checkBranchName()

    category = getBranchCategory(branch_name)

    if category == "stable":
        if nuitka_version.count(".") == 1:
            assert checkChangeLog("New upstream release.")
        else:
            assert checkChangeLog("New upstream hotfix release.")
    else:
        assert checkChangeLog("New upstream pre-release.")

    shutil.rmtree("dist", ignore_errors=True)
    shutil.rmtree("build", ignore_errors=True)

    createReleaseDocumentation()
    assert os.system("python setup.py sdist --formats=gztar") == 0

    os.chdir("dist")

    # Clean the stage for the debian package. The name "deb_dist" is what "py2dsc"
    # uses for its output later on.
    shutil.rmtree("deb_dist", ignore_errors=True)

    # Provide a re-packed tar.gz for the Debian package as input.

    # Create it as a "+ds" file, removing:
    # - the benchmarks (too many sources, not useful to end users, potential license
    #   issues)
    # - the inline copy of scons (not wanted for Debian)

    for filename in os.listdir("."):
        if filename.endswith(".tar.gz"):
            new_name = filename[:-7] + "+ds.tar.gz"

            cleanupTarfileForDebian(filename, new_name)

            entry = runPy2dsc(filename, new_name)

            break
    else:
        assert False

    os.chdir("deb_dist")
    os.chdir(entry)

    # Build the debian package, but disable the running of tests, will be done later
    # in the pbuilder test steps.
    assert os.system("debuild --set-envvar=DEB_BUILD_OPTIONS=nocheck") == 0

    os.chdir("../../..")
    assert os.path.exists("dist/deb_dist")

    # Check with pylint in pedantic mode and don't proceed if there were any
    # warnings given. Nuitka is lintian clean and shall remain that way. For
    # hotfix releases, i.e. "stable" builds, we skip this test though.
    if category == "stable":
        my_print("Skipped lintian checks for stable releases.", style="blue")
    else:
        assert os.system(
            "lintian --pedantic --allow-root dist/deb_dist/*.changes") == 0

    # Move the created debian package files out.
    os.system("cp dist/deb_dist/*.deb dist/")

    # Build inside the pbuilder chroot, and output to dedicated directory.
    shutil.rmtree("package", ignore_errors=True)
    os.makedirs("package")

    # Now update the pbuilder.
    if options.update_pbuilder:
        command = """\
sudo /usr/sbin/pbuilder --update --basetgz  /var/cache/pbuilder/%s.tgz""" % (
            codename)

        assert os.system(command) == 0, codename

    (dsc_filename, ) = resolveShellPatternToFilenames("dist/deb_dist/*.dsc")
    # Execute the package build in the pbuilder with tests.
    command = (
        "sudo",
        "/usr/sbin/pbuilder",
        "--build",
        "--basetgz",
        "/var/cache/pbuilder/%s.tgz" % codename,
        "--hookdir",
        "debian/pbuilder-hookdir",
        "--debemail",
        "Kay Hayen <*****@*****.**>",
        "--buildresult",
        "package",
        dsc_filename,
    )

    check_call(command, shell=False)

    # Cleanup the build directory, not needed anymore.
    shutil.rmtree("build", ignore_errors=True)

    # Now build the repository.
    my_print("Building repository ...", style="blue")

    os.chdir("package")

    os.makedirs("repo")
    os.chdir("repo")

    os.makedirs("conf")

    putTextFileContents(
        "conf/distributions",
        contents="""\
Origin: Nuitka
Label: Nuitka
Codename: %(codename)s
Architectures: i386 amd64 armel armhf powerpc
Components: main
Description: Apt repository for project Nuitka %(codename)s
SignWith: D96ADCA1377F1CEB6B5103F11BFC33752912B99C
""" % {"codename": codename},
    )

    command = ["reprepro", "includedeb", codename]
    command.extend(resolveShellPatternToFilenames("../*.deb"))

    check_call(command, shell=False)

    my_print("Uploading ...", style="blue")

    # Create repo folder unless already done. This is needed for the first
    # build only.
    assert (os.system("ssh [email protected] mkdir -p /var/www/deb/%s/%s/" %
                      (category, codename)) == 0)

    # Update the repository on the web site.
    assert (os.system(
        "rsync -avz --delete dists pool --chown www-data [email protected]:/var/www/deb/%s/%s/"
        % (category, codename)) == 0)

    my_print("Finished.", style="blue")
示例#9
0
def parseArgs():
    # singleton with many cases, pylint: disable=global-statement,too-many-branches,too-many-statements
    global is_nuitka_run, options, positional_args, extra_args, is_debug, is_nondebug, is_fullcompat

    is_nuitka_run, options, positional_args, extra_args = parseOptions(
        logger=Tracing.general)

    Tracing.is_quiet = options.quiet or int(os.environ.get(
        "NUITKA_QUIET", "0"))
    Tracing.use_progressbar = isExperimental("progress")

    if options.verbose_output:
        Tracing.optimization_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            open(options.verbose_output, "w"))

        options.verbose = True

    if options.show_inclusion_output:
        Tracing.inclusion_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            open(options.show_inclusion_output, "w"))

        options.show_inclusion = True

    # Onefile implies standalone build.
    if options.is_onefile:
        options.is_standalone = True

    # Standalone mode implies an executable, not importing "site" module, which is
    # only for this machine, recursing to all modules, and even including the
    # standard library.
    if options.is_standalone:
        if not options.executable:
            Tracing.general.sysexit("""\
Error, conflicting options, cannot make standalone module, only executable.""")

        if getOS() == "NetBSD":
            Tracing.general.warning(
                "Standalone mode on NetBSD is not functional, due to $ORIGIN linkage not being supported."
            )

    for any_case_module in getShallFollowModules():
        if any_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in any_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.general.sysexit("""\
Error, '--follow-import-to' takes only module names, not directory path '%s'."""
                                    % any_case_module)

    for no_case_module in getShallFollowInNoCase():
        if no_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in no_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.general.sysexit("""\
Error, '--nofollow-import-to' takes only module names, not directory path '%s'."""
                                    % no_case_module)

    scons_python = getPythonPathForScons()

    if scons_python is not None and not os.path.isfile(scons_python):
        Tracing.scons_logger.sysexit(
            "Error, no such Python binary %r, should be full path." %
            scons_python)

    if options.output_filename is not None and (isStandaloneMode()
                                                or shallMakeModule()):
        Tracing.general.sysexit("""\
Error, can only specify output filename for acceleration mode, not for module
mode where filenames are mandatory, and not for standalone where there is a
sane default used inside the dist folder.""")

    if getOS() == "Linux":
        if len(getIconPaths()) > 1:
            Tracing.general.sysexit("Error, can only use one icon on Linux.")

    for icon_path in getIconPaths():
        if not os.path.exists(icon_path):
            Tracing.general.sysexit("Error, icon path %r does not exist." %
                                    icon_path)

        if getWindowsIconExecutablePath():
            Tracing.general.sysexit(
                "Error, can only use icons from template executable or from icon files, but not both."
            )

    icon_exe_path = getWindowsIconExecutablePath()
    if icon_exe_path is not None and not os.path.exists(icon_exe_path):
        Tracing.general.sysexit("Error, icon path %r does not exist." %
                                icon_exe_path)

    try:
        file_version = getWindowsFileVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.general.sysexit(
            "Error, file version must be a tuple of up to 4 integer values.")

    try:
        product_version = getWindowsProductVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.general.sysexit(
            "Error, product version must be a tuple of up to 4 integer values."
        )

    if file_version or product_version or getWindowsVersionInfoStrings():
        if not (file_version or product_version) and getWindowsCompanyName():
            Tracing.general.sysexit(
                "Error, company name and file or product version need to be given when any version information is given."
            )

    if isOnefileMode() and not hasOnefileSupportedOS():
        Tracing.general.sysexit("Error, unsupported OS for onefile %r" %
                                getOS())

    if isOnefileMode() and os.name == "nt":
        if not getWindowsCompanyName() and not isWindowsOnefileTempDirMode():
            Tracing.general.sysexit(
                "Error, onefile on Windows requires company name and file or product version to be given or temp dir mode."
            )

    if options.recurse_none and options.recurse_all:
        Tracing.general.sysexit(
            "Conflicting options '--follow-imports' and '--nofollow-imports' given."
        )

    if getShallIncludePackageData() and not isStandaloneMode():
        Tracing.general.sysexit(
            "Error, package data files are only included in standalone or onefile mode."
        )

    for data_file in options.data_files:
        if "=" not in data_file:
            Tracing.general.sysexit(
                "Error, malformed data file description, must specify relative target path with =."
            )

        src, dst = data_file.split("=", 1)

        if os.path.isabs(dst):
            Tracing.general.sysexit(
                "Error, must specify relative target path for data file, not %r."
                % data_file)

        if not resolveShellPatternToFilenames(src):
            Tracing.general.sysexit("Error, %r does not match any files." %
                                    src)

    if options.data_files and not isStandaloneMode():
        Tracing.general.sysexit(
            "Error, data files are only included in standalone or onefile mode."
        )

    for pattern in getShallFollowExtraFilePatterns():
        if os.path.isdir(pattern):
            sys.exit(
                "Error, pattern %r given to --include-plugin-files cannot be a directory name."
                % pattern)

    is_debug = _isDebug()
    is_nondebug = not is_debug
    is_fullcompat = _isFullCompat()
示例#10
0
文件: Options.py 项目: psydox/Nuitka
def parseArgs():
    """Parse the command line arguments

    :meta private:
    """
    # singleton with many cases checking the options right away.
    # pylint: disable=global-statement,too-many-branches,too-many-locals,too-many-statements
    global is_nuitka_run, options, positional_args, extra_args, is_debug, is_nondebug
    global is_fullcompat, is_report_missing, is_verbose

    if os.name == "nt":
        # Windows store Python's don't allow looking at the python, catch that.
        try:
            with openTextFile(sys.executable, "rb"):
                pass
        except OSError:
            Tracing.general.sysexit(
                "Error, the Python from Windows store is not supported, check the User Manual of Nuitka ."
            )

    is_nuitka_run, options, positional_args, extra_args = parseOptions(
        logger=Tracing.options_logger)

    is_debug = _isDebug()
    is_nondebug = not is_debug
    is_fullcompat = _isFullCompat()

    # TODO: Have dedicated option for it.
    is_report_missing = is_debug

    if options.quiet or int(os.environ.get("NUITKA_QUIET", "0")):
        Tracing.setQuiet()

    if not shallDumpBuiltTreeXML():
        Tracing.options_logger.info("Used command line options: %s" %
                                    " ".join(sys.argv[1:]))

    if os.environ.get("NUITKA_REEXECUTION") and not isAllowedToReexecute():
        Tracing.general.sysexit(
            "Error, not allowed to re-execute, but that has happened.")

    if options.progress_bar:
        Progress.enableProgressBar()

    if options.verbose_output:
        Tracing.optimization_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            openTextFile(options.verbose_output, "w", encoding="utf8"))

        options.verbose = True

    is_verbose = options.verbose

    Tracing.optimization_logger.is_quiet = not options.verbose

    if options.show_inclusion_output:
        Tracing.inclusion_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            openTextFile(options.show_inclusion_output, "w", encoding="utf8"))

        options.show_inclusion = True

    Tracing.progress_logger.is_quiet = not options.show_progress

    # Onefile implies standalone build.
    if options.is_onefile:
        options.is_standalone = True

    # Standalone implies no_site build
    if options.is_standalone:
        options.python_flags.insert(0, "no_site")

    # Provide a tempdir spec implies onefile tempdir, even on Linux.
    if options.onefile_tempdir_spec:
        options.is_onefile_tempdir = True

        if os.path.normpath(options.onefile_tempdir_spec) == ".":
            Tracing.options_logger.sysexit("""\
Error, using '.' as a value for '--onefile-tempdir-spec' is not supported,
you cannot unpack the onefile payload into the same directory as the binary,
as that would overwrite it and cause locking issues as well.""")

        if options.onefile_tempdir_spec.count("%") % 2 != 0:
            Tracing.options_logger.warning(
                """Unmatched '%%' is suspicious for '--onefile-tempdir-spec' and may
not do what you want it to do: '%s'""" % options.onefile_tempdir_spec)

        if options.onefile_tempdir_spec.count("%") == 0:
            Tracing.options_logger.warning(
                """Not using any variables for '--onefile-tempdir-spec' should only be
done if your program absolutely needs to be in the same path always: '%s'""" %
                options.onefile_tempdir_spec)

        if os.path.isabs(options.onefile_tempdir_spec):
            Tracing.options_logger.warning(
                """Using an absolute path should be avoided unless you are targeting a
very well known environment: '%s'""" % options.onefile_tempdir_spec)
        elif relpath(options.onefile_tempdir_spec):
            Tracing.options_logger.warning(
                """Using an relative path above the executable should be avoided unless you are targeting a
very well known environment: '%s'""" % options.onefile_tempdir_spec)

    # Standalone mode implies an executable, not importing "site" module, which is
    # only for this machine, recursing to all modules, and even including the
    # standard library.
    if options.is_standalone:
        if options.module_mode:
            Tracing.options_logger.sysexit("""\
Error, conflicting options, cannot make standalone module, only executable.

Modules are supposed to be imported to an existing Python installation, therefore it
makes no sense to include a Python runtime.""")

    for any_case_module in getShallFollowModules():
        if any_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in any_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.options_logger.sysexit("""\
Error, '--follow-import-to' takes only module names or patterns, not directory path '%s'."""
                                           % any_case_module)

    for no_case_module in getShallFollowInNoCase():
        if no_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in no_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.options_logger.sysexit("""\
Error, '--nofollow-import-to' takes only module names or patterns, not directory path '%s'."""
                                           % no_case_module)

    scons_python = getPythonPathForScons()

    if scons_python is not None and not os.path.isfile(scons_python):
        Tracing.options_logger.sysexit(
            "Error, no such Python binary %r, should be full path." %
            scons_python)

    if options.output_filename is not None and (
        (isStandaloneMode() and not isOnefileMode()) or shallMakeModule()):
        Tracing.options_logger.sysexit("""\
Error, may only specify output filename for acceleration and onefile mode,
but not for module mode where filenames are mandatory, and not for
standalone where there is a sane default used inside the dist folder.""")

    if isLinux():
        if len(getIconPaths()) > 1:
            Tracing.options_logger.sysexit(
                "Error, can only use one icon file on Linux.")

    if isMacOS():
        if len(getIconPaths()) > 1:
            Tracing.options_logger.sysexit(
                "Error, can only use one icon file on macOS.")

    for icon_path in getIconPaths():
        if "#" in icon_path and isWin32Windows():
            icon_path, icon_index = icon_path.rsplit("#", 1)

            if not icon_index.isdigit() or int(icon_index) < 0:
                Tracing.options_logger.sysexit(
                    "Error, icon number in %r not valid." %
                    (icon_path + "#" + icon_index))

        if not os.path.exists(icon_path):
            Tracing.options_logger.sysexit(
                "Error, icon path %r does not exist." % icon_path)

        if getWindowsIconExecutablePath():
            Tracing.options_logger.sysexit(
                "Error, can only use icons from template executable or from icon files, but not both."
            )

    icon_exe_path = getWindowsIconExecutablePath()
    if icon_exe_path is not None and not os.path.exists(icon_exe_path):
        Tracing.options_logger.sysexit("Error, icon path %r does not exist." %
                                       icon_exe_path)

    try:
        file_version = getWindowsFileVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.options_logger.sysexit(
            "Error, file version must be a tuple of up to 4 integer values.")

    try:
        product_version = getWindowsProductVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.options_logger.sysexit(
            "Error, product version must be a tuple of up to 4 integer values."
        )

    if getWindowsCompanyName() == "":
        Tracing.options_logger.sysexit(
            """Error, empty string is not an acceptable company name.""")

    if getWindowsProductName() == "":
        Tracing.options_logger.sysexit(
            """Error, empty string is not an acceptable product name.""")

    splash_screen_filename = getWindowsSplashScreen()

    if splash_screen_filename is not None:
        if not os.path.isfile(splash_screen_filename):
            Tracing.options_logger.sysexit(
                "Error, specified splash screen image '%s' does not exist." %
                splash_screen_filename)

    if file_version or product_version or getWindowsVersionInfoStrings():
        if not (file_version or product_version) and getWindowsCompanyName():
            Tracing.options_logger.sysexit(
                "Error, company name and file or product version need to be given when any version information is given."
            )

    if isOnefileMode() and not hasOnefileSupportedOS():
        Tracing.options_logger.sysexit("Error, unsupported OS for onefile %r" %
                                       getOS())

    if options.follow_none and options.follow_all:
        Tracing.options_logger.sysexit(
            "Conflicting options '--follow-imports' and '--nofollow-imports' given."
        )

    for module_pattern in getShallIncludePackageData():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--include-package-data' needs module name or pattern as an argument, not %r."
                % module_pattern)

    for module_pattern in getShallFollowModules():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--follow-import-to' options needs module name or pattern as an argument, not %r."
                % module_pattern)
    for module_pattern in getShallFollowInNoCase():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--nofollow-import-to' options needs module name or pattern as an argument, not %r."
                % module_pattern)

    for data_file in options.data_files:
        if "=" not in data_file:
            Tracing.options_logger.sysexit(
                "Error, malformed data file description, must specify relative target path separated with '='."
            )

        if data_file.count("=") == 1:
            src, dst = data_file.split("=", 1)

            filenames = resolveShellPatternToFilenames(src)

            if len(filenames) > 1 and not dst.endswith(("/", os.path.sep)):
                Tracing.options_logger.sysexit(
                    "Error, pattern '%s' matches more than one file, but target has no trailing slash, not a directory."
                    % src)
        else:
            src, dst, pattern = data_file.split("=", 2)

            filenames = resolveShellPatternToFilenames(
                os.path.join(src, pattern))

        if not filenames:
            Tracing.options_logger.sysexit(
                "Error, '%s' does not match any files." % src)

        if os.path.isabs(dst):
            Tracing.options_logger.sysexit(
                "Error, must specify relative target path for data file, not absolute path '%s'."
                % data_file)

    for data_dir in options.data_dirs:
        if "=" not in data_dir:
            Tracing.options_logger.sysexit(
                "Error, malformed data dir description, must specify relative target path with '=' separating it."
            )

        src, dst = data_dir.split("=", 1)

        if os.path.isabs(dst):
            Tracing.options_logger.sysexit(
                "Error, must specify relative target path for data dir, not %r as in %r."
                % (dst, data_dir))

        if not os.path.isdir(src):
            Tracing.options_logger.sysexit(
                "Error, must specify existing source data directory, not %r as in %r."
                % (dst, data_dir))

    for pattern in getShallFollowExtraFilePatterns():
        if os.path.isdir(pattern):
            Tracing.options_logger.sysexit(
                "Error, pattern %r given to '--include-plugin-files' cannot be a directory name."
                % pattern)

    if options.static_libpython == "yes" and getSystemStaticLibPythonPath(
    ) is None:
        Tracing.options_logger.sysexit(
            "Error, static libpython is not found or not supported for this Python installation."
        )

    if shallUseStaticLibPython() and getSystemStaticLibPythonPath() is None:
        Tracing.options_logger.sysexit(
            """Error, usable static libpython is not found for this Python installation. You \
might be missing required packages. Disable with --static-libpython=no" if you don't \
want to install it.""")

    if isApplePython():
        if isStandaloneMode():
            Tracing.options_logger.sysexit(
                "Error, for standalone mode, Apple Python from macOS is not supported, use e.g. CPython instead."
            )

        if str is bytes:
            Tracing.options_logger.sysexit(
                "Error, Apple Python 2.7 from macOS is not usable as per Apple decision, use e.g. CPython 2.7 instead."
            )

    if isStandaloneMode() and isLinux(
    ) and getExecutablePath("patchelf") is None:
        Tracing.options_logger.sysexit(
            "Error, standalone mode on Linux requires 'patchelf' to be installed. Use 'apt/dnf/yum install patchelf' first."
        )

    pgo_executable = getPgoExecutable()
    if pgo_executable and not isPathExecutable(pgo_executable):
        Tracing.options_logger.sysexit(
            "Error, path '%s' to binary to use for PGO is not executable." %
            pgo_executable)
示例#11
0
def parseArgs(will_reexec):
    # singleton with many cases checking the options right away.
    # pylint: disable=global-statement,too-many-branches,too-many-locals,too-many-statements
    global is_nuitka_run, options, positional_args, extra_args, is_debug, is_nondebug, is_fullcompat

    if os.name == "nt":
        # Windows store Python's don't allow looking at the python, catch that.
        try:
            with open(sys.executable):
                pass
        except OSError:
            Tracing.general.sysexit(
                "Error, the Python from Windows store is not supported, check the User Manual of Nuitka ."
            )

    is_nuitka_run, options, positional_args, extra_args = parseOptions(
        logger=Tracing.options_logger)

    if options.quiet or int(os.environ.get("NUITKA_QUIET", "0")):
        Tracing.setQuiet()

    if not will_reexec and not shallDumpBuiltTreeXML():
        Tracing.options_logger.info("Used command line options: %s" %
                                    " ".join(sys.argv[1:]))

    if options.progress_bar and not will_reexec:
        Progress.enableProgressBar()

    if options.verbose_output and not will_reexec:
        Tracing.optimization_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            open(options.verbose_output, "w"))

        options.verbose = True

    Tracing.optimization_logger.is_quiet = not options.verbose

    if options.show_inclusion_output and not will_reexec:
        Tracing.inclusion_logger.setFileHandle(
            # Can only have unbuffered binary IO in Python3, therefore not disabling buffering here.
            open(options.show_inclusion_output, "w"))

        options.show_inclusion = True

    Tracing.progress_logger.is_quiet = not options.show_progress

    # Onefile implies standalone build.
    if options.is_onefile:
        options.is_standalone = True

    # Provide a tempdir spec implies onefile tempdir.
    if options.windows_onefile_tempdir_spec:
        options.is_windows_onefile_tempdir = True

    # Standalone mode implies an executable, not importing "site" module, which is
    # only for this machine, recursing to all modules, and even including the
    # standard library.
    if options.is_standalone:
        if not options.executable:
            Tracing.options_logger.sysexit("""\
Error, conflicting options, cannot make standalone module, only executable.

Modules are supposed to be imported to an existing Python installation, therefore it
makes no sense to include a Python runtime.""")

    for any_case_module in getShallFollowModules():
        if any_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in any_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.options_logger.sysexit("""\
Error, '--follow-import-to' takes only module names, not directory path '%s'."""
                                           % any_case_module)

    for no_case_module in getShallFollowInNoCase():
        if no_case_module.startswith("."):
            bad = True
        else:
            for char in "/\\:":
                if char in no_case_module:
                    bad = True
                    break
            else:
                bad = False

        if bad:
            Tracing.options_logger.sysexit("""\
Error, '--nofollow-import-to' takes only module names, not directory path '%s'."""
                                           % no_case_module)

    scons_python = getPythonPathForScons()

    if scons_python is not None and not os.path.isfile(scons_python):
        Tracing.options_logger.sysexit(
            "Error, no such Python binary %r, should be full path." %
            scons_python)

    if options.output_filename is not None and (isStandaloneMode()
                                                or shallMakeModule()):
        Tracing.options_logger.sysexit("""\
Error, can only specify output filename for acceleration mode, not for module
mode where filenames are mandatory, and not for standalone where there is a
sane default used inside the dist folder.""")

    if getOS() == "Linux":
        if len(getIconPaths()) > 1:
            Tracing.options_logger.sysexit(
                "Error, can only use one icon on Linux.")

    for icon_path in getIconPaths():
        if "#" in icon_path and isWin32Windows():
            icon_path, icon_index = icon_path.rsplit("#", 1)

            if not icon_index.isdigit() or int(icon_index) < 0:
                Tracing.options_logger.sysexit(
                    "Error, icon number in %r not valid." %
                    (icon_path + "#" + icon_index))

        if not os.path.exists(icon_path):
            Tracing.options_logger.sysexit(
                "Error, icon path %r does not exist." % icon_path)

        if getWindowsIconExecutablePath():
            Tracing.options_logger.sysexit(
                "Error, can only use icons from template executable or from icon files, but not both."
            )

    icon_exe_path = getWindowsIconExecutablePath()
    if icon_exe_path is not None and not os.path.exists(icon_exe_path):
        Tracing.options_logger.sysexit("Error, icon path %r does not exist." %
                                       icon_exe_path)

    try:
        file_version = getWindowsFileVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.options_logger.sysexit(
            "Error, file version must be a tuple of up to 4 integer values.")

    try:
        product_version = getWindowsProductVersion()
    except Exception:  # Catch all the things, don't want any interface, pylint: disable=broad-except
        Tracing.options_logger.sysexit(
            "Error, product version must be a tuple of up to 4 integer values."
        )

    if getWindowsCompanyName() == "":
        Tracing.options_logger.sysexit(
            """Error, empty string is not an acceptable company name.""")

    if getWindowsProductName() == "":
        Tracing.options_logger.sysexit(
            """Error, empty string is not an acceptable product name.""")

    if file_version or product_version or getWindowsVersionInfoStrings():
        if not (file_version or product_version) and getWindowsCompanyName():
            Tracing.options_logger.sysexit(
                "Error, company name and file or product version need to be given when any version information is given."
            )

    if isOnefileMode() and not hasOnefileSupportedOS():
        Tracing.options_logger.sysexit("Error, unsupported OS for onefile %r" %
                                       getOS())

    if isOnefileMode() and os.name == "nt":
        if not getWindowsCompanyName() and not isWindowsOnefileTempDirMode():
            Tracing.options_logger.sysexit(
                """Error, onefile on Windows needs more options.

It requires either company name and product version to be given or
the selection of onefile temp directory mode. Check --help output.""")

    if options.recurse_none and options.recurse_all:
        Tracing.options_logger.sysexit(
            "Conflicting options '--follow-imports' and '--nofollow-imports' given."
        )

    if getShallIncludePackageData() and not isStandaloneMode():
        Tracing.options_logger.sysexit(
            "Error, package data files are only included in standalone or onefile mode."
        )

    for module_pattern in getShallIncludePackageData():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--include-package-data' needs module name or pattern as an argument, not %r."
                % module_pattern)

    for module_pattern in getShallFollowModules():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--follow-import-to' options needs module name or pattern as an argument, not %r."
                % module_pattern)
    for module_pattern in getShallFollowInNoCase():
        if (module_pattern.startswith("-") or "/" in module_pattern
                or "\\" in module_pattern):
            Tracing.options_logger.sysexit(
                "Error, '--nofollow-import-to' options needs module name or pattern as an argument, not %r."
                % module_pattern)

    for data_file in options.data_files:
        if "=" not in data_file:
            Tracing.options_logger.sysexit(
                "Error, malformed data file description, must specify relative target path with =."
            )

        src, dst = data_file.split("=", 1)

        if os.path.isabs(dst):
            Tracing.options_logger.sysexit(
                "Error, must specify relative target path for data file, not %r."
                % data_file)

        if not resolveShellPatternToFilenames(src):
            Tracing.options_logger.sysexit(
                "Error, %r does not match any files." % src)

    for data_dir in options.data_dirs:
        if "=" not in data_dir:
            Tracing.options_logger.sysexit(
                "Error, malformed data dir description, must specify relative target path with '=' separating it."
            )

        src, dst = data_dir.split("=", 1)

        if os.path.isabs(dst):
            Tracing.options_logger.sysexit(
                "Error, must specify relative target path for data dir, not %r as in %r."
                % (dst, data_dir))

        if not os.path.isdir(src):
            Tracing.options_logger.sysexit(
                "Error, must specify existing source data directory, not %r as in %r."
                % (dst, data_dir))

    if (options.data_files or options.data_dirs) and not isStandaloneMode():
        Tracing.options_logger.sysexit(
            "Error, data files are only included in standalone or onefile mode."
        )

    for pattern in getShallFollowExtraFilePatterns():
        if os.path.isdir(pattern):
            Tracing.options_logger.sysexit(
                "Error, pattern %r given to '--include-plugin-files' cannot be a directory name."
                % pattern)

    is_debug = _isDebug()
    is_nondebug = not is_debug
    is_fullcompat = _isFullCompat()
示例#12
0
文件: __main__.py 项目: psydox/Nuitka
def main():
    parser = OptionParser()

    parser.add_option(
        "--verbose",
        action="store_true",
        dest="verbose",
        default=False,
        help="""Default is %default.""",
    )

    parser.add_option(
        "--from-commit",
        action="store_true",
        dest="from_commit",
        default=False,
        help="""From commit hook, do not descend into directories. Default is %default.""",
    )

    parser.add_option(
        "--check-only",
        action="store_true",
        dest="check_only",
        default=False,
        help="""For CI testing, check if it's properly formatted. Default is %default.""",
    )

    parser.add_option(
        "--no-progressbar",
        action="store_false",
        dest="progress_bar",
        default=True,
        help="""Disable progress bar outputs (if tqdm is installed).
Defaults to off.""",
    )

    options, positional_args = parser.parse_args()

    if options.from_commit:
        assert not positional_args
        for desc in getStagedFileChangeDesc():
            autoformat(desc["src_path"], git_stage=desc)
    else:
        if not positional_args:
            positional_args = ["bin", "nuitka", "setup.py", "tests/*/run_all.py"]

        my_print("Working on:", positional_args)

        positional_args = sum(
            (
                resolveShellPatternToFilenames(positional_arg)
                for positional_arg in positional_args
            ),
            [],
        )

        filenames = list(
            scanTargets(
                positional_args,
                suffixes=(".py", ".scons", ".rst", ".txt", ".j2", ".md", ".c", ".h"),
            )
        )

        if not filenames:
            tools_logger.sysexit("No files found.")

        result = 0

        if options.progress_bar:
            enableProgressBar()

        for filename in wrapWithProgressBar(
            filenames, stage="Autoformat", unit="files"
        ):
            if autoformat(filename, git_stage=False, check_only=options.check_only):
                result += 1

        if options.check_only and result > 0:
            tools_logger.sysexit(
                """Error, bin/autoformat-nuitka-source would make changes to %d files, \
make sure to have commit hook installed."""
                % result
            )
        elif result > 0:
            tools_logger.info("autoformat: Changes to formatting of %d files" % result)
        else:
            tools_logger.info("autoformat: No files needed formatting changes.")