File Coverage

script/generate-commands
Criterion Covered Total %
statement 68 72 94.4
branch 16 22 72.7
condition 3 7 42.8
subroutine 12 13 92.3
pod n/a
total 99 114 86.8


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2             # script/generate-commands
3             #
4             # Generates Async::Redis::Commands from redis-doc commands.json
5              
6 3     3   16755 use strict;
  3         6  
  3         133  
7 3     3   15 use warnings;
  3         5  
  3         176  
8 3     3   116 use 5.018;
  3         12  
9 3     3   2448 use Getopt::Long;
  3         57371  
  3         27  
10 3     3   2873 use JSON::PP;
  3         60901  
  3         295  
11 3     3   29 use File::Basename;
  3         5  
  3         7746  
12              
13 3         486676 my ($input, $output, $help);
14 3 50       25 GetOptions(
15             'input=s' => \$input,
16             'output=s' => \$output,
17             'help' => \$help,
18             ) or usage();
19 3 50       3405 usage() if $help;
20              
21 3   50     12 $input //= 'script/commands.json';
22 3   50     17 $output //= 'lib/Async/Redis/Commands.pm';
23              
24 3 100       91 die "Input file not found: $input\n" unless -f $input;
25              
26             # Load commands.json
27 2 50       128 open my $fh, '<', $input or die "Cannot open $input: $!";
28 2         11 my $json = do { local $/; <$fh> };
  2         13  
  2         5164  
29 2         47 close $fh;
30              
31 2         24 my $commands = decode_json($json);
32              
33             # Generate module
34 2         8796669 my $code = generate_module($commands);
35              
36             # Write output
37 2         154 my $dir = dirname($output);
38 2 50 33     108 system("mkdir", "-p", $dir) if $dir && !-d $dir;
39              
40 2 50       522 open my $out, '>', $output or die "Cannot write $output: $!";
41 2         371 print $out $code;
42 2         126 close $out;
43              
44 2         19 say "Generated $output with " . scalar(keys %$commands) . " commands";
45 2         0 exit 0;
46              
47             sub usage {
48 0     0   0 say "Usage: $0 [--input FILE] [--output FILE]";
49 0         0 say " --input Path to commands.json (default: script/commands.json)";
50 0         0 say " --output Output module path (default: lib/Async/Redis/Commands.pm)";
51 0         0 exit 1;
52             }
53              
54             sub generate_module {
55 2     2   8 my ($commands) = @_;
56              
57 2         6 my @methods;
58             my %seen;
59              
60 2         880 for my $cmd (sort keys %$commands) {
61 740         1502 my $info = $commands->{$cmd};
62 740         1220 my $method = cmd_to_method($cmd);
63              
64 740 50       2531 next if $seen{$method}++;
65              
66 740         1824 my $parts = [split /\s+/, $cmd];
67 740         1327 my $is_subcommand = @$parts > 1;
68              
69 740         1306 push @methods, generate_method($method, $parts, $info);
70             }
71              
72 2         84 return <<"END_MODULE";
73             # lib/Async/Redis/Commands.pm
74             # AUTO-GENERATED - DO NOT EDIT
75             # Generated from redis-doc commands.json
76             #
77             # This module provides async method wrappers for all Redis commands.
78             # Consume this role in Async::Redis.
79              
80             package Async::Redis::Commands;
81              
82             use strict;
83             use warnings;
84             use 5.018;
85              
86             use Future::AsyncAwait;
87              
88 2         997 @{[ join("\n\n", @methods) ]}
89              
90             1;
91              
92             __END__