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,54 @@ def __init__(self):
155156 'init' ,
156157 'create a west workspace' ,
157158 f'''\
158- Creates a west workspace.
159-
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-
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.
167-
168- With neither, -m { MANIFEST_URL_DEFAULT } is assumed.
169-
170- Warning: 'west init' renames and/or deletes temporary files inside the
159+ Initialize a west workspace.
160+
161+ West supports two ways of creating a workspace:
162+
163+ 1. Remote Manifest Repositories
164+ -------------------------------
165+ If `-m / --manifest-url` is given, west clones the manifest repository from the
166+ specified URL into a new workspace. Inside that workspace, the local config
167+ option `manifest.path` will be set to point at this cloned directory (relative
168+ path from the git clone to the workspace).
169+
170+ - If `-m / --manifest-url` is not provided, west will use Zephyr manifest
171+ repository by default:
172+ { MANIFEST_URL_DEFAULT } .
173+ - With `--mr`, you can specify the revision (branch, tag, or sha) of the
174+ manifest repository.
175+ - If `--mr / --manifest-revision` is omitted, the repository's default branch
176+ is used (if available).
177+
178+ Note: The west workspace (topdir) will be the current working directory, if
179+ neither --topdir nor [directory] are provided.
180+
181+ 2. Local Manifest
182+ -----------------
183+ If `-l / --local` is given, west initializes a new workspace from an already
184+ existing local manifest. The directory containing the manifest can be provided
185+ in positional argument `[manifest_directory]` (defaults to current working dir)
186+ Inside that workspace, the local config option `manifest.path` will be set to
187+ point at the manifest directory (relative path from `manifest_directory` to the
188+ workspace)
189+
190+ Note: The west workspace (topdir) will be the `manifest_directory`'s parent, if
191+ no other directory is provided in `--topdir`.
192+
193+ Arguments
194+ ---------
195+ --mf
196+ The relative path to the manifest file within the manifest repository
197+ (remote or local). Config option manifest.file will be set to this value.
198+ Defaults to `{ _WEST_YML } ` if not provided.
199+
200+ --topdir
201+ Specifies the directory where west should create the workspace.
202+ The `.west` folder will be created inside this directory.
203+
204+ Known Issues
205+ ------------
206+ 'west init' renames and/or deletes temporary files inside the
171207workspace being created. This fails on some filesystems when some
172208development tool or any other program is trying to read/index these
173209temporary files at the same time. For instance, it is required to stop
@@ -192,9 +228,10 @@ def do_add_parser(self, parser_adder):
192228 parser = self ._parser (
193229 parser_adder ,
194230 usage = '''
195-
196- %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [directory]
197- %(prog)s -l [--mf FILE] directory
231+ remote repository:
232+ %(prog)s [-m URL] [--mr REVISION] [--mf FILE] [-o=GIT_CLONE_OPTION] [-t WORKSPACE_DIR | directory]
233+ local manifest:
234+ %(prog)s -l [-t WORKSPACE_DIR] [--mf FILE] [manifest_directory]
198235''' ,
199236 )
200237
@@ -203,14 +240,16 @@ def do_add_parser(self, parser_adder):
203240 parser .add_argument (
204241 '-m' ,
205242 '--manifest-url' ,
206- help = '''manifest repository URL to clone;
243+ metavar = 'URL' ,
244+ help = '''remote manifest repository URL to clone;
207245 cannot be combined with -l''' ,
208246 )
209247 parser .add_argument (
210248 '-o' ,
211249 '--clone-opt' ,
212250 action = 'append' ,
213251 default = [],
252+ metavar = 'GIT_CLONE_OPTION' ,
214253 help = '''additional option to pass to 'git clone'
215254 (e.g. '-o=--depth=1'); may be given more than once;
216255 cannot be combined with -l''' ,
@@ -219,21 +258,33 @@ def do_add_parser(self, parser_adder):
219258 '--mr' ,
220259 '--manifest-rev' ,
221260 dest = 'manifest_rev' ,
261+ metavar = 'REVISION' ,
222262 help = '''manifest repository branch or tag name
223263 to check out first; cannot be combined with -l''' ,
224264 )
225- parser .add_argument (
226- '--mf' , '--manifest-file' , dest = 'manifest_file' , help = 'manifest file name to use'
227- )
228265 parser .add_argument (
229266 '-l' ,
230267 '--local' ,
231268 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"''' ,
269+ help = '''initialize from an already existing local
270+ manifest instead of cloning a remote manifest.''' ,
271+ )
272+ parser .add_argument (
273+ '--mf' ,
274+ '--manifest-file' ,
275+ dest = 'manifest_file' ,
276+ metavar = 'FILE' ,
277+ help = f'''manifest file to use. It is the relative
278+ path of the manifest file within the repository
279+ (remote or local). Defaults to { _WEST_YML } .''' ,
280+ )
281+ parser .add_argument (
282+ '-t' ,
283+ '--topdir' ,
284+ dest = 'topdir' ,
285+ metavar = 'WORKSPACE_DIR' ,
286+ help = '''the directory of the west workspace, where
287+ .west will be created in.''' ,
237288 )
238289 parser .add_argument (
239290 '--rename-delay' ,
@@ -249,9 +300,10 @@ def do_add_parser(self, parser_adder):
249300 'directory' ,
250301 nargs = '?' ,
251302 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)''' ,
303+ metavar = 'directory' ,
304+ help = '''with --local: the path to the local manifest repository
305+ which contains a west.yml;
306+ otherwise: the directory to create the workspace in''' ,
255307 )
256308
257309 return parser
@@ -302,15 +354,19 @@ def local(self, args) -> Path:
302354 #
303355 # https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent
304356 manifest_dir = Path (args .directory or os .getcwd ()).resolve ()
305- manifest_filename = args .manifest_file or 'west.yml'
357+ manifest_filename = args .manifest_file or _WEST_YML
306358 manifest_file = manifest_dir / manifest_filename
307- topdir = manifest_dir .parent
308- rel_manifest = manifest_dir .name
309- west_dir = topdir / WEST_DIR
310-
311359 if not manifest_file .is_file ():
312360 self .die (f'can\' t init: no { manifest_filename } found in { manifest_dir } ' )
313361
362+ topdir = Path (args .topdir or manifest_dir .parent ).resolve ()
363+
364+ if not manifest_file .is_relative_to (topdir ):
365+ self .die (f'{ manifest_file } must be relative to west topdir' )
366+
367+ rel_manifest = manifest_dir .relative_to (topdir )
368+ west_dir = topdir / WEST_DIR
369+
314370 self .banner ('Initializing from existing manifest repository' , rel_manifest )
315371 self .small_banner (f'Creating { west_dir } and local configuration file' )
316372 self .create (west_dir )
@@ -322,8 +378,11 @@ def local(self, args) -> Path:
322378 return topdir
323379
324380 def bootstrap (self , args ) -> Path :
325- topdir = Path (abspath (args .directory or os .getcwd ()))
326- self .banner ('Initializing in' , topdir )
381+ if args .topdir and args .directory :
382+ self .die ('--topdir cannot be combined with positional argument [directory]' )
383+
384+ topdir = Path (abspath (args .topdir or args .directory or os .getcwd ()))
385+ self .banner (f'Initializing in { topdir } ' )
327386
328387 manifest_url = args .manifest_url or MANIFEST_URL_DEFAULT
329388 if args .manifest_rev :
@@ -378,7 +437,7 @@ def bootstrap(self, args) -> Path:
378437 raise
379438
380439 # Verify the manifest file exists.
381- temp_manifest_filename = args .manifest_file or 'west.yml'
440+ temp_manifest_filename = args .manifest_file or _WEST_YML
382441 temp_manifest = tempdir / temp_manifest_filename
383442 if not temp_manifest .is_file ():
384443 self .die (
0 commit comments