private PathSegment(string originalName, PathSegment parent) : this() { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(originalName)); Contract.Requires<ArgumentNullException>(parent != null); this.currentName = this.originalName = originalName; this.Parent = parent; this.minimized = false; }
/// <summary> /// Executes this instance. /// </summary> public override bool Execute() { if (this.DestinationTemplates.Length != this.SourceTemplates.Length) { this.Log.LogError("SourceTemplates array has length {0} while DestinationTemplates array has length {1}, but must equal.", this.SourceTemplates.Length, this.DestinationTemplates.Length); } if (this.SourceProjects.Length != this.SourceTemplates.Length) { this.Log.LogError("SourceTemplates array has length {0} while SourceProjects array has length {1}, but must equal.", this.SourceTemplates.Length, this.SourceProjects.Length); } var projectItemsToCopy = new List<ITaskItem>(); for (int iTemplate = 0; iTemplate < this.SourceTemplates.Length; iTemplate++) { ITaskItem sourceTemplateTaskItem = this.SourceTemplates[iTemplate]; var template = XElement.Load(sourceTemplateTaskItem.ItemSpec); var templateContentElement = template.Element(XName.Get("TemplateContent", VSTemplateNamespace)); var projectElement = templateContentElement.Element(XName.Get("Project", VSTemplateNamespace)); if (projectElement == null) { Log.LogMessage("Skipping merge of \"{0}\" with a project because no project was referenced from the template.", sourceTemplateTaskItem.ItemSpec); continue; } var projectPath = this.SourceProjects[iTemplate].ItemSpec; var projectDirectory = Path.GetDirectoryName(Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.GetMetadata("FullPath")), projectElement.Attribute("File").Value)); Log.LogMessage("Merging project \"{0}\" with \"{1}\".", projectPath, sourceTemplateTaskItem.ItemSpec); var sourceProject = new Project(); sourceProject.Load(projectPath); var projectItems = sourceProject.EvaluatedItems.Cast<BuildItem>().Where(item => this.ProjectItemTypes.Contains(item.Name)); // Figure out where every project item is in source, and where it will go in the destination, // taking into account a given maximum path length that may require that we shorten the path. PathSegment root = new PathSegment(); root.Add(projectItems.Select(item => item.Include)); root.EnsureSelfAndChildrenNoLongerThan(this.MaximumRelativePathLength); // Collect the project items from the project that are appropriate // to include in the .vstemplate file. foreach (var folder in root.SelfAndDescendents.Where(path => !path.IsLeaf && path.LeafChildren.Any())) { XElement parentNode = projectElement; parentNode = FindOrCreateParent(folder.CurrentPath, projectElement); if (folder.NameChanged) { parentNode.SetAttributeValue("TargetFolderName", folder.OriginalName); } foreach (var item in folder.LeafChildren) { var itemName = XName.Get("ProjectItem", VSTemplateNamespace); // The project item MAY be hard-coded in the .vstemplate file, under the original name. var projectItem = parentNode.Elements(itemName).FirstOrDefault(el => string.Equals(el.Value, Path.GetFileName(item.OriginalName), StringComparison.OrdinalIgnoreCase)); if (projectItem == null) { projectItem = new XElement(itemName, item.CurrentName); parentNode.Add(projectItem); } if (item.NameChanged) { projectItem.Value = item.CurrentName; // set Value in case it was a hard-coded item in the .vstemplate file. projectItem.SetAttributeValue("TargetFileName", item.OriginalName); } if (this.ReplaceParametersExtensions.Contains(Path.GetExtension(item.OriginalPath))) { projectItem.SetAttributeValue("ReplaceParameters", "true"); } } } template.Save(this.DestinationTemplates[iTemplate].ItemSpec); foreach (var pair in root.LeafDescendents) { TaskItem item = new TaskItem(Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath)); string apparentSource = Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath); var sourcePathException = this.SourcePathExceptions.FirstOrDefault(ex => string.Equals(ex.ItemSpec, apparentSource)); if (sourcePathException != null) { item.SetMetadata("SourceFullPath", sourcePathException.GetMetadata("ActualSource")); } else { item.SetMetadata("SourceFullPath", Path.GetFullPath(apparentSource)); } item.SetMetadata("DestinationFullPath", Path.GetFullPath(Path.Combine(Path.GetDirectoryName(this.DestinationTemplates[iTemplate].ItemSpec), pair.CurrentPath))); item.SetMetadata("RecursiveDir", Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec)); item.SetMetadata("Transform", this.ReplaceParametersExtensions.Contains(Path.GetExtension(pair.OriginalName)) ? "true" : "false"); projectItemsToCopy.Add(item); } } this.ProjectItems = projectItemsToCopy.ToArray(); return !Log.HasLoggedErrors; }
private PathSegment Add(string[] segments, int segmentIndex) { Contract.Requires<ArgumentNullException>(segments != null); Contract.Requires<ArgumentOutOfRangeException>(segmentIndex < segments.Length); Contract.Ensures(Contract.Result<PathSegment>() != null); var match = this.Children.SingleOrDefault(child => String.Equals(child.originalName, segments[segmentIndex])); if (match == null) { match = new PathSegment(segments[segmentIndex], this); this.Children.Add(match); } return segments.Length == segmentIndex + 1 ? match : match.Add(segments, segmentIndex + 1); }
/// <summary> /// Executes this instance. /// </summary> public override bool Execute() { if (this.DestinationTemplates.Length != this.SourceTemplates.Length) { this.Log.LogError("SourceTemplates array has length {0} while DestinationTemplates array has length {1}, but must equal.", this.SourceTemplates.Length, this.DestinationTemplates.Length); } if (this.SourceProjects.Length != this.SourceTemplates.Length) { this.Log.LogError("SourceTemplates array has length {0} while SourceProjects array has length {1}, but must equal.", this.SourceTemplates.Length, this.SourceProjects.Length); } var projectItemsToCopy = new List <ITaskItem>(); for (int iTemplate = 0; iTemplate < this.SourceTemplates.Length; iTemplate++) { ITaskItem sourceTemplateTaskItem = this.SourceTemplates[iTemplate]; var template = XElement.Load(sourceTemplateTaskItem.ItemSpec); var templateContentElement = template.Element(XName.Get("TemplateContent", VSTemplateNamespace)); var projectElement = templateContentElement.Element(XName.Get("Project", VSTemplateNamespace)); if (projectElement == null) { Log.LogMessage("Skipping merge of \"{0}\" with a project because no project was referenced from the template.", sourceTemplateTaskItem.ItemSpec); continue; } var projectPath = this.SourceProjects[iTemplate].ItemSpec; var projectDirectory = Path.GetDirectoryName(Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.GetMetadata("FullPath")), projectElement.Attribute("File").Value)); Log.LogMessage("Merging project \"{0}\" with \"{1}\".", projectPath, sourceTemplateTaskItem.ItemSpec); var sourceProject = new Project(); sourceProject.Load(projectPath); var projectItems = sourceProject.EvaluatedItems.Cast <BuildItem>().Where(item => this.ProjectItemTypes.Contains(item.Name)); // Figure out where every project item is in source, and where it will go in the destination, // taking into account a given maximum path length that may require that we shorten the path. PathSegment root = new PathSegment(); root.Add(projectItems.Select(item => item.Include)); root.EnsureSelfAndChildrenNoLongerThan(this.MaximumRelativePathLength); // Collect the project items from the project that are appropriate // to include in the .vstemplate file. foreach (var folder in root.SelfAndDescendents.Where(path => !path.IsLeaf && path.LeafChildren.Any())) { XElement parentNode = projectElement; parentNode = FindOrCreateParent(folder.CurrentPath, projectElement); if (folder.NameChanged) { parentNode.SetAttributeValue("TargetFolderName", folder.OriginalName); } foreach (var item in folder.LeafChildren) { var itemName = XName.Get("ProjectItem", VSTemplateNamespace); // The project item MAY be hard-coded in the .vstemplate file, under the original name. var projectItem = parentNode.Elements(itemName).FirstOrDefault(el => string.Equals(el.Value, Path.GetFileName(item.OriginalName), StringComparison.OrdinalIgnoreCase)); if (projectItem == null) { projectItem = new XElement(itemName, item.CurrentName); parentNode.Add(projectItem); } if (item.NameChanged) { projectItem.Value = item.CurrentName; // set Value in case it was a hard-coded item in the .vstemplate file. projectItem.SetAttributeValue("TargetFileName", item.OriginalName); } if (this.ReplaceParametersExtensions.Contains(Path.GetExtension(item.OriginalPath))) { projectItem.SetAttributeValue("ReplaceParameters", "true"); } } } template.Save(this.DestinationTemplates[iTemplate].ItemSpec); foreach (var pair in root.LeafDescendents) { TaskItem item = new TaskItem(Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath)); string apparentSource = Path.Combine(Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec), pair.OriginalPath); var sourcePathException = this.SourcePathExceptions.FirstOrDefault(ex => string.Equals(ex.ItemSpec, apparentSource)); if (sourcePathException != null) { item.SetMetadata("SourceFullPath", sourcePathException.GetMetadata("ActualSource")); } else { item.SetMetadata("SourceFullPath", Path.GetFullPath(apparentSource)); } item.SetMetadata("DestinationFullPath", Path.GetFullPath(Path.Combine(Path.GetDirectoryName(this.DestinationTemplates[iTemplate].ItemSpec), pair.CurrentPath))); item.SetMetadata("RecursiveDir", Path.GetDirectoryName(this.SourceTemplates[iTemplate].ItemSpec)); item.SetMetadata("Transform", this.ReplaceParametersExtensions.Contains(Path.GetExtension(pair.OriginalName)) ? "true" : "false"); projectItemsToCopy.Add(item); } } this.ProjectItems = projectItemsToCopy.ToArray(); return(!Log.HasLoggedErrors); }