Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Per #374 allow files without krefs #1169

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 91 additions & 69 deletions Netkan/MainClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,38 @@ public static int Main(string[] args)
log.InfoFormat("Processing {0}", options.File);

JObject json = JsonFromFile(options.File);
NetKanRemote remote = FindRemote(json);

JObject metadata;
switch (remote.source)
{
case "kerbalstuff":
metadata = KerbalStuff(json, remote.id, cache);
break;
case "jenkins":
metadata = Jenkins(json, remote.id, cache);
break;
case "github":
if (options.GitHubToken != null)
{
GithubAPI.SetCredentials(options.GitHubToken);
}
NetKanRemote remote = FindRemoteKref(json,user);

metadata = GitHub(json, remote.id, options.PreRelease, cache);
break;
case "http":
metadata = HTTP(json, remote.id, cache, user);
break;
default:
log.FatalFormat("Unknown remote source: {0}", remote.source);
return EXIT_ERROR;
JObject metadata = json;
if (remote == null)
{
log.WarnFormat("Not inflating metadata for {0}", json["identifier"]);
}
else
{
switch (remote.source)
{
case "kerbalstuff":
metadata = KerbalStuff(json, remote.id, cache);
break;
case "jenkins":
metadata = Jenkins(json, remote.id, cache);
break;
case "github":
if (options.GitHubToken != null)
{
GithubAPI.SetCredentials(options.GitHubToken);
}

metadata = GitHub(json, remote.id, options.PreRelease, cache);
break;
case "http":
metadata = HTTP(json, remote.id, cache, user);
break;
default:
log.FatalFormat("Unknown remote source: {0}", remote.source);
return EXIT_ERROR;
}
}

if (metadata == null)
Expand All @@ -99,7 +106,7 @@ public static int Main(string[] args)
CkanModule mod = CkanModule.FromJson(metadata.ToString());

// Make sure our identifiers match.
if (mod.identifier != (string)json["identifier"])
if (mod.identifier != (string) json["identifier"])
{
log.FatalFormat("Error: Have metadata for {0}, but wanted {1}", mod.identifier, json["identifier"]);
return EXIT_ERROR;
Expand All @@ -109,8 +116,16 @@ public static int Main(string[] args)
string file = cache.GetCachedZip(mod.download);
if (file == null)
{
log.FatalFormat("Error: Unable to find {0} in the cache", mod.identifier);
return EXIT_ERROR;
//Last attempt. Should only be triggered by files without krefs
try
{
file = ModuleInstaller.CachedOrDownload(mod.identifier, mod.version, mod.download, cache);
}
catch (Exception)
{
log.FatalFormat("Error: Unable to find {0} in the cache", mod.identifier);
return EXIT_ERROR;
}
}

// Make sure this would actually generate an install
Expand All @@ -129,45 +144,45 @@ public static int Main(string[] args)
// tell if there's been an override of the version fields or not.
foreach (string vref in vrefs(metadata))
{
log.DebugFormat ("Expanding vref {0}", vref);
log.DebugFormat("Expanding vref {0}", vref);

if (vref.StartsWith ("#/ckan/ksp-avc"))
if (vref.StartsWith("#/ckan/ksp-avc"))
{
// HTTP has already included the KSP-AVC data as it needs it earlier in the process
if (remote.source != "http")
{
var versionRemote = FindVersionRemote (metadata, vref);
var version_remote = FindVersionRemote(metadata, vref);

try
{
AVC avc = AVC.FromZipFile (mod, file, versionRemote.id);
AVC avc = AVC.FromZipFile(mod, file, version_remote.id);
// TODO check why the AVC file can be null...
if (avc != null)
{
avc.InflateMetadata (metadata, null, null);
avc.InflateMetadata(metadata, null, null);
}
}
catch (JsonReaderException)
{
user.RaiseMessage ("Bad embedded KSP-AVC file for {0}, halting.", mod);
user.RaiseMessage("Bad embedded KSP-AVC file for {0}, halting.", mod);
return EXIT_ERROR;
}
}
}

if (vref.StartsWith ("#/ckan/kerbalstuff"))
if (vref.StartsWith("#/ckan/kerbalstuff"))
{
log.DebugFormat("Kerbalstuff vref: {0}", vref);
Match match = Regex.Match(vref, @"^#/ckan/([^/]+)/(.+)");

if (!match.Success)
{
// TODO: Have a proper kraken class!
user.RaiseMessage ("Cannot find remote and ID in vref: {0}, halting.", vref);
user.RaiseMessage("Cannot find remote and ID in vref: {0}, halting.", vref);
return EXIT_ERROR;
}

string remote_id = match.Groups [2].ToString ();
string remote_id = match.Groups[2].ToString();
log.DebugFormat("Kerbalstuff id : {0}", remote_id);
try
{
Expand All @@ -176,12 +191,12 @@ public static int Main(string[] args)
{
KSVersion version = new KSVersion();
version.friendly_version = mod.version;
ks.InflateMetadata (metadata, file, version);
ks.InflateMetadata(metadata, file, version);
}
}
catch (JsonReaderException)
{
user.RaiseMessage ("Cannot find remote and ID in vref: {0}, halting.", vref);
user.RaiseMessage("Cannot find remote and ID in vref: {0}, halting.", vref);
return EXIT_ERROR;
}
}
Expand All @@ -193,19 +208,19 @@ public static int Main(string[] args)

// Re-inflate our mod, in case our vref or FixVersionString routines have
// altered it at all.
mod = CkanModule.FromJson (metadata.ToString ());
mod = CkanModule.FromJson(metadata.ToString());

// All done! Write it out!

var version_filename = mod.version.ToString().Replace(':','-');
var version_filename = mod.version.ToString().Replace(':', '-');
string final_path = Path.Combine(options.OutputDir, string.Format("{0}-{1}.ckan", mod.identifier, version_filename));

log.InfoFormat("Writing final metadata to {0}", final_path);

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);

using (JsonTextWriter writer = new JsonTextWriter (sw))
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
Expand All @@ -224,30 +239,30 @@ public static int Main(string[] args)
/// (safely) load all vrefs from file.
/// Returns a list of vref strings.
/// </summary>
internal static List<string> vrefs (JObject orig_metadata)
internal static List<string> vrefs(JObject orig_metadata)
{
List<string> result = new List<string> ();
List<string> result = new List<string>();

JToken vref = orig_metadata [version_token];
JToken vref = orig_metadata[version_token];
// none: null
// single: Newtonsoft.Json.Linq.JValue
// multiple: Newtonsoft.Json.Linq.JArray
if (vref != null)
{
if (vref is JValue)
{
result.Add (vref.ToString());
result.Add(vref.ToString());
}
else if (vref is JArray)
{
foreach (string innerVref in vref.ToArray())
{
result.Add (innerVref);
result.Add(innerVref);
}
}

// Remove $vref from the resulting ckan
orig_metadata.Remove (version_token);
orig_metadata.Remove(version_token);
}

return result;
Expand All @@ -274,9 +289,9 @@ internal static JObject KerbalStuff(JObject orig_metadata, string remote_id, Net
JObject metadata = MetadataFromFileOrDefault(filename, orig_metadata);

// Check if we should auto-inflate.
string kref = (string)metadata[expand_token];
string kref = (string) metadata[expand_token];

if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff")
if (kref == (string) orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff")
{
log.InfoFormat("Inflating from KerbalStuff... {0}", metadata[expand_token]);
ks.InflateMetadata(metadata, filename, latest);
Expand All @@ -296,22 +311,22 @@ internal static JObject KerbalStuff(JObject orig_metadata, string remote_id, Net
/// </summary>
internal static JObject Jenkins(JObject orig_metadata, string remote_id, NetFileCache cache)
{
string versionBase = (string) orig_metadata ["x_ci_version_base"];
log.DebugFormat ("versionBase: {0}", versionBase);
string versionBase = (string) orig_metadata["x_ci_version_base"];
log.DebugFormat("versionBase: {0}", versionBase);

JObject resources = (JObject) orig_metadata ["resources"];
log.DebugFormat ("resources: {0}", resources);
JObject resources = (JObject) orig_metadata["resources"];
log.DebugFormat("resources: {0}", resources);

string baseUri = (string) resources ["ci"];
string baseUri = (string) resources["ci"];
if (baseUri == null)
{
// Fallback, we don't have the defined resource 'ci' in the schema yet...
baseUri = (string) resources ["x_ci"];
baseUri = (string) resources["x_ci"];
}

log.DebugFormat ("baseUri: {0}", baseUri);
log.DebugFormat("baseUri: {0}", baseUri);

JenkinsBuild build = JenkinsAPI.GetLatestBuild (baseUri, versionBase, true);
JenkinsBuild build = JenkinsAPI.GetLatestBuild(baseUri, versionBase, true);

Version version = build.version;

Expand All @@ -323,9 +338,9 @@ internal static JObject Jenkins(JObject orig_metadata, string remote_id, NetFile
JObject metadata = MetadataFromFileOrDefault(filename, orig_metadata);

// Check if we should auto-inflate.
string kref = (string)metadata[expand_token];
string kref = (string) metadata[expand_token];

if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff")
if (kref == (string) orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff")
{
log.InfoFormat("Inflating from Jenkins... {0}", metadata[expand_token]);
build.InflateMetadata(metadata, filename, null);
Expand Down Expand Up @@ -359,9 +374,9 @@ private static JObject GitHub(JObject orig_metadata, string repo, bool prereleas

// Check if we should auto-inflate.

string kref = (string)metadata[expand_token];
string kref = (string) metadata[expand_token];

if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/github")
if (kref == (string) orig_metadata[expand_token] || kref == "#/ckan/github")
{
log.InfoFormat("Inflating from github metadata... {0}", metadata[expand_token]);
release.InflateMetadata(metadata, filename, repo);
Expand All @@ -380,9 +395,9 @@ internal static JObject HTTP(JObject orig_metadata, string remote_id, NetFileCac
var metadata = orig_metadata;

// Check if we should auto-inflate.
string kref = (string)metadata[expand_token];
string kref = (string) metadata[expand_token];

if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/http")
if (kref == (string) orig_metadata[expand_token] || kref == "#/ckan/http")
{
log.InfoFormat("Inflating from HTTP download... {0}", metadata[expand_token]);
metadata["download"] = remote_id;
Expand Down Expand Up @@ -437,7 +452,7 @@ internal static JObject HTTP(JObject orig_metadata, string remote_id, NetFileCac
log.WarnFormat("Not inflating metadata for {0}", orig_metadata["identifier"]);
}

// metadata["download"] = metadata["download"].ToString() + '#' + metadata["version"].ToString();
// metadata["download"] = metadata["download"].ToString() + '#' + metadata["version"].ToString();
return metadata;
}

Expand Down Expand Up @@ -502,12 +517,19 @@ private static JObject ExtractCkanInfo(string filename)
/// <summary>
/// Find a remote source and remote id from a JObject by parsing its expand_token
/// </summary>
internal static NetKanRemote FindRemote(JObject json)
internal static NetKanRemote FindRemoteKref(JObject json, IUser user)
{
string kref = (string) json[expand_token];

if (kref == null)
{
user.RaiseMessage("Warning. No kref found in netkan");
return null;
}

Match match = Regex.Match(kref, @"^#/ckan/([^/]+)/(.+)");

if (! match.Success)
if (!match.Success)
{
// TODO: Have a proper kraken class!
throw new Kraken("Cannot find remote and ID in kref: " + kref);
Expand Down Expand Up @@ -553,7 +575,7 @@ internal static NetFileCache FindCache(CmdLineOptions options, KSPManager ksp_ma
try
{
KSP ksp = ksp_manager.GetPreferredInstance();
log.InfoFormat("Using CKAN cache at {0}",ksp.Cache.GetCachePath());
log.InfoFormat("Using CKAN cache at {0}", ksp.Cache.GetCachePath());
return ksp.Cache;
}
catch
Expand Down Expand Up @@ -605,7 +627,7 @@ internal static JObject FixVersionStrings(JObject metadata)
}
else
{
log.Error("Invaild epoch: "+epoch);
log.Error("Invaild epoch: " + epoch);
throw new BadMetadataKraken(null, "Invaild epoch: " + epoch + "In " + metadata["identifier"]);
}
}
Expand All @@ -620,7 +642,7 @@ internal static JObject FixVersionStrings(JObject metadata)
internal class NetKanRemote
{
public string source; // EG: "kerbalstuff" or "github"
public string id; // EG: "269" or "pjf/DogeCoinFlag"
public string id; // EG: "269" or "pjf/DogeCoinFlag"

internal NetKanRemote(string source, string id)
{
Expand Down