File: help.rb

package info (click to toggle)
ruby-clamp 1.1.1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, trixie
  • size: 312 kB
  • sloc: ruby: 2,359; makefile: 4
file content (100 lines) | stat: -rw-r--r-- 2,279 bytes parent folder | download | duplicates (3)
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
require "stringio"
require "clamp/messages"

module Clamp

  module Help

    def usage(usage)
      @declared_usage_descriptions ||= []
      @declared_usage_descriptions << usage
    end

    attr_reader :declared_usage_descriptions

    def description=(description)
      @description = description.dup
      if @description =~ /^\A\n*( +)/
        indent = Regexp.last_match(1)
        @description.gsub!(/^#{indent}/, "")
      end
      @description.strip!
    end

    def banner(description)
      self.description = description
    end

    attr_reader :description

    def derived_usage_description
      parts = ["[OPTIONS]"]
      parts += parameters.map(&:name)
      parts.join(" ")
    end

    def usage_descriptions
      declared_usage_descriptions || [derived_usage_description]
    end

    def help(invocation_path, builder = Builder.new)
      help = builder
      help.add_usage(invocation_path, usage_descriptions)
      help.add_description(description)
      if has_parameters?
        help.add_list(Clamp.message(:parameters_heading), parameters)
      end
      if has_subcommands?
        help.add_list(Clamp.message(:subcommands_heading), recognised_subcommands)
      end
      help.add_list(Clamp.message(:options_heading), recognised_options)
      help.string
    end

    class Builder

      def initialize
        @out = StringIO.new
      end

      def string
        @out.string
      end

      def add_usage(invocation_path, usage_descriptions)
        puts Clamp.message(:usage_heading) + ":"
        usage_descriptions.each do |usage|
          puts "    #{invocation_path} #{usage}".rstrip
        end
      end

      def add_description(description)
        return unless description
        puts ""
        puts description.gsub(/^/, "  ")
      end

      DETAIL_FORMAT = "    %-29s %s".freeze

      def add_list(heading, items)
        puts "\n#{heading}:"
        items.reject { |i| i.respond_to?(:hidden?) && i.hidden? }.each do |item|
          label, description = item.help
          description.each_line do |line|
            puts format(DETAIL_FORMAT, label, line)
            label = ""
          end
        end
      end

      private

      def puts(*args)
        @out.puts(*args)
      end

    end

  end

end