... |
... |
@@ -143,8 +143,38 @@ class WorkspaceProject(): |
143
|
143
|
# element_name (str): The name of the element that the workspace belongs to.
|
144
|
144
|
#
|
145
|
145
|
def add_project(self, project_path, element_name):
|
146
|
|
- assert (project_path and element_name)
|
147
|
|
- self._projects.append({'project-path': project_path, 'element-name': element_name})
|
|
146
|
+ # TODO: Decide whether to raise an exception if the project already exists.
|
|
147
|
+ project = {'project-path': project_path, 'element-name': element_name}
|
|
148
|
+ if project not in self._projects:
|
|
149
|
+ self._projects.append(project)
|
|
150
|
+
|
|
151
|
+ # set_project()
|
|
152
|
+ #
|
|
153
|
+ # Sets the project to only contain the project_path and element_name specified.
|
|
154
|
+ #
|
|
155
|
+ # Args:
|
|
156
|
+ # project_path (str): the path to the project that opened the workspace.
|
|
157
|
+ # element_name (str): the name of the element that the workspace belongs to.
|
|
158
|
+ #
|
|
159
|
+ def set_project(self, project_path, element_name):
|
|
160
|
+ self._projects = [{'project-path': project_path, 'element-name': element_name}]
|
|
161
|
+
|
|
162
|
+ # remove_project()
|
|
163
|
+ #
|
|
164
|
+ # Removes the first project entry that matches the project_path and element_name
|
|
165
|
+ def remove_project(self, project_path, element_name):
|
|
166
|
+ # NOTE: This will need revisiting if projects' data format changes
|
|
167
|
+ # TODO: Figure out what to do if there is no project for those parameters
|
|
168
|
+ self._projects.remove({'project-path': project_path, 'element-name': element_name})
|
|
169
|
+
|
|
170
|
+ # has_projects()
|
|
171
|
+ #
|
|
172
|
+ # Returns whether there are any projects in this WorkspaceProject
|
|
173
|
+ #
|
|
174
|
+ # Returns:
|
|
175
|
+ # (bool): True if there are any projects, or False if there aren't any
|
|
176
|
+ def has_projects(self):
|
|
177
|
+ return any(self._projects)
|
148
|
178
|
|
149
|
179
|
|
150
|
180
|
# WorkspaceProjectCache()
|
... |
... |
@@ -186,17 +216,21 @@ class WorkspaceProjectCache(): |
186
|
216
|
# directory (str): The directory to search for a WorkspaceProject.
|
187
|
217
|
# project_path (str): The path to the project that refers to this workspace
|
188
|
218
|
# element_name (str): The element in the project that was refers to this workspace
|
|
219
|
+ # append (bool): Whether the project_path and element_name should be appended
|
189
|
220
|
#
|
190
|
221
|
# Returns:
|
191
|
222
|
# (WorkspaceProject): The WorkspaceProject that was found for that directory.
|
192
|
223
|
#
|
193
|
|
- def add(self, directory, project_path, element_name):
|
|
224
|
+ def add(self, directory, project_path, element_name, *, append):
|
194
|
225
|
workspace_project = self.get(directory)
|
195
|
226
|
if not workspace_project:
|
196
|
227
|
workspace_project = WorkspaceProject(directory)
|
197
|
228
|
self._projects[directory] = workspace_project
|
198
|
229
|
|
199
|
|
- workspace_project.add_project(project_path, element_name)
|
|
230
|
+ if append:
|
|
231
|
+ workspace_project.add_project(project_path, element_name)
|
|
232
|
+ else:
|
|
233
|
+ workspace_project.set_project(project_path, element_name)
|
200
|
234
|
return workspace_project
|
201
|
235
|
|
202
|
236
|
# remove()
|
... |
... |
@@ -210,17 +244,26 @@ class WorkspaceProjectCache(): |
210
|
244
|
#
|
211
|
245
|
# Args:
|
212
|
246
|
# directory (str): The directory to search for a WorkspaceProject.
|
|
247
|
+ # project_path (str): the path to the project that should be removed.
|
|
248
|
+ # element_name (str): the name of the element in the project that should be removed.
|
213
|
249
|
#
|
214
|
|
- def remove(self, directory):
|
|
250
|
+ def remove(self, directory, project_path, element_name):
|
215
|
251
|
workspace_project = self.get(directory)
|
216
|
252
|
if not workspace_project:
|
217
|
253
|
raise LoadError(LoadErrorReason.MISSING_FILE,
|
218
|
254
|
"Failed to find a {} file to remove".format(WORKSPACE_PROJECT_FILE))
|
219
|
|
- path = workspace_project.get_filename()
|
220
|
|
- try:
|
221
|
|
- os.unlink(path)
|
222
|
|
- except FileNotFoundError:
|
223
|
|
- pass
|
|
255
|
+
|
|
256
|
+ workspace_project.remove_project(project_path, element_name)
|
|
257
|
+
|
|
258
|
+ if workspace_project.has_projects():
|
|
259
|
+ workspace_project.write()
|
|
260
|
+ else:
|
|
261
|
+ # Remove the WorkspaceProject file if it's now empty
|
|
262
|
+ path = workspace_project.get_filename()
|
|
263
|
+ try:
|
|
264
|
+ os.unlink(path)
|
|
265
|
+ except FileNotFoundError:
|
|
266
|
+ pass
|
224
|
267
|
|
225
|
268
|
|
226
|
269
|
# Workspace()
|
... |
... |
@@ -429,8 +472,10 @@ class Workspaces(): |
429
|
472
|
# target (Element) - The element to create a workspace for
|
430
|
473
|
# path (str) - The path in which the workspace should be kept
|
431
|
474
|
# checkout (bool): Whether to check-out the element's sources into the directory
|
|
475
|
+ # append (bool): Whether the WorkspaceProject file should append this project
|
|
476
|
+ # preserve_workspace_project (bool): Whether the WorkspaceProject should be altered
|
432
|
477
|
#
|
433
|
|
- def create_workspace(self, target, path, *, checkout):
|
|
478
|
+ def create_workspace(self, target, path, *, checkout, append, preserve_workspace_project=False):
|
434
|
479
|
element_name = target._get_full_name()
|
435
|
480
|
project_dir = self._toplevel_project.directory
|
436
|
481
|
if path.startswith(project_dir):
|
... |
... |
@@ -444,7 +489,11 @@ class Workspaces(): |
444
|
489
|
with target.timed_activity("Staging sources to {}".format(path)):
|
445
|
490
|
target._open_workspace()
|
446
|
491
|
|
447
|
|
- workspace_project = self._workspace_project_cache.add(path, project_dir, element_name)
|
|
492
|
+ if preserve_workspace_project:
|
|
493
|
+ workspace_project = self._workspace_project_cache.get(path)
|
|
494
|
+ else:
|
|
495
|
+ workspace_project = self._workspace_project_cache.add(path, project_dir, element_name, append=append)
|
|
496
|
+
|
448
|
497
|
project_file_path = workspace_project.get_filename()
|
449
|
498
|
|
450
|
499
|
if os.path.exists(project_file_path):
|
... |
... |
@@ -469,6 +518,21 @@ class Workspaces(): |
469
|
518
|
return None
|
470
|
519
|
return self._workspaces[element_name]
|
471
|
520
|
|
|
521
|
+ # get_workspace_project()
|
|
522
|
+ #
|
|
523
|
+ # Returns a WorkspaceProject for a given directory, retrieving from the cache if
|
|
524
|
+ # present.
|
|
525
|
+ #
|
|
526
|
+ # Args:
|
|
527
|
+ # directory (str): The directory to search for a WorkspaceProject.
|
|
528
|
+ #
|
|
529
|
+ # Returns:
|
|
530
|
+ # (WorkspaceProject): The WorkspaceProject that was found for that directory.
|
|
531
|
+ # or (NoneType): None, if no WorkspaceProject can be found.
|
|
532
|
+ #
|
|
533
|
+ def get_workspace_project(self, directory):
|
|
534
|
+ return self._workspace_project_cache.get(directory)
|
|
535
|
+
|
472
|
536
|
# update_workspace()
|
473
|
537
|
#
|
474
|
538
|
# Update the datamodel with a new Workspace instance
|
... |
... |
@@ -498,20 +562,23 @@ class Workspaces(): |
498
|
562
|
#
|
499
|
563
|
# Args:
|
500
|
564
|
# element_name (str) - The element name whose workspace to delete
|
|
565
|
+ # preserve_workspace_project (bool): Whether the WorkspaceProject should be altered
|
501
|
566
|
#
|
502
|
|
- def delete_workspace(self, element_name):
|
|
567
|
+ def delete_workspace(self, element_name, preserve_workspace_project=False):
|
503
|
568
|
workspace = self.get_workspace(element_name)
|
504
|
569
|
del self._workspaces[element_name]
|
505
|
570
|
|
506
|
|
- # Remove from the cache if it exists
|
507
|
|
- try:
|
508
|
|
- self._workspace_project_cache.remove(workspace.get_absolute_path())
|
509
|
|
- except LoadError as e:
|
510
|
|
- # We might be closing a workspace with a deleted directory
|
511
|
|
- if e.reason == LoadErrorReason.MISSING_FILE:
|
512
|
|
- pass
|
513
|
|
- else:
|
514
|
|
- raise
|
|
571
|
+ if not preserve_workspace_project:
|
|
572
|
+ # Remove from the cache if it exists
|
|
573
|
+ project_dir = self._toplevel_project.directory
|
|
574
|
+ try:
|
|
575
|
+ self._workspace_project_cache.remove(workspace.get_absolute_path(), project_dir, element_name)
|
|
576
|
+ except LoadError as e:
|
|
577
|
+ # We might be closing a workspace with a deleted directory
|
|
578
|
+ if e.reason == LoadErrorReason.MISSING_FILE:
|
|
579
|
+ pass
|
|
580
|
+ else:
|
|
581
|
+ raise
|
515
|
582
|
|
516
|
583
|
# save_config()
|
517
|
584
|
#
|