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#
@@ -151,19 +152,49 @@ def __init__(self):
151152 'init' ,
152153 'create a west workspace' ,
153154 f'''\
154- Creates a west workspace.
155+ Initialize a west workspace.
155156
156- With -l, creates a workspace around an existing local repository;
157- without -l, creates a workspace by cloning a manifest repository
158- by URL.
157+ West supports two ways of creating a workspace:
159158
160- With -m, clones the repository at that URL and uses it as the
161- manifest repository. If --mr is not given, the remote's default
162- branch will be used, if it exists.
159+ 1. Remote Manifest Repositories
160+ ----------------------------
161+ If `-m` is given, west clones the manifest repository from the specified URL
162+ into the workspace. Config option manifest.path will point at this cloned
163+ directory.
163164
164- With neither, -m { MANIFEST_URL_DEFAULT } is assumed.
165+ - If `-m` is not provided, west defaults to the Zephyr manifest repository:
166+ { MANIFEST_URL_DEFAULT } .
167+ - With `--mr`, you can specify the revision (branch, tag, or sha) of the
168+ manifest repository.
169+ - If `--mr` is omitted, the repository's default branch (if available) is used.
165170
166- Warning: 'west init' renames and/or deletes temporary files inside the
171+ Note: The west workspace will be created in the current working directory, if
172+ neither --topdir nor [directory] are provided.
173+
174+ 2. Local Manifest
175+ --------------
176+ If `--local` is given, west initializes a workspace from an already existing
177+ local manifest. The directory containing the manifest can be provided in
178+ positional argument [directory] (default: current working directory).
179+ Config option manifest.path will point at this directory.
180+
181+ Note: The west workspace will be created in the provided directory's parent, if
182+ no other directory is provided in --topdir.
183+
184+ Arguments
185+ ---------
186+ --mf
187+ The relative path to the manifest file within the manifest repository
188+ (remote or local). Config option manifest.file will be set to this value.
189+ Defaults to `{ _WEST_YML } ` if not provided.
190+
191+ --topdir
192+ Specifies the directory where west should create the workspace.
193+ The `.west` folder will be created inside this directory.
194+
195+ Known Issues
196+ ------------
197+ 'west init' renames and/or deletes temporary files inside the
167198workspace being created. This fails on some filesystems when some
168199development tool or any other program is trying to read/index these
169200temporary files at the same time. For instance, it is required to stop
@@ -187,31 +218,39 @@ def do_add_parser(self, parser_adder):
187218 parser = self ._parser (
188219 parser_adder ,
189220 usage = '''
190-
191- %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [directory]
192- %(prog)s -l [--mf FILE] directory
221+ remote repository:
222+ %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [-t WORKSPACE_DIR] [directory]
223+ local manifest:
224+ %(prog)s -l [-t WORKSPACE_DIR] [--mf FILE] directory
193225''' )
194226
195227 # Remember to update the usage if you modify any arguments.
196228
197229 parser .add_argument ('-m' , '--manifest-url' ,
198- help = '''manifest repository URL to clone;
230+ metavar = 'URL' ,
231+ help = '''remote manifest repository URL to clone;
199232 cannot be combined with -l''' )
200233 parser .add_argument ('-o' , '--clone-opt' , action = 'append' , default = [],
234+ metavar = 'GIT_CLONE_OPTION' ,
201235 help = '''additional option to pass to 'git clone'
202236 (e.g. '-o=--depth=1'); may be given more than once;
203237 cannot be combined with -l''' )
204238 parser .add_argument ('--mr' , '--manifest-rev' , dest = 'manifest_rev' ,
239+ metavar = 'REVISION' ,
205240 help = '''manifest repository branch or tag name
206241 to check out first; cannot be combined with -l''' )
207- parser .add_argument ('--mf' , '--manifest-file' , dest = 'manifest_file' ,
208- help = 'manifest file name to use' )
209242 parser .add_argument ('-l' , '--local' , action = 'store_true' ,
210- help = '''use "directory" as an existing local
211- manifest repository instead of cloning one from
212- MANIFEST_URL; .west is created next to "directory"
213- in this case, and manifest.path points at
214- "directory"''' )
243+ help = '''initialize from an already existing local
244+ manifest instead of cloning a remote manifest.''' )
245+ parser .add_argument ('--mf' , '--manifest-file' , dest = 'manifest_file' ,
246+ metavar = 'FILE' ,
247+ help = f'''manifest file to use. It is the relative
248+ path of the manifest file within the repository
249+ (remote or local). Defaults to { _WEST_YML } .''' )
250+ parser .add_argument ('-t' , '--topdir' , dest = 'topdir' ,
251+ metavar = 'WORKSPACE_DIR' ,
252+ help = '''the directory of the west workspace, where
253+ .west will be created in.''' )
215254 parser .add_argument ('--rename-delay' , type = int ,
216255 help = '''Number of seconds to wait before renaming
217256 some temporary directories. Some filesystems like NTFS
@@ -220,10 +259,10 @@ def do_add_parser(self, parser_adder):
220259 background scanner to complete. ''' )
221260
222261 parser .add_argument (
223- 'directory' , nargs = '?' , default = None ,
224- help = '''with -l, the path to the local manifest repository;
225- without it, the directory to create the workspace in (defaulting
226- to the current working directory in this case) ''' )
262+ 'directory' , nargs = '?' , default = None , metavar = 'directory' ,
263+ help = '''with --local: the path to the local manifest repository
264+ which contains a west.yml;
265+ otherwise: the directory to create the workspace in ''' )
227266
228267 return parser
229268
@@ -271,16 +310,20 @@ def local(self, args) -> Path:
271310 #
272311 # https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent
273312 manifest_dir = Path (args .directory or os .getcwd ()).resolve ()
274- manifest_filename = args .manifest_file or 'west.yml'
313+ manifest_filename = args .manifest_file or _WEST_YML
275314 manifest_file = manifest_dir / manifest_filename
276- topdir = manifest_dir .parent
277- rel_manifest = manifest_dir .name
278- west_dir = topdir / WEST_DIR
279-
280315 if not manifest_file .is_file ():
281316 self .die (f'can\' t init: no { manifest_filename } found in '
282317 f'{ manifest_dir } ' )
283318
319+ topdir = Path (args .topdir or manifest_dir .parent ).resolve ()
320+
321+ if not manifest_file .is_relative_to (topdir ):
322+ self .die (f'{ manifest_file } must be relative to west topdir' )
323+
324+ rel_manifest = manifest_dir .relative_to (topdir )
325+ west_dir = topdir / WEST_DIR
326+
284327 self .banner ('Initializing from existing manifest repository' ,
285328 rel_manifest )
286329 self .small_banner (f'Creating { west_dir } and local configuration file' )
@@ -293,8 +336,11 @@ def local(self, args) -> Path:
293336 return topdir
294337
295338 def bootstrap (self , args ) -> Path :
296- topdir = Path (abspath (args .directory or os .getcwd ()))
297- self .banner ('Initializing in' , topdir )
339+ if args .topdir and args .directory :
340+ self .die ('--topdir cannot be combined with positional argument [directory]' )
341+
342+ topdir = Path (abspath (args .topdir or args .directory or os .getcwd ()))
343+ self .banner (f'Initializing in { topdir } ' )
298344
299345 manifest_url = args .manifest_url or MANIFEST_URL_DEFAULT
300346 if args .manifest_rev :
@@ -347,7 +393,7 @@ def bootstrap(self, args) -> Path:
347393 raise
348394
349395 # Verify the manifest file exists.
350- temp_manifest_filename = args .manifest_file or 'west.yml'
396+ temp_manifest_filename = args .manifest_file or _WEST_YML
351397 temp_manifest = tempdir / temp_manifest_filename
352398 if not temp_manifest .is_file ():
353399 self .die (f'can\' t init: no { temp_manifest_filename } found in '
0 commit comments