From 5eeea56bda776bbdda7ca9d7b481aaccf26c03c2 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 20:13:05 -0400 Subject: [PATCH 01/13] Update export list --- .gitignore | 1 + Core/CKAN-core.csproj | 3 ++- Core/Types/ExportFileType.cs | 12 +++++++++ GUI/CKAN-GUI.csproj | 1 + GUI/ExportOption.cs | 27 ++++++++++++++++++++ GUI/Main.cs | 49 ++++++++++++++++++++++++++++++------ 6 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 Core/Types/ExportFileType.cs create mode 100644 GUI/ExportOption.cs diff --git a/.gitignore b/.gitignore index 0df9ea148c..575582a53a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +packages/ CKAN/*/bin CKAN/*/obj Tests/bin diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index 08b32a12ab..2031050fcd 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -46,6 +46,7 @@ <Compile Include="KSP.cs" /> <Compile Include="ModuleInstaller.cs" /> <Compile Include="CkanTransaction.cs" /> + <Compile Include="Types\ExportFileType.cs" /> <Compile Include="User.cs" /> <Compile Include="Types\Version.cs" /> <Compile Include="Types\KSPVersion.cs" /> @@ -83,4 +84,4 @@ </ItemGroup> <ItemGroup /> <ItemGroup /> -</Project> +</Project> \ No newline at end of file diff --git a/Core/Types/ExportFileType.cs b/Core/Types/ExportFileType.cs new file mode 100644 index 0000000000..87cf1ec99c --- /dev/null +++ b/Core/Types/ExportFileType.cs @@ -0,0 +1,12 @@ +namespace CKAN.Types +{ + public enum ExportFileType + { + Ckan, + PlainText, + Markdown, + BbCode, + Csv, + Tsv + } +} diff --git a/GUI/CKAN-GUI.csproj b/GUI/CKAN-GUI.csproj index c5f6454641..25ada8d56a 100644 --- a/GUI/CKAN-GUI.csproj +++ b/GUI/CKAN-GUI.csproj @@ -77,6 +77,7 @@ <Compile Include="ChooseKSPInstance.Designer.cs"> <DependentUpon>ChooseKSPInstance.cs</DependentUpon> </Compile> + <Compile Include="ExportOption.cs" /> <Compile Include="IGUIPlugin.cs"> <SubType>Code</SubType> </Compile> diff --git a/GUI/ExportOption.cs b/GUI/ExportOption.cs new file mode 100644 index 0000000000..3365de87fb --- /dev/null +++ b/GUI/ExportOption.cs @@ -0,0 +1,27 @@ +using CKAN.Types; + +namespace CKAN +{ + internal sealed class ExportOption + { + private readonly string _string; + + public ExportFileType ExportFileType { get; private set; } + public string FriendlyName { get; private set; } + public string Extension { get; private set; } + + public ExportOption(ExportFileType exportFileType, string friendlyName, string extension) + { + ExportFileType = exportFileType; + FriendlyName = friendlyName; + Extension = extension; + + _string = string.Format("{0}|{1}", FriendlyName, "*." + Extension); + } + + public override string ToString() + { + return _string; + } + } +} diff --git a/GUI/Main.cs b/GUI/Main.cs index 17e14acc73..79e8f0129b 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using CKAN.Properties; +using CKAN.Types; using log4net; using Timer = System.Windows.Forms.Timer; @@ -926,16 +927,50 @@ private void installFromckanToolStripMenuItem_Click(object sender, EventArgs e) /// <param name="e"></param> private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) { - var dlg = new SaveFileDialog(); - dlg.Filter = Resources.CKANFileFilter; - dlg.Title = Resources.ExportInstalledModsDialogTitle; + var exportOptions = new List<ExportOption> + { + new ExportOption(Types.ExportFileType.Ckan, "CKAN metadata (*.ckan)", "ckan"), + new ExportOption(Types.ExportFileType.PlainText, "Plain text (*.txt)", "txt"), + new ExportOption(Types.ExportFileType.Markdown, "Markdown (*.md)", "md"), + new ExportOption(Types.ExportFileType.BbCode, "BBCode (*.txt)", "txt"), + new ExportOption(Types.ExportFileType.Csv, "Comma-seperated values (*.csv)", "csv"), + new ExportOption(Types.ExportFileType.Tsv, "Tab-seperated values (*.tsv)", "tsv") + }; + + var filter = string.Join("|", exportOptions.Select(i => i.ToString()).ToArray()); + + var dlg = new SaveFileDialog + { + Filter = filter, + Title = Resources.ExportInstalledModsDialogTitle + }; if (dlg.ShowDialog() == DialogResult.OK) { - // Save, just to be certain that the installed-*.ckan metapackage is generated - RegistryManager.Instance(CurrentInstance).Save(); - // TODO: The core might eventually save as something other than 'installed-default.ckan' - File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); + var exportOption = exportOptions[dlg.FilterIndex]; + + switch (exportOption.ExportFileType) + { + case ExportFileType.Ckan: + // Save, just to be certain that the installed-*.ckan metapackage is generated + RegistryManager.Instance(CurrentInstance).Save(); + + // TODO: The core might eventually save as something other than 'installed-default.ckan' + File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); + break; + case ExportFileType.PlainText: + break; + case ExportFileType.Markdown: + break; + case ExportFileType.BbCode: + break; + case ExportFileType.Csv: + break; + case ExportFileType.Tsv: + break; + default: + throw new ArgumentOutOfRangeException(); + } } } From f1beaf340e9d50d4454a7d9126025ef9321b7d92 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 20:31:48 -0400 Subject: [PATCH 02/13] Implement PlainText export --- Core/CKAN-core.csproj | 2 ++ Core/Exporters/IExporter.cs | 17 ++++++++++ Core/Exporters/PlainTextExporter.cs | 17 ++++++++++ GUI/Main.cs | 51 ++++++++++++++++------------- 4 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 Core/Exporters/IExporter.cs create mode 100644 Core/Exporters/PlainTextExporter.cs diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index 2031050fcd..5c60d3c3f7 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -41,6 +41,8 @@ </Reference> </ItemGroup> <ItemGroup> + <Compile Include="Exporters\IExporter.cs" /> + <Compile Include="Exporters\PlainTextExporter.cs" /> <Compile Include="Net\AutoUpdate.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="KSP.cs" /> diff --git a/Core/Exporters/IExporter.cs b/Core/Exporters/IExporter.cs new file mode 100644 index 0000000000..7cb98b849d --- /dev/null +++ b/Core/Exporters/IExporter.cs @@ -0,0 +1,17 @@ +using System.IO; + +namespace CKAN.Exporters +{ + /// <summary> + /// Represents an object that can + /// </summary> + public interface IExporter + { + /// <summary> + /// + /// </summary> + /// <param name="registry"></param> + /// <param name="writer"></param> + void Export(Registry registry, TextWriter writer); + } +} diff --git a/Core/Exporters/PlainTextExporter.cs b/Core/Exporters/PlainTextExporter.cs new file mode 100644 index 0000000000..1e229f15df --- /dev/null +++ b/Core/Exporters/PlainTextExporter.cs @@ -0,0 +1,17 @@ +using System.IO; + +namespace CKAN.Exporters +{ + public sealed class PlainTextExporter : IExporter + { + public void Export(Registry registry, TextWriter writer) + { + foreach (var mod in registry.InstalledModules) + { + writer.WriteLine(@"{0} ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + } + + writer.Flush(); + } + } +} diff --git a/GUI/Main.cs b/GUI/Main.cs index 79e8f0129b..ac825baff1 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; +using CKAN.Exporters; using CKAN.Properties; using CKAN.Types; using log4net; @@ -945,31 +946,37 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) Title = Resources.ExportInstalledModsDialogTitle }; - if (dlg.ShowDialog() == DialogResult.OK) { - - var exportOption = exportOptions[dlg.FilterIndex]; + if (dlg.ShowDialog() == DialogResult.OK) + { + var exportOption = exportOptions[dlg.FilterIndex - 1]; // FilterIndex is 1-indexed - switch (exportOption.ExportFileType) + using (var writer = new StreamWriter(new FileStream(dlg.FileName, FileMode.OpenOrCreate))) { - case ExportFileType.Ckan: - // Save, just to be certain that the installed-*.ckan metapackage is generated - RegistryManager.Instance(CurrentInstance).Save(); + var registry = RegistryManager.Instance(CurrentInstance).registry; - // TODO: The core might eventually save as something other than 'installed-default.ckan' - File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); - break; - case ExportFileType.PlainText: - break; - case ExportFileType.Markdown: - break; - case ExportFileType.BbCode: - break; - case ExportFileType.Csv: - break; - case ExportFileType.Tsv: - break; - default: - throw new ArgumentOutOfRangeException(); + switch (exportOption.ExportFileType) + { + case ExportFileType.Ckan: + // Save, just to be certain that the installed-*.ckan metapackage is generated + RegistryManager.Instance(CurrentInstance).Save(); + + // TODO: The core might eventually save as something other than 'installed-default.ckan' + File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); + break; + case ExportFileType.PlainText: + new PlainTextExporter().Export(registry, writer); + break; + case ExportFileType.Markdown: + break; + case ExportFileType.BbCode: + break; + case ExportFileType.Csv: + break; + case ExportFileType.Tsv: + break; + default: + throw new ArgumentOutOfRangeException(); + } } } } From 67322b8b5da8c21bb335dc9191ee1b7f02243465 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 20:40:25 -0400 Subject: [PATCH 03/13] Implement MarkdownExporter --- Core/CKAN-core.csproj | 1 + Core/Exporters/MarkdownExporter.cs | 18 ++++++++++++++++++ Core/Exporters/PlainTextExporter.cs | 3 ++- GUI/Main.cs | 5 ++++- 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 Core/Exporters/MarkdownExporter.cs diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index 5c60d3c3f7..cb64bcc86e 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -42,6 +42,7 @@ </ItemGroup> <ItemGroup> <Compile Include="Exporters\IExporter.cs" /> + <Compile Include="Exporters\MarkdownExporter.cs" /> <Compile Include="Exporters\PlainTextExporter.cs" /> <Compile Include="Net\AutoUpdate.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> diff --git a/Core/Exporters/MarkdownExporter.cs b/Core/Exporters/MarkdownExporter.cs new file mode 100644 index 0000000000..6edde4cfbd --- /dev/null +++ b/Core/Exporters/MarkdownExporter.cs @@ -0,0 +1,18 @@ +using System.IO; +using System.Linq; + +namespace CKAN.Exporters +{ + public sealed class MarkdownExporter : IExporter + { + public void Export(Registry registry, TextWriter writer) + { + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(@"- *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + } + + writer.Flush(); + } + } +} diff --git a/Core/Exporters/PlainTextExporter.cs b/Core/Exporters/PlainTextExporter.cs index 1e229f15df..481030def7 100644 --- a/Core/Exporters/PlainTextExporter.cs +++ b/Core/Exporters/PlainTextExporter.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Linq; namespace CKAN.Exporters { @@ -6,7 +7,7 @@ public sealed class PlainTextExporter : IExporter { public void Export(Registry registry, TextWriter writer) { - foreach (var mod in registry.InstalledModules) + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) { writer.WriteLine(@"{0} ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); } diff --git a/GUI/Main.cs b/GUI/Main.cs index ac825baff1..d9596a3981 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -950,7 +950,9 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) { var exportOption = exportOptions[dlg.FilterIndex - 1]; // FilterIndex is 1-indexed - using (var writer = new StreamWriter(new FileStream(dlg.FileName, FileMode.OpenOrCreate))) + var fileMode = File.Exists(dlg.FileName) ? FileMode.Truncate : FileMode.CreateNew; + + using (var writer = new StreamWriter(new FileStream(dlg.FileName, fileMode))) { var registry = RegistryManager.Instance(CurrentInstance).registry; @@ -967,6 +969,7 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) new PlainTextExporter().Export(registry, writer); break; case ExportFileType.Markdown: + new MarkdownExporter().Export(registry, writer); break; case ExportFileType.BbCode: break; From 19dfdcd517701427fee02ef41a87ccff0d24ec8b Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 20:42:51 -0400 Subject: [PATCH 04/13] Implement BbCodeExporter --- Core/CKAN-core.csproj | 1 + Core/Exporters/BbCodeExporter.cs | 22 ++++++++++++++++++++++ GUI/Main.cs | 1 + 3 files changed, 24 insertions(+) create mode 100644 Core/Exporters/BbCodeExporter.cs diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index cb64bcc86e..d5f045a5ee 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -41,6 +41,7 @@ </Reference> </ItemGroup> <ItemGroup> + <Compile Include="Exporters\BbCodeExporter.cs" /> <Compile Include="Exporters\IExporter.cs" /> <Compile Include="Exporters\MarkdownExporter.cs" /> <Compile Include="Exporters\PlainTextExporter.cs" /> diff --git a/Core/Exporters/BbCodeExporter.cs b/Core/Exporters/BbCodeExporter.cs new file mode 100644 index 0000000000..f97edbade7 --- /dev/null +++ b/Core/Exporters/BbCodeExporter.cs @@ -0,0 +1,22 @@ +using System.IO; +using System.Linq; + +namespace CKAN.Exporters +{ + public sealed class BbCodeExporter : IExporter + { + public void Export(Registry registry, TextWriter writer) + { + writer.WriteLine("[LIST]"); + + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(@"[*][I]{0}[/I] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + } + + writer.WriteLine("[/LIST]"); + + writer.Flush(); + } + } +} diff --git a/GUI/Main.cs b/GUI/Main.cs index d9596a3981..0c3cf7e69d 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -972,6 +972,7 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) new MarkdownExporter().Export(registry, writer); break; case ExportFileType.BbCode: + new BbCodeExporter().Export(registry, writer); break; case ExportFileType.Csv: break; From d09178487ad3834b05a57a4e97bb9b0eb6764693 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 21:12:40 -0400 Subject: [PATCH 05/13] Implement DSVExporter --- Core/CKAN-core.csproj | 1 + .../DelimeterSeperatedValueExporter.cs | 145 ++++++++++++++++++ GUI/Main.cs | 4 + 3 files changed, 150 insertions(+) create mode 100644 Core/Exporters/DelimeterSeperatedValueExporter.cs diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index d5f045a5ee..47deb913f0 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -42,6 +42,7 @@ </ItemGroup> <ItemGroup> <Compile Include="Exporters\BbCodeExporter.cs" /> + <Compile Include="Exporters\DelimeterSeperatedValueExporter.cs" /> <Compile Include="Exporters\IExporter.cs" /> <Compile Include="Exporters\MarkdownExporter.cs" /> <Compile Include="Exporters\PlainTextExporter.cs" /> diff --git a/Core/Exporters/DelimeterSeperatedValueExporter.cs b/Core/Exporters/DelimeterSeperatedValueExporter.cs new file mode 100644 index 0000000000..f1820ac9a8 --- /dev/null +++ b/Core/Exporters/DelimeterSeperatedValueExporter.cs @@ -0,0 +1,145 @@ +using System; +using System.IO; +using System.Linq; + +namespace CKAN.Exporters +{ + public sealed class DelimeterSeperatedValueExporter : IExporter + { + private const string WritePattern = "{1}{0}{2}{0}{3}{0}{4}{0}{5}" + + "{0}{6}{0}{7}{0}{8}{0}{9}{0}{10}" + + "{0}{11}{0}{12}{0}{13}{0}{14}{0}{15}" + + "{0}{16}{0}{17}{0}{18}"; + private readonly string _delimter; + + public DelimeterSeperatedValueExporter(Delimter delimter) + { + switch (delimter) + { + case Delimter.Comma: + _delimter = ","; + break; + case Delimter.Tab: + _delimter = "\t"; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void Export(Registry registry, TextWriter writer) + { + writer.WriteLine(WritePattern, + _delimter, + "identifier", + "version", + "name", + "abstract", + "description", + "author", + "kind", + "download", + "download_size", + "ksp_version", + "ksp_version_min", + "ksp_version_max", + "license", + "release_status", + "repository", + "homepage", + "bugtracker", + "kerbalstuff" + ); + + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(WritePattern, + _delimter, + mod.Module.identifier, + mod.Module.version, + QuoteIfNecessary(mod.Module.name), + QuoteIfNecessary(mod.Module.@abstract), + QuoteIfNecessary(mod.Module.description), + QuoteIfNecessary(string.Join(";", mod.Module.author)), + QuoteIfNecessary(mod.Module.kind), + WriteUri(mod.Module.download), + mod.Module.download_size, + mod.Module.ksp_version, + mod.Module.ksp_version_min, + mod.Module.ksp_version_max, + mod.Module.license, + mod.Module.release_status, + WriteRepository(mod.Module.resources), + WriteHomepage(mod.Module.resources), + WriteBugtracker(mod.Module.resources), + WriteKerbalStuff(mod.Module.resources) + ); + } + + writer.Flush(); + } + + private string WriteUri(Uri uri) + { + return uri != null ? QuoteIfNecessary(uri.ToString()) : string.Empty; + } + + private string WriteRepository(ResourcesDescriptor resources) + { + if (resources != null && resources.repository != null) + { + return QuoteIfNecessary(resources.repository.ToString()); + } + + return string.Empty; + } + + private string WriteHomepage(ResourcesDescriptor resources) + { + if (resources != null && resources.homepage != null) + { + return QuoteIfNecessary(resources.homepage.ToString()); + } + + return string.Empty; + } + + private string WriteBugtracker(ResourcesDescriptor resources) + { + if (resources != null && resources.bugtracker != null) + { + return QuoteIfNecessary(resources.bugtracker.ToString()); + } + + return string.Empty; + } + + private string WriteKerbalStuff(ResourcesDescriptor resources) + { + if (resources != null && resources.kerbalstuff != null) + { + return QuoteIfNecessary(resources.kerbalstuff.ToString()); + } + + return string.Empty; + } + + private string QuoteIfNecessary(string value) + { + if (value != null && value.IndexOf(_delimter, StringComparison.Ordinal) >= 0) + { + return "\"" + value + "\""; + } + else + { + return value; + } + } + + public enum Delimter + { + Comma, + Tab + } + } +} diff --git a/GUI/Main.cs b/GUI/Main.cs index 0c3cf7e69d..0146abd2d7 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -975,8 +975,12 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) new BbCodeExporter().Export(registry, writer); break; case ExportFileType.Csv: + new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) + .Export(registry, writer); break; case ExportFileType.Tsv: + new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) + .Export(registry, writer); break; default: throw new ArgumentOutOfRangeException(); From 7c308d39b0089d55db18782257294f92f840e2d4 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 21:26:34 -0400 Subject: [PATCH 06/13] Implement in command line --- Cmdline/Action/List.cs | 149 +++++++++++++++++++++++++++++------------ Cmdline/Options.cs | 3 + 2 files changed, 111 insertions(+), 41 deletions(-) diff --git a/Cmdline/Action/List.cs b/Cmdline/Action/List.cs index 4be34529e7..3ba6ad69dd 100644 --- a/Cmdline/Action/List.cs +++ b/Cmdline/Action/List.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; +using CKAN.Exporters; +using CKAN.Types; using log4net; namespace CKAN.CmdLine @@ -23,7 +26,20 @@ public int RunCommand(CKAN.KSP ksp, object raw_options) Registry registry = RegistryManager.Instance(ksp).registry; - if (!(options.porcelain)) + + ExportFileType? exportFileType = null; + + if (!string.IsNullOrWhiteSpace(options.export)) + { + exportFileType = GetExportFileType(options.export); + + if (exportFileType == null) + { + user.RaiseError("Unknown export format: {0}", options.export); + } + } + + if (!(options.porcelain) && exportFileType == null) { user.RaiseMessage("\nKSP found at {0}\n", ksp.GameDir()); user.RaiseMessage("KSP Version: {0}\n", ksp.Version()); @@ -31,66 +47,117 @@ public int RunCommand(CKAN.KSP ksp, object raw_options) user.RaiseMessage("Installed Modules:\n"); } - var installed = new SortedDictionary<string, Version>(registry.Installed()); - - foreach (KeyValuePair<string, Version> mod in installed) + if (exportFileType == null) { - Version current_version = mod.Value; + var installed = new SortedDictionary<string, Version>(registry.Installed()); - string bullet = "*"; - - if (current_version is ProvidesVersion) - { - // Skip virtuals for now. - continue; - } - else if (current_version is DllVersion) - { - // Autodetected dll - bullet = "-"; - } - else + foreach (KeyValuePair<string, Version> mod in installed) { - try - { - // Check if upgrades are available, and show appropriately. - CkanModule latest = registry.LatestAvailable(mod.Key, ksp.Version()); + Version current_version = mod.Value; - log.InfoFormat("Latest {0} is {1}", mod.Key, latest); + string bullet = "*"; - if (latest == null) - { - // Not compatible! - bullet = "X"; - } - else if (latest.version.IsEqualTo(current_version)) + if (current_version is ProvidesVersion) + { + // Skip virtuals for now. + continue; + } + else if (current_version is DllVersion) + { + // Autodetected dll + bullet = "-"; + } + else + { + try { - // Up to date - bullet = "-"; + // Check if upgrades are available, and show appropriately. + CkanModule latest = registry.LatestAvailable(mod.Key, ksp.Version()); + + log.InfoFormat("Latest {0} is {1}", mod.Key, latest); + + if (latest == null) + { + // Not compatible! + bullet = "X"; + } + else if (latest.version.IsEqualTo(current_version)) + { + // Up to date + bullet = "-"; + } + else if (latest.version.IsGreaterThan(mod.Value)) + { + // Upgradable + bullet = "^"; + } } - else if (latest.version.IsGreaterThan(mod.Value)) + catch (ModuleNotFoundKraken) { - // Upgradable - bullet = "^"; + log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key); + bullet = "?"; } } - catch (ModuleNotFoundKraken) - { - log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key); - bullet = "?"; - } + + user.RaiseMessage("{0} {1} {2}", bullet, mod.Key, mod.Value); } + } + else + { + var writer = Console.Out; - user.RaiseMessage("{0} {1} {2}", bullet, mod.Key, mod.Value); + switch (exportFileType.Value) + { + case ExportFileType.PlainText: + new PlainTextExporter().Export(registry, writer); + break; + case ExportFileType.Markdown: + new MarkdownExporter().Export(registry, writer); + break; + case ExportFileType.BbCode: + new BbCodeExporter().Export(registry, writer); + break; + case ExportFileType.Csv: + new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) + .Export(registry, writer); + break; + case ExportFileType.Tsv: + new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) + .Export(registry, writer); + break; + default: + throw new ArgumentOutOfRangeException(); + } } - if (!(options.porcelain)) + if (!(options.porcelain) && exportFileType == null) { user.RaiseMessage("\nLegend: -: Up to date. X: Incompatible. ^: Upgradable. ?: Unknown "); } return Exit.OK; } + + private ExportFileType? GetExportFileType(string export) + { + export = export.ToLowerInvariant(); + + switch (export) + { + case "text": + return ExportFileType.PlainText; + case "markdown": + return ExportFileType.Markdown; + case "bbcode": + return ExportFileType.BbCode; + case "csv": + return ExportFileType.Csv; + case "tsv": + return ExportFileType.Tsv; + default: + return null; + } + } } } diff --git a/Cmdline/Options.cs b/Cmdline/Options.cs index bf59f046e8..baf229f4c7 100644 --- a/Cmdline/Options.cs +++ b/Cmdline/Options.cs @@ -176,6 +176,9 @@ internal class ListOptions : CommonOptions { [Option("porcelain", HelpText = "Dump raw list of modules, good for shell scripting")] public bool porcelain { get; set; } + + [Option("export", HelpText = "Export list of modules in specified format to stdout")] + public string export { get; set; } } internal class VersionOptions : CommonOptions From 5b47647eacad635189b18b74059b8fe832ccc95d Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Wed, 10 Jun 2015 23:46:19 -0400 Subject: [PATCH 07/13] Add some leading spaces to Markdown export --- Core/Exporters/MarkdownExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Exporters/MarkdownExporter.cs b/Core/Exporters/MarkdownExporter.cs index 6edde4cfbd..a467708418 100644 --- a/Core/Exporters/MarkdownExporter.cs +++ b/Core/Exporters/MarkdownExporter.cs @@ -9,7 +9,7 @@ public void Export(Registry registry, TextWriter writer) { foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) { - writer.WriteLine(@"- *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + writer.WriteLine(@" - *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); } writer.Flush(); From b25cd7c8103a52fc8e46bcc164204f4c6b66bd36 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Thu, 11 Jun 2015 10:05:33 -0400 Subject: [PATCH 08/13] Update doc comments --- Core/Exporters/IExporter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/Exporters/IExporter.cs b/Core/Exporters/IExporter.cs index 7cb98b849d..2870c5e0c8 100644 --- a/Core/Exporters/IExporter.cs +++ b/Core/Exporters/IExporter.cs @@ -3,15 +3,15 @@ namespace CKAN.Exporters { /// <summary> - /// Represents an object that can + /// Represents an object that can export a list of mods in a machine/human readable text format. /// </summary> public interface IExporter { /// <summary> - /// + /// Export the installed mods. /// </summary> - /// <param name="registry"></param> - /// <param name="writer"></param> + /// <param name="registry">The registry of mods to be exported.</param> + /// <param name="writer">The text writer to write the export to.</param> void Export(Registry registry, TextWriter writer); } } From f018bfe5c49c8601d687485c6c20175878dcdfb7 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Fri, 12 Jun 2015 09:36:45 -0400 Subject: [PATCH 09/13] Use Stream instead of TextWriter --- Cmdline/Action/List.cs | 12 +-- Core/Exporters/BbCodeExporter.cs | 17 ++-- .../DelimeterSeperatedValueExporter.cs | 91 ++++++++++--------- Core/Exporters/IExporter.cs | 8 +- Core/Exporters/MarkdownExporter.cs | 11 ++- Core/Exporters/PlainTextExporter.cs | 12 ++- GUI/Main.cs | 12 +-- 7 files changed, 85 insertions(+), 78 deletions(-) diff --git a/Cmdline/Action/List.cs b/Cmdline/Action/List.cs index 3ba6ad69dd..a583eaafe5 100644 --- a/Cmdline/Action/List.cs +++ b/Cmdline/Action/List.cs @@ -104,26 +104,26 @@ public int RunCommand(CKAN.KSP ksp, object raw_options) } else { - var writer = Console.Out; + var stream = Console.OpenStandardOutput(); switch (exportFileType.Value) { case ExportFileType.PlainText: - new PlainTextExporter().Export(registry, writer); + new PlainTextExporter().Export(registry, stream); break; case ExportFileType.Markdown: - new MarkdownExporter().Export(registry, writer); + new MarkdownExporter().Export(registry, stream); break; case ExportFileType.BbCode: - new BbCodeExporter().Export(registry, writer); + new BbCodeExporter().Export(registry, stream); break; case ExportFileType.Csv: new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) - .Export(registry, writer); + .Export(registry, stream); break; case ExportFileType.Tsv: new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) - .Export(registry, writer); + .Export(registry, stream); break; default: throw new ArgumentOutOfRangeException(); diff --git a/Core/Exporters/BbCodeExporter.cs b/Core/Exporters/BbCodeExporter.cs index f97edbade7..1bd0471e13 100644 --- a/Core/Exporters/BbCodeExporter.cs +++ b/Core/Exporters/BbCodeExporter.cs @@ -5,18 +5,19 @@ namespace CKAN.Exporters { public sealed class BbCodeExporter : IExporter { - public void Export(Registry registry, TextWriter writer) + public void Export(Registry registry, Stream stream) { - writer.WriteLine("[LIST]"); - - foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + using (var writer = new StreamWriter(stream)) { - writer.WriteLine(@"[*][I]{0}[/I] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); - } + writer.WriteLine("[LIST]"); - writer.WriteLine("[/LIST]"); + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(@"[*][I]{0}[/I] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + } - writer.Flush(); + writer.WriteLine("[/LIST]"); + } } } } diff --git a/Core/Exporters/DelimeterSeperatedValueExporter.cs b/Core/Exporters/DelimeterSeperatedValueExporter.cs index f1820ac9a8..e9abd6b04b 100644 --- a/Core/Exporters/DelimeterSeperatedValueExporter.cs +++ b/Core/Exporters/DelimeterSeperatedValueExporter.cs @@ -27,56 +27,57 @@ public DelimeterSeperatedValueExporter(Delimter delimter) } } - public void Export(Registry registry, TextWriter writer) + public void Export(Registry registry, Stream stream) { - writer.WriteLine(WritePattern, - _delimter, - "identifier", - "version", - "name", - "abstract", - "description", - "author", - "kind", - "download", - "download_size", - "ksp_version", - "ksp_version_min", - "ksp_version_max", - "license", - "release_status", - "repository", - "homepage", - "bugtracker", - "kerbalstuff" - ); - - foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + using (var writer = new StreamWriter(stream)) { writer.WriteLine(WritePattern, _delimter, - mod.Module.identifier, - mod.Module.version, - QuoteIfNecessary(mod.Module.name), - QuoteIfNecessary(mod.Module.@abstract), - QuoteIfNecessary(mod.Module.description), - QuoteIfNecessary(string.Join(";", mod.Module.author)), - QuoteIfNecessary(mod.Module.kind), - WriteUri(mod.Module.download), - mod.Module.download_size, - mod.Module.ksp_version, - mod.Module.ksp_version_min, - mod.Module.ksp_version_max, - mod.Module.license, - mod.Module.release_status, - WriteRepository(mod.Module.resources), - WriteHomepage(mod.Module.resources), - WriteBugtracker(mod.Module.resources), - WriteKerbalStuff(mod.Module.resources) + "identifier", + "version", + "name", + "abstract", + "description", + "author", + "kind", + "download", + "download_size", + "ksp_version", + "ksp_version_min", + "ksp_version_max", + "license", + "release_status", + "repository", + "homepage", + "bugtracker", + "kerbalstuff" ); - } - writer.Flush(); + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(WritePattern, + _delimter, + mod.Module.identifier, + mod.Module.version, + QuoteIfNecessary(mod.Module.name), + QuoteIfNecessary(mod.Module.@abstract), + QuoteIfNecessary(mod.Module.description), + QuoteIfNecessary(string.Join(";", mod.Module.author)), + QuoteIfNecessary(mod.Module.kind), + WriteUri(mod.Module.download), + mod.Module.download_size, + mod.Module.ksp_version, + mod.Module.ksp_version_min, + mod.Module.ksp_version_max, + mod.Module.license, + mod.Module.release_status, + WriteRepository(mod.Module.resources), + WriteHomepage(mod.Module.resources), + WriteBugtracker(mod.Module.resources), + WriteKerbalStuff(mod.Module.resources) + ); + } + } } private string WriteUri(Uri uri) @@ -141,5 +142,7 @@ public enum Delimter Comma, Tab } + + } } diff --git a/Core/Exporters/IExporter.cs b/Core/Exporters/IExporter.cs index 2870c5e0c8..0eca948bc1 100644 --- a/Core/Exporters/IExporter.cs +++ b/Core/Exporters/IExporter.cs @@ -3,15 +3,15 @@ namespace CKAN.Exporters { /// <summary> - /// Represents an object that can export a list of mods in a machine/human readable text format. + /// Represents an object that can export a list of mods in a machine or human readable format. /// </summary> public interface IExporter { /// <summary> - /// Export the installed mods. + /// Export installed mods. /// </summary> /// <param name="registry">The registry of mods to be exported.</param> - /// <param name="writer">The text writer to write the export to.</param> - void Export(Registry registry, TextWriter writer); + /// <param name="stream">The output stream to be written to.</param> + void Export(Registry registry, Stream stream); } } diff --git a/Core/Exporters/MarkdownExporter.cs b/Core/Exporters/MarkdownExporter.cs index a467708418..84dcbf4ec2 100644 --- a/Core/Exporters/MarkdownExporter.cs +++ b/Core/Exporters/MarkdownExporter.cs @@ -5,14 +5,15 @@ namespace CKAN.Exporters { public sealed class MarkdownExporter : IExporter { - public void Export(Registry registry, TextWriter writer) + public void Export(Registry registry, Stream stream) { - foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + using (var writer = new StreamWriter(stream)) { - writer.WriteLine(@" - *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(@" - *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + } } - - writer.Flush(); } } } diff --git a/Core/Exporters/PlainTextExporter.cs b/Core/Exporters/PlainTextExporter.cs index 481030def7..ba6b9ed2cc 100644 --- a/Core/Exporters/PlainTextExporter.cs +++ b/Core/Exporters/PlainTextExporter.cs @@ -5,14 +5,16 @@ namespace CKAN.Exporters { public sealed class PlainTextExporter : IExporter { - public void Export(Registry registry, TextWriter writer) + + public void Export(Registry registry, Stream stream) { - foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + using (var writer = new StreamWriter(stream)) { - writer.WriteLine(@"{0} ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) + { + writer.WriteLine(@"{0} ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + } } - - writer.Flush(); } } } diff --git a/GUI/Main.cs b/GUI/Main.cs index 0146abd2d7..a945989a5a 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -952,7 +952,7 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) var fileMode = File.Exists(dlg.FileName) ? FileMode.Truncate : FileMode.CreateNew; - using (var writer = new StreamWriter(new FileStream(dlg.FileName, fileMode))) + using (var stream = new FileStream(dlg.FileName, fileMode)) { var registry = RegistryManager.Instance(CurrentInstance).registry; @@ -966,21 +966,21 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); break; case ExportFileType.PlainText: - new PlainTextExporter().Export(registry, writer); + new PlainTextExporter().Export(registry, stream); break; case ExportFileType.Markdown: - new MarkdownExporter().Export(registry, writer); + new MarkdownExporter().Export(registry, stream); break; case ExportFileType.BbCode: - new BbCodeExporter().Export(registry, writer); + new BbCodeExporter().Export(registry, stream); break; case ExportFileType.Csv: new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) - .Export(registry, writer); + .Export(registry, stream); break; case ExportFileType.Tsv: new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) - .Export(registry, writer); + .Export(registry, stream); break; default: throw new ArgumentOutOfRangeException(); From cf138c74cb67a777690cd590cc321e6ad09f1743 Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Fri, 12 Jun 2015 09:37:25 -0400 Subject: [PATCH 10/13] Use bold instead of italics --- Core/Exporters/BbCodeExporter.cs | 2 +- Core/Exporters/MarkdownExporter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Exporters/BbCodeExporter.cs b/Core/Exporters/BbCodeExporter.cs index 1bd0471e13..6060421872 100644 --- a/Core/Exporters/BbCodeExporter.cs +++ b/Core/Exporters/BbCodeExporter.cs @@ -13,7 +13,7 @@ public void Export(Registry registry, Stream stream) foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) { - writer.WriteLine(@"[*][I]{0}[/I] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); + writer.WriteLine(@"[*][B]{0}[/B] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version); } writer.WriteLine("[/LIST]"); diff --git a/Core/Exporters/MarkdownExporter.cs b/Core/Exporters/MarkdownExporter.cs index 84dcbf4ec2..20a3197bf9 100644 --- a/Core/Exporters/MarkdownExporter.cs +++ b/Core/Exporters/MarkdownExporter.cs @@ -11,7 +11,7 @@ public void Export(Registry registry, Stream stream) { foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) { - writer.WriteLine(@" - *{0}* `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + writer.WriteLine(@" - **{0}** `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); } } } From 7305ce014726b697e40940221eed391d9b9658af Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Fri, 12 Jun 2015 09:46:39 -0400 Subject: [PATCH 11/13] Use a meta-exporter to consolidate code --- Cmdline/Action/List.cs | 25 ++--------------- Core/CKAN-core.csproj | 1 + Core/Exporters/Exporter.cs | 40 +++++++++++++++++++++++++++ GUI/Main.cs | 55 +++++++++++++------------------------- 4 files changed, 62 insertions(+), 59 deletions(-) create mode 100644 Core/Exporters/Exporter.cs diff --git a/Cmdline/Action/List.cs b/Cmdline/Action/List.cs index a583eaafe5..9f58c53b34 100644 --- a/Cmdline/Action/List.cs +++ b/Cmdline/Action/List.cs @@ -105,29 +105,8 @@ public int RunCommand(CKAN.KSP ksp, object raw_options) else { var stream = Console.OpenStandardOutput(); - - switch (exportFileType.Value) - { - case ExportFileType.PlainText: - new PlainTextExporter().Export(registry, stream); - break; - case ExportFileType.Markdown: - new MarkdownExporter().Export(registry, stream); - break; - case ExportFileType.BbCode: - new BbCodeExporter().Export(registry, stream); - break; - case ExportFileType.Csv: - new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) - .Export(registry, stream); - break; - case ExportFileType.Tsv: - new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) - .Export(registry, stream); - break; - default: - throw new ArgumentOutOfRangeException(); - } + new Exporter(exportFileType.Value).Export(registry, stream); + stream.Flush(); } if (!(options.porcelain) && exportFileType == null) diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj index 47deb913f0..fcd0e24c30 100644 --- a/Core/CKAN-core.csproj +++ b/Core/CKAN-core.csproj @@ -43,6 +43,7 @@ <ItemGroup> <Compile Include="Exporters\BbCodeExporter.cs" /> <Compile Include="Exporters\DelimeterSeperatedValueExporter.cs" /> + <Compile Include="Exporters\Exporter.cs" /> <Compile Include="Exporters\IExporter.cs" /> <Compile Include="Exporters\MarkdownExporter.cs" /> <Compile Include="Exporters\PlainTextExporter.cs" /> diff --git a/Core/Exporters/Exporter.cs b/Core/Exporters/Exporter.cs new file mode 100644 index 0000000000..fa9db557cd --- /dev/null +++ b/Core/Exporters/Exporter.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using CKAN.Types; + +namespace CKAN.Exporters +{ + public sealed class Exporter : IExporter + { + private readonly IExporter _exporter; + + public Exporter(ExportFileType exportFileType) + { + switch (exportFileType) + { + case ExportFileType.PlainText: + _exporter = new PlainTextExporter(); + break; + case ExportFileType.Markdown: + _exporter = new MarkdownExporter(); + break; + case ExportFileType.BbCode: + _exporter = new BbCodeExporter(); + break; + case ExportFileType.Csv: + _exporter = new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma); + break; + case ExportFileType.Tsv: + _exporter = new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void Export(Registry registry, Stream stream) + { + _exporter.Export(registry, stream); + } + } +} diff --git a/GUI/Main.cs b/GUI/Main.cs index a945989a5a..f8b3521133 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -930,12 +930,12 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) { var exportOptions = new List<ExportOption> { - new ExportOption(Types.ExportFileType.Ckan, "CKAN metadata (*.ckan)", "ckan"), - new ExportOption(Types.ExportFileType.PlainText, "Plain text (*.txt)", "txt"), - new ExportOption(Types.ExportFileType.Markdown, "Markdown (*.md)", "md"), - new ExportOption(Types.ExportFileType.BbCode, "BBCode (*.txt)", "txt"), - new ExportOption(Types.ExportFileType.Csv, "Comma-seperated values (*.csv)", "csv"), - new ExportOption(Types.ExportFileType.Tsv, "Tab-seperated values (*.tsv)", "tsv") + new ExportOption(ExportFileType.Ckan, "CKAN metadata (*.ckan)", "ckan"), + new ExportOption(ExportFileType.PlainText, "Plain text (*.txt)", "txt"), + new ExportOption(ExportFileType.Markdown, "Markdown (*.md)", "md"), + new ExportOption(ExportFileType.BbCode, "BBCode (*.txt)", "txt"), + new ExportOption(ExportFileType.Csv, "Comma-seperated values (*.csv)", "csv"), + new ExportOption(ExportFileType.Tsv, "Tab-seperated values (*.tsv)", "tsv") }; var filter = string.Join("|", exportOptions.Select(i => i.ToString()).ToArray()); @@ -950,40 +950,23 @@ private void exportModListToolStripMenuItem_Click(object sender, EventArgs e) { var exportOption = exportOptions[dlg.FilterIndex - 1]; // FilterIndex is 1-indexed - var fileMode = File.Exists(dlg.FileName) ? FileMode.Truncate : FileMode.CreateNew; + if (exportOption.ExportFileType == ExportFileType.Ckan) + { + // Save, just to be certain that the installed-*.ckan metapackage is generated + RegistryManager.Instance(CurrentInstance).Save(); - using (var stream = new FileStream(dlg.FileName, fileMode)) + // TODO: The core might eventually save as something other than 'installed-default.ckan' + File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); + } + else { - var registry = RegistryManager.Instance(CurrentInstance).registry; + var fileMode = File.Exists(dlg.FileName) ? FileMode.Truncate : FileMode.CreateNew; - switch (exportOption.ExportFileType) + using (var stream = new FileStream(dlg.FileName, fileMode)) { - case ExportFileType.Ckan: - // Save, just to be certain that the installed-*.ckan metapackage is generated - RegistryManager.Instance(CurrentInstance).Save(); - - // TODO: The core might eventually save as something other than 'installed-default.ckan' - File.Copy(Path.Combine(CurrentInstance.CkanDir(), "installed-default.ckan"), dlg.FileName); - break; - case ExportFileType.PlainText: - new PlainTextExporter().Export(registry, stream); - break; - case ExportFileType.Markdown: - new MarkdownExporter().Export(registry, stream); - break; - case ExportFileType.BbCode: - new BbCodeExporter().Export(registry, stream); - break; - case ExportFileType.Csv: - new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Comma) - .Export(registry, stream); - break; - case ExportFileType.Tsv: - new DelimeterSeperatedValueExporter(DelimeterSeperatedValueExporter.Delimter.Tab) - .Export(registry, stream); - break; - default: - throw new ArgumentOutOfRangeException(); + var registry = RegistryManager.Instance(CurrentInstance).registry; + + new Exporter(exportOption.ExportFileType).Export(registry, stream); } } } From 0a0f08cca06fbbdb30e9cd663eeb5bed28550fbd Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Fri, 12 Jun 2015 10:39:28 -0400 Subject: [PATCH 12/13] Add doc comment to Exporter --- Cmdline/Action/List.cs | 2 +- Core/Exporters/Exporter.cs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Cmdline/Action/List.cs b/Cmdline/Action/List.cs index 9f58c53b34..d0202dae1b 100644 --- a/Cmdline/Action/List.cs +++ b/Cmdline/Action/List.cs @@ -117,7 +117,7 @@ public int RunCommand(CKAN.KSP ksp, object raw_options) return Exit.OK; } - private ExportFileType? GetExportFileType(string export) + private static ExportFileType? GetExportFileType(string export) { export = export.ToLowerInvariant(); diff --git a/Core/Exporters/Exporter.cs b/Core/Exporters/Exporter.cs index fa9db557cd..5ccd3ee593 100644 --- a/Core/Exporters/Exporter.cs +++ b/Core/Exporters/Exporter.cs @@ -4,6 +4,14 @@ namespace CKAN.Exporters { + /// <summary> + /// An implementation of <see cref="IExporter"/> that knows how to export to the different types of + /// <see cref="ExportFileType"/>. + /// </summary> + /// <remarks> + /// <see cref="ExportFileType.Ckan"/> is currently unhandled as that requires use of the + /// <see cref="RegistryManager"/> rather than just the <see cref="Registry"/>. + /// </remarks> public sealed class Exporter : IExporter { private readonly IExporter _exporter; From c3ae159db63f2d55c8db3e612f9ad3fb707c067d Mon Sep 17 00:00:00 2001 From: Dwayne Bent <dbb@dbb.io> Date: Sat, 13 Jun 2015 08:30:27 -0400 Subject: [PATCH 13/13] Markdown spec has no indentation for lists --- Core/Exporters/MarkdownExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Exporters/MarkdownExporter.cs b/Core/Exporters/MarkdownExporter.cs index 20a3197bf9..87f3434106 100644 --- a/Core/Exporters/MarkdownExporter.cs +++ b/Core/Exporters/MarkdownExporter.cs @@ -11,7 +11,7 @@ public void Export(Registry registry, Stream stream) { foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name)) { - writer.WriteLine(@" - **{0}** `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); + writer.WriteLine(@"- **{0}** `{1} {2}`", mod.Module.name, mod.identifier, mod.Module.version); } } }