Exemple #1
0
        /// <summary>
        /// Fetch le things from le KerbalStuff.
        /// Returns a JObject that should be a fully formed CKAN file.
        /// </summary>
        internal static JObject KerbalStuff(JObject orig_metadata, string remote_id, NetFileCache cache)
        {
            // Look up our mod on KS by its ID.
            KSMod ks = KSAPI.Mod(Convert.ToInt32(remote_id));

            KSVersion latest = ks.Latest();

            Version version = latest.friendly_version;

            log.DebugFormat("Mod: {0} {1}", ks.name, version);

            // Find the latest download.
            string filename = latest.Download((string) orig_metadata["identifier"], cache);

            JObject metadata = MetadataFromFileOrDefault(filename, orig_metadata);

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

            if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff")
            {
                log.InfoFormat("Inflating from KerbalStuff... {0}", metadata[expand_token]);
                ks.InflateMetadata(metadata, filename, latest);
                metadata.Remove(expand_token);
            }
            else
            {
                log.WarnFormat("Not inflating metadata for {0}", orig_metadata["identifier"]);
            }

            return metadata;
        }
Exemple #2
0
        public void KSHome()
        {
            var ks = new CKAN.NetKAN.KSMod {name = "foo bar", id = 123};

            // KSHome no longer escapes URLs.
            Assert.AreEqual("https://kerbalstuff.com/mod/123/foo bar", ks.KSHome().ToString());
        }
Exemple #3
0
        public void KSHome()
        {
            var ks = new CKAN.NetKAN.KSMod {
                name = "foo bar", id = 123
            };

            // KSHome no longer escapes URLs.
            Assert.AreEqual("https://kerbalstuff.com/mod/123/foo bar", ks.KSHome().ToString());
        }
Exemple #4
0
        public static CKAN.NetKAN.KSMod test_ksmod()
        {
            var ksmod = new CKAN.NetKAN.KSMod
            {
                license           = "CC-BY",
                name              = "Dogecoin Flag",
                short_description = "Such test. Very unit. Wow.",
                author            = "pjf",
                versions          = new KSVersion[1]
            };

            ksmod.versions[0] = new KSVersion
            {
                friendly_version = new Version("0.25"),
                download_path    = new Uri("http://example.com/")
            };

            return(ksmod);
        }
Exemple #5
0
        public static CKAN.NetKAN.KSMod test_ksmod()
        {
            var ksmod = new CKAN.NetKAN.KSMod
            {
                license = "CC-BY",
                name = "Dogecoin Flag",
                short_description = "Such test. Very unit. Wow.",
                author = "pjf",
                versions = new KSVersion[1]
            };

            ksmod.versions[0] = new KSVersion
            {
                friendly_version = new Version("0.25"),
                download_path = new Uri("http://example.com/")
            };

            return ksmod;
        }
Exemple #6
0
        // GH #199: Don't pre-fill KSP version fields if we see a ksp_min/max
        public void KSP_Version_Inflate_199()
        {
            JObject metadata = JObject.Parse(TestData.DogeCoinFlag_101());

            // Add our own field, and remove existing ones.
            metadata["ksp_version_min"] = "0.23.5";
            metadata["ksp_version"]     = null;
            metadata["ksp_version_max"] = null;

            // Sanity check: make sure we don't have a ksp_version field to begin with.
            Assert.AreEqual(null, (string)metadata["ksp_version"]);

            CKAN.NetKAN.KSMod ksmod = test_ksmod();

            ksmod.InflateMetadata(metadata, TestData.DogeCoinFlagZip(), ksmod.versions[0]);

            // Make sure min is still there, and the rest unharmed.
            Assert.AreEqual(null, (string)metadata["ksp_version"]);
            Assert.AreEqual(null, (string)metadata["ksp_version_max"]);
            Assert.AreEqual("0.23.5", (string)metadata["ksp_version_min"]);
        }
Exemple #7
0
        private const string version_token = "$vref"; // It'd be nice if we could have repeated $krefs.

        public static int Main(string[] args)
        {
            BasicConfigurator.Configure();
            LogManager.GetRepository().Threshold = Level.Error;
            var user = new ConsoleUser(false);

            var options = new CmdLineOptions();

            Parser.Default.ParseArgumentsStrict(args, options);

            if (options.Verbose)
            {
                LogManager.GetRepository().Threshold = Level.Info;
            }
            else if (options.Debug)
            {
                LogManager.GetRepository().Threshold = Level.Debug;
            }

            if (options.NetUserAgent != null)
            {
                Net.UserAgentString = options.NetUserAgent;
            }

            if (options.File == null)
            {
                log.Fatal("Usage: netkan [--verbose|--debug] [--prerelease] [--outputdir=...] <filename>");
                return(EXIT_BADOPT);
            }

            NetFileCache cache = FindCache(options, new KSPManager(user), user);

            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);
                }

                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)
            {
                log.Error("There was an error, aborting");
                return(EXIT_ERROR);
            }

            // Make sure that at the very least this validates against our own
            // internal model.

            CkanModule mod = CkanModule.FromJson(metadata.ToString());

            // Make sure our identifiers match.
            if (mod.identifier != (string)json["identifier"])
            {
                log.FatalFormat("Error: Have metadata for {0}, but wanted {1}", mod.identifier, json["identifier"]);
                return(EXIT_ERROR);
            }

            // Find our cached file, we'll need it later.
            string file = cache.GetCachedZip(mod.download);

            if (file == null)
            {
                log.FatalFormat("Error: Unable to find {0} in the cache", mod.identifier);
                return(EXIT_ERROR);
            }

            // Make sure this would actually generate an install
            try
            {
                ModuleInstaller.FindInstallableFiles(mod, file, null);
            }
            catch (BadMetadataKraken kraken)
            {
                log.FatalFormat("Error: Bad metadata for {0}: {1}", kraken.module, kraken.Message);
                return(EXIT_ERROR);
            }

            // Now inflate our original metadata from AVC, if we have it.
            // The reason we inflate our metadata and not the module is that in the module we can't
            // 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);

                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);

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

                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);
                        return(EXIT_ERROR);
                    }

                    string remote_id = match.Groups [2].ToString();
                    log.DebugFormat("Kerbalstuff id  : {0}", remote_id);
                    try
                    {
                        KSMod ks = KSAPI.Mod(Convert.ToInt32(remote_id));
                        if (ks != null)
                        {
                            KSVersion version = new KSVersion();
                            version.friendly_version = mod.version;
                            ks.InflateMetadata(metadata, file, version);
                        }
                    }
                    catch (JsonReaderException)
                    {
                        user.RaiseMessage("Cannot find remote and ID in vref: {0}, halting.", vref);
                        return(EXIT_ERROR);
                    }
                }
            }

            // Fix our version string, if required.
            metadata = FixVersionStrings(metadata);

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

            // All done! Write it out!

            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))
            {
                writer.Formatting  = Formatting.Indented;
                writer.Indentation = 4;
                writer.IndentChar  = ' ';

                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(writer, metadata);
            }

            File.WriteAllText(final_path, sw + Environment.NewLine);

            return(EXIT_OK);
        }
Exemple #8
0
 // GH #214: Make sure we pick up the right version
 public void KS_Version_Select_214()
 {
     CKAN.NetKAN.KSMod mod = KSAPI.Mod(TestData.KS_CustomAsteroids_string());
     Assert.AreEqual(711, mod.Latest().id, "GH #214 - Select default_version_id");
 }