Example #1
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();

            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.File == null)
            {
                log.Fatal("Usage: netkan [--verbose|--debug] [--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 "github":
                    if (options.GitHubToken != null)
                    {
                        GithubAPI.SetCredentials(options.GitHubToken);
                    }

                    metadata = GitHub(json, remote.id, cache);
                    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.

            // TODO: Remove magic string "#/ckan/ksp-avc"
            if (metadata[version_token] != null && (string) metadata[version_token] == "#/ckan/ksp-avc")
            {
                metadata.Remove(version_token);

                try {
                    AVC avc = AVC.FromZipFile(mod, file);
                    avc.InflateMetadata(metadata, null, null);
                }
                catch (JsonReaderException)
                {                    
                    user.RaiseMessage("Bad embedded KSP-AVC file for {0}, halting.", mod);
                    return EXIT_ERROR;
                }

                // If we've done this, we need to re-inflate our mod, too.
                mod = CkanModule.FromJson(metadata.ToString());
            }

            // All done! Write it out!

            string final_path = Path.Combine(options.OutputDir, String.Format ("{0}-{1}.ckan", mod.identifier, mod.version));

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

            return EXIT_OK;
        }
Example #2
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);
        }