2424from west import util
2525from west .commands import CommandError , Verbosity , WestCommand
2626from west .configuration import Configuration
27- from west .manifest import MANIFEST_REV_BRANCH as MANIFEST_REV
28- from west .manifest import QUAL_MANIFEST_REV_BRANCH as QUAL_MANIFEST_REV
29- from west .manifest import QUAL_REFS_WEST as QUAL_REFS
3027from west .manifest import (
28+ _WEST_YML ,
3129 ImportFlag ,
3230 Manifest ,
3331 ManifestImportFailed ,
3432 ManifestProject ,
3533 Submodule ,
3634 _manifest_content_at ,
3735)
36+ from west .manifest import MANIFEST_REV_BRANCH as MANIFEST_REV
37+ from west .manifest import QUAL_MANIFEST_REV_BRANCH as QUAL_MANIFEST_REV
38+ from west .manifest import QUAL_REFS_WEST as QUAL_REFS
3839from west .manifest import is_group as is_project_group
3940
4041#
@@ -155,19 +156,49 @@ def __init__(self):
155156 'init' ,
156157 'create a west workspace' ,
157158 f'''\
158- Creates a west workspace.
159+ Initialize a west workspace.
160+
161+ West supports two ways of creating a workspace:
159162
160- With -l, creates a workspace around an existing local repository;
161- without -l, creates a workspace by cloning a manifest repository
162- by URL.
163+ 1. Remote Manifest Repositories
164+ ----------------------------
165+ If `-m` is given, west clones the manifest repository from the specified URL
166+ into the workspace. Config option manifest.path will point at this cloned
167+ directory.
163168
164- With -m, clones the repository at that URL and uses it as the
165- manifest repository. If --mr is not given, the remote's default
166- branch will be used, if it exists.
169+ - If `-m` is not provided, west defaults to the Zephyr manifest repository:
170+ { MANIFEST_URL_DEFAULT } .
171+ - With `--mr`, you can specify the revision (branch, tag, or sha) of the
172+ manifest repository.
173+ - If `--mr` is omitted, the repository's default branch (if available) is used.
167174
168- With neither, -m { MANIFEST_URL_DEFAULT } is assumed.
175+ Note: The west workspace will be created in the current working directory, if
176+ neither --topdir nor [directory] are provided.
169177
170- Warning: 'west init' renames and/or deletes temporary files inside the
178+ 2. Local Manifest
179+ --------------
180+ If `--local` is given, west initializes a workspace from an already existing
181+ local manifest. The directory containing the manifest can be provided in
182+ positional argument [directory] (default: current working directory).
183+ Config option manifest.path will point at this directory.
184+
185+ Note: The west workspace will be created in the provided directory's parent, if
186+ no other directory is provided in --topdir.
187+
188+ Arguments
189+ ---------
190+ --mf
191+ The relative path to the manifest file within the manifest repository
192+ (remote or local). Config option manifest.file will be set to this value.
193+ Defaults to `{ _WEST_YML } ` if not provided.
194+
195+ --topdir
196+ Specifies the directory where west should create the workspace.
197+ The `.west` folder will be created inside this directory.
198+
199+ Known Issues
200+ ------------
201+ 'west init' renames and/or deletes temporary files inside the
171202workspace being created. This fails on some filesystems when some
172203development tool or any other program is trying to read/index these
173204temporary files at the same time. For instance, it is required to stop
@@ -192,9 +223,10 @@ def do_add_parser(self, parser_adder):
192223 parser = self ._parser (
193224 parser_adder ,
194225 usage = '''
195-
196- %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [directory]
197- %(prog)s -l [--mf FILE] directory
226+ remote repository:
227+ %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [-t WORKSPACE_DIR] [directory]
228+ local manifest:
229+ %(prog)s -l [-t WORKSPACE_DIR] [--mf FILE] directory
198230''' ,
199231 )
200232
@@ -203,14 +235,16 @@ def do_add_parser(self, parser_adder):
203235 parser .add_argument (
204236 '-m' ,
205237 '--manifest-url' ,
206- help = '''manifest repository URL to clone;
238+ metavar = 'URL' ,
239+ help = '''remote manifest repository URL to clone;
207240 cannot be combined with -l''' ,
208241 )
209242 parser .add_argument (
210243 '-o' ,
211244 '--clone-opt' ,
212245 action = 'append' ,
213246 default = [],
247+ metavar = 'GIT_CLONE_OPTION' ,
214248 help = '''additional option to pass to 'git clone'
215249 (e.g. '-o=--depth=1'); may be given more than once;
216250 cannot be combined with -l''' ,
@@ -219,21 +253,33 @@ def do_add_parser(self, parser_adder):
219253 '--mr' ,
220254 '--manifest-rev' ,
221255 dest = 'manifest_rev' ,
256+ metavar = 'REVISION' ,
222257 help = '''manifest repository branch or tag name
223258 to check out first; cannot be combined with -l''' ,
224259 )
225- parser .add_argument (
226- '--mf' , '--manifest-file' , dest = 'manifest_file' , help = 'manifest file name to use'
227- )
228260 parser .add_argument (
229261 '-l' ,
230262 '--local' ,
231263 action = 'store_true' ,
232- help = '''use "directory" as an existing local
233- manifest repository instead of cloning one from
234- MANIFEST_URL; .west is created next to "directory"
235- in this case, and manifest.path points at
236- "directory"''' ,
264+ help = '''initialize from an already existing local
265+ manifest instead of cloning a remote manifest.''' ,
266+ )
267+ parser .add_argument (
268+ '--mf' ,
269+ '--manifest-file' ,
270+ dest = 'manifest_file' ,
271+ metavar = 'FILE' ,
272+ help = f'''manifest file to use. It is the relative
273+ path of the manifest file within the repository
274+ (remote or local). Defaults to { _WEST_YML } .''' ,
275+ )
276+ parser .add_argument (
277+ '-t' ,
278+ '--topdir' ,
279+ dest = 'topdir' ,
280+ metavar = 'WORKSPACE_DIR' ,
281+ help = '''the directory of the west workspace, where
282+ .west will be created in.''' ,
237283 )
238284 parser .add_argument (
239285 '--rename-delay' ,
@@ -249,9 +295,10 @@ def do_add_parser(self, parser_adder):
249295 'directory' ,
250296 nargs = '?' ,
251297 default = None ,
252- help = '''with -l, the path to the local manifest repository;
253- without it, the directory to create the workspace in (defaulting
254- to the current working directory in this case)''' ,
298+ metavar = 'directory' ,
299+ help = '''with --local: the path to the local manifest repository
300+ which contains a west.yml;
301+ otherwise: the directory to create the workspace in''' ,
255302 )
256303
257304 return parser
@@ -302,15 +349,19 @@ def local(self, args) -> Path:
302349 #
303350 # https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent
304351 manifest_dir = Path (args .directory or os .getcwd ()).resolve ()
305- manifest_filename = args .manifest_file or 'west.yml'
352+ manifest_filename = args .manifest_file or _WEST_YML
306353 manifest_file = manifest_dir / manifest_filename
307- topdir = manifest_dir .parent
308- rel_manifest = manifest_dir .name
309- west_dir = topdir / WEST_DIR
310-
311354 if not manifest_file .is_file ():
312355 self .die (f'can\' t init: no { manifest_filename } found in { manifest_dir } ' )
313356
357+ topdir = Path (args .topdir or manifest_dir .parent ).resolve ()
358+
359+ if not manifest_file .is_relative_to (topdir ):
360+ self .die (f'{ manifest_file } must be relative to west topdir' )
361+
362+ rel_manifest = manifest_dir .relative_to (topdir )
363+ west_dir = topdir / WEST_DIR
364+
314365 self .banner ('Initializing from existing manifest repository' , rel_manifest )
315366 self .small_banner (f'Creating { west_dir } and local configuration file' )
316367 self .create (west_dir )
@@ -322,8 +373,11 @@ def local(self, args) -> Path:
322373 return topdir
323374
324375 def bootstrap (self , args ) -> Path :
325- topdir = Path (abspath (args .directory or os .getcwd ()))
326- self .banner ('Initializing in' , topdir )
376+ if args .topdir and args .directory :
377+ self .die ('--topdir cannot be combined with positional argument [directory]' )
378+
379+ topdir = Path (abspath (args .topdir or args .directory or os .getcwd ()))
380+ self .banner (f'Initializing in { topdir } ' )
327381
328382 manifest_url = args .manifest_url or MANIFEST_URL_DEFAULT
329383 if args .manifest_rev :
@@ -378,7 +432,7 @@ def bootstrap(self, args) -> Path:
378432 raise
379433
380434 # Verify the manifest file exists.
381- temp_manifest_filename = args .manifest_file or 'west.yml'
435+ temp_manifest_filename = args .manifest_file or _WEST_YML
382436 temp_manifest = tempdir / temp_manifest_filename
383437 if not temp_manifest .is_file ():
384438 self .die (
0 commit comments