summaryrefslogtreecommitdiff
path: root/utils/generate-command-help.rb
blob: 3ef00b3b5895dd181345c8129dd68c4adff28833 (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env ruby -w
# Usage: generate-command-help.r [path/to/commands.json]
#    or: generate-commands-json.py | generate-command-help.rb -
#
# Defaults to downloading commands.json from the redis-doc repo if not provided
# or STDINed.

GROUPS = [
  "generic",
  "string",
  "list",
  "set",
  "sorted-set",
  "hash",
  "pubsub",
  "transactions",
  "connection",
  "server",
  "scripting",
  "hyperloglog",
  "cluster",
  "geo",
  "stream",
  "bitmap"
].freeze

GROUPS_BY_NAME = Hash[*
  GROUPS.each_with_index.map do |n,i|
    [n,i]
  end.flatten
].freeze

def argument arg
  if "block" == arg["type"]
    name = arg["arguments"].map do |entry|
      argument entry
    end.join " "
  elsif "oneof" == arg["type"]
    name = arg["arguments"].map do |entry|
      argument entry
    end.join "|"
  elsif "pure-token" == arg["type"]
    name = nil    # prepended later
  else
    name = arg["name"].is_a?(Array) ? arg["name"].join(" ") : arg["name"]
  end
  if arg["multiple"]
    name = "#{name} [#{name} ...]"
  end
  if arg["token"]
    name = [arg["token"], name].compact.join " "
  end
  if arg["optional"]
    name = "[#{name}]"
  end
  name
end

def arguments command
  return "" unless command["arguments"]
  command["arguments"].map do |arg|
    argument arg
  end.join " "
end

def commands
  return @commands if @commands

  require "rubygems"
  require "net/http"
  require "net/https"
  require "json"
  require "uri"
  if ARGV.length > 0
    if ARGV[0] == '-'
      data = STDIN.read
    elsif FileTest.exist? ARGV[0]
      data = File.read(ARGV[0])
    else
      raise Exception.new "File not found: #{ARGV[0]}"
    end
  else
    url = URI.parse "https://raw.githubusercontent.com/redis/redis-doc/master/commands.json"
    client = Net::HTTP.new url.host, url.port
    client.use_ssl = true
    response = client.get url.path
    if !response.is_a?(Net::HTTPSuccess)
      response.error!
      return
    else
      data = response.body
    end
  end
  @commands = JSON.parse(data)
end

def generate_groups
  GROUPS.map do |n|
    "\"#{n}\""
  end.join(",\n    ");
end

def generate_commands
  commands.to_a.sort do |x,y|
    x[0] <=> y[0]
  end.map do |key, command|
    group = GROUPS_BY_NAME[command["group"]]
    if group.nil?
      STDERR.puts "Please update groups array in #{__FILE__}"
      raise "Unknown group #{command["group"]}"
    end

    ret = <<-SPEC
{ "#{key}",
    "#{arguments(command)}",
    "#{command["summary"]}",
    #{group},
    "#{command["since"]}" }
    SPEC
    ret.strip
  end.join(",\n    ")
end

# Write to stdout
puts <<-HELP_H
/* Automatically generated by #{__FILE__}, do not edit. */

#ifndef __REDIS_HELP_H
#define __REDIS_HELP_H

static char *commandGroups[] = {
    #{generate_groups}
};

struct commandHelp {
  char *name;
  char *params;
  char *summary;
  int group;
  char *since;
} commandHelp[] = {
    #{generate_commands}
};

#endif
HELP_H