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") |