Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Karlaš <david.karlas@microsoft.com>2017-11-24 12:53:45 +0300
committerDavid Karlaš <david.karlas@microsoft.com>2018-02-21 17:17:19 +0300
commit0fbfe8c5c4b9aba750f3919d3a6b8dba3a612930 (patch)
treec6f0c568ecdf32548a24c578827f556c262f5c25
parent136a3322119e147fa69d9a5a74a7a64da2199ce5 (diff)
Initial .vsix support
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs167
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs23
-rw-r--r--Mono.Addins/Mono.Addins.Description/AddinDescription.cs97
-rw-r--r--Mono.Addins/Mono.Addins.Description/PackageFormat.cs32
-rw-r--r--Mono.Addins/Mono.Addins.csproj1
5 files changed, 290 insertions, 30 deletions
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
index ce9ab5c..a05bb84 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
@@ -367,14 +367,49 @@ namespace Mono.Addins.Setup
{
List<string> outFiles = new List<string> ();
foreach (string file in filePaths) {
- string f = BuildPackageInternal (statusMonitor, debugSymbols, targetDirectory, file);
+ string f = BuildPackageInternal (statusMonitor, debugSymbols, targetDirectory, file, PackageFormat.Mpack);
+ if (f != null)
+ outFiles.Add (f);
+ }
+ return outFiles.ToArray ();
+ }
+
+ /// <summary>
+ /// Packages an add-in
+ /// </summary>
+ /// <param name="statusMonitor">
+ /// Progress monitor where to show progress status
+ /// </param>
+ /// <param name="debugSymbols">
+ /// True if debug symbols (.pdb or .mdb) should be included in the package, if they exist
+ /// </param>
+ /// <param name="targetDirectory">
+ /// Directory where to generate the package
+ /// </param>
+ /// <param name="format">
+ /// Which format to produce .mpack or .vsix
+ /// </param>
+ /// <param name="filePaths">
+ /// Paths to the add-ins to be packaged. Paths can be either the main assembly of an add-in, or an add-in
+ /// manifest (.addin or .addin.xml).
+ /// </param>
+ /// <remarks>
+ /// This method can be used to create a package for an add-in, which can then be pushed to an on-line
+ /// repository. The package will include the main assembly or manifest of the add-in and any external
+ /// file declared in the add-in metadata.
+ /// </remarks>
+ public string [] BuildPackage (IProgressStatus statusMonitor, bool debugSymbols, string targetDirectory, PackageFormat format , params string [] filePaths)
+ {
+ List<string> outFiles = new List<string> ();
+ foreach (string file in filePaths) {
+ string f = BuildPackageInternal (statusMonitor, debugSymbols, targetDirectory, file, format);
if (f != null)
outFiles.Add (f);
}
return outFiles.ToArray ();
}
- string BuildPackageInternal (IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath)
+ string BuildPackageInternal (IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath, PackageFormat format)
{
AddinDescription conf = registry.GetAddinDescription (monitor, filePath);
if (conf == null) {
@@ -396,30 +431,59 @@ namespace Mono.Addins.Setup
name = conf.LocalId;
name = Addin.GetFullId (conf.Namespace, name, conf.Version);
name = name.Replace (',','_').Replace (".__", ".");
-
- string outFilePath = Path.Combine (targetDirectory, name) + ".mpack";
+
+ string outFilePath = Path.Combine (targetDirectory, name);
+ switch(format){
+ case PackageFormat.Mpack:
+ outFilePath += ".mpack";
+ break;
+ case PackageFormat.Vsix:
+ outFilePath += ".vsix";
+ break;
+ default:
+ throw new NotSupportedException (format.ToString ());
+ }
ZipOutputStream s = new ZipOutputStream (File.Create (outFilePath));
s.SetLevel(5);
-
+
+ if (format == PackageFormat.Vsix) {
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = false;
+ doc.LoadXml (conf.SaveToVsixXml ().OuterXml);
+ MemoryStream ms = new MemoryStream ();
+ XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
+ tw.Formatting = Formatting.Indented;
+ doc.WriteTo (tw);
+ tw.Flush ();
+ byte [] data = ms.ToArray ();
+
+ var infoEntry = new ZipEntry ("extension.vsixmanifest") { Size = data.Length };
+ s.PutNextEntry (infoEntry);
+ s.Write (data, 0, data.Length);
+ s.CloseEntry ();
+ }
+
// Generate a stripped down description of the add-in in a file, since the complete
// description may be declared as assembly attributes
-
- XmlDocument doc = new XmlDocument ();
- doc.PreserveWhitespace = false;
- doc.LoadXml (conf.SaveToXml ().OuterXml);
- CleanDescription (doc.DocumentElement);
- MemoryStream ms = new MemoryStream ();
- XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
- tw.Formatting = Formatting.Indented;
- doc.WriteTo (tw);
- tw.Flush ();
- byte[] data = ms.ToArray ();
-
- var infoEntry = new ZipEntry ("addin.info") { Size = data.Length };
- s.PutNextEntry (infoEntry);
- s.Write (data, 0, data.Length);
- s.CloseEntry ();
+
+ if (format == PackageFormat.Mpack || format == PackageFormat.Vsix) {
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = false;
+ doc.LoadXml (conf.SaveToXml ().OuterXml);
+ CleanDescription (doc.DocumentElement);
+ MemoryStream ms = new MemoryStream ();
+ XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
+ tw.Formatting = Formatting.Indented;
+ doc.WriteTo (tw);
+ tw.Flush ();
+ byte [] data = ms.ToArray ();
+
+ var infoEntry = new ZipEntry ("addin.info") { Size = data.Length };
+ s.PutNextEntry (infoEntry);
+ s.Write (data, 0, data.Length);
+ s.CloseEntry ();
+ }
// Now add the add-in files
@@ -473,12 +537,67 @@ namespace Mono.Addins.Setup
s.CloseEntry ();
}
}
-
- s.Finish();
- s.Close();
+
+ if (format == PackageFormat.Vsix) {
+ files.Add ("addin.info");
+ files.Add ("extension.vsixmanifest");
+ XmlDocument doc = new XmlDocument ();
+ doc.PreserveWhitespace = false;
+ XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration ("1.0", "UTF-8", null);
+ XmlElement root = doc.DocumentElement;
+ doc.InsertBefore (xmlDeclaration, root);
+ HashSet<string> alreadyAddedExtensions = new HashSet<string> ();
+ var typesEl = doc.CreateElement ("Types");
+ typesEl.SetAttribute ("xmlns", "http://schemas.openxmlformats.org/package/2006/content-types");
+ foreach (var file in files) {
+ var extension = Path.GetExtension (file);
+ if (alreadyAddedExtensions.Contains (extension))
+ continue;
+ alreadyAddedExtensions.Add (extension);
+ var typeEl = doc.CreateElement ("Default");
+ typeEl.SetAttribute ("Extension", extension);
+ typeEl.SetAttribute ("ContentType", GetContentType (extension));
+ typesEl.AppendChild (typeEl);
+ }
+ doc.AppendChild (typesEl);
+ MemoryStream ms = new MemoryStream ();
+ XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
+ tw.Formatting = Formatting.Indented;
+ doc.WriteTo (tw);
+ tw.Flush ();
+ byte [] data = ms.ToArray ();
+
+ var infoEntry = new ZipEntry ("[Content_Types].xml") { Size = data.Length };
+ s.PutNextEntry (infoEntry);
+ s.Write (data, 0, data.Length);
+ s.CloseEntry ();
+ }
+
+ s.Finish ();
+ s.Close ();
return outFilePath;
}
+ static string GetContentType (string extension)
+ {
+ switch (extension) {
+ case "txt": return "text/plain";
+ case "pkgdef": return "text/plain";
+ case "xml": return "text/xml";
+ case "vsixmanifest": return "text/xml";
+ case "htm or html": return "text/html";
+ case "rtf": return "application/rtf";
+ case "pdf": return "application/pdf";
+ case "gif": return "image/gif";
+ case "jpg or jpeg": return "image/jpg";
+ case "tiff": return "image/tiff";
+ case "vsix": return "application/zip";
+ case "zip": return "application/zip";
+ case "dll": return "application/octet-stream";
+ default: return "application/octet-stream";
+ }
+ }
+
class SatelliteAssemblyFinder
{
Dictionary<string, List<string>> cultureSubdirCache = new Dictionary<string, List<string>> ();
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs b/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs
index ab678a7..2b74796 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs
@@ -469,13 +469,24 @@ namespace Mono.Addins.Setup
throw new InstallException ("A directory name is required.");
service.BuildRepository (new ConsoleProgressStatus (verbose), args[0]);
}
-
- void BuildPackage (string[] args)
+
+ void BuildPackage (string [] args)
{
if (args.Length < 1)
throw new InstallException ("A file name is required.");
-
- service.BuildPackage (new ConsoleProgressStatus (verbose), bool.Parse (GetOption ("debugSymbols", "false")), GetOption ("d", "."), GetArguments ());
+ var formatString = GetOption ("format", "mpack");
+ PackageFormat format;
+ switch (formatString) {
+ case "mpack":
+ format = PackageFormat.Mpack;
+ break;
+ case "vsix":
+ format = PackageFormat.Vsix;
+ break;
+ default:
+ throw new ArgumentException ($"Unsupported package format \"{formatString}\", supported formats are mpack and vsix.");
+ }
+ service.BuildPackage (new ConsoleProgressStatus (verbose), bool.Parse (GetOption ("debugSymbols", "false")), GetOption ("d", "."), format, GetArguments ());
}
void PrintLibraries (string[] args)
@@ -1111,8 +1122,8 @@ namespace Mono.Addins.Setup
cmd = new SetupCommand (cat, "pack", "p", new SetupCommandHandler (BuildPackage));
cmd.Description = "Creates a package from an add-in configuration file.";
- cmd.Usage = "<file-path> [-d:output-directory] [-debugSymbols:(true|false)]";
- cmd.AppendDesc ("Creates an add-in package (.mpack file) which includes all files ");
+ cmd.Usage = "<file-path> [-d:output-directory] [-format:(mpack|vsix)] [-debugSymbols:(true|false)]";
+ cmd.AppendDesc ("Creates an add-in package (.mpack or .vsix file) which includes all files ");
cmd.AppendDesc ("needed to deploy an add-in. The command parameter is the path to");
cmd.AppendDesc ("the add-in's configuration file. If 'debugSymbols' is set to true");
cmd.AppendDesc ("then pdb or mdb debug symbols will automatically be included in the");
diff --git a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
index 158dbec..4d3bf62 100644
--- a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
+++ b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
@@ -892,6 +892,103 @@ namespace Mono.Addins.Description
}
}
}
+
+ public XmlDocument SaveToVsixXml ()
+ {
+ if (!canWrite)
+ throw new InvalidOperationException ("Can't write incomplete description.");
+
+ XmlElement packageManifestEl;
+
+ var vsixDoc = new XmlDocument ();
+ vsixDoc.AppendChild (vsixDoc.CreateElement ("PackageManifest"));
+
+ packageManifestEl = vsixDoc.DocumentElement;
+ packageManifestEl.SetAttribute ("Version", "2.0.0");
+ packageManifestEl.SetAttribute ("xmlns", "http://schemas.microsoft.com/developer/vsx-schema/2011");
+
+ var metadata = vsixDoc.CreateElement ("Metadata");
+ var identity = vsixDoc.CreateElement ("Identity");
+ identity.SetAttribute ("Language", "en-US");
+ identity.SetAttribute ("Id", LocalId);
+ identity.SetAttribute ("Version", Version);
+ identity.SetAttribute ("Publisher", Properties.GetPropertyValue ("VisualStudio.Publisher"));
+ metadata.AppendChild (identity);
+
+ var displayNameEl = vsixDoc.CreateElement ("DisplayName");
+ displayNameEl.InnerText = Name;
+ metadata.AppendChild (displayNameEl);
+
+ var descriptionEl = vsixDoc.CreateElement ("Description");
+ descriptionEl.SetAttribute ("xml:space", "preserve");
+ descriptionEl.InnerText = Description;
+ metadata.AppendChild (descriptionEl);
+
+ var moreInfoEl = vsixDoc.CreateElement ("MoreInfo");
+ moreInfoEl.InnerText = Url;
+ metadata.AppendChild (moreInfoEl);
+
+ var tagsEl = vsixDoc.CreateElement ("Tags");
+ if (!string.IsNullOrEmpty (Properties.GetPropertyValue ("VisualStudio.Tags")))
+ tagsEl.InnerText = Properties.GetPropertyValue ("VisualStudio.Tags");
+ metadata.AppendChild (tagsEl);
+
+ var categoriesEl = vsixDoc.CreateElement ("Categories");
+ categoriesEl.InnerText = Category;
+ metadata.AppendChild (categoriesEl);
+
+ var galleryFlagsEl = vsixDoc.CreateElement ("GalleryFlags");
+ var galleryFlags = Properties.GetPropertyValue ("VisualStudio.GalleryFlags");
+ if (string.IsNullOrEmpty (galleryFlags))
+ galleryFlags = "Public";
+ galleryFlagsEl.InnerText = galleryFlags;
+ metadata.AppendChild (galleryFlagsEl);
+
+ var badgesEl = vsixDoc.CreateElement ("Badges");
+ //TODO:Add Badges support
+ metadata.AppendChild (badgesEl);
+
+ var icon = Properties.GetPropertyValue ("Icon32");
+ if (!string.IsNullOrEmpty (icon)) {
+ var iconEl = vsixDoc.CreateElement ("Icon");
+ iconEl.InnerText = icon;
+ metadata.AppendChild (iconEl);
+ }
+ var license = Copyright;
+ if (!string.IsNullOrEmpty (license)) {
+ var licenseEl = vsixDoc.CreateElement ("License");
+ licenseEl.InnerText = license;
+ metadata.AppendChild (licenseEl);
+ }
+
+ packageManifestEl.AppendChild (metadata);
+
+ var installationEl = vsixDoc.CreateElement ("Installation");
+ var installationTargetEl = vsixDoc.CreateElement ("InstallationTarget");
+ installationTargetEl.SetAttribute ("Id", "Microsoft.VisualStudio.Mac");
+ installationEl.AppendChild (installationTargetEl);
+ packageManifestEl.AppendChild (installationEl);
+
+ packageManifestEl.AppendChild (vsixDoc.CreateElement ("Dependencies"));
+
+ var assetsEl = vsixDoc.CreateElement ("Assets");
+ var addinInfoAsset = vsixDoc.CreateElement ("Asset");
+ addinInfoAsset.SetAttribute ("Type", "Microsoft.VisualStudio.Mac.AddinInfo");
+ addinInfoAsset.SetAttribute ("Path", "addin.info");
+ addinInfoAsset.SetAttribute ("Addressable", "true");
+ assetsEl.AppendChild (addinInfoAsset);
+
+ if (!string.IsNullOrEmpty (icon)) {
+ var iconAsset = vsixDoc.CreateElement ("Asset");
+ iconAsset.SetAttribute ("Type", "Microsoft.VisualStudio.Services.Icons.Default");
+ iconAsset.SetAttribute ("Path", icon);
+ iconAsset.SetAttribute ("Addressable", "true");
+ assetsEl.AppendChild (iconAsset);
+ }
+ packageManifestEl.AppendChild (assetsEl);
+
+ return vsixDoc;
+ }
void SaveCoreProperty (XmlElement elem, string val, string attr, string prop)
{
diff --git a/Mono.Addins/Mono.Addins.Description/PackageFormat.cs b/Mono.Addins/Mono.Addins.Description/PackageFormat.cs
new file mode 100644
index 0000000..8a22673
--- /dev/null
+++ b/Mono.Addins/Mono.Addins.Description/PackageFormat.cs
@@ -0,0 +1,32 @@
+//
+// PackageFormat.cs
+//
+// Author:
+// David Karlaš
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+namespace Mono.Addins.Description
+{
+ public enum PackageFormat
+ {
+ Mpack,
+ Vsix
+ }
+}
diff --git a/Mono.Addins/Mono.Addins.csproj b/Mono.Addins/Mono.Addins.csproj
index a4522af..e7a1d01 100644
--- a/Mono.Addins/Mono.Addins.csproj
+++ b/Mono.Addins/Mono.Addins.csproj
@@ -155,6 +155,7 @@
<Compile Include="Mono.Addins\AddinCategoryAttribute.cs" />
<Compile Include="Mono.Addins\AddinFlagsAttribute.cs" />
<Compile Include="Mono.Addins\AddinLocalizerAttribute.cs" />
+ <Compile Include="Mono.Addins.Description\PackageFormat.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>