Skip to content

Commit

Permalink
cli changes (#685)
Browse files Browse the repository at this point in the history
* cli changes

* wip

* update nigiri
  • Loading branch information
felixguendling authored Dec 11, 2024
1 parent 0cb0e1b commit 34908e1
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .pkg
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[nigiri]
[email protected]:motis-project/nigiri.git
branch=master
commit=2cf648ac22315fb6578be3f5d689f4d94e81b457
commit=f647fb695d730f78f925eaed312ca4d849cb1da9
[cista]
[email protected]:felixguendling/cista.git
branch=master
Expand Down
4 changes: 2 additions & 2 deletions .pkg.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
11919117500806763401
12451556664381891228
cista 6362f3ad8c3133a0abf64e5d8c9ea3e21f531ee8
zlib-ng 68ab3e2d80253ec5dc3c83691d9ff70477b32cd3
boost 930f38eb0365ceb7853273e03da4d9e7787abfb9
Expand Down Expand Up @@ -27,7 +27,7 @@ opentelemetry-cpp 60770dc9dc63e3543fc87d605b2e88fd53d7a414
pugixml 60175e80e2f5e97e027ac78f7e14c5acc009ce50
unordered_dense b33b037377ca966bbdd9cccc3417e46e88f83bfb
wyhash 1e012b57fc2227a9e583a57e2eacb3da99816d99
nigiri 2cf648ac22315fb6578be3f5d689f4d94e81b457
nigiri f647fb695d730f78f925eaed312ca4d849cb1da9
conf f9bf4bd83bf55a2170725707e526cbacc45dcc66
expat 636c9861e8e7c119f3626d1e6c260603ab624516
libosmium 6e6d6b3081cc8bdf25dda89730e25c36eb995516
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ Features can be turned on and off as needed.
- Download one or more GTFS datasets and place them in the folder

```bash
./motis my.osm.pbf my.gtfs.zip
./motis config my.osm.pbf gtfs.zip # generates a minimal config.yml
./motis import # preprocesses data
./motis server # starts a HTTP server on port 8080
```

This will preprocess the input files and create a `data` folder.
Expand All @@ -81,7 +83,9 @@ wget https://github.com/motis-project/motis/releases/latest/download/motis-${TAR
tar xf motis-${TARGET}.tar.bz2
wget https://github.com/motis-project/test-data/raw/aachen/aachen.osm.pbf
wget https://opendata.avv.de/current_GTFS/AVV_GTFS_Masten_mit_SPNV.zip
./motis aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis import
./motis server
```

**Windows**
Expand All @@ -90,7 +94,9 @@ wget https://opendata.avv.de/current_GTFS/AVV_GTFS_Masten_mit_SPNV.zip
Invoke-WebRequest https://github.com/motis-project/motis/releases/latest/download/motis-windows.zip -OutFile motis-windows.zip
Expand-Archive motis-windows.zip
Invoke-WebRequest https://github.com/motis-project/test-data/archive/refs/heads/aachen.zip -OutFile aachen.zip
./motis aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis import
./motis server
```

# Documentation
Expand Down
38 changes: 38 additions & 0 deletions exe/flags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <filesystem>

#include "boost/program_options.hpp"

namespace motis {

inline void add_data_path_opt(boost::program_options::options_description& desc,
std::filesystem::path& p) {
desc.add_options()(
"data,d", boost::program_options::value(&p)->default_value(p),
"The data path contains all preprocessed data as well as a `config.yml`. "
"It will be created by the `motis import` command. After the import has "
"finished, `motis server` only needs the `data` folder and can run "
"without the input files (such as OpenStreetMap file, GTFS datasets, "
"tiles-profiles, etc.)");
}

inline void add_config_path_opt(
boost::program_options::options_description& desc,
std::filesystem::path& p) {
desc.add_options()(
"config,c", boost::program_options::value(&p)->default_value(p),
"Configuration YAML file. Legacy INI files are still supported but this "
"support will be dropped in the future.");
}

inline boost::program_options::variables_map parse_opt(
int ac, char** av, boost::program_options::options_description& desc) {
namespace po = boost::program_options;
auto vm = po::variables_map{};
po::store(po::command_line_parser(ac, av).options(desc).run(), vm);
po::notify(vm);
return vm;
}

} // namespace motis
162 changes: 72 additions & 90 deletions exe/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "motis/import.h"
#include "motis/server.h"

#include "./flags.h"

#if !defined(MOTIS_VERSION)
#define MOTIS_VERSION "unknown"
#endif
Expand All @@ -23,96 +25,90 @@ namespace fs = std::filesystem;
using namespace motis;

int main(int ac, char** av) {
auto data_path = fs::path{"data"};
auto config_path = fs::path{"config.yml"};

auto desc = po::options_description{"Global options"};
desc.add_options() //
("version", "Prints the MOTIS version") //
("help", "Prints this help message") //
("data,d", po::value(&data_path)->default_value(data_path),
"The data path contains all preprocessed data as well as a `config.yml` "
"and is required by `motis server`. It will be created by the `motis "
"import` command. After the import has finished, `motis server` only "
"needs the `data` folder and can run without the input files (such as "
"OpenStreetMap file, GTFS datasets, tiles-profiles, etc.)") //
("config,c", po::value(&config_path)->default_value(config_path),
"Configuration YAML file. Legacy INI files are still supported but this "
"support will be dropped in the future.") //
("command", po::value<std::string>(),
"Command to execute:\n"
" - \"import\": preprocesses the input data\n"
" and creates the `data` folder.\n"
" - \"server\": serves static files\n"
" and all API endpoints such as\n"
" routing, geocoding, tiles, etc.") //
("paths", po::value<std::vector<std::string>>(),
"List of paths to import for the simple mode. File type will be "
"determined based on extension:\n"
" - \".osm.pbf\" will be used as\n"
" OpenStreetMap file.\n"
" This enables street routing,\n"
" geocoding and map tiles\n"
" - the rest will be interpreted as\n"
" static timetables.\n"
" This enables transit routing");

auto const help = [&]() {
std::cout << "MOTIS " << MOTIS_VERSION << "\n\n"
<< "Usage:\n"
" - simple: motis [PATHS...]\n"
" - import: motis import [-c config.yml] [-d data_dir]\n"
" - server: motis server [-d data_dir]\n\n"
<< desc << "\n";
};

enum mode { kImport, kServer, kSimple } mode = kSimple;
if (ac > 1) {
auto const cmd = std::string_view{av[1]};
switch (cista::hash(cmd)) {
case cista::hash("import"):
mode = kImport;
--ac;
++av;
break;
case cista::hash("server"):
mode = kServer;
--ac;
++av;
break;
}
} else {
help();
return 1;
}

auto pos = po::positional_options_description{}.add("paths", -1);
auto vm = po::variables_map{};
po::store(po::command_line_parser(ac, av).options(desc).positional(pos).run(),
vm);
po::notify(vm);

if (vm.count("version")) {
std::cout << MOTIS_VERSION << "\n";
if (ac > 1 && av[1] == "--help"sv) {
fmt::println(
"MOTIS {}\n\n"
"Usage:\n"
" --help print this help message\n"
" --version print program version\n\n"
"Commands:\n"
" config generate a config file from a list of input files\n"
" import prepare input data, creates the data directory\n"
" server starts a web server serving the API\n",
MOTIS_VERSION);
return 0;
} else if (vm.count("help")) {
help();
} else if (ac <= 1 || (ac >= 2 && av[1] == "--version"sv)) {
fmt::println("{}", MOTIS_VERSION);
return 0;
}

switch (mode) {
case kServer:
// Skip program argument, quit if no command.
--ac;
++av;

// Execute command.
auto const cmd = std::string_view{av[0]};
--ac;
++av;
switch (cista::hash(cmd)) {
case cista::hash("config"): {
auto paths = std::vector<std::string>{};
for (auto i = 0; i != ac; ++i) {
paths.push_back(std::string{av[i]});
}
if (paths.empty() || paths.front() == "--help") {
fmt::println(
"usage: motis config [PATHS...]\n\n"
"Generates a config.yml file in the current working "
"directory.\n\n"
"File type will be determined based on extension:\n"
" - \".osm.pbf\" will be used as OpenStreetMap file.\n"
" This enables street routing, geocoding and map tiles\n"
" - the rest will be interpreted as static timetables.\n"
" This enables transit routing."
"\n\n"
"Example: motis config germany-latest.osm.pbf "
"germany.gtfs.zip\n");
return paths.front() == "--help" ? 0 : 1;
}
std::ofstream{"config.yml"} << config::read_simple(paths) << "\n";
return 0;
}

case cista::hash("server"):
try {
auto data_path = fs::path{"data"};

auto desc = po::options_description{"Server Options"};
add_data_path_opt(desc, data_path);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}

auto const c = config::read(data_path / "config.yml");
return server(data{data_path, c}, c);
} catch (std::exception const& e) {
std::cerr << "unable to start server: " << e.what() << "\n";
return 1;
}

case kImport: {
case cista::hash("import"): {
auto c = config{};
try {
auto data_path = fs::path{"data"};
auto config_path = fs::path{"config.yml"};

auto desc = po::options_description{"Import Options"};
add_data_path_opt(desc, data_path);
add_config_path_opt(desc, config_path);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}

c = config_path.extension() == ".ini" ? config::read_legacy(config_path)
: config::read(config_path);
auto const bars = utl::global_progress_bars{false};
Expand All @@ -124,20 +120,6 @@ int main(int ac, char** av) {
return 1;
}
}

case kSimple:
try {
auto const bars = utl::global_progress_bars{false};
auto args = vm.count("paths")
? vm.at("paths").as<std::vector<std::string>>()
: std::vector<std::string>{};

auto const c = config::read_simple(args);
server(import(c, data_path), c);
} catch (std::exception const& e) {
std::cerr << "error: " << e.what() << "\n";
}
return 0;
}

google::protobuf::ShutdownProtobufLibrary();
Expand Down

0 comments on commit 34908e1

Please sign in to comment.