diff options
| -rw-r--r-- | scripts/lib/devtool/standard.py | 127 | 
1 files changed, 90 insertions, 37 deletions
| diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index b129db3e74..6cdd44cd8d 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py @@ -37,25 +37,39 @@ def add(args, config, basepath, workspace):      import bb      import oe.recipeutils -    if args.recipename in workspace: -        raise DevtoolError("recipe %s is already in your workspace" % -                            args.recipename) +    if args.recipename and not args.srctree: +        # These are positional arguments, but because we're nice, allow +        # specifying source tree without name if we can detect that that +        # is what the user meant +        if os.sep in args.recipename: +            args.srctree = args.recipename +            args.recipename = None +        elif os.path.isdir(args.recipename): +            logger.warn('Ambiguous argument %s - assuming you mean it to be the recipe name') -    reason = oe.recipeutils.validate_pn(args.recipename) -    if reason: -        raise DevtoolError(reason) +    if args.recipename: +        if args.recipename in workspace: +            raise DevtoolError("recipe %s is already in your workspace" % +                               args.recipename) +        reason = oe.recipeutils.validate_pn(args.recipename) +        if reason: +            raise DevtoolError(reason) -    # FIXME this ought to be in validate_pn but we're using that in other contexts -    if '/' in args.recipename: -        raise DevtoolError('"/" is not a valid character in recipe names') +        # FIXME this ought to be in validate_pn but we're using that in other contexts +        if '/' in args.recipename: +            raise DevtoolError('"/" is not a valid character in recipe names')      if args.srctree:          srctree = os.path.abspath(args.srctree) +        srctreeparent = None +        tmpsrcdir = None      else: -        srctree = get_default_srctree(config, args.recipename) -        logger.info('Using default source tree path %s' % srctree) +        srctree = None +        srctreeparent = get_default_srctree(config) +        bb.utils.mkdirhier(srctreeparent) +        tmpsrcdir = tempfile.mkdtemp(prefix='devtoolsrc', dir=srctreeparent) -    if os.path.exists(srctree): +    if srctree and os.path.exists(srctree):          if args.fetch:              if not os.path.isdir(srctree):                  raise DevtoolError("Cannot fetch into source tree path %s as " @@ -69,33 +83,21 @@ def add(args, config, basepath, workspace):          if args.srctree:              raise DevtoolError("Specified source tree %s could not be found" %                                 args.srctree) -        else: +        elif srctree:              raise DevtoolError("No source tree exists at default path %s - "                                 "either create and populate this directory, "                                 "or specify a path to a source tree, or use "                                 "the -f/--fetch option to fetch source code "                                 "and extract it to the source directory" %                                 srctree) +        else: +            raise DevtoolError("You must either specify a source tree " +                               "or -f to fetch source") -    recipedir = os.path.join(config.workspace_path, 'recipes', args.recipename) -    bb.utils.mkdirhier(recipedir) -    rfv = None      if args.version:          if '_' in args.version or ' ' in args.version:              raise DevtoolError('Invalid version string "%s"' % args.version) -        rfv = args.version -    if args.fetch: -        if args.fetch.startswith('git://'): -            rfv = 'git' -        elif args.fetch.startswith('svn://'): -            rfv = 'svn' -        elif args.fetch.startswith('hg://'): -            rfv = 'hg' -    if rfv: -        bp = "%s_%s" % (args.recipename, rfv) -    else: -        bp = args.recipename -    recipefile = os.path.join(recipedir, "%s.bb" % bp) +      if args.color == 'auto' and sys.stdout.isatty():          color = 'always'      else: @@ -103,19 +105,71 @@ def add(args, config, basepath, workspace):      extracmdopts = ''      if args.fetch:          source = args.fetch -        extracmdopts = '-x %s' % srctree +        if srctree: +            extracmdopts += ' -x %s' % srctree +        else: +            extracmdopts += ' -x %s' % tmpsrcdir      else:          source = srctree +    if args.recipename: +        extracmdopts += ' -N %s' % args.recipename      if args.version:          extracmdopts += ' -V %s' % args.version      if args.binary:          extracmdopts += ' -b' + +    tempdir = tempfile.mkdtemp(prefix='devtool')      try: -        stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, recipefile, source, extracmdopts)) -    except bb.process.ExecutionError as e: -        raise DevtoolError('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) +        try: +            stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, tempdir, source, extracmdopts)) +        except bb.process.ExecutionError as e: +            if e.exitcode == 15: +                raise DevtoolError('Unable to auto-determine name from source tree, please specify it with -N/--name') +            else: +                raise DevtoolError('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) + +        recipes = glob.glob(os.path.join(tempdir, '*.bb')) +        if recipes: +            recipename = os.path.splitext(os.path.basename(recipes[0]))[0].split('_')[0] +            if recipename in workspace: +                raise DevtoolError('A recipe with the same name as the one being created (%s) already exists in your workspace' % recipename) +            recipedir = os.path.join(config.workspace_path, 'recipes', recipename) +            bb.utils.mkdirhier(recipedir) +            recipefile = os.path.join(recipedir, os.path.basename(recipes[0])) +            appendfile = recipe_to_append(recipefile, config) +            if os.path.exists(appendfile): +                # This shouldn't be possible, but just in case +                raise DevtoolError('A recipe with the same name as the one being created already exists in your workspace') +            if os.path.exists(recipefile): +                raise DevtoolError('A recipe file %s already exists in your workspace; this shouldn\'t be there - please delete it before continuing' % recipefile) +            if tmpsrcdir: +                srctree = os.path.join(srctreeparent, recipename) +                if os.path.exists(tmpsrcdir): +                    if os.path.exists(srctree): +                        if os.path.isdir(srctree): +                            try: +                                os.rmdir(srctree) +                            except OSError as e: +                                if e.errno == errno.ENOTEMPTY: +                                    raise DevtoolError('Source tree path %s already exists and is not empty' % srctree) +                                else: +                                    raise +                        else: +                            raise DevtoolError('Source tree path %s already exists and is not a directory' % srctree) +                    logger.info('Using default source tree path %s' % srctree) +                    shutil.move(tmpsrcdir, srctree) +                else: +                    raise DevtoolError('Couldn\'t find source tree created by recipetool') +            bb.utils.mkdirhier(recipedir) +            shutil.move(recipes[0], recipefile) +        else: +            raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout)) +    finally: +        if tmpsrcdir and os.path.exists(tmpsrcdir): +            shutil.rmtree(tmpsrcdir) +        shutil.rmtree(tempdir) -    _add_md5(config, args.recipename, recipefile) +    _add_md5(config, recipename, recipefile)      if args.fetch and not args.no_git:          setup_git_repo(srctree, args.version, 'devtool') @@ -130,7 +184,6 @@ def add(args, config, basepath, workspace):      if not rd:          return 1 -    appendfile = recipe_to_append(recipefile, config)      bb.utils.mkdirhier(os.path.dirname(appendfile))      with open(appendfile, 'w') as f:          f.write('inherit externalsrc\n') @@ -148,7 +201,7 @@ def add(args, config, basepath, workspace):              f.write('    rm -f ${D}/singletask.lock\n')              f.write('}\n') -    _add_md5(config, args.recipename, appendfile) +    _add_md5(config, recipename, appendfile)      logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) @@ -1195,7 +1248,7 @@ def register_commands(subparsers, context):      defsrctree = get_default_srctree(context.config)      parser_add = subparsers.add_parser('add', help='Add a new recipe',                                         description='Adds a new recipe to the workspace to build a specified source tree. Can optionally fetch a remote URI and unpack it to create the source tree.') -    parser_add.add_argument('recipename', help='Name for new recipe to add (just name - no version, path or extension)') +    parser_add.add_argument('recipename', nargs='?', help='Name for new recipe to add (just name - no version, path or extension). If not specified, will attempt to auto-detect it.')      parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)      group = parser_add.add_mutually_exclusive_group()      group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") | 
