Skip to content

Commit

Permalink
Merge pull request #1099 from KSP-CKAN/topic/friendly_mod_export
Browse files Browse the repository at this point in the history
Friendly Mod Export
  • Loading branch information
dbent committed Jun 14, 2015
2 parents e233a4f + c3ae159 commit d76e0ba
Show file tree
Hide file tree
Showing 14 changed files with 456 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
packages/
CKAN/*/bin
CKAN/*/obj
Tests/bin
Expand Down
130 changes: 88 additions & 42 deletions Cmdline/Action/List.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -23,74 +26,117 @@ 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());

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);
user.RaiseMessage("{0} {1} {2}", bullet, mod.Key, mod.Value);
}
}
else
{
var stream = Console.OpenStandardOutput();
new Exporter(exportFileType.Value).Export(registry, stream);
stream.Flush();
}

if (!(options.porcelain))
if (!(options.porcelain) && exportFileType == null)
{
user.RaiseMessage("\nLegend: -: Up to date. X: Incompatible. ^: Upgradable. ?: Unknown ");
}

return Exit.OK;
}

private static 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;
}
}
}
}

3 changes: 3 additions & 0 deletions Cmdline/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion Core/CKAN-core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,18 @@
</Reference>
</ItemGroup>
<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" />
<Compile Include="Net\AutoUpdate.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<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" />
Expand Down Expand Up @@ -83,4 +90,4 @@
</ItemGroup>
<ItemGroup />
<ItemGroup />
</Project>
</Project>
23 changes: 23 additions & 0 deletions Core/Exporters/BbCodeExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.IO;
using System.Linq;

namespace CKAN.Exporters
{
public sealed class BbCodeExporter : IExporter
{
public void Export(Registry registry, Stream stream)
{
using (var writer = new StreamWriter(stream))
{
writer.WriteLine("[LIST]");

foreach (var mod in registry.InstalledModules.OrderBy(i => i.Module.name))
{
writer.WriteLine(@"[*][B]{0}[/B] ({1} {2})", mod.Module.name, mod.identifier, mod.Module.version);
}

writer.WriteLine("[/LIST]");
}
}
}
}
148 changes: 148 additions & 0 deletions Core/Exporters/DelimeterSeperatedValueExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
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, Stream stream)
{
using (var writer = new StreamWriter(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))
{
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)
{
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
}


}
}
Loading

0 comments on commit d76e0ba

Please sign in to comment.