Chapter 38. A-A-P Python functions

These Aap specific functions can be used in Python code:

aap_has(name)

Returns non-zero if Aap supports feature "name". These features can be checked:

: command-nameWhether the command "command-name" is supported.

Example:

        @if aap_has(":tree"):
           :tree . {filename = .*\.aap}
              :print recipe found: $name

ask_prefix(name)

Ask the user where to install the package "name". Returns a tuple (asroot, prefix). "asroot" is a boolean indicating whether the package is to be installed as root (using :asroot). "prefix" is the root for the install.

If the user is root it will return (1, "/usr/local/") without asking. When aborted it returns an empty prefix.

childdir(arg)

Prepend $CHILDDIR to every item in "arg". This makes items with a path relative to the child recipe relative to the parent recipe. Example:
         _parent.DISTFILES += `childdir(DISTFILES)`
Can only be used in a child recipe. Also see topdir() and var_abspath().

do_BSD_port(name, target)

Attempt to install the BSD port "name". This includes the directory in which the port lives, e.g.: "devel/templ".

The BSD port system will take care of dependencies. This may result in many more ports to be installed than the one you asked for.

"target" is passed to the "make" command for the port. When "target" is "all" the port is build but not installed. When "target" is "install" it will be build and installed.

When needed the user will be asked to enter the root password. The "make" command is run in a separate root shell (every command must be confirmed for security reasons).

Returns non-zero for success.

expand2dictlist(expr)

Turns a variable with a string value into a list of dictionaries. Each dictionary has a "name" entry for the item itself and other entries are attributes. Wildcards in "expr" are expanded. See var2dictlist() for not expanding wildcards. Example:

        source = file1 {force} file2 file3
        @for item in expand2dictlist(source):
        @    if item.get("force"):
                 :print forced item: `item["name"]`

expand2list(expr)

Turns a variable with a string value into a list of items. Attributes are discarded. Delayed evaluation is taken care of.

Wildcards in "expr" are expanded. See var2list() for not expanding wildcards. Example:

         source = file1 file2 file3
         @for fname in expand2list(source):
             :sys prog $fname

expand2string(expr)

Expand wildcards, "~user" and "~/user" in "expr". Returns the expanded string. "expr" is handled as a list of items, white space is collapsed into a single space.

file2string(fname, dict = None)

Reads the file "fname" and concatenates the lines into one string. Lines starting with a '#' are ignored. One space is inserted in between joined lines, other white space (including CR and VT) at the start and end of a line is removed.

When "fname" doesn't exist or can't be read an error message is given and an empty string is returned. Aap does continue with the following commands.

"dict" is used to obtain the value for $MESSAGE. The default is None. To avoid the error message for a not existing file use something like this:
        @foofile = file2string("foo", {"MESSAGE" : ""})

get_attr(name)

Returns a dictionary with the attributes of "name". If "name" is unknown or has no attributes, an empty dictionary is returned. Example:
        :attr {logical = yes} foobar
        @print "foobar attributes: ", get_attr("foobar")

has_target(target)

Returns a number, depending on whether a dependency exists in which "target" is a target item:

0there is no dependency for "target"
1a dependency for "target" exists, there is no dependency with build commands
2a dependency for "target" with build commands exists

Example:

        @if not has_target("fetch"):

has_targetarg(targets)

Returns non-zero if one of the items in "targets" was used as a build target in the aap command. Example:

        @if has_targetarg("commit tar"):
            :include maintainer.aap

has_build_target()

Returns non-zero if Aap was started with a target that will build something or no target at all (the default target is expected to build something). Returns zero if the only targets are "clean", "cleanmore", "cleanALL" or "fetch".

Useful to skip configuration when it's pointless.

program_path(name, path = None, pathext = None, skip = None)

Returns the path for program "name". This uses the $PATH environment variable or os.defpath if it isn't set.

Additionally, the directory where Aap is installed and the "bin" subdirectory are searched. This finds tools supplied with Aap and installed packages. This is not done when the optional "path" argument is supplied.

On MS-Windows and OS/2 also checks with extensions added. This uses the $PATHEXT environment variable if set (The separator used is ';' if there is one, the system-dependent separator otherwise). Otherwise the extnsions ".exe", ".com", ".bat", ".cmd" are used. When "name" includes a suffix (a dot in the last component) adding extensions is not done.

