Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/meta/lib/oe/packagegroup.py b/meta/lib/oe/packagegroup.py
new file mode 100644
index 0000000..12eb421
--- /dev/null
+++ b/meta/lib/oe/packagegroup.py
@@ -0,0 +1,36 @@
+import itertools
+
+def is_optional(feature, d):
+    packages = d.getVar("FEATURE_PACKAGES_%s" % feature, True)
+    if packages:
+        return bool(d.getVarFlag("FEATURE_PACKAGES_%s" % feature, "optional"))
+    else:
+        return bool(d.getVarFlag("PACKAGE_GROUP_%s" % feature, "optional"))
+
+def packages(features, d):
+    for feature in features:
+        packages = d.getVar("FEATURE_PACKAGES_%s" % feature, True)
+        if not packages:
+            packages = d.getVar("PACKAGE_GROUP_%s" % feature, True)
+        for pkg in (packages or "").split():
+            yield pkg
+
+def required_packages(features, d):
+    req = filter(lambda feature: not is_optional(feature, d), features)
+    return packages(req, d)
+
+def optional_packages(features, d):
+    opt = filter(lambda feature: is_optional(feature, d), features)
+    return packages(opt, d)
+
+def active_packages(features, d):
+    return itertools.chain(required_packages(features, d),
+                           optional_packages(features, d))
+
+def active_recipes(features, d):
+    import oe.packagedata
+
+    for pkg in active_packages(features, d):
+        recipe = oe.packagedata.recipename(pkg, d)
+        if recipe:
+            yield recipe