diff options
Diffstat (limited to 'src/cli.cr')
-rw-r--r-- | src/cli.cr | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/cli.cr b/src/cli.cr new file mode 100644 index 0000000..5815c88 --- /dev/null +++ b/src/cli.cr @@ -0,0 +1,118 @@ +# Command-line interface +# Copyright (C) 2023 Nguyễn Gia Phong +# +# This file if part of hybring. +# +# Hybring is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Hybring is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with hybring. If not, see <https://www.gnu.org/licenses/>. + +require "ini" +require "option_parser" + +require "./http" + +enum Subcommand + Serve + Usage +end + +struct Configuration + @db : Path + getter db + @api : String + getter api + @opennic_local : Path + getter opennic_local + @opennic_remote : String + getter opennic_remote + @icann_local : Path + getter icann_local + @icann_remote : String + getter icann_remote + + def initialize(path) + ini = INI.parse File.read path + @db = Path[ini["general"]["db"]] + @api = ini["general"]["api"] + @opennic_local = Path[ini["opennic"]["local"]] + @opennic_remote = ini["opennic"]["remote"] + @icann_local = Path[ini["icann"]["local"]] + @icann_remote = ini["icann"]["remote"] + end +end + +subcmd = Subcommand::Usage +usage = "" +config_path, port = nil, 8910 + +parser = OptionParser.new do |parser| + banner_prefix = "usage: #{Path[PROGRAM_NAME].basename}" + parser.banner = "#{banner_prefix} [subcommand] [arguments]" + parser.on "serve", "start the HTTP server" do + subcmd = Subcommand::Serve + parser.banner = "#{banner_prefix} serve --config=PATH [--port=N]" + usage = parser.to_s + parser.on "-c PATH", "--config=PATH", + "path to configuration file (required)" do |path| + config_path = path + end + parser.on "-p N", "--port=N", "listening port (default to 8910)" do |n| + port = n.to_i + end + end + parser.on "-h", "--help", "show this help message and exit" do + puts parser + exit + end + + parser.invalid_option do |flag| + STDERR.puts "error: invalid option: #{flag}" + subcmd = Subcommand::Usage + end + parser.missing_option do |flag| + STDERR.puts "error: missing argument for #{flag}" + subcmd = Subcommand::Usage + end + parser.unknown_args do |before_dash, after_dash| + next if before_dash.empty? && after_dash.empty? + STDERR << "error: unknown arguments:" + STDERR << " " << before_dash.join " " if !before_dash.empty? + STDERR << " -- " << after_dash.join " " if !after_dash.empty? + STDERR.puts + subcmd = Subcommand::Usage + end +end + +parser.parse +cfg = case subcmd + when .serve? + unless config_path + STDERR << usage + exit 1 + end + begin + Configuration.new config_path.not_nil! + rescue ex + STDERR.puts "error: failed to read config from #{config_path}: #{ex}" + exit 1 + end + end + +case subcmd +in .serve? + server = Server.new cfg.not_nil! + server.listen port +in .usage? + STDERR.puts parser + exit 1 +end |