Пример #1
0
        static void Main(string[] args)
        {
            IUser user = new ConsoleUser(false);

            repoPath          = args[0];
            repoUrlPrefix     = args[1];
            githubAccessToken = args[2];

            Directory.CreateDirectory(Path.Combine(repoPath, "cache"));
            NetFileCache netFileCache = new NetFileCache(Path.Combine(repoPath, "cache"));
            CombinedModFileNormalizer modFileNormalizer = new CombinedModFileNormalizer(new IModFileNormalizer[]
            {
                new RarToZipNormalizer(),
                new SevenZipToZipNormalizer(),
                new ModZipRootNormalizer()
            });
            ModDirectoryManager    manualModDirectoryManager  = new ModDirectoryManager(repoUrlPrefix, repoPath, "mods", modFileNormalizer, netFileCache);
            ModDirectoryManager    githubModsDirectoryManager = new ModDirectoryManager(repoUrlPrefix, repoPath, "mods-github", modFileNormalizer, netFileCache);
            CombinedCfanAggregator combinedAggregator         = new CombinedCfanAggregator(new ICfanAggregator[]
            {
                new LocalRepositoryAggregator(manualModDirectoryManager),
                new GithubAggregator(githubModsDirectoryManager, new GithubRepositoriesDataProvider(), githubAccessToken),
                new FactorioComAggregator(),
            });
            var cfanJsons = combinedAggregator.getAllCfanJsons(user).ToList();

            cfanJsons.Where(p => !CfanJson.requiresFactorioComAuthorization(p)).ToList().ForEach(p => saveCfanJson(user, p));
            cfanJsons.ForEach(p => saveCfanJson(user, p, v2: true));
            createFinalRepositoryTarGz(user);
            createFinalRepositoryTarGz(user, v2: true);
            user.RaiseMessage("Done.");
        }
Пример #2
0
        public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCommandOptions options)
        {
            var exitCode = Exit.OK;

            Parser.Default.ParseArgumentsStrict(options.options.ToArray(), new CompatOptions(), (string option, object suboptions) =>
            {
                // ParseArgumentsStrict calls us unconditionally, even with bad arguments
                if (!string.IsNullOrEmpty(option) && suboptions != null)
                {
                    CommonOptions comOpts = (CommonOptions)suboptions;
                    comOpts.Merge(opts);
                    _user       = new ConsoleUser(comOpts.Headless);
                    _kspManager = manager ?? new GameInstanceManager(_user);
                    exitCode    = comOpts.Handle(_kspManager, _user);
                    if (exitCode != Exit.OK)
                    {
                        return;
                    }

                    switch (option)
                    {
                    case "list":
                        {
                            var ksp = MainClass.GetGameInstance(_kspManager);

                            const string versionHeader = "Version";
                            const string actualHeader  = "Actual";

                            var output = ksp
                                         .GetCompatibleVersions()
                                         .Select(i => new
                            {
                                Version = i,
                                Actual  = false
                            })
                                         .ToList();

                            output.Add(new
                            {
                                Version = ksp.Version(),
                                Actual  = true
                            });

                            output = output
                                     .OrderByDescending(i => i.Actual)
                                     .ThenByDescending(i => i.Version)
                                     .ToList();

                            var versionWidth = Enumerable
                                               .Repeat(versionHeader, 1)
                                               .Concat(output.Select(i => i.Version.ToString()))
                                               .Max(i => i.Length);

                            var actualWidth = Enumerable
                                              .Repeat(actualHeader, 1)
                                              .Concat(output.Select(i => i.Actual.ToString()))
                                              .Max(i => i.Length);

                            const string columnFormat = "{0}  {1}";

                            _user.RaiseMessage(string.Format(columnFormat,
                                                             versionHeader.PadRight(versionWidth),
                                                             actualHeader.PadRight(actualWidth)
                                                             ));

                            _user.RaiseMessage(string.Format(columnFormat,
                                                             new string('-', versionWidth),
                                                             new string('-', actualWidth)
                                                             ));

                            foreach (var line in output)
                            {
                                _user.RaiseMessage(string.Format(columnFormat,
                                                                 line.Version.ToString().PadRight(versionWidth),
                                                                 line.Actual.ToString().PadRight(actualWidth)
                                                                 ));
                            }
                        }
                        break;

                    case "add":
                        {
                            var ksp        = MainClass.GetGameInstance(_kspManager);
                            var addOptions = (CompatAddOptions)suboptions;

                            GameVersion GameVersion;
                            if (GameVersion.TryParse(addOptions.Version, out GameVersion))
                            {
                                var newCompatibleVersion = ksp.GetCompatibleVersions();
                                newCompatibleVersion.Add(GameVersion);
                                ksp.SetCompatibleVersions(newCompatibleVersion);
                            }
                            else
                            {
                                _user.RaiseError("ERROR: Invalid KSP version.");
                                exitCode = Exit.ERROR;
                            }
                        }
                        break;

                    case "forget":
                        {
                            var ksp        = MainClass.GetGameInstance(_kspManager);
                            var addOptions = (CompatForgetOptions)suboptions;

                            GameVersion GameVersion;
                            if (GameVersion.TryParse(addOptions.Version, out GameVersion))
                            {
                                if (GameVersion != ksp.Version())
                                {
                                    var newCompatibleVersion = ksp.GetCompatibleVersions();
                                    newCompatibleVersion.RemoveAll(i => i == GameVersion);
                                    ksp.SetCompatibleVersions(newCompatibleVersion);
                                }
                                else
                                {
                                    _user.RaiseError("ERROR: Cannot forget actual KSP version.");
                                    exitCode = Exit.ERROR;
                                }
                            }
                            else
                            {
                                _user.RaiseError("ERROR: Invalid KSP version.");
                                exitCode = Exit.ERROR;
                            }
                        }
                        break;

                    default:
                        exitCode = Exit.BADOPT;
                        break;
                    }
                }
            }, () => { exitCode = MainClass.AfterHelp(); });
            return(exitCode);
        }
Пример #3
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;
        }
Пример #4
0
        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.

            // TODO: Given all the other post-processing we do, we should really
            // be doing these checks at the end (after overrides, vrefs, etc).

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

            // Apply overrides, if applicable.
            metadata = new NetkanOverride(metadata).ProcessOverrides();

            // Finally, strip all our `x_netkan` flags.
            metadata = StripNetkanMetadata(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;
        }
Пример #5
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);
        }