diff options
author | Diva Canto <diva@metaverseink.com> | 2019-11-18 00:31:38 +0300 |
---|---|---|
committer | Diva Canto <diva@metaverseink.com> | 2019-11-18 00:31:38 +0300 |
commit | e787249690eb4c5b6bfced57880959ac1e2413e4 (patch) | |
tree | 9d6a736a5a2527bd03859ec7835952f3d74612a0 /Mono.Addins.Setup | |
parent | dc133bdc0519d90c99713e0352051c4b497df0a6 (diff) | |
parent | 124fd2d88fdabf54c378bdf5041584f9e06b6816 (diff) |
Merge branch 'master' of https://github.com/mono/mono-addins
Diffstat (limited to 'Mono.Addins.Setup')
28 files changed, 870 insertions, 495 deletions
diff --git a/Mono.Addins.Setup/ChangeLog b/Mono.Addins.Setup/ChangeLog deleted file mode 100644 index 39e4c4c..0000000 --- a/Mono.Addins.Setup/ChangeLog +++ /dev/null @@ -1,279 +0,0 @@ -2010-10-14 Lluis Sanchez Gual <lluis@novell.com> - - * SetupService.cs: Build package now returns a list of the - generated files. - -2010-07-01 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Generate documentation. - -2010-07-01 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/Package.cs: - * Mono.Addins.Setup/AddinInfo.cs: - * Mono.Addins.Setup/SetupTool.cs: - * Mono.Addins.Setup/SetupService.cs: - * Mono.Addins.Setup/RepositoryRecord.cs: - * Mono.Addins.Setup/InstallException.cs: - * Mono.Addins.Setup/PackageCollection.cs: - * Mono.Addins.Setup/RepositoryRegistry.cs: - * Mono.Addins.Setup/AddinRepositoryEntry.cs: - * Mono.Addins.Setup/ConsoleAddinInstaller.cs: Added some - documentation. - -2010-05-25 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Fix output directory for the - Release configuration. - -2010-04-08 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/AddinStore.cs: Properly get the url path - (old way didn't work on windows). - -2010-04-08 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/RepositoryRegistry.cs: GetAvailableUpdates - (id,version) doesn't work. It makes no sense to ask for - updates for a specific add-in version. Added - GetAvaliableAddinUpdates methods which take only an id and - no version. - -2010-03-30 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: csc doesn't like iso-2. - -2010-03-29 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Make sure the solution builds on - MS.NET 2.0. - -2010-03-26 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Flush. - -2009-11-13 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupTool.cs: Allow specifying multiple - levels of verbosity. - -2009-09-01 Lluis Sanchez Gual <lluis@novell.com> - - * AssemblyInfo.cs: Bump Mono.Addins version. - -2009-08-25 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/PcFileCache.cs: Updated from MD. - -2009-08-24 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/PcFileCache.cs: - * Mono.Addins.Setup/SetupService.cs: Make it buildable in .net - 2.0. - -2009-08-21 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupService.cs: Applications can now - register a test command to be used for testing add-ins. - Don't use the pkg-config command, use instead the - PcFileCache. - - * Mono.Addins.Setup/PcFileCache.cs: Updated. - -2009-08-20 Lluis Sanchez Gual <lluis@novell.com> - - * Makefile.am: - * Mono.Addins.Setup.csproj: - * Mono.Addins.Setup/SetupTool.cs: - * Mono.Addins.Setup/PcFileCache.cs: - * Mono.Addins.Setup/SetupService.cs: Added a new project which - Implements an msbuild task for resolving add-in references. - -2009-08-19 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Update target framework to 2.0. - -2009-06-17 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupService.cs: Added method for getting - a registry from a package name. - - * Mono.Addins.Setup/SetupTool.cs: Added some more help for the - info command. - -2009-06-04 Lluis Sanchez Gual <lluis@novell.com> - - * Makefile.am: - * Mono.Addins.Setup.csproj: Remove unnecessary Mono.Posix - reference. - -2009-05-28 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Properly sign assemblies. - -2009-02-06 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupTool.cs: Added command for getting - the list of assemblies of an add-in. - -2009/02/06 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Updated. - -2008-11-10 Lluis Sanchez Gual <lluis@novell.com> - - * mono-addins-setup.pc.in: Respect custom libdir during ./configure. - Fixes bug #443205. Patch by Diego Pettenò. - -2008-11-10 Lluis Sanchez Gual <lluis@novell.com> - - * Makefile.am: Fix building with parallel make jobs (-j8). Fixes bug - #443206. Patch by Diego Pettenò. - -2008-08-22 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj, Mono.Addins.Setup.mdp: Use msbuild file - format for projects. Removed the old MD1 projects. - -2008-07-15 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupTool.cs: Add missing parameter documentation. - -2008-06-11 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.mdp: Updated. - * Mono.Addins.Setup/SetupTool.cs: Don't allow uninstalling add-ins with - the CantUninstall flag. Same for hidden flag. - -2008-02-06 Lluis Sanchez Gual <lluis@novell.com> - - * AssemblyInfo.cs: Added support for pluggable add-in assembly reflectors. - Implemented an add-in assembly reflector based on Cecil. - -2008-01-18 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/RepositoryRegistry.cs: Don't break the api. - -2008-01-17 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/AddinPackage.cs: Delete subdirectories when - uninstalling. - * Mono.Addins.Setup/AddinStore.cs: Use a more informative uninstall message. - * Mono.Addins.Setup/RepositoryRegistry.cs: Fix a nullref. Improved error - reporting. - -2007-12-15 Lluis Sanchez Gual <lluis@novell.com> - - * mono-addins-setup.pc.in: Update assembly paths. - -2007-12-12 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupTool.cs: Typo fix. - * Makefile.am: Generate and install policy files for old Mono.Addins - versions. - -2007-12-05 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/AddinPackage.cs: When checking if an add-in is - installed, don't provide the version number. This will return whatever - version is installed. - -2007-12-04 Lluis Sanchez Gual <lluis@novell.com> - - * mono-addins-setup.pc.in: Fix dependencies. - -2007-12-03 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.mdp: Updated. - * Mono.Addins.Setup/SetupTool.cs: Added initial support for generating - add-in documentation as XML. - -2007-10-29 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.mdp: Update paths. - -2007-10-18 Lluis Sanchez Gual <lluis@novell.com> - - * AssemblyInfo.cs: Get ready for 0.3 release. - -2007-09-10 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/RepositoryRegistry.cs: Make sure RegisterRepository - always returns a reference to the new repo. - -2007-07-05 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.mdp: Minor fix. - -2007-07-03 Lluis Sanchez Gual <lluis@novell.com> - - * AssemblyInfo.cs, Mono.Addins.Setup.mdp, Makefile.am: Sign the - assembly. - * Mono.Addins.Setup/ConsoleAddinInstaller.cs: New IAddinInstaller - implementation. - -2007-07-02 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.ProgressMonitoring/ConsoleProgressMonitor.cs, - Mono.Addins.Setup.ProgressMonitoring/ProgressStatusMonitor.cs, - Mono.Addins.Setup.ProgressMonitoring/NullProgressMonitor.cs, - Mono.Addins.Setup/IProgressMonitor.cs: Track api changes. - * Mono.Addins.Setup/SetupService.cs, Mono.Addins.Setup/AddinStore.cs: - Added new overload for ResolveDependencies. - * Mono.Addins.Setup/SetupTool.cs: Added new CheckInstall command. Fixed - some issues with add-in id comparison. - * Mono.Addins.Setup/AddinRepositoryEntry.cs, - Mono.Addins.Setup/RepositoryRegistry.cs: When looking for - installable add-ins, sort the result by version number. Some fix in - the code that compares ids. - -2007-05-07 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupService.cs: When creating a package, - generating a valid file name when the add-in doesn't have an ID. - Fixed the generated html page. Don't add the go-mono repository by - default. - * Mono.Addins.Setup/AddinInfo.cs: Generate a better default name when - not provided. - * Mono.Addins.Setup/RepositoryRegistry.cs: Added method for registering - a repository without updating it. - -2007-05-04 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.mdp: Updated. - * Mono.Addins/ExtensionContext.cs: Fixed GetExtensionObjects overload - which was not using the correct reuseCachedInstance value. - * Mono.Addins/ExtensionTree.cs: Improved error message. When looking - for a type in an assembly, avoid throwing an exception too early, - since it may be found in other assemblies. - * Mono.Addins.Database/AddinDatabase.cs: In the addin info cache, also - store information about unsuccessful lookups, to avoid looking for - an add-in again if we found that it doesn't exist. In Update(), - don't use verbose output by default. - -2007-04-04 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.ProgressMonitoring/NullProgressMonitor.cs: Fix - warning. - * Mono.Addins.Setup/SetupTool.cs, Makefile.am: Use ISO-1 compliant c# - only. - -2007-04-04 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.csproj: Added msbuild project files. Patch by - Matthijs ter Woord. - * Mono.Addins.Setup/AddinPackage.cs, Mono.Addins.Setup/AddinStore.cs, - Mono.Addins.Setup/SetupTool.cs, - Mono.Addins.Setup/RepositoryRegistry.cs: Removed Mono.Posix - dependency. Patch by Matthijs ter Woord. - -2007-03-30 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup/SetupTool.cs: Cosmetic fixes. - * Mono.Addins.Setup/RepositoryRegistry.cs: Fix NRE (repoList may change - as a result of initializing the configuration). - -2007-03-23 Lluis Sanchez Gual <lluis@novell.com> - - * Mono.Addins.Setup.mdp, Makefile.am: Removed unused file. - diff --git a/Mono.Addins.Setup/Makefile.am b/Mono.Addins.Setup/Makefile.am deleted file mode 100644 index 72615ce..0000000 --- a/Mono.Addins.Setup/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -ASSEMBLY = ../bin/Mono.Addins.Setup.dll -ASSEMBLY_NAME=Mono.Addins.Setup -PC_FILES_IN = mono-addins-setup.pc.in - -install-data-local: gac-install -uninstall-local: gac-uninstall - -include $(top_srcdir)/Makefile.include -include $(top_srcdir)/xbuild.include - -CLEANFILES += $(POLICY_ASSEMBLIES) $(POLICY_CONFIGS) - - diff --git a/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressStatusMonitor.cs b/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressStatusMonitor.cs index f4f2c61..952a80e 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressStatusMonitor.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressStatusMonitor.cs @@ -29,6 +29,7 @@ using System; using System.IO; +using System.Text; namespace Mono.Addins.Setup.ProgressMonitoring { @@ -37,6 +38,7 @@ namespace Mono.Addins.Setup.ProgressMonitoring IProgressStatus status; LogTextWriter logger; ProgressTracker tracker = new ProgressTracker (); + StringBuilder logBuffer = new StringBuilder (); public ProgressStatusMonitor (IProgressStatus status) { @@ -55,6 +57,7 @@ namespace Mono.Addins.Setup.ProgressMonitoring public void BeginTask (string name, int totalWork) { + FlushLog (); tracker.BeginTask (name, totalWork); status.SetMessage (tracker.CurrentTask); status.SetProgress (tracker.GlobalWork); @@ -62,6 +65,7 @@ namespace Mono.Addins.Setup.ProgressMonitoring public void BeginStepTask (string name, int totalWork, int stepSize) { + FlushLog (); tracker.BeginStepTask (name, totalWork, stepSize); status.SetMessage (tracker.CurrentTask); status.SetProgress (tracker.GlobalWork); @@ -69,12 +73,14 @@ namespace Mono.Addins.Setup.ProgressMonitoring public void Step (int work) { + FlushLog (); tracker.Step (work); status.SetProgress (tracker.GlobalWork); } public void EndTask () { + FlushLog (); tracker.EndTask (); status.SetMessage (tracker.CurrentTask); status.SetProgress (tracker.GlobalWork); @@ -82,7 +88,21 @@ namespace Mono.Addins.Setup.ProgressMonitoring void WriteLog (string text) { - status.Log (text); + int pi = 0; + int i = text.IndexOf ('\n'); + while (i != -1) { + string line = text.Substring (pi, i - pi); + if (logBuffer.Length > 0) { + logBuffer.Append (line); + status.Log (logBuffer.ToString ()); + logBuffer.Clear (); + } else { + status.Log (line); + } + pi = i + 1; + i = text.IndexOf ('\n', pi); + } + logBuffer.Append (text, pi, text.Length - pi); } public TextWriter Log { @@ -91,11 +111,13 @@ namespace Mono.Addins.Setup.ProgressMonitoring public void ReportWarning (string message) { + FlushLog (); status.ReportWarning (message); } public void ReportError (string message, Exception ex) { + FlushLog (); status.ReportError (message, ex); } @@ -105,15 +127,25 @@ namespace Mono.Addins.Setup.ProgressMonitoring public void Cancel () { + FlushLog (); status.Cancel (); } public int LogLevel { get { return status.LogLevel; } } + + void FlushLog () + { + if (logBuffer.Length > 0) { + status.Log (logBuffer.ToString ()); + logBuffer.Clear (); + } + } public void Dispose () { + FlushLog (); } } } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressTracker.cs b/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressTracker.cs index 5698ea9..e36e00e 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressTracker.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup.ProgressMonitoring/ProgressTracker.cs @@ -126,11 +126,15 @@ namespace Mono.Addins.Setup.ProgressMonitoring if (done) return 1.0; double work = 0; + double totalSize = 0; for (int n = tasks.Count - 1; n >= 0; n--) { Task t = (Task) tasks [n]; - work = t.GetWorkPercent (work) * (double)t.StepSize; + work += Math.Max (0, t.GetWorkPercent (work) * (double)t.StepSize); + totalSize += t.StepSize; } - return work; + if (totalSize > 0) + work /= totalSize; + return Math.Min (1.0, work); } } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup.csproj b/Mono.Addins.Setup/Mono.Addins.Setup.csproj index 79d7983..c63b747 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup.csproj +++ b/Mono.Addins.Setup/Mono.Addins.Setup.csproj @@ -1,53 +1,59 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> + <Import Project="..\TargetFrameworks.props" /> + <Import Project="..\Version.props" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>8.0.30703</ProductVersion> <ProjectGuid>{A85C9721-C054-4BD8-A1F3-0227615F0A36}</ProjectGuid> <OutputType>Library</OutputType> <AssemblyName>Mono.Addins.Setup</AssemblyName> - <SchemaVersion>2.0</SchemaVersion> <RootNamespace>Mono.Addins.Setup</RootNamespace> <SignAssembly>True</SignAssembly> <AssemblyOriginatorKeyFile>..\mono-addins.snk</AssemblyOriginatorKeyFile> - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <PackageId>Mono.Addins.Setup</PackageId> + <Description>Mono.Addins is a framework for creating extensible applications, and for creating add-ins which extend applications. Mono.Addins.Setup provides an API for managing add-ins, creating add-in packages and publishing add-ins in on-line repositories.</Description> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>True</DebugSymbols> <DebugType>full</DebugType> - <Optimize>True</Optimize> + <Optimize>false</Optimize> <OutputPath>..\bin</OutputPath> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> <ConsolePause>False</ConsolePause> - <NoWarn>1574</NoWarn> + <NoWarn>1574;1591</NoWarn> <DocumentationFile>..\bin\Mono.Addins.Setup.xml</DocumentationFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>none</DebugType> + <DebugType>pdbonly</DebugType> <Optimize>True</Optimize> <OutputPath>..\bin</OutputPath> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> <ConsolePause>False</ConsolePause> + <DebugSymbols>true</DebugSymbols> + <NoWarn>1574;1591</NoWarn> + <DocumentationFile>..\bin\Mono.Addins.Setup.xml</DocumentationFile> + <PackOnBuild>True</PackOnBuild> </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Xml" /> <Reference Include="System.Core" /> - <Reference Include="ICSharpCode.SharpZipLib"> - <HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> - </Reference> - </ItemGroup> - <ItemGroup> + <Reference Include="System.Net.Http" /> + <PackageReference Include="SharpZipLib" Version="1.1.0" /> <ProjectReference Include="..\Mono.Addins\Mono.Addins.csproj"> <Project>{91DD5A2D-9FE3-4C3C-9253-876141874DAD}</Project> <Name>Mono.Addins</Name> <Private>False</Private> </ProjectReference> + <PackageReference Include="NuGet.Build.Packaging" Version="0.2.0" /> </ItemGroup> <ItemGroup> <Compile Include="Mono.Addins.Setup\AddinInfo.cs" /> @@ -82,17 +88,10 @@ <Compile Include="Mono.Addins.Setup\PcFileCache.cs" /> <Compile Include="Mono.Addins.Setup\TextFormatter.cs" /> <Compile Include="Mono.Addins.Setup\WebRequestHelper.cs" /> - </ItemGroup> - <ItemGroup> - <None Include="ChangeLog" /> - <None Include="packages.config" /> + <Compile Include="Mono.Addins.Setup\AddinRepositoryProvider.cs" /> + <Compile Include="Mono.Addins.Setup\MonoAddinsRepositoryProvider.cs" /> + <Compile Include="Mono.Addins.Setup\HttpClientProvider.cs" /> + <Compile Include="Mono.Addins.Setup\DownloadFileRequest.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> - <ProjectExtensions> - <MonoDevelop> - <Properties> - <Deployment.LinuxDeployData scriptName="mono.addins.setup" /> - </Properties> - </MonoDevelop> - </ProjectExtensions> -</Project>
\ No newline at end of file +</Project> diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinInfo.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinInfo.cs index 1e119ab..5447815 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinInfo.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinInfo.cs @@ -35,7 +35,7 @@ using Mono.Addins.Description; namespace Mono.Addins.Setup { - internal class AddinInfo: AddinHeader + public class AddinInfo: AddinHeader { string id = ""; string namspace = ""; @@ -148,6 +148,8 @@ namespace Mono.Addins.Setup set { category = value; } } + #pragma warning disable CS0612 // Type or member is obsolete + [XmlArrayItem ("AddinDependency", typeof(AddinDependency))] [XmlArrayItem ("NativeDependency", typeof(NativeDependency))] [XmlArrayItem ("AssemblyDependency", typeof(AssemblyDependency))] @@ -161,7 +163,9 @@ namespace Mono.Addins.Setup public DependencyCollection OptionalDependencies { get { return optionalDependencies; } } - + + #pragma warning restore CS0612 // Type or member is obsolete + [XmlArrayItem ("Property", typeof(AddinProperty))] public AddinPropertyCollectionImpl Properties { get { return properties; } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinPackage.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinPackage.cs index c18b1d9..6929928 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinPackage.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinPackage.cs @@ -41,6 +41,7 @@ using Mono.Addins; using Mono.Addins.Description; using System.Collections.Generic; using System.Linq; +using Mono.Addins.Database; namespace Mono.Addins.Setup { @@ -90,12 +91,16 @@ namespace Mono.Addins.Setup static AddinInfo ReadAddinInfo (string file) { ZipFile zfile = new ZipFile (file); - foreach (ZipEntry ze in zfile) { - if (ze.Name == "addin.info") { - using (Stream s = zfile.GetInputStream (ze)) { - return AddinInfo.ReadFromAddinFile (new StreamReader (s)); + try { + foreach (ZipEntry ze in zfile) { + if (ze.Name == "addin.info") { + using (Stream s = zfile.GetInputStream (ze)) { + return AddinInfo.ReadFromAddinFile (new StreamReader (s)); + } } } + } finally { + zfile.Close (); } throw new InstallException ("Addin configuration file not found in package."); } @@ -134,27 +139,36 @@ namespace Mono.Addins.Setup // Extract the files using (FileStream fs = new FileStream (packFile, FileMode.Open, FileAccess.Read)) { ZipFile zip = new ZipFile (fs); - foreach (ZipEntry entry in zip) { - string path = Path.Combine (tempFolder, entry.Name); - string dir = Path.GetDirectoryName (path); - if (!Directory.Exists (dir)) - Directory.CreateDirectory (dir); - - byte[] buffer = new byte [8192]; - int n=0; - Stream inStream = zip.GetInputStream (entry); - Stream outStream = null; - try { - outStream = File.Create (path); - while ((n = inStream.Read (buffer, 0, buffer.Length)) > 0) - outStream.Write (buffer, 0, n); - } finally { - inStream.Close (); - if (outStream != null) - outStream.Close (); + try { + foreach (ZipEntry entry in zip) { + string name; + if (Path.PathSeparator == '\\') + name = entry.Name.Replace ('/', '\\'); + else + name = entry.Name.Replace ('\\', '/'); + string path = Path.Combine (tempFolder, name); + string dir = Path.GetDirectoryName (path); + if (!Directory.Exists (dir)) + Directory.CreateDirectory (dir); + + byte [] buffer = new byte [8192]; + int n = 0; + Stream inStream = zip.GetInputStream (entry); + Stream outStream = null; + try { + outStream = File.Create (path); + while ((n = inStream.Read (buffer, 0, buffer.Length)) > 0) + outStream.Write (buffer, 0, n); + } finally { + inStream.Close (); + if (outStream != null) + outStream.Close (); + } } + } finally { + zip.Close (); } - } + } foreach (string s in Directory.GetFiles (tempFolder)) { if (Path.GetFileName (s) == "addin.info") { @@ -272,7 +286,7 @@ namespace Mono.Addins.Setup { string basePath = Path.GetDirectoryName (conf.AddinFile); foreach (string relPath in conf.AllFiles) { - string afile = Path.Combine (basePath, relPath); + string afile = Path.Combine (basePath, Util.NormalizePath (relPath)); if (File.Exists (afile)) yield return afile; } @@ -294,7 +308,7 @@ namespace Mono.Addins.Setup { if (disablingOnUninstall) { disablingOnUninstall = false; - service.Registry.DisableAddin (info.Id); + service.Registry.DisableAddin (info.Id, true); return; } @@ -374,7 +388,7 @@ namespace Mono.Addins.Setup string basePath = Path.GetDirectoryName (configFile); foreach (string relPath in conf.AllFiles) { - string path = Path.Combine (basePath, relPath); + string path = Path.Combine (basePath, Util.NormalizePath (relPath)); if (!File.Exists (path)) continue; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs index 75a7529..ff5cea6 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs @@ -34,7 +34,7 @@ using System.Threading; namespace Mono.Addins.Setup { - internal class PackageRepositoryEntry: RepositoryEntry, AddinRepositoryEntry, IComparable + public class PackageRepositoryEntry: RepositoryEntry, AddinRepositoryEntry, IComparable { AddinInfo addin; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryProvider.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryProvider.cs new file mode 100644 index 0000000..ddd745f --- /dev/null +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryProvider.cs @@ -0,0 +1,33 @@ +// +// AddinRepositoryProvider.cs +// +// Author: +// David Karlaš <david.karlas@microsoft.com> +// +// Copyright (c) 2018 Microsoft Corp +// +// 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.Setup +{ + public abstract class AddinRepositoryProvider + { + public abstract Repository DownloadRepository (IProgressMonitor monitor, Uri absUri, AddinRepository rr); + } +} diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinStore.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinStore.cs index eef58f2..ddf6cf4 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinStore.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinStore.cs @@ -46,6 +46,7 @@ using Mono.Addins.Serialization; using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Threading.Tasks; namespace Mono.Addins.Setup { @@ -641,28 +642,29 @@ namespace Mono.Addins.Setup try { monitor.BeginTask ("Requesting " + url, 2); - var resp = WebRequestHelper.GetResponse ( - () => (HttpWebRequest)WebRequest.Create (url), - r => r.Headers ["Pragma"] = "no-cache" - ); - monitor.Step (1); - monitor.BeginTask ("Downloading " + url, (int) resp.ContentLength); + var task = DownloadFileRequest.DownloadFile (url, noCache: true); + task.Wait (); - file = Path.GetTempFileName (); - fs = new FileStream (file, FileMode.Create, FileAccess.Write); - s = resp.GetResponseStream (); - byte[] buffer = new byte [4096]; - - int n; - while ((n = s.Read (buffer, 0, buffer.Length)) != 0) { - monitor.Step (n); - fs.Write (buffer, 0, n); - if (monitor.IsCancelRequested) - throw new InstallException ("Installation cancelled."); + using (var request = task.Result) { + monitor.Step (1); + monitor.BeginTask ("Downloading " + url, (int) request.ContentLength); + + file = Path.GetTempFileName (); + fs = new FileStream (file, FileMode.Create, FileAccess.Write); + s = request.Stream; + byte[] buffer = new byte [4096]; + + int n; + while ((n = s.Read (buffer, 0, buffer.Length)) != 0) { + monitor.Step (n); + fs.Write (buffer, 0, n); + if (monitor.IsCancelRequested) + throw new InstallException ("Installation cancelled."); + } + fs.Close (); + s.Close (); + return file; } - fs.Close (); - s.Close (); - return file; } catch { if (fs != null) fs.Close (); @@ -673,10 +675,9 @@ namespace Mono.Addins.Setup throw; } finally { monitor.EndTask (); - monitor.EndTask (); } } - + internal bool HasWriteAccess (string file) { FileInfo f = new FileInfo (file); diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinSystemConfigurationReaderWriter.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinSystemConfigurationReaderWriter.cs index 370b3db..130f059 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinSystemConfigurationReaderWriter.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinSystemConfigurationReaderWriter.cs @@ -219,7 +219,7 @@ namespace Mono.Addins.Setup Reader.ReadStartElement(); Reader.MoveToContent(); - bool b10=false, b11=false, b12=false, b13=false, b14=false, b15=false; + bool b10=false, b11=false, b12=false, b13=false, b14=false, b15=false, b16=false; while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) { @@ -244,13 +244,14 @@ namespace Mono.Addins.Setup b13 = true; string s19 = Reader.ReadElementString (); ob.@Name = s19; - } - else if (Reader.LocalName == "Url" && Reader.NamespaceURI == "" && !b12) { + } else if (Reader.LocalName == "Url" && Reader.NamespaceURI == "" && !b12) { b12 = true; string s20 = Reader.ReadElementString (); ob.@Url = s20; - } - else if (Reader.LocalName == "LastModified" && Reader.NamespaceURI == "" && !b14) { + } else if (Reader.LocalName == "ProviderId" && Reader.NamespaceURI == "" && !b16) { + b16 = true; + ob.ProviderId = Reader.ReadElementString (); + } else if (Reader.LocalName == "LastModified" && Reader.NamespaceURI == "" && !b14) { b14 = true; string s21 = Reader.ReadElementString (); ob.@LastModified = XmlConvert.ToDateTime (s21, XmlDateTimeSerializationMode.RoundtripKind); @@ -370,6 +371,7 @@ namespace Mono.Addins.Setup WriteElementString ("IsReference", "", (ob.@IsReference?"true":"false")); WriteElementString ("File", "", ob.@File); WriteElementString ("Url", "", ob.@Url); + WriteElementString ("ProviderId", "", ob.ProviderId); WriteElementString ("Name", "", ob.@Name); WriteElementString ("LastModified", "", XmlConvert.ToString (ob.@LastModified, XmlDateTimeSerializationMode.RoundtripKind)); if (ob.@Enabled != true) { diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/DownloadFileRequest.cs b/Mono.Addins.Setup/Mono.Addins.Setup/DownloadFileRequest.cs new file mode 100644 index 0000000..565c063 --- /dev/null +++ b/Mono.Addins.Setup/Mono.Addins.Setup/DownloadFileRequest.cs @@ -0,0 +1,129 @@ +// +// WebRequestWrapper.cs +// +// Author: +// Matt Ward <matt.ward@microsoft.com> +// +// Copyright (c) 2018 Microsoft +// +// 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; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Mono.Addins.Setup +{ + abstract class DownloadFileRequest : IDisposable + { + public abstract void Dispose (); + public abstract int ContentLength { get; } + public abstract Stream Stream { get; } + + public static Task<DownloadFileRequest> DownloadFile (string url, bool noCache) + { + if (HttpClientProvider.HasCustomCreation || !WebRequestHelper.HasCustomRequestHandler) + return HttpClientDownloadFileRequest.Create (url, noCache); + + return WebRequestDownloadFileRequest.Create (url, noCache); + } + } + + class HttpClientDownloadFileRequest : DownloadFileRequest + { + HttpClient client; + HttpResponseMessage response; + Stream stream; + + public static Task<DownloadFileRequest> Create (string url, bool noCache) + { + // Use Task.Run to avoid hanging the UI thread when waiting for the GetAsync method to return + // with the response for an .mpack file download. + return Task.Run<DownloadFileRequest> (async () => { + var client = HttpClientProvider.CreateHttpClient (url); + if (noCache) + client.DefaultRequestHeaders.Add ("Pragma", "no-cache"); + + var response = await client.GetAsync (url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait (false); + var stream = await response.Content.ReadAsStreamAsync ().ConfigureAwait (false); + + return new HttpClientDownloadFileRequest { + client = client, + response = response, + stream = stream + }; + }); + } + + public override int ContentLength { + get { return (int)response.Content.Headers.ContentLength; } + } + + public override Stream Stream { + get { return stream; } + } + + public override void Dispose () + { + stream?.Dispose (); + response?.Dispose (); + client.Dispose (); + } + } + + class WebRequestDownloadFileRequest : DownloadFileRequest + { + WebResponse response; + Stream stream; + + public static Task<DownloadFileRequest> Create (string url, bool noCache) + { + var response = WebRequestHelper.GetResponse ( + () => (HttpWebRequest)WebRequest.Create (url), + r => { + if (noCache) + r.Headers ["Pragma"] = "no-cache"; + } + ); + + var request = new WebRequestDownloadFileRequest { + response = response, + stream = response.GetResponseStream () + }; + + return Task.FromResult<DownloadFileRequest> (request); + } + + public override int ContentLength { + get { return (int)response.ContentLength; } + } + + public override Stream Stream { + get { return stream; } + } + + public override void Dispose () + { + stream?.Dispose (); + response.Dispose (); + } + } +} diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/HttpClientProvider.cs b/Mono.Addins.Setup/Mono.Addins.Setup/HttpClientProvider.cs new file mode 100644 index 0000000..387cb59 --- /dev/null +++ b/Mono.Addins.Setup/Mono.Addins.Setup/HttpClientProvider.cs @@ -0,0 +1,65 @@ +// +// HttpClientProvider.cs +// +// Author: +// Matt Ward <matt.ward@microsoft.com> +// +// Copyright (c) 2018 Microsoft +// +// 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; +using System.Net; +using System.Net.Http; + +namespace Mono.Addins.Setup +{ + /// <summary> + /// Creates a HttpClient with support for authenticated proxies. + /// </summary> + public static class HttpClientProvider + { + static Func<string, HttpClient> httpClientFactory; + + public static void SetHttpClientFactory (Func<string, HttpClient> factory) + { + httpClientFactory = factory; + } + + static internal bool HasCustomCreation { + get { return httpClientFactory != null; } + } + + /// <summary> + /// Creates a new HttpClient. + /// </summary> + /// <returns>The HttpClient.</returns> + /// <param name="uri">The request url.</param> + public static HttpClient CreateHttpClient (string uri) + { + if (httpClientFactory != null) + return httpClientFactory.Invoke (uri); + + var handler = new HttpClientHandler { + AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip + }; + return new HttpClient (handler); + } + } +} diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/IProgressMonitor.cs b/Mono.Addins.Setup/Mono.Addins.Setup/IProgressMonitor.cs index 12a5818..7f70f48 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/IProgressMonitor.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/IProgressMonitor.cs @@ -32,7 +32,7 @@ using System.IO; namespace Mono.Addins { - internal interface IProgressMonitor: IDisposable + public interface IProgressMonitor: IDisposable { void BeginTask (string name, int totalWork); void BeginStepTask (string name, int totalWork, int stepSize); diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/MonoAddinsRepositoryProvider.cs b/Mono.Addins.Setup/Mono.Addins.Setup/MonoAddinsRepositoryProvider.cs new file mode 100644 index 0000000..a6199de --- /dev/null +++ b/Mono.Addins.Setup/Mono.Addins.Setup/MonoAddinsRepositoryProvider.cs @@ -0,0 +1,43 @@ +// +// MonoAddinsRepositoryProvider.cs +// +// Author: +// David Karlaš <david.karlas@microsoft.com> +// +// Copyright (c) 2018 Microsoft Corp +// +// 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.Setup +{ + class MonoAddinsRepositoryProvider : AddinRepositoryProvider + { + private readonly SetupService service; + + public MonoAddinsRepositoryProvider (SetupService service) + { + this.service = service; + } + + public override Repository DownloadRepository (IProgressMonitor monitor, Uri absUri, AddinRepository rr) + { + return (Repository)service.Store.DownloadObject (monitor, absUri.ToString (), typeof (Repository)); + } + } +} diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/PcFileCache.cs b/Mono.Addins.Setup/Mono.Addins.Setup/PcFileCache.cs index cadccf3..8c0d897 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/PcFileCache.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/PcFileCache.cs @@ -546,7 +546,7 @@ namespace Mono.PkgConfig StringBuilder sb = new StringBuilder (); int last = 0; while (i != -1 && i < value.Length) { - sb.Append (value.Substring (last, i - last)); + sb.Append (value, last, i - last); if (i == 0 || value [i - 1] != '$') { // Evaluate if var is not escaped i += 2; @@ -572,7 +572,7 @@ namespace Mono.PkgConfig if (i < value.Length - 1) i = value.IndexOf ("${", i); } - sb.Append (value.Substring (last, value.Length - last)); + sb.Append (value, last, value.Length - last); return sb.ToString (); } } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs b/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs index 22ea391..5c28af8 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs @@ -37,7 +37,7 @@ using System.Threading.Tasks; namespace Mono.Addins.Setup { - internal class Repository + public class Repository { RepositoryEntryCollection repositories; RepositoryEntryCollection addins; @@ -128,21 +128,27 @@ namespace Mono.Addins.Setup } res.FilePath = cachedFile; - WebRequestHelper.GetResponseAsync (() => (HttpWebRequest)WebRequest.Create (u)).ContinueWith (t => { + var request = DownloadFileRequest.DownloadFile (u.ToString (), false).ContinueWith (t => { try { - var resp = t.Result; - string dir = Path.GetDirectoryName (res.FilePath); - lock (this) { - if (!Directory.Exists (dir)) - Directory.CreateDirectory (dir); - } - byte[] buffer = new byte [8092]; - using (var s = resp.GetResponseStream ()) { - using (var f = File.OpenWrite (res.FilePath)) { - int nr = 0; - while ((nr = s.Read (buffer, 0, buffer.Length)) > 0) - f.Write (buffer, 0, nr); + using (var resp = t.Result) { + string dir = Path.GetDirectoryName (res.FilePath); + lock (this) { + if (!Directory.Exists (dir)) + Directory.CreateDirectory (dir); + } + if (File.Exists (res.FilePath)) { + res.SetDone (); + return; + } + byte [] buffer = new byte [8092]; + using (var s = resp.Stream) { + using (var f = File.OpenWrite (res.FilePath)) { + int nr = 0; + while ((nr = s.Read (buffer, 0, buffer.Length)) > 0) + f.Write (buffer, 0, nr); + } } + res.SetDone (); } } catch (Exception ex) { res.Error = ex; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntry.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntry.cs index 6ce998a..83fd406 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntry.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntry.cs @@ -31,7 +31,7 @@ using System; namespace Mono.Addins.Setup { - internal class RepositoryEntry + public class RepositoryEntry { string url; internal Repository owner; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntryCollection.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntryCollection.cs index eca6472..ff8214c 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntryCollection.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryEntryCollection.cs @@ -31,7 +31,7 @@ using System.Collections; namespace Mono.Addins.Setup { - internal class RepositoryEntryCollection: CollectionBase + public class RepositoryEntryCollection: CollectionBase { Repository owner; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryReaderWriter.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryReaderWriter.cs index f574561..893bdad 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryReaderWriter.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryReaderWriter.cs @@ -536,6 +536,8 @@ namespace Mono.Addins.Setup return ob; } + #pragma warning disable CS0612 // Type or member is obsolete + public Mono.Addins.Description.NativeDependency ReadObject_NativeReference (bool isNullable, bool checkType) { Mono.Addins.Description.NativeDependency ob = null; @@ -589,6 +591,7 @@ namespace Mono.Addins.Setup return ob; } + #pragma warning restore CS0612 // Type or member is obsolete public Mono.Addins.Description.AddinDependency ReadObject_AddinReference (bool isNullable, bool checkType) { @@ -879,9 +882,11 @@ namespace Mono.Addins.Setup else if (ob.@Dependencies[n53].GetType() == typeof(Mono.Addins.Description.AssemblyDependency)) { WriteObject_AssemblyDependency (((Mono.Addins.Description.AssemblyDependency) ob.@Dependencies[n53]), "AssemblyDependency", "", false, false, true); } + #pragma warning disable CS0612 // Type or member is obsolete else if (ob.@Dependencies[n53].GetType() == typeof(Mono.Addins.Description.NativeDependency)) { WriteObject_NativeReference (((Mono.Addins.Description.NativeDependency) ob.@Dependencies[n53]), "NativeDependency", "", false, false, true); } + #pragma warning restore CS0612 // Type or member is obsolete else if (ob.@Dependencies[n53].GetType() == typeof(Mono.Addins.Description.AddinDependency)) { WriteObject_AddinReference (((Mono.Addins.Description.AddinDependency) ob.@Dependencies[n53]), "AddinDependency", "", false, false, true); } @@ -896,9 +901,11 @@ namespace Mono.Addins.Setup else if (ob.@OptionalDependencies[n54].GetType() == typeof(Mono.Addins.Description.AssemblyDependency)) { WriteObject_AssemblyDependency (((Mono.Addins.Description.AssemblyDependency) ob.@OptionalDependencies[n54]), "AssemblyDependency", "", false, false, true); } + #pragma warning disable CS0612 // Type or member is obsolete else if (ob.@OptionalDependencies[n54].GetType() == typeof(Mono.Addins.Description.NativeDependency)) { WriteObject_NativeReference (((Mono.Addins.Description.NativeDependency) ob.@OptionalDependencies[n54]), "NativeDependency", "", false, false, true); } + #pragma warning restore CS0612 // Type or member is obsolete else if (ob.@OptionalDependencies[n54].GetType() == typeof(Mono.Addins.Description.AddinDependency)) { WriteObject_AddinReference (((Mono.Addins.Description.AddinDependency) ob.@OptionalDependencies[n54]), "AddinDependency", "", false, false, true); } @@ -943,6 +950,8 @@ namespace Mono.Addins.Setup if (writeWrappingElem) WriteEndElement (ob); } + #pragma warning disable CS0612 // Type or member is obsolete + void WriteObject_NativeReference (Mono.Addins.Description.NativeDependency ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) { if (((object)ob) == null) @@ -968,6 +977,8 @@ namespace Mono.Addins.Setup if (writeWrappingElem) WriteEndElement (ob); } + #pragma warning restore CS0612 // Type or member is obsolete + void WriteObject_AddinReference (Mono.Addins.Description.AddinDependency ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) { if (((object)ob) == null) diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs index cb9920a..beabe2b 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs @@ -50,6 +50,8 @@ namespace Mono.Addins.Setup get { return id; } set { id = value; } } + + public string ProviderId { get; set; } public bool IsReference { get { return isReference; } @@ -119,7 +121,7 @@ namespace Mono.Addins.Setup newRep.CachedFilesDir = CachedFilesDir; } } - + /// <summary> /// An on-line add-in repository /// </summary> @@ -170,5 +172,13 @@ namespace Mono.Addins.Setup bool Enabled { get; } + + /// <summary> + /// Defineds type of repository provider. + /// </summary> + /// <value>Provider string id.</value> + string ProviderId { + get; + } } } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRegistry.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRegistry.cs index acbb1bd..dcb4246 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRegistry.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRegistry.cs @@ -53,7 +53,7 @@ namespace Mono.Addins.Setup } /// <summary> - /// Subscribes to an on-line repository + /// Subscribes to an on-line repository, notice that default registry provider is "MonoAddins" /// </summary> /// <param name="monitor"> /// Progress monitor where to show progress status and log @@ -70,11 +70,11 @@ namespace Mono.Addins.Setup /// </remarks> public AddinRepository RegisterRepository (IProgressStatus monitor, string url) { - return RegisterRepository (monitor, url, false); + return RegisterRepository (monitor, url, false, "MonoAddins"); } - + /// <summary> - /// Subscribes to an on-line repository + /// Subscribes to an on-line repository, notice that default registry provider is "MonoAddins" /// </summary> /// <param name="monitor"> /// Progress monitor where to show progress status and log @@ -90,20 +90,45 @@ namespace Mono.Addins.Setup /// </returns> public AddinRepository RegisterRepository (IProgressStatus monitor, string url, bool updateNow) { + return RegisterRepository (monitor, url, updateNow, "MonoAddins"); + } + + /// <summary> + /// Subscribes to an on-line repository + /// </summary> + /// <param name="monitor"> + /// Progress monitor where to show progress status and log + /// </param> + /// <param name="url"> + /// URL of the repository + /// </param> + /// <param name="updateNow"> + /// When set to True, the repository index will be downloaded. + /// </param> + /// <param name="providerId"> + /// What kind of repository + /// </param> + /// <returns> + /// A repository reference + /// </returns> + public AddinRepository RegisterRepository (IProgressStatus monitor, string url, bool updateNow, string providerId) + { if (string.IsNullOrEmpty (url)) throw new ArgumentException ("Emtpy url"); - - if (!url.EndsWith (".mrep")) { - if (url [url.Length - 1] != '/') - url += "/"; - url = url + "main.mrep"; + + if (providerId == "MonoAddins") { + if (!url.EndsWith (".mrep")) { + if (url [url.Length - 1] != '/') + url += "/"; + url = url + "main.mrep"; + } } RepositoryRecord rr = FindRepositoryRecord (url); if (rr != null) return rr; - rr = RegisterRepository (url, false); + rr = RegisterRepository (url, false, providerId); try { if (updateNow) { @@ -124,20 +149,22 @@ namespace Mono.Addins.Setup } } - internal RepositoryRecord RegisterRepository (string url, bool isReference) + internal RepositoryRecord RegisterRepository (string url, bool isReference, string providerId) { RepositoryRecord rr = FindRepositoryRecord (url); if (rr != null) { if (rr.IsReference && !isReference) { rr.IsReference = false; - service.SaveConfiguration (); } + rr.ProviderId = providerId; + service.SaveConfiguration (); return rr; } rr = new RepositoryRecord (); rr.Url = url; rr.IsReference = isReference; + rr.ProviderId = providerId; string name = service.RepositoryCachePath; if (!Directory.Exists (name)) @@ -329,9 +356,10 @@ namespace Mono.Addins.Setup monitor.BeginTask ("Updating from " + absUri.ToString (), 2); Repository newRep = null; Exception error = null; - + try { - newRep = (Repository) service.Store.DownloadObject (monitor, absUri.ToString (), typeof(Repository)); + var provider = service.GetAddinRepositoryProvider (rr.ProviderId); + newRep = provider.DownloadRepository (monitor, absUri, rr); } catch (Exception ex) { error = ex; } @@ -348,7 +376,7 @@ namespace Mono.Addins.Setup string refRepUrl = refRepUri.ToString (); RepositoryRecord refRep = FindRepositoryRecord (refRepUrl); if (refRep == null) - refRep = RegisterRepository (refRepUrl, true); + refRep = RegisterRepository (refRepUrl, true, rr.ProviderId); refRep.Enabled = rr.Enabled; // Update the repo if the modified timestamp changes or if there is no timestamp info if (refRep.LastModified != re.LastModified || re.LastModified == DateTime.MinValue || !File.Exists (refRep.File)) { diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs index b81108d..d29bed1 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs @@ -28,15 +28,16 @@ using System; -using System.Xml; -using System.IO; using System.Collections; using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Xml; using ICSharpCode.SharpZipLib.Zip; +using Mono.Addins.Database; using Mono.Addins.Description; using Mono.Addins.Setup.ProgressMonitoring; -using Microsoft.Win32; -using System.Diagnostics; using Mono.PkgConfig; namespace Mono.Addins.Setup @@ -76,6 +77,7 @@ namespace Mono.Addins.Setup repositories = new RepositoryRegistry (this); store = new AddinStore (this); + AddAddinRepositoryProvider ("MonoAddins", new MonoAddinsRepositoryProvider (this)); } /// <summary> @@ -89,6 +91,7 @@ namespace Mono.Addins.Setup this.registry = registry; repositories = new RepositoryRegistry (this); store = new AddinStore (this); + AddAddinRepositoryProvider ("MonoAddins", new MonoAddinsRepositoryProvider (this)); } /// <summary> @@ -103,6 +106,13 @@ namespace Mono.Addins.Setup } string RootConfigFile { + get { return Path.Combine (registry.RegistryPath, "addins-setup-v2.config"); } + } + + /// <summary> + /// This should only be used for migration purposes + /// </summary> + string RootConfigFileOld { get { return Path.Combine (registry.RegistryPath, "addins-setup.config"); } } @@ -296,7 +306,29 @@ namespace Mono.Addins.Setup { return AddinInfo.ReadFromDescription (addin.Description); } - + + Dictionary<string, AddinRepositoryProvider> providersList = new Dictionary<string, AddinRepositoryProvider> (); + + public AddinRepositoryProvider GetAddinRepositoryProvider (string providerId) + { + + if (string.IsNullOrEmpty (providerId)) + providerId = "MonoAddins"; + if (providersList.TryGetValue (providerId, out var addinRepositoryProvider)) + return addinRepositoryProvider; + throw new KeyNotFoundException (providerId); + } + + public void AddAddinRepositoryProvider (string providerId, AddinRepositoryProvider provider) + { + providersList [providerId] = provider; + } + + public void RemoveAddinRepositoryProvider (string providerId) + { + providersList.Remove (providerId); + } + /// <summary> /// Gets a list of add-ins which depend on an add-in /// </summary> @@ -338,16 +370,77 @@ namespace Mono.Addins.Setup /// </remarks> public string[] BuildPackage (IProgressStatus statusMonitor, string targetDirectory, params string[] filePaths) { + return BuildPackage (statusMonitor, false, targetDirectory, filePaths); + } + + /// <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="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, params string[] filePaths) + { List<string> outFiles = new List<string> (); foreach (string file in filePaths) { - string f = BuildPackageInternal (statusMonitor, 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, 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) { @@ -355,7 +448,7 @@ namespace Mono.Addins.Setup return null; } - string basePath = Path.GetDirectoryName (filePath); + string basePath = Path.GetDirectoryName (Path.GetFullPath (filePath)); if (targetDirectory == null) targetDirectory = basePath; @@ -369,66 +462,219 @@ 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 (); - - ZipEntry infoEntry = new ZipEntry ("addin.info"); - s.PutNextEntry (infoEntry); - s.Write (data, 0, data.Length); - + + 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 - - ArrayList list = new ArrayList (); - if (!conf.AllFiles.Contains (Path.GetFileName (filePath))) - list.Add (Path.GetFileName (filePath)); + + var files = new HashSet<string> (); + + files.Add (Path.GetFileName (Util.NormalizePath (filePath))); + foreach (string f in conf.AllFiles) { - list.Add (f); + var file = Util.NormalizePath (f); + files.Add (file); + if (debugSymbols) { + if (File.Exists (Path.ChangeExtension (file, ".pdb"))) + files.Add (Path.ChangeExtension (file, ".pdb")); + else if (File.Exists (file + ".mdb")) + files.Add (file + ".mdb"); + } } foreach (var prop in conf.Properties) { try { - if (File.Exists (Path.Combine (basePath, prop.Value))) - list.Add (prop.Value); + var file = Util.NormalizePath (prop.Value); + if (File.Exists (Path.Combine (basePath, file))) { + files.Add (file); + } } catch { // Ignore errors } } + + //add satellite assemblies for assemblies in the list + var satelliteFinder = new SatelliteAssemblyFinder (); + foreach (var f in files.ToList ()) { + foreach (var satellite in satelliteFinder.FindSatellites (Path.Combine (basePath, f))) { + var relativeSatellite = satellite.Substring (basePath.Length + 1); + files.Add (relativeSatellite); + } + } monitor.Log ("Creating package " + Path.GetFileName (outFilePath)); - foreach (string file in list) { + foreach (string file in files) { string fp = Path.Combine (basePath, file); using (FileStream fs = File.OpenRead (fp)) { byte[] buffer = new byte [fs.Length]; fs.Read (buffer, 0, buffer.Length); - - ZipEntry entry = new ZipEntry (file); + + var fileName = Path.DirectorySeparatorChar == '\\' ? file.Replace ('\\', '/') : file; + var entry = new ZipEntry (fileName) { Size = fs.Length }; s.PutNextEntry (entry); s.Write (buffer, 0, buffer.Length); + 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 (string.IsNullOrEmpty (extension)) + continue; + if (extension.StartsWith (".", StringComparison.Ordinal)) + extension = extension.Substring (1); + 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"; + case "info": return "text/xml";//Mono.Addins info file + default: return "application/octet-stream"; + } + } + + class SatelliteAssemblyFinder + { + Dictionary<string, List<string>> cultureSubdirCache = new Dictionary<string, List<string>> (); + HashSet<string> cultureNames = new HashSet<string> (StringComparer.OrdinalIgnoreCase); + + public SatelliteAssemblyFinder () + { + foreach (var cultureName in CultureInfo.GetCultures (CultureTypes.AllCultures)) { + cultureNames.Add (cultureName.Name); + } + } + + List<string> GetCultureSubdirectories (string directory) + { + if (!cultureSubdirCache.TryGetValue (directory, out List<string> cultureDirs)) { + cultureDirs = Directory.EnumerateDirectories (directory) + .Where (d => cultureNames.Contains (Path.GetFileName ((d)))) + .ToList (); + + cultureSubdirCache [directory] = cultureDirs; + } + return cultureDirs; + } + + public IEnumerable<string> FindSatellites (string assemblyPath) + { + if (!assemblyPath.EndsWith (".dll", StringComparison.OrdinalIgnoreCase)) { + yield break; + } + + var satelliteName = Path.GetFileNameWithoutExtension (assemblyPath) + ".resources.dll"; + + foreach (var cultureDir in GetCultureSubdirectories (Path.GetDirectoryName (assemblyPath))) { + string cultureName = Path.GetFileName (cultureDir); + string satellitePath = Path.Combine (cultureDir, satelliteName); + if (File.Exists (satellitePath)) { + yield return satellitePath; + } + } + } + } void CleanDescription (XmlElement parent) { @@ -580,29 +826,33 @@ namespace Mono.Addins.Setup { Random r = new Random (); ZipFile zfile = new ZipFile (file); - foreach (var prop in ainfo.Properties) { - ZipEntry ze = zfile.GetEntry (prop.Value); - if (ze != null) { - string fname; - do { - fname = Path.Combine (targetDir, r.Next().ToString ("x") + Path.GetExtension (prop.Value)); - } while (File.Exists (fname)); - - if (!Directory.Exists (targetDir)) - Directory.CreateDirectory (targetDir); - - using (var f = File.OpenWrite (fname)) { - using (Stream s = zfile.GetInputStream (ze)) { - byte[] buffer = new byte [8092]; - int nr = 0; - while ((nr = s.Read (buffer, 0, buffer.Length)) > 0) - f.Write (buffer, 0, nr); + try { + foreach (var prop in ainfo.Properties) { + ZipEntry ze = zfile.GetEntry (prop.Value); + if (ze != null) { + string fname; + do { + fname = Path.Combine (targetDir, r.Next ().ToString ("x") + Path.GetExtension (prop.Value)); + } while (File.Exists (fname)); + + if (!Directory.Exists (targetDir)) + Directory.CreateDirectory (targetDir); + + using (var f = File.OpenWrite (fname)) { + using (Stream s = zfile.GetInputStream (ze)) { + byte [] buffer = new byte [8092]; + int nr = 0; + while ((nr = s.Read (buffer, 0, buffer.Length)) > 0) + f.Write (buffer, 0, nr); + } } + prop.Value = Path.Combine (addinFilesDir, Path.GetFileName (fname)); } - prop.Value = Path.Combine (addinFilesDir, Path.GetFileName (fname)); } + } finally { + zfile.Close (); } - } + } void GenerateIndexPage (Repository rep, ArrayList addins, string basePath) { @@ -626,7 +876,10 @@ namespace Mono.Addins.Setup internal AddinSystemConfiguration Configuration { get { if (config == null) { - config = (AddinSystemConfiguration) AddinStore.ReadObject (RootConfigFile, typeof(AddinSystemConfiguration)); + if (File.Exists (RootConfigFile)) + config = (AddinSystemConfiguration)AddinStore.ReadObject (RootConfigFile, typeof (AddinSystemConfiguration)); + else + config = (AddinSystemConfiguration)AddinStore.ReadObject (RootConfigFileOld, typeof (AddinSystemConfiguration)); if (config == null) config = new AddinSystemConfiguration (); } @@ -645,6 +898,8 @@ namespace Mono.Addins.Setup { if (File.Exists (RootConfigFile)) File.Delete (RootConfigFile); + if (File.Exists (RootConfigFileOld)) + File.Delete (RootConfigFileOld); ResetAddinInfo (); } diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs b/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs index d6c1872..35fc475 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/SetupTool.cs @@ -204,8 +204,11 @@ namespace Mono.Addins.Setup PackageCollection packs = new PackageCollection (); for (int n=0; n<args.Length; n++) { Addin addin = registry.GetAddin (GetFullId (args[n])); - if (addin != null) + if (addin != null) { + if (!addin.Enabled) + addin.Enabled = true; continue; + } string aname = Addin.GetIdName (GetFullId (args[n])); string aversion = Addin.GetIdVersion (args[n]); if (aversion.Length == 0) aversion = null; @@ -466,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), 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) @@ -519,6 +533,20 @@ namespace Mono.Addins.Setup registry.Rebuild (new ConsoleProgressStatus (verbose)); } + void GenerateAddinScanDataFiles (string[] args) + { + bool recursive = false; + int i = 0; + if (args.Length > 0 && args [0] == "-r") { + recursive = true; + i = 1; + } + if (i >= args.Length) + registry.GenerateAddinScanDataFiles (new ConsoleProgressStatus (verbose), recursive:recursive); + else + registry.GenerateAddinScanDataFiles (new ConsoleProgressStatus (verbose), args[0], recursive); + } + void DumpRegistryFile (string[] args) { if (args.Length < 1) @@ -1083,7 +1111,20 @@ namespace Mono.Addins.Setup cmd = new SetupCommand (cat, "reg-build", "rgb", new SetupCommandHandler (RepairRegistry)); cmd.Description = "Rebuilds the add-in registry."; - cmd.AppendDesc ("Regenerates the add-in registry"); + cmd.AppendDesc ("Regenerates the add-in registry."); + commands.Add (cmd); + + cmd = new SetupCommand (cat, "reg-gen-data", "rgd", new SetupCommandHandler (GenerateAddinScanDataFiles)); + cmd.Usage = "[-r] <path>"; + cmd.Description = "Generates add-in scan data files."; + cmd.AppendDesc ("Generates binary add-in scan data files next to each"); + cmd.AppendDesc ("add-in file. When such a file is present for an"); + cmd.AppendDesc ("add-in, the add-in scanner will load the information"); + cmd.AppendDesc ("from the data file instead of doing a full scan."); + cmd.AppendDesc ("Data files will be generated only add-ins located"); + cmd.AppendDesc ("in the provided folder."); + cmd.AppendDesc ("Options:"); + cmd.AppendDesc ("-r: Recursively look in subdirectories."); commands.Add (cmd); cmd = new SetupCommand (cat, "info", null, new SetupCommandHandler (PrintAddinInfo)); @@ -1108,10 +1149,12 @@ 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]"; - 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."); + 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"); + cmd.AppendDesc ("final package."); commands.Add (cmd); cmd = new SetupCommand (cat, "help", "h", new SetupCommandHandler (PrintHelp)); diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/TextFormatter.cs b/Mono.Addins.Setup/Mono.Addins.Setup/TextFormatter.cs index 0aa3719..c1f37a1 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/TextFormatter.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/TextFormatter.cs @@ -201,7 +201,7 @@ namespace Mono.Addins.Setup } if (n != sn) - currentWord.Append (text.Substring (sn, n - sn)); + currentWord.Append (text, sn, n - sn); if (foundSpace) { AppendCurrentWord (text[n]); n++; diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/WebRequestHelper.cs b/Mono.Addins.Setup/Mono.Addins.Setup/WebRequestHelper.cs index 5685b5a..f962c44 100644 --- a/Mono.Addins.Setup/Mono.Addins.Setup/WebRequestHelper.cs +++ b/Mono.Addins.Setup/Mono.Addins.Setup/WebRequestHelper.cs @@ -46,6 +46,10 @@ namespace Mono.Addins.Setup _handler = handler; } + static internal bool HasCustomRequestHandler { + get { return _handler != null; } + } + /// <summary> /// Gets the web response, using the request handler to handle proxy authentication /// if necessary. diff --git a/Mono.Addins.Setup/mono-addins-setup.pc.in b/Mono.Addins.Setup/mono-addins-setup.pc.in deleted file mode 100644 index ec6cb95..0000000 --- a/Mono.Addins.Setup/mono-addins-setup.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=${pcfiledir}/../.. -exec_prefix=${prefix} -pkglibdir=${prefix}/lib/mono/@PACKAGE@ - -Libraries=${pkglibdir}/@MONO_ADDINS_SETUP_DEFAULT_LIB@ - -Name: Mono.Addins.Setup -Description: -Version: @VERSION@ - -Requires: mono-addins -Libs: -r:${pkglibdir}/@MONO_ADDINS_SETUP_DEFAULT_LIB@ diff --git a/Mono.Addins.Setup/packages.config b/Mono.Addins.Setup/packages.config deleted file mode 100644 index e6c29bd..0000000 --- a/Mono.Addins.Setup/packages.config +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
-</packages>
\ No newline at end of file |