コード例 #1
0
 def from_files(cls, files):
     new = cls()
     for f in files:
         if not f.endswith(".ac"): continue
         try:
             new.append(Config.from_file(f))
         except Exception as exc:
             cprint("Exception while parsing %s:\n%s" % (f, str(exc)),
                    "red")
             raise
     return new
コード例 #2
0
 def cprint(self):
     """Colored printout."""
     for line in self.string.splitlines():
         if line.startswith("#"):
             cprint(line, "blue")
         else:
             i = line.find("=")
             if i == -1:
                 print(line)
             else:
                 print(colored(line[:i], "yellow"), line[i:], sep="")
コード例 #3
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_show(options):
    """Find configuration file from its basename and print it to terminal."""
    if options.basename is None or not options.basename:
        confopts = AbinitConfigureOptions.from_myoptions_conf()
        return abiconf_list(options)

    configs = get_configs(options)
    for i, config in enumerate(configs):
        if config.basename == options.basename:
            print(config)
            return 0
    else:
        cprint("Cannot find configuration file for `%s`" % options.basename,
               "red")
        return abiconf_list(options)
コード例 #4
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_list(options):
    """List all configuration files."""
    configs = get_configs(options)

    width = 92
    for i, config in enumerate(configs):
        if options.verbose == 0:
            if i == 0:
                cprint(marquee("Available configuration files"), "yellow")
            print("[%d] %s" % (i, config.basename))
        else:
            cprint(marquee(config.basename, width=width), "yellow")
            config.cprint()
            print(width * "=")

    if options.verbose == 0: print("\nUse -v for further information")
    return 0
コード例 #5
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_script(options):
    """Generate submission script from configuration file."""
    path = options.path
    if path is None:
        return abiconf_list(options)

    if os.path.exists(path):
        conf = Config.from_file(path)
    else:
        configs = ConfigList.get_clusters()
        for conf in configs:
            if conf.basename == path: break
        else:
            cprint("Cannot find %s in internal list" % path, "red")
            return abiconf_list(options)

    print(conf.get_script_str())
    return 0
コード例 #6
0
    def from_dir(cls, top):
        """Parse all .ac files starting located inside directory top."""
        new = cls()

        for dirpath, dirnames, filenames in os.walk(top):
            for f in filenames:
                if not f.endswith(".ac"): continue
                path = os.path.join(dirpath, f)
                #print(path)
                try:
                    new.append(Config.from_file(path))
                except Exception as exc:
                    cprint(
                        "Exception while parsing %s:\n%s" % (path, str(exc)),
                        "red")
                    raise

        return new
コード例 #7
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_opts(options):
    """List available configure options."""
    confopts = AbinitConfigureOptions.from_myoptions_conf()

    if options.optnames is None or not options.optnames:
        # Print all options.
        cprint(marquee("Available options"), "yellow")
        table = [("name", "default", "status")]

        if options.verbose == 0:
            for opt in confopts.values():
                table.append((opt.name, str(opt.default), opt.status))
            pprint_table(table)
            print("\nUse -v for further information")

        else:
            for opt in confopts.values():
                cprint(marquee(opt.name), "yellow")
                print(opt)

    else:
        for optname in options.optnames:
            opt = confopts[optname]
            cprint(marquee(opt.name), "yellow")
            print(opt)

    return 0
コード例 #8
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_keys(options):
    """Find configuration files containing keywords."""
    configs = get_configs(options)
    if options.keys is None or not options.keys:
        # Print list of available keywords.
        all_keys = set()
        for conf in configs:
            all_keys.update(conf.meta["keywords"])

        cprint(marquee("Available keywords"), "yellow")
        for chunk in chunks(all_keys, 7):
            cprint(", ".join(chunk), "magenta")

    else:
        # Find configuration files containing keywords.
        keys = options.keys
        if is_string(keys): keys = [keys]
        keys = set(keys)
        nfound = 0
        for conf in configs:
            if keys.issubset(conf.meta["keywords"]):
                nfound += 1
                print("")
                cprint(marquee(conf.basename), "yellow")
                if options.verbose:
                    conf.cprint()
                else:
                    pprint(conf.meta)

        if options.verbose == 0 and nfound != 0:
            print("\nUse -v for further information")

    return 0
