diff options
Diffstat (limited to 'scripts/lib')
| -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): | |||
| 37 | import bb | 37 | import bb |
| 38 | import oe.recipeutils | 38 | import oe.recipeutils |
| 39 | 39 | ||
| 40 | if args.recipename in workspace: | 40 | if args.recipename and not args.srctree: |
| 41 | raise DevtoolError("recipe %s is already in your workspace" % | 41 | # These are positional arguments, but because we're nice, allow |
| 42 | args.recipename) | 42 | # specifying source tree without name if we can detect that that |
| 43 | # is what the user meant | ||
| 44 | if os.sep in args.recipename: | ||
| 45 | args.srctree = args.recipename | ||
| 46 | args.recipename = None | ||
| 47 | elif os.path.isdir(args.recipename): | ||
| 48 | logger.warn('Ambiguous argument %s - assuming you mean it to be the recipe name') | ||
| 43 | 49 | ||
| 44 | reason = oe.recipeutils.validate_pn(args.recipename) | 50 | if args.recipename: |
| 45 | if reason: | 51 | if args.recipename in workspace: |
| 46 | raise DevtoolError(reason) | 52 | raise DevtoolError("recipe %s is already in your workspace" % |
| 53 | args.recipename) | ||
| 54 | reason = oe.recipeutils.validate_pn(args.recipename) | ||
| 55 | if reason: | ||
| 56 | raise DevtoolError(reason) | ||
| 47 | 57 | ||
| 48 | # FIXME this ought to be in validate_pn but we're using that in other contexts | 58 | # FIXME this ought to be in validate_pn but we're using that in other contexts |
| 49 | if '/' in args.recipename: | 59 | if '/' in args.recipename: |
| 50 | raise DevtoolError('"/" is not a valid character in recipe names') | 60 | raise DevtoolError('"/" is not a valid character in recipe names') |
| 51 | 61 | ||
| 52 | if args.srctree: | 62 | if args.srctree: |
| 53 | srctree = os.path.abspath(args.srctree) | 63 | srctree = os.path.abspath(args.srctree) |
| 64 | srctreeparent = None | ||
| 65 | tmpsrcdir = None | ||
| 54 | else: | 66 | else: |
| 55 | srctree = get_default_srctree(config, args.recipename) | 67 | srctree = None |
| 56 | logger.info('Using default source tree path %s' % srctree) | 68 | srctreeparent = get_default_srctree(config) |
| 69 | bb.utils.mkdirhier(srctreeparent) | ||
| 70 | tmpsrcdir = tempfile.mkdtemp(prefix='devtoolsrc', dir=srctreeparent) | ||
| 57 | 71 | ||
| 58 | if os.path.exists(srctree): | 72 | if srctree and os.path.exists(srctree): |
| 59 | if args.fetch: | 73 | if args.fetch: |
| 60 | if not os.path.isdir(srctree): | 74 | if not os.path.isdir(srctree): |
| 61 | raise DevtoolError("Cannot fetch into source tree path %s as " | 75 | raise DevtoolError("Cannot fetch into source tree path %s as " |
| @@ -69,33 +83,21 @@ def add(args, config, basepath, workspace): | |||
| 69 | if args.srctree: | 83 | if args.srctree: |
| 70 | raise DevtoolError("Specified source tree %s could not be found" % | 84 | raise DevtoolError("Specified source tree %s could not be found" % |
| 71 | args.srctree) | 85 | args.srctree) |
| 72 | else: | 86 | elif srctree: |
| 73 | raise DevtoolError("No source tree exists at default path %s - " | 87 | raise DevtoolError("No source tree exists at default path %s - " |
| 74 | "either create and populate this directory, " | 88 | "either create and populate this directory, " |
| 75 | "or specify a path to a source tree, or use " | 89 | "or specify a path to a source tree, or use " |
| 76 | "the -f/--fetch option to fetch source code " | 90 | "the -f/--fetch option to fetch source code " |
| 77 | "and extract it to the source directory" % | 91 | "and extract it to the source directory" % |
| 78 | srctree) | 92 | srctree) |
| 93 | else: | ||
| 94 | raise DevtoolError("You must either specify a source tree " | ||
| 95 | "or -f to fetch source") | ||
| 79 | 96 | ||
| 80 | recipedir = os.path.join(config.workspace_path, 'recipes', args.recipename) | ||
| 81 | bb.utils.mkdirhier(recipedir) | ||
| 82 | rfv = None | ||
| 83 | if args.version: | 97 | if args.version: |
| 84 | if '_' in args.version or ' ' in args.version: | 98 | if '_' in args.version or ' ' in args.version: |
| 85 | raise DevtoolError('Invalid version string "%s"' % args.version) | 99 | raise DevtoolError('Invalid version string "%s"' % args.version) |
| 86 | rfv = args.version | 100 | |
| 87 | if args.fetch: | ||
| 88 | if args.fetch.startswith('git://'): | ||
| 89 | rfv = 'git' | ||
| 90 | elif args.fetch.startswith('svn://'): | ||
| 91 | rfv = 'svn' | ||
| 92 | elif args.fetch.startswith('hg://'): | ||
| 93 | rfv = 'hg' | ||
| 94 | if rfv: | ||
| 95 | bp = "%s_%s" % (args.recipename, rfv) | ||
| 96 | else: | ||
| 97 | bp = args.recipename | ||
| 98 | recipefile = os.path.join(recipedir, "%s.bb" % bp) | ||
| 99 | if args.color == 'auto' and sys.stdout.isatty(): | 101 | if args.color == 'auto' and sys.stdout.isatty(): |
| 100 | color = 'always' | 102 | color = 'always' |
| 101 | else: | 103 | else: |
| @@ -103,19 +105,71 @@ def add(args, config, basepath, workspace): | |||
| 103 | extracmdopts = '' | 105 | extracmdopts = '' |
| 104 | if args.fetch: | 106 | if args.fetch: |
| 105 | source = args.fetch | 107 | source = args.fetch |
| 106 | extracmdopts = '-x %s' % srctree | 108 | if srctree: |
| 109 | extracmdopts += ' -x %s' % srctree | ||
| 110 | else: | ||
| 111 | extracmdopts += ' -x %s' % tmpsrcdir | ||
| 107 | else: | 112 | else: |
| 108 | source = srctree | 113 | source = srctree |
| 114 | if args.recipename: | ||
| 115 | extracmdopts += ' -N %s' % args.recipename | ||
| 109 | if args.version: | 116 | if args.version: |
| 110 | extracmdopts += ' -V %s' % args.version | 117 | extracmdopts += ' -V %s' % args.version |
| 111 | if args.binary: | 118 | if args.binary: |
| 112 | extracmdopts += ' -b' | 119 | extracmdopts += ' -b' |
| 120 | |||
| 121 | tempdir = tempfile.mkdtemp(prefix='devtool') | ||
| 113 | try: | 122 | try: |
| 114 | stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, recipefile, source, extracmdopts)) | 123 | try: |
| 115 | except bb.process.ExecutionError as e: | 124 | stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, tempdir, source, extracmdopts)) |
| 116 | raise DevtoolError('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) | 125 | except bb.process.ExecutionError as e: |
| 126 | if e.exitcode == 15: | ||
| 127 | raise DevtoolError('Unable to auto-determine name from source tree, please specify it with -N/--name') | ||
| 128 | else: | ||
| 129 | raise DevtoolError('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) | ||
| 130 | |||
| 131 | recipes = glob.glob(os.path.join(tempdir, '*.bb')) | ||
| 132 | if recipes: | ||
| 133 | recipename = os.path.splitext(os.path.basename(recipes[0]))[0].split('_')[0] | ||
| 134 | if recipename in workspace: | ||
| 135 | raise DevtoolError('A recipe with the same name as the one being created (%s) already exists in your workspace' % recipename) | ||
| 136 | recipedir = os.path.join(config.workspace_path, 'recipes', recipename) | ||
| 137 | bb.utils.mkdirhier(recipedir) | ||
| 138 | recipefile = os.path.join(recipedir, os.path.basename(recipes[0])) | ||
| 139 | appendfile = recipe_to_append(recipefile, config) | ||
| 140 | if os.path.exists(appendfile): | ||
| 141 | # This shouldn't be possible, but just in case | ||
| 142 | raise DevtoolError('A recipe with the same name as the one being created already exists in your workspace') | ||
| 143 | if os.path.exists(recipefile): | ||
| 144 | raise DevtoolError('A recipe file %s already exists in your workspace; this shouldn\'t be there - please delete it before continuing' % recipefile) | ||
| 145 | if tmpsrcdir: | ||
| 146 | srctree = os.path.join(srctreeparent, recipename) | ||
| 147 | if os.path.exists(tmpsrcdir): | ||
| 148 | if os.path.exists(srctree): | ||
| 149 | if os.path.isdir(srctree): | ||
| 150 | try: | ||
| 151 | os.rmdir(srctree) | ||
| 152 | except OSError as e: | ||
| 153 | if e.errno == errno.ENOTEMPTY: | ||
| 154 | raise DevtoolError('Source tree path %s already exists and is not empty' % srctree) | ||
| 155 | else: | ||
| 156 | raise | ||
| 157 | else: | ||
| 158 | raise DevtoolError('Source tree path %s already exists and is not a directory' % srctree) | ||
| 159 | logger.info('Using default source tree path %s' % srctree) | ||
| 160 | shutil.move(tmpsrcdir, srctree) | ||
| 161 | else: | ||
| 162 | raise DevtoolError('Couldn\'t find source tree created by recipetool') | ||
| 163 | bb.utils.mkdirhier(recipedir) | ||
| 164 | shutil.move(recipes[0], recipefile) | ||
| 165 | else: | ||
| 166 | raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout)) | ||
| 167 | finally: | ||
| 168 | if tmpsrcdir and os.path.exists(tmpsrcdir): | ||
| 169 | shutil.rmtree(tmpsrcdir) | ||
| 170 | shutil.rmtree(tempdir) | ||
| 117 | 171 | ||
| 118 | _add_md5(config, args.recipename, recipefile) | 172 | _add_md5(config, recipename, recipefile) |
| 119 | 173 | ||
| 120 | if args.fetch and not args.no_git: | 174 | if args.fetch and not args.no_git: |
| 121 | setup_git_repo(srctree, args.version, 'devtool') | 175 | setup_git_repo(srctree, args.version, 'devtool') |
| @@ -130,7 +184,6 @@ def add(args, config, basepath, workspace): | |||
| 130 | if not rd: | 184 | if not rd: |
| 131 | return 1 | 185 | return 1 |
| 132 | 186 | ||
| 133 | appendfile = recipe_to_append(recipefile, config) | ||
| 134 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | 187 | bb.utils.mkdirhier(os.path.dirname(appendfile)) |
| 135 | with open(appendfile, 'w') as f: | 188 | with open(appendfile, 'w') as f: |
| 136 | f.write('inherit externalsrc\n') | 189 | f.write('inherit externalsrc\n') |
| @@ -148,7 +201,7 @@ def add(args, config, basepath, workspace): | |||
| 148 | f.write(' rm -f ${D}/singletask.lock\n') | 201 | f.write(' rm -f ${D}/singletask.lock\n') |
| 149 | f.write('}\n') | 202 | f.write('}\n') |
| 150 | 203 | ||
| 151 | _add_md5(config, args.recipename, appendfile) | 204 | _add_md5(config, recipename, appendfile) |
| 152 | 205 | ||
| 153 | logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) | 206 | logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) |
| 154 | 207 | ||
| @@ -1195,7 +1248,7 @@ def register_commands(subparsers, context): | |||
| 1195 | defsrctree = get_default_srctree(context.config) | 1248 | defsrctree = get_default_srctree(context.config) |
| 1196 | parser_add = subparsers.add_parser('add', help='Add a new recipe', | 1249 | parser_add = subparsers.add_parser('add', help='Add a new recipe', |
| 1197 | 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.') | 1250 | 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.') |
| 1198 | parser_add.add_argument('recipename', help='Name for new recipe to add (just name - no version, path or extension)') | 1251 | 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.') |
| 1199 | parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree) | 1252 | parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree) |
| 1200 | group = parser_add.add_mutually_exclusive_group() | 1253 | group = parser_add.add_mutually_exclusive_group() |
| 1201 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") | 1254 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") |
