-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Description
Some item operations explode the list. We have to provide alternative behavior that does not explode list.
The following comment is copy pasted from the evaluator:
///A ProjectItemElement could have resulted in several items if it contains wildcards or item or property expressions.
///Before any edit to a ProjectItem (remove, rename, set metadata, or remove metadata) this must be called to make
///sure that the edit does not affect any other ProjectItems originating in the same ProjectItemElement.
Project.SplitItemElementIfNecessary(ProjectItemElement itemElement)
Project.RemoveItem(ProjectItem) (1-2 weeks)
- Scenarios
- User deletes file via file system or via VS
- CPS reacts by calling RemoveItem on all ProjectItems with that value
- User deletes file via file system or via VS
- The current Project.RemoveItem(ProjectItem)
- Removes item inside the Include attribute
- Explodes the item tag if it evaluated to multiple items
- Modifications to not explode
- If Include contains only (globs and literal strings)
- If item is covered by glob, then don't do anything
- If item is covered by literal list, remove all the literals that have the same value as the item to remove
- Extra credit for removing literals that have properties inside of them (Include="foo$(prop)")
- Else (items and properties present: Include="*.a;@(AnItem);$(AProperty);3.a;2.a;3.a")
- Option1
- Apply previous behavior (explode)
- Justification
- If you don't explode and add an exclude, csproj becomes bloated over time as the user deletes elements
- CPS should call RemoveItem on the correct item tags (e.g. call RemoveItem on tags that reference the item directly via globs / literals, and not on the tags that indirectly reference that item)
- Option2
- Split the item tag in 2 tags:
- A tag with just the globs and the literals, and then recursivelly call RemoveItem on this tag
- A tag with the indirect references and add the item to remove in the exclude
- Split the item tag in 2 tags:
- Option3
- Split the item tag in more tags:
- A tag with just the globs and the literals, and then recursivelly call RemoveItem on this tag
- Explode the items coming from indirect references
- Split the item tag in more tags:
- Option1
- If Include contains only (globs and literal strings)
Add Exclude for Item (1 week) - CPS currently has own implementation. We could add our own so they don't have to implement it
- Scenarios
- User wants to exclude a file from the build
- CPS wants to add an exclude to implement project model semantics
- Inputs
- Overload1
- Item - the ProjectItem whose underlying ProjectItemElement needs to have the exclude applied to
- Overload2
- Element - the ProjectItemElement to append the exclude on
- directoryToIgnore - full path to a directory to ignore. The exclude attribute gets appended with "directoryToIgnore//."
- Overload1
- Returns
- Same implementation as RemoveItem: true if item was present in the project
- Remarks
- Edits the underlying xml for the specified item to exclude the item's evaluated value / directory
- Does not do anything if the exclude tag already has an exclude containing it
//exclude a single file, and you know it's corresponding ProjectItem
bool ExcludeItem(ProjectItem item)
//exclude a whole directory, and you know the corresponding ProjectItemElement where to add the exclude
bool ExcludeItem(ProjectItemElement element, string directoryToIgnore)ProjectItem.(Set|Remove)metadata (TODO)
In the presence of globs, the new Item Update attribute should be used instead of these.
ProjectItem.Rename (~1-2 weeks)
- Modifications to not explode
- If Include contains only (globs and literal strings)
- Same as remove, but rename literals instead of delete.
- [?] what to do if old name is in glob but new name is not in glob?
- Option1: Add the new name that is not in glob as a literal
- Option2: don't do anything
- [?] what to do if literal incorporates a property
- Don't do anything
- Raise exception
- Explode the item out and rename, potentially breaking the build logic
- Else (items and properties present: Include="*.a;@(AnItem);$(AProperty);3.a;2.a;3.a")
- Option1 from RemoveItem
- Apply previous behavior (explode)
- Justification
- If you don't explode and add an exclude, csproj becomes bloated over time as the user deletes elements
- CPS should call RemoveItem on the correct item tags (e.g. call RemoveItem on tags that reference the item directly via globs / literals, and not on the tags that indirectly reference that item)
- Option3 from RemoveItem
- Split the item tag in more tags:
- A tag with just the globs and the literals, and then recursively call Rename on this tag
- Explode the items coming from indirect references and rename
- Split the item tag in more tags:
- Option1 from RemoveItem
- If Include contains only (globs and literal strings)
Project.AddItem (TODO)
- Only works (does not explode) when:
- the existing item or item group has no condition
- the existing item tag has no excludes
- neither the item nor the considered item tag have metadata
Flag to propagate item operations instead of exploding (2 weeks)
- [?] do we want this?
- Recursively propagate the above operations on indirect references
- act on glob and literal lists
- Recursivelycall the same operation on referenced items
- explode referenced properties
- Do string magic inside the properties. Recursively, since properties can reference each other.