public static string GetLogicalPath(this IItemContainer item, IItemContainer ancestor) { var itemPath = item.GetLogicalPath(); var ancestorPath = ancestor.GetLogicalPath(); //Ensure the ancestor is valid if (itemPath.StartsWith(ancestorPath, StringComparison.OrdinalIgnoreCase)) { return(itemPath.Substring(ancestorPath.Length + 1)); } // not related to ancestor return(itemPath); }
public static IItem GetToolkitManifest(this IItemContainer element) { Guard.NotNull(() => element, element); var owningProject = (IProject)element.Traverse(x => x.Parent, item => item.Kind == ItemKind.Project); if (owningProject == null) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, Resources.SolutionExtensions_ItemNotInProject, element.GetLogicalPath())); } return(owningProject.GetToolkitManifest()); }
/// <summary> /// Transforms the template and adds the content with the given name to the specified parent. /// </summary> public IItemContainer Unfold(string name, IItemContainer parent) { Guard.NotNull(() => parent, parent); Guard.NotNullOrEmpty(() => name, name); //var sessionHost = this.templating as ITextTemplatingSessionHost; using (tracer.StartActivity(Resources.TextTemplate_TraceStartUnfold, this.templateFile, parent.GetLogicalPath())) { this.templating.BeginErrorSession(); try { // TODO: add support for parameters. //foreach (var parameter in Parameters) //{ // sessionHost.Session[parameter.Name] = parameter.GetTypedValue(); //} var callback = new TemplateCallback(tracer, templateFile); var content = this.templating.ProcessTemplate(templateFile, templateContent, callback); var targetName = name; if (!Path.HasExtension(targetName)) { targetName = targetName + callback.FileExtension; } // BUGFIX: FBRT does not checkout the file, if SCC. var targetItem = parent.Find<IItem>(targetName).FirstOrDefault(); if (targetItem != null) { targetItem.Checkout(); } using (new TempFileCleaner()) { // HACK: \o/ feature runtime VsFileContentTemplate creates a temp file and // doesn't delete it, so we go FSW to detect it. return parent.AddContent(content, targetName, true, false, callback.OutputEncoding); } } finally { this.templating.EndErrorSession(); } } }
/// <summary> /// Runs the configured template data against the element. /// </summary> public override void Execute() { //tracer.TraceData(TraceEventType.Verbose, Resources.GenerateProductCodeCommand_StartedEvent, this.CurrentElement); // Note: we are NOT doing this.ValidateObject() thing here as we are setting the base class // properties ourselves. This will be a problem if this is automatically validated by the runtime. if (this.PatternManager != null) { if (!this.PatternManager.IsOpen) { throw new InvalidOperationException(Resources.GenerateProductCodeCommand_PatternManagerNotOpen); } this.ModelFile = this.PatternManager.StoreFile; tracer.Info( Resources.GenerateProductCodeCommand_TraceModelFile, this.ModelFile); } this.ModelElement = this.CurrentElement as ModelElement; Guard.NotNull(() => this.Settings, this.Settings); IItemContainer existingArtifact = null; var originalTargetFilename = this.TargetFileName; // If there is an existing artifact that we can resolve, override the configured settings and // reuse that one instead. var existingArtifactLink = SolutionArtifactLinkReference .GetReferenceValues(this.CurrentElement, r => GetIdFromReferenceTag(r) == this.Settings.Id) .FirstOrDefault(); if (existingArtifactLink != null) { // Try to locate the existing solution item existingArtifact = this.UriService.TryResolveUri <IItemContainer>(existingArtifactLink); if (existingArtifact != null) { // If the item exists, then we'll override the configured paths to point // to the located element. this.TargetPath = existingArtifact.Parent.GetLogicalPath(); this.TargetFileName = existingArtifact.Name; tracer.Verbose( Resources.GenerateProductCodeCommand_Trace_ExistingArtifactUsed, existingArtifact.GetLogicalPath()); } else { // Otherwise, we'll use the configured path and filename. tracer.Info(Resources.GenerateProductCodeCommand_Trace_ExistingArtifactUriNotFound, existingArtifactLink); } } //Re-evaluate all properties of current element RefreshProvidedValues(); // Generate the file according to current settings and porperty values base.Execute(); //Restore targetfilename if (existingArtifactLink != null) { if (existingArtifact != null) { this.TargetFileName = originalTargetFilename; } } // If an item was generated if (this.GeneratedItem != null) { tracer.Verbose( Resources.GenerateProductCodeCommand_Trace_GeneratedArtifact, this.GeneratedItem.GetLogicalPath()); // Add new artifact link if (existingArtifactLink == null) { // Add the new link and set the tag to our settings, so that we know // it's the link generated by this command instance. var newLink = this.UriService.CreateUri(this.GeneratedItem); SolutionArtifactLinkReference .AddReference(this.CurrentElement, newLink) .Tag = BindingSerializer.Serialize(new ReferenceTag { Tag = this.Tag ?? string.Empty, SyncNames = this.SyncName, TargetFileName = this.TargetFileName, Id = this.Settings.Id }); tracer.Verbose( Resources.GenerateProductCodeCommand_Trace_NewArtifactLinkAdded, newLink); } else { // Update existing artifact link // If existing artifact was not found (perhaps its now deleted), a new // link will be generated for the newly added item, so we must update the existing reference. if (existingArtifact == null) { var newLink = this.UriService.CreateUri(this.GeneratedItem); var reference = this.CurrentElement.References.First(r => GetIdFromReferenceTag(r) == Settings.Id); SolutionArtifactLinkReference.SetReference(reference, newLink); tracer.Verbose( Resources.GenerateProductCodeCommand_Trace_UpdatedExistingArtifactLink, newLink); } else { // Existing artifact found if (this.SyncName) { // Must rename the file to the new filename, (paths remains the same) // Recalculate the filename var resolver = new PathResolver(this.ModelElement, this.UriService, this.TargetPath, (!string.IsNullOrEmpty(this.TargetFileName)) ? this.TargetFileName : ((IProductElement)this.ModelElement).InstanceName); resolver.Resolve(); var proposedItemName = resolver.FileName; if (this.SanitizeName) { proposedItemName = SanitizeItemName(proposedItemName); } // Rename file if different name now (taking into account whether extension is specified in TargetFileName or not) if (!proposedItemName.Equals( (string.IsNullOrEmpty(Path.GetExtension(proposedItemName))) ? Path.GetFileNameWithoutExtension(this.GeneratedItem.Name) : this.GeneratedItem.Name, StringComparison.OrdinalIgnoreCase)) { tracer.Info( Resources.GenerateProductCodeCommand_TraceRenameSolutionItem, this.GeneratedItem.Name, proposedItemName); var uiService = (IVsUIShell)this.ServiceProvider.GetService(typeof(IVsUIShell)); var newItemName = this.GeneratedItem.Rename(proposedItemName, true, uiService); tracer.Info( Resources.GenerateProductCodeCommand_TraceSolutionItemRenamed, this.GeneratedItem.Name, newItemName); } } } } } }
/// <summary> /// Transforms the template and adds the content with the given name to the specified parent. /// </summary> public IItemContainer Unfold(string name, IItemContainer parent) { Guard.NotNull(() => parent, parent); Guard.NotNullOrEmpty(() => name, name); //var sessionHost = this.templating as ITextTemplatingSessionHost; using (tracer.StartActivity(Resources.TextTemplate_TraceStartUnfold, this.templateFile, parent.GetLogicalPath())) { this.templating.BeginErrorSession(); try { // TODO: add support for parameters. //foreach (var parameter in Parameters) //{ // sessionHost.Session[parameter.Name] = parameter.GetTypedValue(); //} var callback = new TemplateCallback(tracer, templateFile); var content = this.templating.ProcessTemplate(templateFile, templateContent, callback); var targetName = name; if (!Path.HasExtension(targetName)) { targetName = targetName + callback.FileExtension; } // BUGFIX: FBRT does not checkout the file, if SCC. var targetItem = parent.Find <IItem>(targetName).FirstOrDefault(); if (targetItem != null) { targetItem.Checkout(); } using (new TempFileCleaner()) { // HACK: \o/ feature runtime VsFileContentTemplate creates a temp file and // doesn't delete it, so we go FSW to detect it. return(parent.AddContent(content, targetName, true, false, callback.OutputEncoding)); } } finally { this.templating.EndErrorSession(); } } }
private void SetArtifactLink(UnfoldScope scope) { var container = scope.Automation.Owner; // Determine created item IItemContainer createdItem = null; createdItem = this.Solution.Find <IProject>(p => p.PhysicalPath == this.projectCreated).SingleOrDefault(); if (createdItem == null) { createdItem = this.Solution.Find <IItem>(pi => pi.PhysicalPath == this.projectItemCreated).SingleOrDefault(); } if (createdItem != null) { if (this.UriService.CanCreateUri <IItemContainer>(createdItem)) { // Set the artifact link SolutionArtifactLinkReference .SetReference(container, this.UriService.CreateUri <IItemContainer>(createdItem)) .Tag = BindingSerializer.Serialize(scope.ReferenceTag); } else { tracer.Warn(Properties.Resources.InstantiationTemplateWizard_CantCreateUri, createdItem.GetLogicalPath()); } } }
private void SyncGeneratedProjectFiles(IDictionary <string, string> generatedFiles, string sourceFolderPath, IItemContainer targetContainer) { var targetContainerPath = targetContainer.GetLogicalPath(); tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingExcludedFiles, targetContainer.GetLogicalPath()); // Ensure that all (*.MHT) files on the disk are included the targetContainer var targetContainerFiles = Directory.GetFiles(targetContainer.PhysicalPath, GeneratedFileExtensionFilter); foreach (var targetContainerFile in targetContainerFiles) { var projectItem = targetContainer.Find <IItem>(targetContainerFile).FirstOrDefault(); if (projectItem == null) { // Add existing file to project (SCC handles the 'Add' automatically) tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingExcludedFile, targetContainerFile, targetContainerPath); targetContainer.Add(targetContainerFile); } } tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingNewFiles, targetContainer.GetLogicalPath()); // Copy all generated files to project (overwrite existing) foreach (var generatedFile in generatedFiles) { var generatedFileName = generatedFile.Key; var targetContainerItem = targetContainer.Find <IItem>(generatedFileName).FirstOrDefault(); if (targetContainerItem == null) { // Add new file to project (SCC Handles the 'Add' automatically) tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingNewFile, generatedFileName, targetContainerPath); targetContainer.Add(Path.Combine(sourceFolderPath, generatedFileName)); } else { // SCC 'Checkout' existing file (or make writable), and copy file to disk location tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceOverwriteExistingFile, generatedFileName, targetContainerPath); targetContainerItem.Checkout(); File.Copy(Path.Combine(sourceFolderPath, generatedFileName), Path.Combine(targetContainer.PhysicalPath, generatedFileName), true); } } // Remove any non-current items var itemsToDelete = new List <string>(); var targetContainerItems = targetContainer.Items.OfType <IItem>(); foreach (var targetContainerItem in targetContainerItems) { if (!generatedFiles.ContainsKey(targetContainerItem.Name)) { itemsToDelete.Add(targetContainerItem.Name); } else { // Ensure build properties tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceSettingBuildAction, targetContainerItem.Name, targetContainerPath); targetContainerItem.Data.ItemType = BuildAction.Content.ToString(); targetContainerItem.Data.IncludeInVSIX = Boolean.TrueString.ToLowerInvariant(); } } tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceDeleteSuperfluousFiles, targetContainer.GetLogicalPath()); if (itemsToDelete.Any()) { foreach (var item in itemsToDelete) { tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceDeleteSuperfluousFile, item, targetContainerPath); var itemToDelete = targetContainer.Find <IItem>(item).FirstOrDefault(); if (itemToDelete != null) { itemToDelete.Delete(); } } } }
private void SyncGeneratedProjectFiles(IDictionary<string, string> generatedFiles, string sourceFolderPath, IItemContainer targetContainer) { var targetContainerPath = targetContainer.GetLogicalPath(); tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingExcludedFiles, targetContainer.GetLogicalPath()); // Ensure that all (*.MHT) files on the disk are included the targetContainer var targetContainerFiles = Directory.GetFiles(targetContainer.PhysicalPath, GeneratedFileExtensionFilter); foreach (var targetContainerFile in targetContainerFiles) { var projectItem = targetContainer.Find<IItem>(targetContainerFile).FirstOrDefault(); if (projectItem == null) { // Add existing file to project (SCC handles the 'Add' automatically) tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingExcludedFile, targetContainerFile, targetContainerPath); targetContainer.Add(targetContainerFile); } } tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingNewFiles, targetContainer.GetLogicalPath()); // Copy all generated files to project (overwrite existing) foreach (var generatedFile in generatedFiles) { var generatedFileName = generatedFile.Key; var targetContainerItem = targetContainer.Find<IItem>(generatedFileName).FirstOrDefault(); if (targetContainerItem == null) { // Add new file to project (SCC Handles the 'Add' automatically) tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceAddingNewFile, generatedFileName, targetContainerPath); targetContainer.Add(Path.Combine(sourceFolderPath, generatedFileName)); } else { // SCC 'Checkout' existing file (or make writable), and copy file to disk location tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceOverwriteExistingFile, generatedFileName, targetContainerPath); targetContainerItem.Checkout(); File.Copy(Path.Combine(sourceFolderPath, generatedFileName), Path.Combine(targetContainer.PhysicalPath, generatedFileName), true); } } // Remove any non-current items var itemsToDelete = new List<string>(); var targetContainerItems = targetContainer.Items.OfType<IItem>(); foreach (var targetContainerItem in targetContainerItems) { if (!generatedFiles.ContainsKey(targetContainerItem.Name)) { itemsToDelete.Add(targetContainerItem.Name); } else { // Ensure build properties tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceSettingBuildAction, targetContainerItem.Name, targetContainerPath); targetContainerItem.Data.ItemType = BuildAction.Content.ToString(); targetContainerItem.Data.IncludeInVSIX = Boolean.TrueString.ToLowerInvariant(); } } tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceDeleteSuperfluousFiles, targetContainer.GetLogicalPath()); if (itemsToDelete.Any()) { foreach (var item in itemsToDelete) { tracer.Info( Resources.CreateGuidanceDocumentsCommand_TraceDeleteSuperfluousFile, item, targetContainerPath); var itemToDelete = targetContainer.Find<IItem>(item).FirstOrDefault(); if (itemToDelete != null) { itemToDelete.Delete(); } } } }