aboutsummaryrefslogtreecommitdiffstats
path: root/lib/plum/rack/cli.rb
blob: 967764fbf96dc936158a732e95f24589e21b4362 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require "optparse"
require "rack/builder"

module Plum
  module Rack
    class CLI
      def initialize(argv)
        @argv = argv
        @options = {}

        parse!
      end

      def run
        @server.start
      end

      private
      def parse!
        @parser = setup_parser
        @parser.parse!(@argv)

        config = transform_options
        # TODO: parse rack_opts?
        rack_app, rack_opts = ::Rack::Builder.parse_file(@argv.shift || "config.ru")

        @server = Plum::Rack::Server.new(rack_app, config)
      end

      def transform_options
        if @options[:config]
          dsl = DSL::Config.new.instance_eval(File.read(@options[:config]))
          config = dsl.config
        else
          config = Config.new
        end

        ENV["RACK_ENV"] = @options[:env] if @options[:env]
        config[:debug] = @options[:debug] unless @options[:debug].nil?
        config[:server_push] = @options[:server_push] unless @options[:server_push].nil?

        if @options[:socket]
          config[:listeners] << { listener: UNIXListener,
                                  path: @options[:socket] }
        end

        if !@options[:socket] || @options[:host] || @options[:port]
          if @options[:tls] == false
            config[:listeners] << { listener: TCPListener,
                                    hostname: @options[:host] || "0.0.0.0",
                                    port: @options[:port] || 8080 }
          else
            config[:listeners] << { listener: TLSListener,
                                    hostname: @options[:host] || "0.0.0.0",
                                    port: @options[:port] || 8080,
                                    certificate: @options[:cert] && File.read(@options[:cert]),
                                    certificate_key: @options[:cert] && File.read(@options[:key]) }
          end
        end

        config
      end

      def setup_parser
        parser = OptionParser.new do |o|
          o.on "-C", "--config PATH", "Load PATH as a config" do |arg|
            @options[:config] = arg
          end

          o.on "-D", "--debug", "Run puma in debug mode" do
            @options[:debug] = true
          end

          o.on "-e", "--environment ENV", "Rack environment (default: development)" do |arg|
            @options[:env] = arg
          end

          o.on "-a", "--address HOST", "Bind to host HOST (default: 0.0.0.0)" do |arg|
            @options[:host] = arg
          end

          o.on "-p", "--port PORT", "Bind to port PORT (default: 8080)" do |arg|
            @options[:port] = arg.to_i
          end

          o.on "-S", "--socket PATH", "Bind to UNIX domain socket" do |arg|
            @options[:socket] = arg
          end

          o.on "--http", "Use http URI scheme (use raw TCP)" do |arg|
            @options[:tls] = false
          end

          o.on "--https", "Use https URI scheme (use TLS; default)" do |arg|
            @options[:tls] = true
          end

          o.on "--server-push BOOL", "Enable HTTP/2 server push" do |arg|
            @options[:server_push] = arg != "false"
          end

          o.on "--cert PATH", "Use PATH as server certificate" do |arg|
            @options[:cert] = arg
          end

          o.on "--key PATH", "Use PATH as server certificate's private key" do |arg|
            @options[:key] = arg
          end

          o.on "-v", "--version", "Show version" do
            puts "plum version #{::Plum::VERSION}"
            exit(0)
          end

          o.on "-h", "--help", "Show this message" do
            puts o
            exit(0)
          end

          o.banner = "plum [options] [rackup config file]"
        end
      end
    end
  end
end