Hi Chris, On Tuesday 15 September 2015 20:57:46 Christopher Larson wrote: > This sub-command creates a bbappend for the specified target and prints the > path to the bbappend. The -w argument, as with some of the other recipetool > commands, will make a version-independent bbappend. > > Example usage: recipetool newappend meta-mylayer virtual/kernel > > [YOCTO #7964] > > Signed-off-by: Christopher Larson <[email protected]> > --- > scripts/lib/recipetool/newappend.py | 126 > ++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) > create mode 100644 scripts/lib/recipetool/newappend.py > > diff --git a/scripts/lib/recipetool/newappend.py > b/scripts/lib/recipetool/newappend.py new file mode 100644 > index 0000000..be9077c > --- /dev/null > +++ b/scripts/lib/recipetool/newappend.py > @@ -0,0 +1,126 @@ > +# Recipe creation tool - newappend plugin > +# > +# This sub-command creates a bbappend for the specified target and prints > the +# path to the bbappend. > +# > +# Example: recipetool newappend meta-mylayer busybox > +# > +# Copyright (C) 2015 Christopher Larson <[email protected]> > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License version 2 as > +# published by the Free Software Foundation. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License along > +# with this program; if not, write to the Free Software Foundation, Inc., > +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + > +import argparse > +import errno > +import logging > +import os > +import re > + > + > +logger = logging.getLogger('recipetool') > +tinfoil = None > + > + > +def plugin_init(pluginlist): > + # Don't need to do anything here right now, but plugins must have this > function defined + pass > + > + > +def tinfoil_init(instance): > + global tinfoil > + tinfoil = instance > + > + > +def _provide_to_pn(cooker, provide): > + """Get the name of the preferred recipe for the specified provide.""" > + import bb.providers > + filenames = cooker.recipecache.providers[provide] > + eligible, foundUnique = bb.providers.filterProviders(filenames, > provide, cooker.expanded_data, cooker.recipecache) + filename = > eligible[0] > + pn = cooker.recipecache.pkg_fn[filename] > + return pn > + > + > +def _get_recipe_file(cooker, pn): > + import oe.recipeutils > + recipefile = oe.recipeutils.pn_to_recipe(cooker, pn) > + if not recipefile: > + skipreasons = oe.recipeutils.get_unavailable_reasons(cooker, pn) > + if skipreasons: > + logger.error('\n'.join(skipreasons)) > + else: > + logger.error("Unable to find any recipe file matching %s" % pn) > + return recipefile > + > + > +def layer(layerpath): > + if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')): > + raise argparse.ArgumentTypeError('{0!r} must be a path to a valid > layer'.format(layerpath)) + return layerpath > + > + > +def newappend(args): > + pn = _provide_to_pn(tinfoil.cooker, args.target) > + recipe_path = _get_recipe_file(tinfoil.cooker, pn) > + > + # Map recipe path to the layer it's in > + for layerpath in tinfoil.config_data.getVar('BBLAYERS', True).split(): > + layerconf = os.path.join(layerpath, 'conf', 'layer.conf') > + l = bb.data.init() > + l.setVar('LAYERDIR', layerpath) > + l = bb.parse.handle(layerconf, l) > + l.expandVarref('LAYERDIR') > + > + for layername in l.getVar('BBFILE_COLLECTIONS', True).split(): > + pattern = l.getVar('BBFILE_PATTERN_' + layername, True) > + if pattern and re.match(pattern, recipe_path): > + recipe_layer_path = layerpath > + break > + else: > + continue > + break > + else: > + recipe_layer_path = > os.path.dirname(os.path.dirname(os.path.dirname(recipe_path))) + > + recipe_relpath = os.path.relpath(recipe_path, recipe_layer_path) > + append_relpath = recipe_relpath + 'append' > + append_path = os.path.join(args.destlayer, append_relpath) > + > + if args.wildcard_version and '_' in os.path.basename(append_path): > + base, _ = os.path.splitext(append_path) > + base, _ = base.rsplit('_', 1) > + append_path = base + '_%.bbappend' > + > + if not os.path.exists(append_path): > + try: > + os.makedirs(os.path.dirname(append_path)) > + except OSError as exc: > + if exc.errno != errno.EEXIST: > + raise > + > + try: > + open(append_path, 'a') > + except (OSError, IOError) as exc: > + logger.critical(str(exc)) > + return 1 > + > + print(append_path) > + > + > +def register_command(subparsers): > + parser = subparsers.add_parser('newappend', > + help='Create a bbappend for the > specified target in the specified layer') + parser.add_argument('-w', > '--wildcard-version', help='Use wildcard to make the bbappend apply to any > recipe version', action='store_true') + parser.add_argument('destlayer', > help='Base directory of the destination layer to write the bbappend to', > type=layer) + parser.add_argument('target', help='Target recipe/provide > to append') + parser.set_defaults(func=newappend, parserecipes=True)
So the first thing that springs to mind here is that there's a bunch of code to do the major part of this in recipeutils (e.g. finding the correct name and location for a bbappend file is done by get_bbappend_path()) - shouldn't we be using that here? Cheers, Paul -- Paul Eggleton Intel Open Source Technology Centre -- _______________________________________________ Openembedded-core mailing list [email protected] http://lists.openembedded.org/mailman/listinfo/openembedded-core
