File Coverage

blib/lib/Mojolicious/Command/swagger2.pm
Criterion Covered Total %
statement 53 91 58.2
branch 23 48 47.9
condition 10 22 45.4
subroutine 8 12 66.6
pod 1 1 100.0
total 95 174 54.6


line stmt bran cond sub pod time code
1             package Mojolicious::Command::swagger2;
2 1     1   273686 use Mojo::Base 'Mojolicious::Command';
  1         5  
  1         9  
3 1     1   56617 use Mojo::Util;
  1         2  
  1         40  
4 1     1   593 use Swagger2;
  1         3  
  1         12  
5              
6             my $app = __PACKAGE__;
7              
8             # used in tests
9             our $OUT = \*STDOUT;
10              
11             has description => 'Interface with Swagger2.';
12             has usage => <<"HERE";
13             Usage:
14              
15             # Make a request to a Swagger server
16             @{[__PACKAGE__->_usage('client')]}
17              
18             # Edit an API file in your browser
19             # This command also takes whatever option "morbo" takes
20             @{[__PACKAGE__->_usage('edit')]}
21              
22             # Write POD to STDOUT
23             @{[__PACKAGE__->_usage('pod')]}
24              
25             # Run perldoc on the generated POD
26             @{[__PACKAGE__->_usage('perldoc')]}
27              
28             # Validate an API file
29             @{[__PACKAGE__->_usage('validate')]}
30              
31             HERE
32              
33             sub run {
34 3     3 1 3209 my $self = shift;
35 3   50     12 my $action = shift || 'unknown';
36 3         39 my $code = $self->can("_action_$action");
37              
38 3 50       12 die $self->usage unless $code;
39 3         7 $self->$code(@_);
40             }
41              
42             sub _action_client {
43 3     3   8 my ($self, $file, @args) = @_;
44              
45 3 100       10 unshift @args, $file if $ENV{SWAGGER_API_FILE};
46 3   100     23 $ENV{SWAGGER_COERCE_VALUES} //= 1;
47              
48 3         5 my $method = shift @args;
49 3         7 my $args = {};
50 3         7 my $base_url = $ENV{SWAGGER_BASE_URL};
51 3         4 my $i = 0;
52              
53 3 100 100     31 return print $OUT $self->_usage_client unless $ENV{SWAGGER_API_FILE} ||= $file;
54 2 100 66     19 return print $OUT $self->_documentation_for('') if !$method or $method =~ /\W/;
55              
56 1         483 require Swagger2::Client;
57 1         6 my $client = Swagger2::Client->generate($ENV{SWAGGER_API_FILE});
58              
59 1         10 for (@args) {
60 1 50       8 return $self->_documentation_for($method) if $_ eq 'help';
61 0 0       0 $base_url = $args[$i + 1] if $_ eq '-b';
62 0 0       0 $args = Mojo::JSON::decode_json($args[0]) if /^\{/;
63 0 0       0 $args->{$1} = $2 if /^(\w+)=(.*)/;
64 0         0 $i++;
65             }
66              
67 0 0       0 $client->base_url->parse($base_url) if $base_url;
68             eval {
69 0         0 my $res = $client->$method($args);
70 0 0       0 print $OUT $res->json ? Mojo::Util::dumper($res->json) : $res->body;
71 0         0 1;
72 0 0       0 } or do {
73 0         0 my $e = $@;
74 0         0 $e =~ s! at .* line.*!!s;
75 0         0 warn "ERROR! $e\n";
76             };
77             }
78              
79             sub _action_edit {
80 0     0   0 my ($self, $file, @args) = @_;
81              
82 0 0       0 unshift @args, $file if $ENV{SWAGGER_API_FILE};
83 0   0     0 $ENV{SWAGGER_API_FILE} ||= $file || '';
      0        
84 0         0 $ENV{SWAGGER_LOAD_EDITOR} = 1;
85 0   0     0 $file ||= __FILE__;
86 0         0 require Swagger2::Editor;
87 0         0 system 'morbo', -w => $file, @args, $INC{'Swagger2/Editor.pm'};
88             }
89              
90             sub _action_perldoc {
91 0     0   0 my ($self, $file) = @_;
92              
93 0 0       0 die $self->_usage('perldoc'), "\n" unless $file;
94 0         0 require Mojo::Asset::File;
95 0         0 my $asset = Mojo::Asset::File->new;
96 0         0 $asset->add_chunk(Swagger2->new($file)->pod->to_string);
97 0         0 system perldoc => $asset->path;
98             }
99              
100             sub _action_pod {
101 0     0   0 my ($self, $file) = @_;
102              
103 0 0       0 die $self->_usage('pod'), "\n" unless $file;
104 0         0 print $OUT Swagger2->new($file)->pod->to_string;
105             }
106              
107             sub _action_validate {
108 0     0   0 my ($self, $file) = @_;
109 0         0 my @errors;
110              
111 0 0       0 die $self->_usage('validate'), "\n" unless $file;
112 0         0 @errors = Swagger2->new($file)->validate;
113              
114 0 0       0 unless (@errors) {
115 0         0 print $OUT "$file is valid.\n";
116 0         0 return;
117             }
118              
119 0         0 for my $e (@errors) {
120 0         0 print $OUT "$e\n";
121             }
122             }
123              
124             sub _documentation_for {
125 2     2   4 my ($self, $needle) = @_;
126 2         14 my $pod = Swagger2->new($ENV{SWAGGER_API_FILE})->pod;
127 2   50     133 my $paths = $pod->{api_spec}->get('/paths') || {};
128 2         41 my @methods;
129              
130 2         12 for my $path (sort keys %$paths) {
131 4         6 for my $method (sort keys %{$paths->{$path}}) {
  4         17  
132 10   33     29 push @methods, $paths->{$path}{$method}{operationId} || join ' ', $method, $path;
133 10 100       64 delete $paths->{$path}{$method} unless $methods[-1] eq $needle;
134             }
135 4 100       7 delete $paths->{$path} unless %{$paths->{$path}};
  4         17  
136             }
137              
138 2 100       8 unless ($needle) {
139 1         15 print $OUT "$_\n" for sort @methods;
140 1         22 return;
141             }
142              
143 1         6 require Pod::Simple;
144 1         11 my $pod_text = Pod::Text->new;
145 1         205 $pod_text->output_fh($OUT);
146 1         11 $pod_text->parse_string_document($pod->_paths_to_string);
147             }
148              
149             sub _usage {
150 5     5   7 my $self = shift;
151 5 100       20 return "Usage: mojo swagger2 edit" if $_[0] eq 'edit';
152 4 100       11 return "Usage: mojo swagger2 perldoc path/to/spec.json" if $_[0] eq 'perldoc';
153 3 100       11 return "Usage: mojo swagger2 pod path/to/spec.json" if $_[0] eq 'pod';
154 2 100       9 return "Usage: mojo swagger2 validate path/to/spec.json" if $_[0] eq 'validate';
155 1 50       12 return "Usage: mojo swagger2 client path/to/spec.json [args]" if $_[0] eq 'client';
156 0         0 die "No usage for '@_'";
157             }
158              
159             sub _usage_client {
160 1     1   2 my $self = shift;
161              
162 1         13 return <
163             Usage:
164             # Call a method with arguments
165             mojo swagger2 client path/to/spec.json [args]
166              
167             # List methods
168             mojo swagger2 client path/to/spec.json
169              
170             # Get documentation for a method
171             mojo swagger2 client path/to/spec.json help
172              
173             # Specify spec and/or base URL from environment.
174             # Useful for shell wrappers
175             SWAGGER_API_FILE=path/to/spec.json mojo swagger2 client
176             SWAGGER_BASE_URL=https://example.com/1.0 mojo swagger2 client
177              
178             # Example arguments
179             mojo swagger2 client path/to/spec.json list_pets '{"limit":10}'
180             mojo swagger2 client path/to/spec.json list_pets limit=10 owner=joe
181             mojo swagger2 client path/to/spec.json -b https://example.com/1.0 list_pets limit=10 owner=joe
182             HERE
183             }
184              
185             1;
186              
187             =encoding utf8
188              
189             =head1 NAME
190              
191             Mojolicious::Command::swagger2 - mojo swagger2 command
192              
193             =head1 DEPRECATION WARNING
194              
195             See L.
196              
197             =head1 DESCRIPTION
198              
199             L is a command for interfacing with L.
200              
201             =head1 SYNOPSIS
202              
203             # Call a method with arguments
204             mojo swagger2 client path/to/spec.json [args]
205              
206             # List methods
207             mojo swagger2 client path/to/spec.json
208              
209             # Get documentation for a method
210             mojo swagger2 client path/to/spec.json help
211              
212             # Specify spec and/or base URL from environment.
213             # Useful for shell wrappers
214             SWAGGER_API_FILE=path/to/spec.json mojo swagger2 client
215             SWAGGER_BASE_URL=https://example.com/1.0 mojo swagger2 client
216              
217             # Example arguments
218             mojo swagger2 client path/to/spec.json list_pets '{"limit":10}'
219             mojo swagger2 client path/to/spec.json list_pets limit=10 owner=joe
220             mojo swagger2 client path/to/spec.json -b https://example.com/1.0 list_pets limit=10 owner=joe
221              
222             =head1 ATTRIBUTES
223              
224             =head2 description
225              
226             Returns description of this command.
227              
228             =head2 usage
229              
230             Returns usage of this command.
231              
232             =head1 METHODS
233              
234             =head2 run
235              
236             See L.
237              
238             =head1 COPYRIGHT AND LICENSE
239              
240             Copyright (C) 2014-2015, Jan Henning Thorsen
241              
242             This program is free software, you can redistribute it and/or modify it under
243             the terms of the Artistic License version 2.0.
244              
245             =head1 AUTHOR
246              
247             Jan Henning Thorsen - C
248              
249             =cut