]> Dogcows Code - chaz/graphql-client/commitdiff
add --filter argument
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sun, 22 Mar 2020 09:39:37 +0000 (03:39 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sun, 22 Mar 2020 09:44:11 +0000 (03:44 -0600)
bin/graphql
dist.ini
lib/GraphQL/Client/CLI.pm
t/cli.t

index 61279223b4590b7ad2c04e7d548ef2a91e4bc462..2b5c03b8f1daf353d9ddab51a2a8dafeb075a03f 100755 (executable)
@@ -6,8 +6,8 @@
 
     graphql <URL> <QUERY> [ [--variables JSON] | [--variable KEY=VALUE]... ]
             [--operation-name NAME] [--transport KEY=VALUE]...
-            [--[no-]unpack] [--format json|json:pretty|yaml|perl|csv|tsv|table]
-            [--output FILE]
+            [--[no-]unpack] [--filter JSONPATH]
+            [--format json|json:pretty|yaml|perl|csv|tsv|table] [--output FILE]
 
     graphql --version|--help|--manual
 
@@ -117,6 +117,14 @@ practice.
 
 Use C<--no-unpack> to disable if unpack mode was enabled via C<GRAPHQL_CLIENT_OPTIONS>.
 
+=head2 C<--filter JSONPATH>
+
+Filter the response based on a L<JSONPath|JSON::Path/SYNOPSIS> expression.
+
+Requires L<JSON::Path>.
+
+Alias: C<-p>
+
 =head1 FORMAT
 
 The argument for L</"--format STR"> can be one of:
index c6f74b2b3a7a823cd0f03c2165f95f5f1272dc13..78e688a07e71d39a6fc10e379d228fad18e0212b 100644 (file)
--- a/dist.ini
+++ b/dist.ini
@@ -22,14 +22,16 @@ remove_runtime      = Pod::Usage
 remove_runtime      = Text::CSV
 remove_runtime      = Text::Table::Any
 remove_runtime      = YAML
+remove_runtime      = JSON::Path::Evaluator
 [Prereqs / RuntimeRecommends]
 HTTP::Tiny          = 0
 Pod::Usage          = 0
 [Prereqs / RuntimeSuggests]
-Data::Dumper        = 0
-Text::CSV           = 0
-Text::Table::Any    = 0
-YAML                = 0
+Data::Dumper            = 0
+JSON::Path::Evaluator   = 0
+Text::CSV               = 0
+Text::Table::Any        = 0
+YAML                    = 0
 [Prereqs / DevelopRecommends]
 ; for fatpack.pl
 App::FatPacker      = 0
index 66b391cb723b30a4bbf11addb19990d1fc7c7a3b..c23e07fe4af9aeb5115218a0daf07ee051a726f1 100644 (file)
@@ -84,6 +84,17 @@ sub main {
         *STDOUT = $out;
     }
 
+    if (my $filter = $options->{filter}) {
+        eval { require JSON::Path::Evaluator } or die "Missing dependency: JSON::Path\n";
+        my @values = JSON::Path::Evaluator::evaluate_jsonpath($data, $filter);
+        if (@values == 1) {
+            $data = $values[0];
+        }
+        else {
+            $data = \@values;
+        }
+    }
+
     binmode(STDOUT, 'encoding(UTF-8)');
     _print_data($data, $format);
 
@@ -115,6 +126,7 @@ sub _get_options {
         'operation-name|n=s'    => \$options{operation_name},
         'transport|t=s%'        => \$options{transport},
         'format|f=s'            => \$options{format},
+        'filter|p=s'            => \$options{filter},
         'unpack!'               => \$options{unpack},
         'output|o=s'            => \$options{outfile},
     ) or _pod2usage(2);
@@ -167,27 +179,42 @@ sub _print_data {
 
         my $unpacked = $data;
         # $unpacked = $data->{data} if !$unpack && !$err;
-        $unpacked = $data->{data} if $data && $data->{data};
+        $unpacked = $data->{data} if ref $data eq 'HASH' && $data->{data};
 
         # check the response to see if it can be formatted
         my @columns;
         my $rows = [];
-        if (keys %$unpacked == 1) {
-            my ($val) = values %$unpacked;
-            if (ref $val eq 'ARRAY') {
-                my $first = $val->[0];
-                if ($first && ref $first eq 'HASH') {
-                    @columns = sort keys %$first;
-                    $rows = [
-                        map { [map { _stringify($_) } @{$_}{@columns}] } @$val
-                    ];
-                }
-                elsif ($first) {
-                    @columns = keys %$unpacked;
-                    $rows = [map { [map { _stringify($_) } $_] } @$val];
+        if (ref $unpacked eq 'HASH') {
+            if (keys %$unpacked == 1) {
+                my ($val) = values %$unpacked;
+                if (ref $val eq 'ARRAY') {
+                    my $first = $val->[0];
+                    if ($first && ref $first eq 'HASH') {
+                        @columns = sort keys %$first;
+                        $rows = [
+                            map { [map { _stringify($_) } @{$_}{@columns}] } @$val
+                        ];
+                    }
+                    elsif ($first) {
+                        @columns = keys %$unpacked;
+                        $rows = [map { [map { _stringify($_) } $_] } @$val];
+                    }
                 }
             }
         }
+        elsif (ref $unpacked eq 'ARRAY') {
+            my $first = $unpacked->[0];
+            if ($first && ref $first eq 'HASH') {
+                @columns = sort keys %$first;
+                $rows = [
+                    map { [map { _stringify($_) } @{$_}{@columns}] } @$unpacked
+                ];
+            }
+            elsif ($first) {
+                @columns = qw(column);
+                $rows = [map { [map { _stringify($_) } $_] } @$unpacked];
+            }
+        }
 
         if (@columns) {
             if ($format eq 'table') {
@@ -214,13 +241,26 @@ sub _print_data {
             exit 3;
         }
     }
+    elsif ($format eq 'string') {
+        if (!ref $data) {
+            print $data, "\n";
+        }
+        elsif (ref $data eq 'ARRAY') {
+            print join("\n", @$data);
+        }
+        else {
+            _print_data($data);
+            print STDERR sprintf("Error: Response could not be formatted as %s.\n", $format);
+            exit 3;
+        }
+    }
     elsif ($format eq 'perl') {
         eval { require Data::Dumper } or die "Missing dependency: Data::Dumper\n";
         print Data::Dumper::Dumper($data);
     }
     else {
-        print STDERR "Error: Format not supported: $format\n";
         _print_data($data);
+        print STDERR "Error: Format not supported: $format\n";
         exit 3;
     }
 }
diff --git a/t/cli.t b/t/cli.t
index 2fa501ceac917a4f2dc88bac39e0d127ea579208..a32af83b333f6189b694c70185f0d36b0e2a0cc6 100755 (executable)
--- a/t/cli.t
+++ b/t/cli.t
@@ -13,6 +13,7 @@ delete $ENV{GRAPHQL_CLIENT_OPTIONS};
 subtest 'get_options' => sub {
     my $expected = {
         format          => 'json:pretty',
+        filter          => undef,
         help            => undef,
         manual          => undef,
         operation_name  => undef,
This page took 0.033115 seconds and 4 git commands to generate.