private void WritePkgDef(VsixProperties props, Logger l) { var content = string.Format(_pkgDefTemplate, props.Id); var path = Path.Combine(_rootDir, "template.pkgdef"); File.WriteAllText(path, content); }
public static VsixProject Create(string rootDir, VsixProperties props, Logger l) { var vsixProject = _vsixProjectTemplate.Value; var doc = XDocument.Parse(vsixProject); var project = new VsixProject(rootDir, doc); project.WriteManifest(props, l); project.WritePkgDef(props, l); return(project); }
public static async Task <int> PackVsix( string source, string vsix, bool force, string obj, string vsixVersion, string moreInfo, string licenseFile, string releaseNotes, string packageIcon, string previewImg, string[] packageTags, string gettingStarted, string[] templateIcon, string[] languageTag, string[] platformTags, string[] typeTags, string[] defaultName) { var l = new Logger(); if (source is null) { l.LogError("No source file given. Pass --help to show help text."); return(1); } if (!File.Exists(source)) { l.LogError($"Source file '{source}' does not exist."); return(1); } l.Log($"Generating VSIX template package for '{source}'."); var templateIconMappings = templateIcon?.Select(s => new TemplatePropertyMapping(s)); var languageTagMappings = languageTag?.Select(s => new TemplatePropertyMapping(s)); var platformTagsMappings = platformTags?.Select(s => new TemplatePropertyMapping(s)); var typeTagsMappings = typeTags?.Select(s => new TemplatePropertyMapping(s)); var defaultNameMappings = defaultName?.Select(s => new TemplatePropertyMapping(s)); l.Log("Parsing NuGet metadata."); var pkg = await NuPackage.Open(source); var metadata = pkg.Metadata; var vsixProps = VsixProperties.FromNuspec(metadata); var sourceFolder = Path.GetDirectoryName(source); vsix = vsix ?? Path.Combine(sourceFolder, vsixProps.Id + ".vsix"); if (File.Exists(vsix) && !force) { l.LogError($"File exists at output path '{vsix}'. Set the --force flag to overwrite it."); return(1); } if (vsixVersion != null) { vsixProps.Version = vsixVersion; } if (moreInfo != null) { vsixProps.MoreInfo = moreInfo; } if (licenseFile != null) { vsixProps.License = licenseFile; } if (releaseNotes != null) { vsixProps.ReleaseNotes = releaseNotes; } if (packageIcon != null) { vsixProps.Icon = packageIcon; } if (previewImg != null) { vsixProps.PreviewImage = previewImg; } if (packageTags != null) { var splitPackageTags = packageTags.SelectMany(ts => ts.Split(new char[0], StringSplitOptions.RemoveEmptyEntries)); vsixProps.Tags = string.Join(';', splitPackageTags); } if (gettingStarted != null) { vsixProps.GettingStartedGuide = gettingStarted; } var archive = pkg.Archive; var templateJsonFiles = archive.Entries.Where(e => e.FullName.EndsWith(".template.config/template.json")); l.Log("Generating .vstemplate files."); var templateContexts = new List <TemplateContext>(); foreach (var templateJsonFile in templateJsonFiles) { var templateJsonContent = new StreamReader(templateJsonFile.Open()).ReadToEnd(); // TODO apply props overrides var props = TemplateProperties.ParseTemplateJson(templateJsonContent); props.Icon = MapTemplateProperties(props.Identity, templateIconMappings)?.FirstOrDefault(); if (languageTagMappings != null && languageTagMappings.Any()) { props.LanguageTag = MapTemplateProperties(props.Identity, languageTagMappings)?.FirstOrDefault() ?? props.LanguageTag; } props.PlatformTags = MapTemplateProperties(props.Identity, platformTagsMappings); props.ProjectTypeTags = MapTemplateProperties(props.Identity, typeTagsMappings); props.DefaultName = MapTemplateProperties(props.Identity, defaultNameMappings)?.FirstOrDefault() ?? props.DefaultName; var vsTemplate = CreateVSTemplate(true, props); var context = new TemplateContext(templateJsonContent, props, vsTemplate); templateContexts.Add(context); } var di = Directory.CreateDirectory(obj); // clear obj directory foreach (var fi in di.GetFiles()) { fi.Delete(); } foreach (var fi in di.GetDirectories()) { fi.Delete(true); } l.Log("Creating VSIX project."); l.Indent(); var vsixDir = Path.Combine(obj, "Vsix"); Directory.CreateDirectory(vsixDir); var vsixProject = VsixProject.Create(vsixDir, vsixProps, l); var vsixProjectPath = Path.Combine(vsixDir, "Vsix.csproj"); var sourceFileName = Path.GetFileName(source); File.Copy(source, Path.Combine(vsixDir, sourceFileName)); vsixProject.AddNupkg(sourceFileName); foreach (var ctx in templateContexts) { var zipFileName = ctx.TemplateJsonProps.Identity + ".zip"; var tmpZipFolder = Path.Combine(obj, "zip", ctx.TemplateJsonProps.Identity); Directory.CreateDirectory(tmpZipFolder); File.WriteAllText(Path.Combine(tmpZipFolder, "template.json"), ctx.TemplateJsonContent); ctx.VSTemplate.Write(Path.Combine(tmpZipFolder, "template.vstemplate")); if (ctx.TemplateJsonProps.Icon != null) { File.Copy(ctx.TemplateJsonProps.Icon, Path.Combine(tmpZipFolder, ctx.TemplateJsonProps.IconZipPath)); } ZipFile.CreateFromDirectory(tmpZipFolder, Path.Combine(vsixDir, zipFileName)); vsixProject.AddTemplateZip(zipFileName, Path.Combine("Templates", ctx.TemplateJsonProps.Identity)); l.Log($"Added template '{ctx.TemplateJsonProps.Identity}'."); } vsixProject.Write(vsixProjectPath); l.Dedent(); if (!BuildVsix(l, obj, vsixProjectPath)) { l.LogError("Failed to build vsix."); return(1); } var builtVsixPath = Path.Combine(vsixDir, "bin", "Vsix.vsix"); var outputVsixDir = Path.GetDirectoryName(vsix); if (!Directory.Exists(outputVsixDir)) { Directory.CreateDirectory(outputVsixDir); } File.Copy(builtVsixPath, vsix, force); l.Log($"VSIX generated at {Path.GetFullPath(vsix)}."); return(0); }
private void WriteManifest(VsixProperties props, Logger l) { // The elements here need to be in this exact order or schema validation for the manifest fails. var doc = XDocument.Parse(_vsixManifestTemplate.Value); var metadata = doc.Descendants(_metadataName).First(); var identity = new XElement(_identityName); identity.SetAttributeValue(_idAttrName, props.Id); identity.SetAttributeValue(_versionAttrName, props.Version); identity.SetAttributeValue(_publisherAttrName, props.Publisher); identity.SetAttributeValue(_languageAttrName, "en-us"); metadata.Add(identity); if (props.DisplayName != null) { metadata.AddElement(_displayNameName, props.DisplayName); } if (props.Description != null) { metadata.AddElement(_descriptionName, props.Description); } if (props.MoreInfo != null) { metadata.AddElement(_moreInfoName, props.MoreInfo); } // License if (props.License != null) { var ext = Path.GetExtension(props.License); var localName = "license" + ext; if (AddExternalContent(props.License, localName, l)) { metadata.AddElement(_licenseName, localName); } } // GettingStartedGuide - http(s) URL or local .html file if (props.GettingStartedGuide != null) { var isWebUrl = Uri.TryCreate(props.GettingStartedGuide, UriKind.RelativeOrAbsolute, out var uri) && uri.Scheme.StartsWith("http"); if (isWebUrl) { metadata.AddElement(_gettingStartedGuideName, props.GettingStartedGuide); } else { var ext = Path.GetExtension(props.GettingStartedGuide); var localName = "getting-started" + ext; if (AddExternalContent(props.GettingStartedGuide, localName, l)) { metadata.AddElement(_gettingStartedGuideName, localName); } } } // ReleaseNotes - http(s) URL or local file if (props.ReleaseNotes != null) { var isWebUrl = Uri.TryCreate(props.ReleaseNotes, UriKind.RelativeOrAbsolute, out var uri) && uri.Scheme.StartsWith("http"); if (isWebUrl) { metadata.AddElement(_releaseNotesName, props.ReleaseNotes); } else { var ext = Path.GetExtension(props.ReleaseNotes); var localName = "release-notes" + ext; if (AddExternalContent(props.ReleaseNotes, localName, l)) { metadata.AddElement(_releaseNotesName, localName); } } } // Icon if (props.Icon != null) { var ext = Path.GetExtension(props.Icon); var localName = "icon" + ext; if (AddExternalContent(props.Icon, localName, l)) { metadata.AddElement(_iconName, localName); } } // PreviewImage if (props.PreviewImage != null) { var ext = Path.GetExtension(props.PreviewImage); if (props.PreviewImage == props.Icon) { var localName = "icon" + ext; metadata.AddElement(_previewImageName, localName); } else { var localName = "preview" + ext; if (AddExternalContent(props.PreviewImage, localName, l)) { metadata.AddElement(_previewImageName, localName); } } } if (props.Tags != null) { metadata.AddElement(_tagsName, props.Tags); } var path = Path.Combine(_rootDir, "source.extension.vsixmanifest"); doc.Save(path); }