Esempio n. 1
0
		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;
		}
Esempio n. 3
0
		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);
        }