You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.7KB

  1. #[macro_use]
  2. extern crate clap;
  3. extern crate serde_json;
  4. #[macro_use]
  5. extern crate log;
  6. extern crate ansi_term;
  7. extern crate bincode;
  8. extern crate byteorder;
  9. extern crate chan;
  10. extern crate env_logger;
  11. extern crate futures;
  12. extern crate iron;
  13. extern crate mount;
  14. extern crate persistent;
  15. extern crate staticfile;
  16. extern crate tantivy;
  17. extern crate time;
  18. extern crate urlencoded;
  19. #[macro_use]
  20. extern crate serde_derive;
  21. use std::io::Write;
  22. use clap::{App, AppSettings, Arg, SubCommand};
  23. mod commands;
  24. pub mod timer;
  25. use self::commands::*;
  26. fn main() {
  27. env_logger::init().unwrap();
  28. let index_arg = Arg::with_name("index")
  29. .short("i")
  30. .long("index")
  31. .value_name("directory")
  32. .help("Tantivy index directory filepath")
  33. .required(true);
  34. #[allow(unused_mut)]
  35. let mut cli_menu = App::new("Tantivy")
  36. .setting(AppSettings::SubcommandRequiredElseHelp)
  37. .version(env!("CARGO_PKG_VERSION"))
  38. .author("Paul Masurel <paul.masurel@gmail.com>")
  39. .about("Tantivy Search Engine's command line interface.")
  40. .subcommand(
  41. SubCommand::with_name("new")
  42. .about("Create a new index. The schema will be populated with a simple example schema")
  43. .arg(index_arg.clone())
  44. )
  45. .subcommand(
  46. SubCommand::with_name("serve")
  47. .about("Start a server")
  48. .arg(index_arg.clone())
  49. .arg(Arg::with_name("host")
  50. .long("host")
  51. .value_name("host")
  52. .help("host to listen to")
  53. )
  54. .arg(Arg::with_name("port")
  55. .short("p")
  56. .long("port")
  57. .value_name("port")
  58. .help("Port")
  59. .default_value("localhost")
  60. )
  61. )
  62. .subcommand(
  63. SubCommand::with_name("index")
  64. .about("Index files")
  65. .arg(index_arg.clone())
  66. .arg(Arg::with_name("file")
  67. .short("f")
  68. .long("file")
  69. .value_name("file")
  70. .help("File containing the documents to index."))
  71. .arg(Arg::with_name("num_threads")
  72. .short("t")
  73. .long("num_threads")
  74. .value_name("num_threads")
  75. .help("Number of indexing threads. By default num cores - 1 will be used")
  76. .default_value("3"))
  77. .arg(Arg::with_name("memory_size")
  78. .short("m")
  79. .long("memory_size")
  80. .value_name("memory_size")
  81. .help("Total memory_size in bytes. It will be split for the different threads.")
  82. .default_value("1000000000"))
  83. .arg(Arg::with_name("nomerge")
  84. .long("nomerge")
  85. .help("Do not merge segments"))
  86. )
  87. .subcommand(
  88. SubCommand::with_name("search")
  89. .about("Search an index.")
  90. .arg(index_arg.clone())
  91. .arg(Arg::with_name("query")
  92. .short("q")
  93. .long("query")
  94. .value_name("query")
  95. .help("Query")
  96. .required(true))
  97. .arg(Arg::with_name("num_hits")
  98. .short("n")
  99. .long("num_hits")
  100. .value_name("num_hits")
  101. .help("Limit number of search results to top <num_hits> hits")
  102. .takes_value(true)
  103. .required(false))
  104. )
  105. .subcommand(
  106. SubCommand::with_name("merge")
  107. .about("Merge all the segments of an index")
  108. .arg(index_arg.clone())
  109. );
  110. #[cfg(feature = "bench")]
  111. {
  112. cli_menu = cli_menu
  113. .subcommand(
  114. SubCommand::with_name("bench")
  115. .about("Run a benchmark on your index")
  116. .arg(index_arg.clone())
  117. .arg(Arg::with_name("queries")
  118. .short("q")
  119. .long("queries")
  120. .value_name("queries")
  121. .help("File containing queries (one per line) to run in the benchmark.")
  122. .required(true))
  123. .arg(Arg::with_name("num_repeat")
  124. .short("n")
  125. .long("num_repeat")
  126. .value_name("num_repeat")
  127. .help("Number of times to repeat the benchmark.")
  128. .default_value("1"))
  129. )
  130. }
  131. let cli_options = cli_menu.get_matches();
  132. let (subcommand, some_options) = cli_options.subcommand();
  133. let options = some_options.unwrap();
  134. let run_cli = match subcommand {
  135. "new" => run_new_cli,
  136. "index" => run_index_cli,
  137. "serve" => run_serve_cli,
  138. "search" => run_search_cli,
  139. "merge" => run_merge_cli,
  140. //"bench" => run_bench_cli,
  141. #[allow(unused)]
  142. other => {
  143. #[cfg(feature = "bench")]
  144. {
  145. if other == "bench" {
  146. run_bench_cli
  147. } else {
  148. panic!("Subcommand {} is unknown", subcommand)
  149. }
  150. }
  151. #[cfg(not(feature = "bench"))]
  152. {
  153. panic!("Subcommand {} is unknown", subcommand)
  154. }
  155. }
  156. };
  157. if let Err(ref e) = run_cli(options) {
  158. let stderr = &mut std::io::stderr();
  159. let errmsg = "Error writing ot stderr";
  160. writeln!(stderr, "{}", e).expect(errmsg);
  161. std::process::exit(1);
  162. }
  163. }