コード例 #9
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_convert(options):
    """Read a configuration file without metadata section and convert it."""
    path = options.path
    try:
        Config.from_file(path)
        cprint("%s is already a valid abiconf file. Nothing to do" % path,
               "magenta")
        return 0
    except:
        pass

    # Build template with metadata section
    lines = ConfigMeta.get_template_lines()

    # Add it to the file.
    with open(path, "rt") as fh:
        lines += fh.readlines()
    with open(path, "wt") as fh:
        fh.writelines(lines)

    conf = Config.from_file(path)
    print(conf)
    return 0
コード例 #10
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_hostname(options):
    """Find configuration files for this hostname."""
    def show_hostnames():
        cprint(marquee("Available hostnames"), "yellow")
        all_hosts = sorted({conf.meta["hostname"] for conf in configs})
        for chunk in chunks(all_hosts, 7):
            cprint(", ".join(chunk), "blue")

    if options.show_hostnames:
        show_hostnames()
        return 0

    hostname = gethostname() if options.hostname is None else options.hostname
    nfound = 0
    configs = get_configs(options)
    for conf in configs:
        # TODO: Should handle foo.bar.be case
        #if not (hostname in conf.meta["keywords"] or hostname in conf.basename):
        #print(conf)
        if not hostname in conf.meta["hostname"]:
            continue
        nfound += 1
        cprint(marquee(conf.basename), "yellow")
        if options.verbose:
            conf.cprint()
        else:
            pprint(conf.meta)

    if nfound == 0:
        cprint(
            "No configuration file for `%s`. Will print internal list." %
            hostname, "red")
        show_hostnames()
    else:
        if options.verbose == 0: print("\nUse -v for further information")

    return 0
コード例 #11
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
 def show_hostnames():
     cprint(marquee("Available hostnames"), "yellow")
     all_hosts = sorted({conf.meta["hostname"] for conf in configs})
     for chunk in chunks(all_hosts, 7):
         cprint(", ".join(chunk), "blue")
