diff --git a/src/west/app/project.py b/src/west/app/project.py index 336c9343..dc0bd877 100644 --- a/src/west/app/project.py +++ b/src/west/app/project.py @@ -306,6 +306,13 @@ def local(self, args) -> Path: # # https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent manifest_dir = Path(args.directory or os.getcwd()).resolve() + + try: + already = util.west_topdir(manifest_dir, fall_back=False) + self.die_already(already) + except util.WestNotFound: + pass + manifest_filename = args.manifest_file or 'west.yml' manifest_file = manifest_dir / manifest_filename topdir = manifest_dir.parent @@ -317,7 +324,7 @@ def local(self, args) -> Path: self.banner('Initializing from existing manifest repository', rel_manifest) self.small_banner(f'Creating {west_dir} and local configuration file') - self.create(west_dir) + self.create(west_dir, exist_ok=False) os.chdir(topdir) self.config = Configuration(topdir=topdir) self.config.set('manifest.path', os.fspath(rel_manifest)) @@ -410,6 +417,16 @@ def bootstrap(self, args) -> Path: manifest_abspath = topdir / manifest_path + # We already looked for old .west/ pollution earlier but only at the highest + # topdir/.west level because we didn't know the manifest_path yet. Now that we know + # "manifest_path", look again for any existing, clashing .west/ located at a lower + # level somewhere between the new topdir and the new manifest_path. This check will be + # especially useful once the new --topdir feature is available, see + # https://github.com/zephyrproject-rtos/west/issues/774 + already = util.west_topdir(manifest_abspath, fall_back=False) + if not topdir.samefile(already): + self.die_already(already) + # Some filesystems like NTFS can't rename files in use. # See west issue #558. Will ReFS address this? ren_delay = args.rename_delay diff --git a/tests/test_project.py b/tests/test_project.py index 122dc844..6bd9ca51 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -958,8 +958,6 @@ def test_update_some_with_imports(repos_tmpdir): }, ) - cmd(['init', '-l', manifest_repo]) - # Updating unknown projects should fail as always. with pytest.raises(SystemExit): @@ -1037,7 +1035,6 @@ def test_update_submodules_list(repos_tmpdir): ''' }, ) - cmd(['init', '-l', manifest_repo]) # Make tagged_repo to be zephyr project submodule. subprocess.check_call(SUBMODULE_ADD + [str(tagged_repo), 'tagged_repo'], cwd=zephyr) @@ -1161,7 +1158,6 @@ def test_update_all_submodules(repos_tmpdir): ''' }, ) - cmd(['init', '-l', manifest_repo]) # Make tagged_repo to be zephyr project submodule. subprocess.check_call(SUBMODULE_ADD + [str(tagged_repo), 'tagged_repo'], cwd=zephyr) @@ -1273,7 +1269,6 @@ def test_update_no_submodules(repos_tmpdir): ''' }, ) - cmd(['init', '-l', manifest_repo]) # Make tagged_repo to be zephyr project submodule. subprocess.check_call(SUBMODULE_ADD + [str(tagged_repo), 'tagged_repo'], cwd=zephyr) @@ -1379,7 +1374,6 @@ def test_update_submodules_strategy(repos_tmpdir): ''' }, ) - cmd(['init', '-l', manifest_repo]) # Make tagged_repo to be zephyr project submodule. subprocess.check_call(SUBMODULE_ADD + [str(tagged_repo), 'tagged_repo'], cwd=zephyr) @@ -1770,6 +1764,7 @@ def test_init_again(west_init_tmpdir): expected_msg = f'FATAL ERROR: already initialized in {west_init_tmpdir}' + # A bare `init` defaults to cloning -m http://zephyrproject/zephyr exc, stderr = cmd_raises('init', SystemExit, cwd=west_init_tmpdir) assert exc.value.code == 1 assert expected_msg in stderr @@ -1778,14 +1773,25 @@ def test_init_again(west_init_tmpdir): assert exc.value.code == 1 assert expected_msg in stderr + # Test --local and a manifest directory argument + _tmpdir_parts = Path(west_init_tmpdir).parts + for i in range(1, len(_tmpdir_parts) + 1): + _cd = Path(*_tmpdir_parts[0:i]) + assert _cd.exists() + _rel_top = Path(*_tmpdir_parts[i:]) + assert (_cd / _rel_top / '.west').exists() + exc, stderr = cmd_raises(['init', _rel_top / 'zephyr', '--local'], SystemExit, cwd=_cd) + assert exc.value.code == 1 + assert expected_msg in stderr + manifest = west_init_tmpdir / '..' / 'repos' / 'zephyr' exc, stderr = cmd_raises( f'-vvv init -m {manifest} workspace', RuntimeError, cwd=west_init_tmpdir.dirname ) assert expected_msg in stderr - expected_msg = "die with -vvv or more shows a stack trace. exit_code argument is ignored" - assert expected_msg in str(exc.value) + expected_vvv_msg = "die with -vvv or more shows a stack trace. exit_code argument is ignored" + assert expected_vvv_msg in str(exc.value) def test_init_local_manifest_project(repos_tmpdir): @@ -2643,7 +2649,6 @@ def test_import_project_release_fork(repos_tmpdir): }, ) - cmd(['init', '-l', manifest_repo]) with pytest.raises(ManifestImportFailed): Manifest.from_topdir(topdir=ws) @@ -2729,7 +2734,6 @@ def test_import_project_release_dir(tmpdir): }, ) - cmd(['init', '-l', manifest_repo]) with pytest.raises(ManifestImportFailed): Manifest.from_topdir(topdir=ws) @@ -2772,7 +2776,6 @@ def test_import_project_rolling(repos_tmpdir): }, ) - cmd(['init', '-l', manifest_repo]) with pytest.raises(ManifestImportFailed): Manifest.from_topdir(topdir=ws)