@@ -538,3 +538,105 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
custom_setup_dir = 'special-setup-dir-with-cmdline-overrides'
out = self.runbbsetup("init --non-interactive -L test-repo {} --setup-dir-name {} test-config-1 gadget".format(self.testrepopath, custom_setup_dir))
_check_local_sources(custom_setup_dir)
+
+ def test_vscode(self):
+ if 'BBPATH' in os.environ:
+ del os.environ['BBPATH']
+ os.chdir(self.tempdir)
+
+ self.runbbsetup("settings set default registry 'git://{};protocol=file;branch=master;rev=master'".format(self.registrypath))
+ self.add_file_to_testrepo('test-file', 'initial\n')
+ self.add_json_config_to_registry('test-config-1.conf.json', 'master', 'master')
+
+ # --init-vscode should create bitbake.code-workspace
+ self.runbbsetup("init --non-interactive --init-vscode test-config-1 gadget")
+ setuppath = self.get_setup_path('test-config-1', 'gadget')
+ workspace_file = os.path.join(setuppath, 'bitbake.code-workspace')
+ self.assertTrue(os.path.exists(workspace_file),
+ "bitbake.code-workspace should be created with --init-vscode")
+
+ with open(workspace_file) as f:
+ workspace = json.load(f)
+
+ # top-level structure
+ self.assertIn('folders', workspace)
+ self.assertIn('settings', workspace)
+ self.assertIn('extensions', workspace)
+ self.assertIn('yocto-project.yocto-bitbake',
+ workspace['extensions']['recommendations'])
+
+ # folders: conf dir + test-repo (symlinks like oe-init-build-env-dir are skipped)
+ folder_names = {f['name'] for f in workspace['folders']}
+ self.assertIn('conf', folder_names)
+ self.assertIn('test-repo', folder_names)
+
+ # folder paths must be relative so the workspace is portable
+ for f in workspace['folders']:
+ self.assertFalse(os.path.isabs(f['path']),
+ "Folder path should be relative, got: {}".format(f['path']))
+
+ # bitbake extension settings
+ settings = workspace['settings']
+ self.assertTrue(settings.get('bitbake.disableConfigModification'))
+ self.assertEqual(settings['bitbake.pathToBuildFolder'],
+ os.path.join(setuppath, 'build'))
+ self.assertEqual(settings['bitbake.pathToEnvScript'],
+ os.path.join(setuppath, 'build', 'init-build-env'))
+
+ # file associations
+ self.assertIn('*.conf', settings.get('files.associations', {}))
+ self.assertIn('*.inc', settings.get('files.associations', {}))
+
+ # python extra paths: test-repo/scripts/ exists and should be listed
+ extra_paths = settings.get('python.analysis.extraPaths', [])
+ self.assertTrue(any('scripts' in p for p in extra_paths),
+ "python.analysis.extraPaths should include the scripts dir")
+ self.assertEqual(settings.get('python.analysis.extraPaths'),
+ settings.get('python.autoComplete.extraPaths'))
+
+ # --no-init-vscode should NOT create a workspace file
+ self.runbbsetup("init --non-interactive --no-init-vscode test-config-1 gadget-notemplate")
+ notemplate_path = self.get_setup_path('test-config-1', 'gadget-notemplate')
+ self.assertFalse(
+ os.path.exists(os.path.join(notemplate_path, 'bitbake.code-workspace')),
+ "bitbake.code-workspace should not be created with --no-init-vscode")
+
+ # update with --init-vscode after a layer change should preserve
+ # user-added folders and settings while still rewriting managed ones
+ workspace['folders'].append({"name": "user-folder", "path": "user/custom"})
+ workspace['settings']['my.user.setting'] = 'preserved'
+ with open(workspace_file, 'w') as f:
+ json.dump(workspace, f, indent=4)
+
+ self.add_file_to_testrepo('test-file', 'updated\n')
+ os.environ['BBPATH'] = os.path.join(setuppath, 'build')
+ self.runbbsetup("update --update-bb-conf='no' --init-vscode")
+ del os.environ['BBPATH']
+
+ with open(workspace_file) as f:
+ updated = json.load(f)
+ self.assertIn('user/custom', {f['path'] for f in updated['folders']},
+ "User-added folder was removed during update")
+ self.assertIn('my.user.setting', updated['settings'],
+ "User-added setting was removed during update")
+
+ # update with a corrupt workspace file should log an error and leave it unchanged
+ self.add_file_to_testrepo('test-file', 'updated-again\n')
+ with open(workspace_file, 'w') as f:
+ f.write('{invalid json')
+ os.environ['BBPATH'] = os.path.join(setuppath, 'build')
+ self.runbbsetup("update --update-bb-conf='no' --init-vscode")
+ del os.environ['BBPATH']
+ with open(workspace_file) as f:
+ content = f.read()
+ self.assertEqual(content, '{invalid json',
+ "Corrupt workspace file should not be modified")
+
+ # update with --init-vscode when nothing has changed should still
+ # regenerate the workspace file (e.g. after manual deletion)
+ os.remove(workspace_file)
+ os.environ['BBPATH'] = os.path.join(setuppath, 'build')
+ self.runbbsetup("update --update-bb-conf='no' --init-vscode")
+ del os.environ['BBPATH']
+ self.assertTrue(os.path.exists(workspace_file),
+ "bitbake.code-workspace should be recreated by update --init-vscode even when nothing changed")