src/main/java/com/conveyal/gtfs/GTFS.java
public static void main (String[] args) throws IOException {
        Options options = getOptions();
        CommandLine cmd;
        try {
            cmd = new DefaultParser().parse(options, args);
        } catch (ParseException e) {
            LOG.error("Error parsing command line", e);
            printHelp(options);
            return;
        }

        if (cmd.hasOption("help")) {
            printHelp(options);
            return;
        }

        if (!cmd.getArgList().isEmpty()) {
            LOG.error("Extraneous arguments present: {}", cmd.getArgs());
            printHelp(options);
            return;
        }

        if (!(cmd.hasOption("export") || cmd.hasOption("snapshot") || cmd.hasOption("load") || cmd.hasOption("validate") || cmd.hasOption("delete"))) {
            LOG.error("Must specify one of 'snapshot', 'load', 'validate', 'export', or 'delete'.");
            printHelp(options);
            return;
        }
        boolean storeResults = cmd.hasOption("json");
        // Object mapper and directory used for writing load or validation results to file if required.
        ObjectMapper mapper = null;
        File directory = null;
        if (storeResults) {
            // Instantiate mapper for use with outputting load/validation results.
            mapper = new ObjectMapper();
            directory = cmd.getOptionValue("json") != null ? new File(cmd.getOptionValue("json")) : Files.createTempDir();
            LOG.info("Storing results in directory: {}", directory.getAbsolutePath());
        }
        String databaseUrl = cmd.getOptionValue("database", DEFAULT_DATABASE_URL);
        String databaseUser = cmd.getOptionValue("user");
        String databasePassword = cmd.getOptionValue("password");
        LOG.info("Connecting to {} as user {}", databaseUrl, databaseUser);

        // Create a JDBC connection pool for the specified database.
        // Missing (null) username and password will fall back on host-based authentication.
        DataSource dataSource = createDataSource(databaseUrl, databaseUser, databasePassword);

        // Record the unique identifier of the newly loaded feed
        FeedLoadResult loadResult = null;
        if (cmd.hasOption("load")) {
            String filePath = cmd.getOptionValue("load");
            loadResult = load(filePath, dataSource);
            if (storeResults) {
                File loadResultFile = new File(directory, String.format("%s-load.json", loadResult.uniqueIdentifier));
                LOG.info("Storing load result at {}", loadResultFile.getAbsolutePath());
                mapper.writerWithDefaultPrettyPrinter().writeValue(loadResultFile, loadResult);
            }
            LOG.info("The unique identifier for this feed is: {}", loadResult.uniqueIdentifier);
        }

        if (cmd.hasOption("validate")) {
            String feedToValidate = cmd.getOptionValue("validate");
            if (feedToValidate != null && loadResult != null) {
                LOG.warn("Validating the specified feed {} instead of {} (just loaded)",
                        feedToValidate, loadResult.uniqueIdentifier);
            }
            if (feedToValidate == null && loadResult != null) {
                feedToValidate = loadResult.uniqueIdentifier;
            }
            if (feedToValidate != null) {
                LOG.info("Validating feed with unique identifier {}", feedToValidate);
                ValidationResult validationResult = validate (feedToValidate, dataSource);
                if (storeResults) {
                    File validationResultFile = new File(directory, String.format("%s-validation.json", feedToValidate));
                    LOG.info("Storing validation result at {}", validationResultFile.getAbsolutePath());
                    mapper.writerWithDefaultPrettyPrinter().writeValue(validationResultFile, validationResult);
                }
                LOG.info("Done validating.");
            } else {
                LOG.error("No feed to validate. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("snapshot")) {
            String namespaceToSnapshot = cmd.getOptionValue("snapshot");
            if (namespaceToSnapshot == null && loadResult != null) {
                namespaceToSnapshot = loadResult.uniqueIdentifier;
            }
            if (namespaceToSnapshot != null) {
                LOG.info("Snapshotting feed with unique identifier {}", namespaceToSnapshot);
                FeedLoadResult snapshotResult = makeSnapshot(namespaceToSnapshot, dataSource);
                if (storeResults) {
                    File snapshotResultFile = new File(directory, String.format("%s-snapshot.json", snapshotResult.uniqueIdentifier));
                    LOG.info("Storing validation result at {}", snapshotResultFile.getAbsolutePath());
                    mapper.writerWithDefaultPrettyPrinter().writeValue(snapshotResultFile, snapshotResult);
                }
                LOG.info("Done snapshotting. The unique identifier for this snapshot is: {}", snapshotResult.uniqueIdentifier);
            } else {
                LOG.error("No feed to snapshot. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("export")) {
            String namespaceToExport = cmd.getOptionValue("export");
            String outFile = cmd.getOptionValue("outFile");
            if (namespaceToExport == null && loadResult != null) {
                namespaceToExport = loadResult.uniqueIdentifier;
            }
            if (namespaceToExport != null) {
                LOG.info("Exporting feed with unique identifier {}", namespaceToExport);
                FeedLoadResult exportResult = export(namespaceToExport, outFile, dataSource, true);
                LOG.info("Done exporting.");
            } else {
                LOG.error("No feed to export. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("delete")) {
            String namespaceToDelete = cmd.getOptionValue("delete");

            if (namespaceToDelete != null) {
                LOG.info("Deleting feed with unique identifier {}", namespaceToDelete);
                try {
                    delete(namespaceToDelete, dataSource);
                    LOG.info("Feed {} has been successfully deleted.", namespaceToDelete);
                } catch (SQLException | InvalidNamespaceException e) {
                    e.printStackTrace();
                }
            } else {
                LOG.error("No feed to delete. Specify one with the --delete argument.");
            }
        }
    }
public static void main (String[] args) throws IOException {
        Options options = getOptions();
        CommandLine cmd;
        try {
            cmd = new DefaultParser().parse(options, args);
        } catch (ParseException e) {
            LOG.error("Error parsing command line", e);
            printHelp(options);
            return;
        }

        if (cmd.hasOption("help")) {
            printHelp(options);
            return;
        }

        if (!cmd.getArgList().isEmpty()) {
            LOG.error("Extraneous arguments present: {}", cmd.getArgs());
            printHelp(options);
            return;
        }

        if (!(cmd.hasOption("export") || cmd.hasOption("snapshot") || cmd.hasOption("load") || cmd.hasOption("validate") || cmd.hasOption("delete"))) {
            LOG.error("Must specify one of 'snapshot', 'load', 'validate', 'export', or 'delete'.");
            printHelp(options);
            return;
        }
        boolean storeResults = cmd.hasOption("json");
        // Object mapper and directory used for writing load or validation results to file if required.
        ObjectMapper mapper = null;
        File directory = null;
        if (storeResults) {
            // Instantiate mapper for use with outputting load/validation results.
            mapper = new ObjectMapper();
            directory = cmd.getOptionValue("json") != null ? new File(cmd.getOptionValue("json")) : Files.createTempDir();
            LOG.info("Storing results in directory: {}", directory.getAbsolutePath());
        }
        String databaseUrl = cmd.getOptionValue("database", DEFAULT_DATABASE_URL);
        String databaseUser = cmd.getOptionValue("user");
        String databasePassword = cmd.getOptionValue("password");
        LOG.info("Connecting to {} as user {}", databaseUrl, databaseUser);

        // Create a JDBC connection pool for the specified database.
        // Missing (null) username and password will fall back on host-based authentication.
        DataSource dataSource = createDataSource(databaseUrl, databaseUser, databasePassword);

        // Record the unique identifier of the newly loaded feed
        FeedLoadResult loadResult = null;
        if (cmd.hasOption("load")) {
            String filePath = cmd.getOptionValue("load");
            loadResult = load(filePath, dataSource);
            if (storeResults) {
                File loadResultFile = new File(directory, String.format("%s-load.json", loadResult.uniqueIdentifier));
                LOG.info("Storing load result at {}", loadResultFile.getAbsolutePath());
                mapper.writerWithDefaultPrettyPrinter().writeValue(loadResultFile, loadResult);
            }
            LOG.info("The unique identifier for this feed is: {}", loadResult.uniqueIdentifier);
        }

        if (cmd.hasOption("validate")) {
            String feedToValidate = cmd.getOptionValue("validate");
            if (feedToValidate != null && loadResult != null) {
                LOG.warn("Validating the specified feed {} instead of {} (just loaded)",
                        feedToValidate, loadResult.uniqueIdentifier);
            }
            if (feedToValidate == null && loadResult != null) {
                feedToValidate = loadResult.uniqueIdentifier;
            }
            if (feedToValidate != null) {
                LOG.info("Validating feed with unique identifier {}", feedToValidate);
                ValidationResult validationResult = validate (feedToValidate, dataSource);
                if (storeResults) {
                    File validationResultFile = new File(directory, String.format("%s-validation.json", feedToValidate));
                    LOG.info("Storing validation result at {}", validationResultFile.getAbsolutePath());
                    mapper.writerWithDefaultPrettyPrinter().writeValue(validationResultFile, validationResult);
                }
                LOG.info("Done validating.");
            } else {
                LOG.error("No feed to validate. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("snapshot")) {
            String namespaceToSnapshot = cmd.getOptionValue("snapshot");
            if (namespaceToSnapshot == null && loadResult != null) {
                namespaceToSnapshot = loadResult.uniqueIdentifier;
            }
            if (namespaceToSnapshot != null) {
                LOG.info("Snapshotting feed with unique identifier {}", namespaceToSnapshot);
                FeedLoadResult snapshotResult = makeSnapshot(namespaceToSnapshot, dataSource);
                if (storeResults) {
                    File snapshotResultFile = new File(directory, String.format("%s-snapshot.json", snapshotResult.uniqueIdentifier));
                    LOG.info("Storing validation result at {}", snapshotResultFile.getAbsolutePath());
                    mapper.writerWithDefaultPrettyPrinter().writeValue(snapshotResultFile, snapshotResult);
                }
                LOG.info("Done snapshotting. The unique identifier for this snapshot is: {}", snapshotResult.uniqueIdentifier);
            } else {
                LOG.error("No feed to snapshot. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("export")) {
            String namespaceToExport = cmd.getOptionValue("export");
            String outFile = cmd.getOptionValue("outFile");
            if (namespaceToExport == null && loadResult != null) {
                namespaceToExport = loadResult.uniqueIdentifier;
            }
            if (namespaceToExport != null) {
                LOG.info("Exporting feed with unique identifier {}", namespaceToExport);
                FeedLoadResult exportResult = export(namespaceToExport, outFile, dataSource, true);
                LOG.info("Done exporting.");
            } else {
                LOG.error("No feed to export. Specify one, or load a feed in the same command.");
            }
        }

        if (cmd.hasOption("delete")) {
            String namespaceToDelete = cmd.getOptionValue("delete");

            if (namespaceToDelete != null) {
                LOG.info("Deleting feed with unique identifier {}", namespaceToDelete);
                try {
                    delete(namespaceToDelete, dataSource);
                    LOG.info("Feed {} has been successfully deleted.", namespaceToDelete);
                } catch (SQLException | InvalidNamespaceException e) {
                    e.printStackTrace();
                }
            } else {
                LOG.error("No feed to delete. Specify one with the --delete argument.");
            }
        }
    }
A command-line interface that lets you load GTFS feeds into a database and validate the loaded feeds.
It also lets you run a GraphQL API for all the feeds loaded into the database.