コード例 #12
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def main():
    def str_examples():
        return """\
Usage example:
    abiconf.py hostname [HOST]       => Find configuration files for hostname HOST.
    abiconf.py list                  => List all configuration files.
    abiconf.py workon [ACNAME]       => Create build directory and compile the code with this
                                        configuration file.
    abiconf.py script [ACNAME]       => Generate job script template.
    abiconf.py keys intel mkl        => Find configuration files with these keywords.
    abiconf.py doc                   => Print documented template.
    abiconf.py opts [opt_name]       => List available configure options.
    abiconf.py get [ACNAME]          => Get a copy of the configuration file.
    abiconf.py new [FILENAME]        => Generate template file.
    abiconf.py convert acfile        => Add metadata section to an old autoconf file.

Options for developers
    abiconf.py bbcov    [DIRorFILEs]   => Test autoconf options coverage
"""

    def show_examples_and_exit(error_code=1):
        """Display the usage of the script."""
        print(str_examples())
        sys.exit(error_code)

    import argparse
    # Parent parser for common options.
    copts_parser = argparse.ArgumentParser(add_help=False)
    copts_parser.add_argument(
        '-v',
        '--verbose',
        default=0,
        action='count',  # -vv --> verbose=2
        help='Verbose, can be supplied multiple times to increase verbosity.')
    copts_parser.add_argument('--no-colors',
                              default=False,
                              action="store_true",
                              help='Disable ASCII colors.')

    # Parent parser for command that have a `buildbot` variant.
    bb_parser = argparse.ArgumentParser(add_help=False)
    bb_parser.add_argument(
        '-b',
        '--buildbot',
        default=False,
        action='store_true',
        help=("Activate buildbot mode. Configuration files are read from "
              "~abinit/doc/build/config-examples"))

    # Build the main parser.
    parser = argparse.ArgumentParser(
        epilog=str_examples(),
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('-V',
                        '--version',
                        action='version',
                        version=release.__version__)

    # Create the parsers for the sub-commands
    subparsers = parser.add_subparsers(dest='command',
                                       help='sub-command help',
                                       description="Valid subcommands")

    # Subparser for hostname command.
    p_hostname = subparsers.add_parser('hostname',
                                       parents=[copts_parser, bb_parser],
                                       help=abiconf_hostname.__doc__)
    p_hostname.add_argument(
        "hostname",
        nargs="?",
        default=None,
        help=
        "Find configuration file for this hostname. If not given hostname is autodetected."
    )
    p_hostname.add_argument("-s",
                            "--show-hostnames",
                            default=False,
                            action="store_true",
                            help="List available hostnames.")

    # Subparser for list command.
    p_list = subparsers.add_parser('list',
                                   parents=[copts_parser, bb_parser],
                                   help=abiconf_list.__doc__)

    p_show = subparsers.add_parser('show',
                                   parents=[copts_parser, bb_parser],
                                   help=abiconf_show.__doc__)
    p_show.add_argument("basename",
                        nargs="?",
                        default=None,
                        help="Name of the configuration file.")

    # Subparser for keys command.
    p_keys = subparsers.add_parser('keys',
                                   parents=[copts_parser, bb_parser],
                                   help=abiconf_keys.__doc__)
    p_keys.add_argument("keys",
                        nargs="*",
                        default=None,
                        help="Find configuration files with these keywords. "
                        "Show available keywords if no value is provided.")

    # Subparser for script.
    p_script = subparsers.add_parser('script',
                                     parents=[copts_parser],
                                     help=abiconf_script.__doc__)
    p_script.add_argument(
        'path',
        nargs="?",
        default=None,
        help="Configuration file or database entry. None to print all files.")

    # Subparser for convert.
    p_conv = subparsers.add_parser('convert',
                                   parents=[copts_parser],
                                   help=abiconf_convert.__doc__)
    p_conv.add_argument('path', help="Configuration file in old format.")

    # Subparser for new command.
    p_new = subparsers.add_parser('new',
                                  parents=[copts_parser],
                                  help=abiconf_new.__doc__)
    p_new.add_argument('new_filename',
                       nargs="?",
                       default=None,
                       help="Name of new configuration file.")

    # Subparser for doc command.
    p_doc = subparsers.add_parser('doc',
                                  parents=[copts_parser],
                                  help="Print documented template.")

    # Subparser for opts command.
    p_opts = subparsers.add_parser('opts',
                                   parents=[copts_parser],
                                   help=abiconf_opts.__doc__)
    p_opts.add_argument('optnames',
                        nargs="*",
                        default=None,
                        help="Select options to show.")

    # Subparser for bb_cov command.
    p_bbcov = subparsers.add_parser('bbcov',
                                    parents=[copts_parser],
                                    help=abiconf_bbcov.__doc__)
    p_bbcov.add_argument('paths',
                         nargs="*",
                         default=None,
                         help="ac file or directory with ac files.")

    # Subparser for workon command.
    p_workon = subparsers.add_parser('workon',
                                     parents=[copts_parser, bb_parser],
                                     help=abiconf_workon.__doc__)
    p_workon.add_argument(
        'confname',
        nargs="?",
        default=None,
        help=
        "Configuration file to be used. Either abiconf basename or local file."
    )
    p_workon.add_argument("-m",
                          '--make',
                          action="store_true",
                          default=False,
                          help="Run configure/make. Default: False.")
    p_workon.add_argument("-j",
                          '--jobs',
                          type=int,
                          default=0,
                          help="Number of threads used to compile/make.")
    p_workon.add_argument("-r",
                          '--remove',
                          default=False,
                          action="store_true",
                          help="Remove build directory.")

    try:
        options = parser.parse_args()
    except Exception as exc:
        show_examples_and_exit(1)

    if options.no_colors:
        # Disable colors
        termcolor.enable(False)

    if options.command == "doc":
        template = get_actemplate_string()
        for line in template.splitlines():
            if len(line) > 2 and line[0] == "#" and line[1] != " ":
                # Option
                i = line.find("=")
                if i != -1:
                    print(colored(line[:i], "yellow"), line[i:], sep="")
                else:
                    cprint(line, "yellow")
            else:
                # Comment
                cprint(line, "blue")
        return 0

    else:
        # Dispatch.
        return globals()["abiconf_" + options.command](options)
コード例 #13
0
ファイル: abiconf.py プロジェクト: vishankkumar/abiconfig
def abiconf_workon(options):
    """
    Compile the code with the settings and the modules specified
    in the autoconf file.
    """
    # If confname is not specified, print full list and return
    if options.confname is None:
        print("Available configuration files.")
        return abiconf_list(options)

    configs = get_configs(options)

    confname = options.confname
    if os.path.exists(confname):
        if os.path.isfile(confname):
            # Init conf from local file
            conf = Config.from_file(confname)
        else:
            raise RuntimeError("Found directory with same name as AC file!")
    else:
        # Find it in the abiconf database.
        for conf in configs:
            if conf.basename == confname or conf.path == confname: break
        else:
            cprint(
                "Cannot find configuration file associated to `%s`" % confname,
                "red")
            return abiconf_list(options)

    if options.verbose:
        #cprint("Reading configuration file %s" % confname, "yellow")
        print("Configuration file:")
        print(conf)

    # Script must be executed inside the abinit source tree.
    #abinit_top = find_abinit_toptree()

    cwd = os.getcwd()
    workdir = os.path.join(cwd, "_build_" + confname)
    script = os.path.join(workdir, "workon_" + confname + ".sh")
    acfile = os.path.join(workdir, conf.basename)

    # Look before you leap.
    if os.path.exists(workdir):
        if not options.remove:
            cprint(
                "Build directory `%s` already exists. Use `-r to remove it`. Returning"
                % workdir, "red")
            return 1
        else:
            shutil.rmtree(workdir)

    # Create build directory, copy ac file.
    # generare shell script to load modules, run configure and make.
    cprint("Creating build directory %s" % workdir, "yellow")
    os.mkdir(workdir)
    shutil.copy(conf.path, acfile)

    # Write shell script to start new with modules and run it.
    has_nag = "nag" in conf.meta["keywords"]
    nthreads = options.jobs
    if nthreads == 0: nthreads = max(1, get_ncpus() // 2)

    with open(script, "w+") as fh:
        fh.write("#!/bin/bash\n")
        fh.write("# Generated by abiconf.py on %s\n" % time.strftime("%c"))
        fh.write("cd %s\n" % workdir)
        for cmd in conf.meta.get("pre_configure", []):
            fh.write("%s\n" % cmd)

        conf_lines = [
            "[ ! -f __configure_done__ ] && ../configure --with-config-file='%s' && touch __configure_done__\n"
            % os.path.basename(acfile),
        ]
        if has_nag:
            # taken from pre_configure_nag.sh
            conf_lines.insert(
                0,
                "sed -i -e 's/ -little/& \| -library/' -e 's/\-\\#\\#\\#/& -dryrun/' ../configure\n"
            )
            # taken from post_configure_nag.sh
            conf_lines.append(
                "sed -i -e 's/\t\$.FCFLAGS. \\//' src/98_main/Makefile\n")

        fh.writelines(conf_lines)

        for cmd in conf.meta.get("post_configure", []):
            fh.write("%s\n" % cmd)

        # command > >(tee stdout.log) 2> >(tee stderr.log >&2)
        # http://stackoverflow.com/questions/692000/how-do-i-write-stderr-to-a-file-while-using-tee-with-a-pipe
        #cprint("`make stdout` redirected to make.stdout file", "yellow")
        #cprint("`make stderr` redirected to make.stderr file", "yellow")
        fh.write(
            "make -j%d > >(tee make.stdout) 2> >(tee make.stderr >&2) \n" %
            nthreads)

        for cmd in conf.meta.get("post_make", []):
            fh.write("%s\n" % cmd)
        fh.write("# make check\n")

        fh.seek(0)

        if options.verbose:
            cprint("abiconf script:", "yellow")
            for line in fh.readlines():
                print(line, end="")

    retcode = 0
    if not options.make:
        cprint(
            "Use:\n\t`source %s`\n\nto configure/make\n" %
            os.path.relpath(script), "yellow")
    else:
        # The code gets stuck here if -jN. Should find better approach
        os.chdir(workdir)
        retcode = os.system(". %s" % script)
        if retcode != 0:
            cprint("make returned retcode %s" % retcode, "red")
            stderr_path = os.path.join(workdir, "make.stderr")
            with open(stderr_path, "rt") as fh:
                err = fh.read()
                if err:
                    cprint("Errors found in %s" % stderr_path, "red")
                    cprint(err, "red")
        os.chdir(cwd)

    path = os.path.join(workdir, "template_job.sh")
    cprint("Writing submission script template to %s" % os.path.relpath(path),
           "yellow")
    with open(path, "wt") as fh:
        fh.write(conf.get_script_str())

    path = os.path.join(workdir, "launch_runtests_job.sh")
    cprint(
        "Writing submission script for runtests.py to %s" %
        os.path.relpath(path), "yellow")
    with open(path, "wt") as fh:
        fh.write(conf.get_runtests_script_str())

    return retcode
コード例 #14
0
    def buildbot_coverage(self, options, verbose=0):
        # Init mapping option.name --> [(config0.path, value0), (config1.path, value1), ...]
        # This dict is used to test if all the options are tested in the configuration files:
        #       - empty list --> the option is never used.
        #       - non-empty list --> the option is used in len(list) files.
        #         An additional check on the values may be required at the end.
        retcode = 0
        optmap = {optname: [] for optname in options}

        # Mapping: config.path --> list_of_errors
        config_errors = defaultdict(list)

        # Ignore these options.
        builtin_opts = set([
            "CPP",
            "CC",
            "CFLAGS",
            "CXX",
            "FC",
            "FCFLAGS",
            "AR",
            "ARFLAGS_EXTRA",
            "MPI_RUNNER",
            "CFLAGS_EXTRA",
            "CXXFLAGS",
            "FCFLAGS_EXTRA",
            "RANLIB",
            "NM",
            "LD",
            "CPPFLAGS_EXTRA",
            "FC_LDFLAGS_EXTRA",
            "FPPFLAGS",
            "NVCC",
            "NVCC_CFLAGS",
            "CC_LIBS_EXTRA",
            "FC_LIBS_EXTRA",
        ])

        for conf in self:
            for name, value in conf.items():
                if name in builtin_opts or name.startswith("fcflags_opt"):
                    continue
                if name not in options:
                    config_errors[conf.path].append("Unknown option: %s" %
                                                    name)
                    retcode += 1
                    continue
                opt = options[name]
                #if opt.status in ("dropped", "removed"):
                #value_errors = opt.validate(value)
                #if value_errors: config_errors[conf.path].extend(value_errors)
                optmap[name].append((conf.path, value))

        # Print errors detected in configuration files.
        if config_errors:
            retcode += 1
            cprint(
                "Found %d erroneous configuration files" % len(config_errors),
                "red")
            for path, errors in config_errors.items():
                cprint("In configuration file: %s" % path, "red")
                for i, err in enumerate(errors):
                    print("[%d] %s" % (i, err))
                print(90 * "-")

        # Print possible problems detected in optmap.
        optval_usage = {}
        for name, tuples in optmap.items():
            #count[name] = len(tuples)
            if not tuples:
                retcode += 1
                cprint("%s is never used" % name, "magenta")
            else:
                #print("%s is used in %s configuration files" % (name, len(tuples)))
                opt = options[name]
                if opt.values:
                    # Test if all values are tested in the config file.
                    optval_usage[name] = {v: [] for v in opt.values}
                    #print(d[name])
                    for path, val in tuples:
                        if "+" not in val:
                            optval_usage[name][val].append(path)
                        else:
                            # handle "mkl+magma" case
                            for v in val.split("+"):
                                optval_usage[name][v].append(path)

        i = 0
        for name, d in optval_usage.items():
            if all(l for l in d.values()): continue
            i += 1
            if i == 1:
                print(" ")
                cprint(
                    "The following values are never used in the config files",
                    "yellow")
                retcode += 1
            cprint("[%s]" % name, "yellow")
            for k, l in d.items():
                if not l: cprint(k, "yellow")

        return retcode
コード例 #15
0
 def get_buildbot_configs(cls, start_path="."):
     abinit_top = find_abinit_toptree(start_path=start_path)
     bbconfig_dir = os.path.join(abinit_top, "doc", "build",
                                 "config-examples")
     cprint("Looking for buildbot AC files in %s" % bbconfig_dir, "yellow")
     return cls.from_dir(bbconfig_dir)