Returns the first program found. Returns None when "name" could not be found.

Only finds executable files, not ordinary files.

Optional arguments:

pathsearch path to use instead of $PATH; when a string items are separated with os.pathsep
pathextextensions to try. Can be a list or a string. When a string is used items must be separated with os.pathsep
skipname of directory to skip, "name" is not found in this directory

Example, search for program "foo.py" and "foo.sh":

        p = `program_path("foo", pathext = [ '.py', '.sh' ])`

redir_system(cmd, use_tee = 1)

Execute shell commands "cmd" and return two items: a number indicating success and the stdout.

By default "tee" is used to display the output as well as redirecting it. When no output is desired set "use_tee" to zero. Example:
        ok, text = redir_system("ls", 0)
        if ok:
             print "ls output: %s" % text
        else:
             print "ls failed"

skipbuild()

Returns non-zero when build commands are to be skipped. This is when Aap was started with the --nobuild or --touch argument.

sort_list(list)

sorts a list and returns the list. Example:

        INP = `sort_list(glob("*.inp"))`

The Python list.sort() method doesn't return the sorted list.

src2obj(source, sufname = "OBJSUF")

Transform a string, which is a list of source files, into the corresponding list of object files. Each item in "source" is changed by prepending $BDIR and changing or appending the suffix specified with "sufname" (defaults to $OBJSUF). The attribute "var_BDIR" is used when it exists.

suffix(name)

Return the file name suffix. If there isn't one an empty string is returned. Example: suffix("foo.c") returns "c".

Note that the dot isn't included, while variables like $OBJSUF do include the dot.

sufreplace(from, to, expr)

Returns "expr" with all occurences of the suffix "from" changed to "to". When "from" is empty any suffix is changed to "to". "expr" can be a list of file names. Example:

        OBJECT = `sufreplace("", OBJSUF, SOURCE)`

tempfname()

Returns the name of a file which does not exist and can be used temporarily.

The recipe should take of deleting the file, but Aap may delete the directory in which the file resides when it exits. Thus don't depend on the file to continue to exist after Aap exits.

topdir(arg)

Prepend $TOPDIR to every item in "arg". This makes items with a path relative to the current recipe relative to the toplevel recipe. Example:

        _top.DISTFILES += `topdir(DISTFILES)`

Also see childdir() and var_abspath().

var_abspath(var)

Returns "var" with all file names turned into absolute paths. Prepends the current directory to each item in "var" which isn't an absolute path name. Example:
        :print `var_abspath("foo bar")`
Running this in "/home/mool/test" results in:

        /home/mool/test/foo /home/mool/test/bar

var2dictlist(var)

Turns "var" into a list of dictionaries. "var" must be a string or a variable. Each dictionary has a "name" entry for the item itself and other entries are attributes. Example:

        source = file1 {force} file2 file3
        @for item in var2dictlist(source):
        @    if item.get("force"):
            :print forced item: `item["name"]`

See expand2dictlist() for expanding wildcards.

var2list(var)

Turns "var" into a list of items. "var" must be a string or a variable. Attributes are discarded. Delayed evaluation is taken care of. Example:

        source = file1 file2 file3
        @for fname in var2list(source):
            :sys prog $fname

See expand2list() for expanding wildcards.

var2string(var)

Does delayed evaluation of "var" when necessary. Variables that should be expanded when used use the ExpandVar class and cannot be used directly. The unexpanded value is accessible with "var.val". Illustration:
        bar = aaa
        foo $= $bar
        bar = bbb
        :print $$foo: $foo
        :print Unexpanded: `foo.val`
        :print Expanded: `var2string(foo)`
Output:

        $foo: bbb
        Unexpanded: $bar
        Expanded: bbb

This also takes care of changing a Python list and other variable types to a string. A None value is turned into an empty string.

wildescape(expr)

Return the string "expr" with wildcard characters escaped, so that expanding wildcards will result in "expr". This puts the characters '*', '?' and '[' inside []. Example:

                  files = `glob("images/*")`
                  :attr {asdf} `wildescape(files)`

Equivalent to:

                  :attr {asdf} images/*

While developing Aap some functions have been renamed. The old names are still available to keep old recipes from working. But some day these will be removed.

obsolete name new name
aap_sufreplace() sufreplace()
aap_abspath() var_abspath()
aap_expand() var2string()
expandvar() expand2string()