/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \previouspage FileTagger
    \nextpage JobLimit
    \qmltype Group
    \inqmlmodule QbsLanguageItems
    \ingroup list-of-items
    \keyword QML.Group

    \brief Groups files and other items in a product or module.

    This item is attached to a \l{Product}{product} or \l{Module}{module} and used to group files
    and other items that have something in common.

    \section1 Typical Uses of Groups by Example

    \code
    Application {
        Group {
            name: "common files"
            files: ["myclass.h", "myclass_common_impl.cpp"]
        }
        Group {
            name: "Windows files"
            condition: qbs.targetOS.includes("windows")
            files: "myclass_win_impl.cpp"
        }
        Group {
            name: "Unix files"
            condition: qbs.targetOS.includes("unix")
            files: "unixhelper.cpp"
            Group {
                name: "Linux files"
                condition: qbs.targetOS.includes("linux")
                files: "myclass_linux_impl.cpp"
            }
            Group {
                name: "FreeBSD files"
                condition: qbs.targetOS.includes("freebsd")
                files: "myclass_freebsd_impl.cpp"
            }
        }
        Group {
            name: "Files to install"
            qbs.install: true
            qbs.installDir: "share"
            files: "runtime_resource.txt"
        }
    }
    \endcode

    \section1 Wildcards

    When specifying files, you can use the wildcards \c "*", \c "?" and \c "[]", which
    have their
    \l{https://en.wikipedia.org/wiki/Wildcard_character#File_and_directory_patterns}{usual meaning}
    as in Unix Shell. By default, matching files are only picked up directly from the
    parent directory, but you can tell \QBS to consider the whole directory tree.
    It is also possible to exclude certain files from the list.
    The pattern \c "**" used in a pathname expansion context will match all files and zero or more
    directories and subdirectories.
    For example:
    \snippet reference/items/language/group.qbs 0

    \section1 Attaching Module Properties to Source Files

    Within a \c Group item, module properties can be attached either to all files in the
    product, or to only the files in that group. The following example demonstrates both:
    \code
    Product {
        // ...
        Group {
            condition: project.hasSpecialFeature
            cpp.defines: "FEATURE_SPECIFIC"
            product.cpp.defines: "WITH_FEATURE"
            files: "feature.cpp"
        }
    }
    \endcode
    Here, the macro \c "FEATURE_SPECIFIC" will only be visible inside \c feature.cpp, whereas
    \c "WITH_FEATURE" applies to all source files in the product.

    A group-level property binding starting with \c "product." is semantically equivalent
    to putting the same property binding without that prefix inside a top-level \l Properties item
    with the same condition as the group. The above example could therefore also have been written
    like this:
    \code
    Product {
        // ...
        Group {
            condition: project.hasSpecialFeature
            cpp.defines: "FEATURE_SPECIFIC"
            files: "feature.cpp"
        }
        Properties {
            condition: project.hasSpecialFeature
            cpp.defines: "WITH_FEATURE"
        }
    }
    \endcode
    Obviously, the original variant is to be preferred, as it does not duplicate the condition
    and keeps related code close together.

    It should be noted that there is a third way to write the same example, with a \l Properties
    item inside the group:
    \code
    Product {
        // ...
        Group {
            condition: project.hasSpecialFeature
            cpp.defines: "FEATURE_SPECIFIC"
            files: "feature.cpp"
            Properties {
                cpp.defines: "WITH_FEATURE"
            }
        }
    }
    \endcode
    This construct just adds verbosity here, but might be useful in cases where the product-level
    property binding is dependent on an additional condition.

    \section1 Attaching Module Properties to Generated Files

    A group can also be used to attach properties to build artifacts such as executables or
    libraries. In the following example, an application is installed to "<install root>/bin".
    \code
    Application {
        Group {
            fileTagsFilter: "application"
            qbs.install: true
            qbs.installDir: "bin"
        }
    }
    \endcode

    \section1 Groups in Modules

    Groups may also appear in \l{Module}{modules}, which causes the respective
    sources to be added to the products depending on the said module, unless
    the \l{filesAreTargets} property is set.

    \section1 Grouping Related Items

    Groups can contain other items, namely \l Depends, \l FileTagger, \l Rule and \l Scanner items.
    They can also contain other groups, that is, they can be nested. The \l{condition} of
    a groups's child item gets logically ANDed with the one of the parent group. Additionally,
    if the child item is a group itself, the child group inherits the module properties and
    \l{FileTagger}{file tags} as well as the prefix of its parent group.
*/

/*!
    \qmlproperty string Group::name

    The name of the group. Not used internally; mainly useful for IDEs.

    \defaultvalue "Group x", where x is a unique number among all the
    groups in the product.
*/

/*!
    \qmlproperty pathList Group::files

    The files in the group. Mutually exclusive with \l{fileTagsFilter}.
    Relative paths are resolved using the parent directory of the file
    that contains the Group item. However, if the \l{prefix} property is set to
    an absolute path, then that one becomes the base directory.

    The values can contain wildcards.

    \defaultvalue An empty list
*/

/*!
    \qmlproperty bool Group::filesAreTargets

    If this property is \c true and the group is in a \l{Module}, the files in the
    group will not become source artifacts of the product that depends on the module.
    Instead, they are treated like target artifacts of products. That is, they will be
    matched against the \l{Rule::inputsFromDependencies}{inputsFromDependencies}
    file tag list of \l{Rule}{rules} in products that depend on the module.

    \defaultvalue \c false
*/

/*!
    \qmlproperty string Group::prefix

    A string to prepend to all files. Slashes are allowed and have directory
    semantics.

    \defaultvalue The prefix of the parent group if one exists, otherwise empty.
*/

/*!
    \qmlproperty stringList Group::fileTagsFilter

    List of \l{Artifact::fileTags}{artifact.fileTags} to match. Any properties
    set in this group will be applied to the product's artifacts whose file tags
    match the ones listed here.

    The file tags that the group's \l{fileTags} property specifies will
    be added to the matching artifacts.

    This property is mutually exclusive with \l{files}.

    \defaultvalue An empty list
*/

/*!
    \qmlproperty bool Group::condition

    Determines whether the files in the group are actually considered part of
    the project.

    \defaultvalue \c true
*/

/*!
    \qmlproperty stringList Group::fileTags

    A list of file tags to attach to the group's files. These can then be
    matched by a \l{Rule}{rule}.

    \note \l{FileTagger}{File taggers} are never applied to a file that has this
    property set.

    \defaultvalue An empty list
*/

/*!
    \qmlproperty bool Group::overrideTags

    Determines how tags on files that are listed both at the top level of
    a product (or the parent group, if there is one) and a group are handled.
    If this property is \c true, then the \l{FileTagger}{file tags} set via the
    group replace the ones set via the product or parent group.
    If it is \c false, the \e {group tags} are added to the \e {parent tags}.

    This property is ignored if \l{fileTagsFilter} is set.

    \defaultvalue \c true
*/

/*!
    \qmlproperty pathList Group::excludeFiles

    A list of files that are \e subtracted from the \l{files} list.

    The values can contain wildcards.

    This property is ignored if \l{fileTagsFilter} is set.

    \defaultvalue An empty list
*/
