summaryrefslogtreecommitdiffstats
path: root/scripts/lib
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib')
-rw-r--r--scripts/lib/devtool/standard.py127
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")