gremlin2dot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +28 -0
- data/README.md +6 -0
- data/bin/gremlin2dot +84 -0
- data/lib/gremlin2dot/data_model.rb +60 -0
- data/lib/gremlin2dot/graph_builder.rb +54 -0
- data/lib/gremlin2dot/unmangler.rb +67 -0
- data/lib/gremlin2dot.rb +3 -0
- metadata +95 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 329541aa877df7ee19cd655d44becf877b32739d76b41dfd1b5a97b3aad1f619
         | 
| 4 | 
            +
              data.tar.gz: 074615b05287eda09c507586b86891bf30d1f34cf113e6b031ae7906550fe60c
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 51e50cc7cd8e90042a07beb665665073f9aa626056c52b40865eb92b1fbdd1e1c57a8dfaa3bf0eec7ea77fe68caf4c260b711e2f6e94a5096b8336145f1f64b6
         | 
| 7 | 
            +
              data.tar.gz: 77e8a9450f43d4b50a0540c18695991b7b4a319b7a9efb0d23bd987c71034572518c04679f7347de8e4e7ded6b50da315b9e204f887f8536b99c9c13e36b729f
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            GEM
         | 
| 2 | 
            +
              specs:
         | 
| 3 | 
            +
                domain_name (0.5.20180417)
         | 
| 4 | 
            +
                  unf (>= 0.0.5, < 1.0.0)
         | 
| 5 | 
            +
                http-cookie (1.0.3)
         | 
| 6 | 
            +
                  domain_name (~> 0.5)
         | 
| 7 | 
            +
                mime-types (3.1)
         | 
| 8 | 
            +
                  mime-types-data (~> 3.2015)
         | 
| 9 | 
            +
                mime-types-data (3.2016.0521)
         | 
| 10 | 
            +
                netrc (0.11.0)
         | 
| 11 | 
            +
                rest-client (2.0.2)
         | 
| 12 | 
            +
                  http-cookie (>= 1.0.2, < 2.0)
         | 
| 13 | 
            +
                  mime-types (>= 1.16, < 4.0)
         | 
| 14 | 
            +
                  netrc (~> 0.8)
         | 
| 15 | 
            +
                ruby-graphviz (1.2.2)
         | 
| 16 | 
            +
                unf (0.1.4)
         | 
| 17 | 
            +
                  unf_ext
         | 
| 18 | 
            +
                unf_ext (0.0.7.5)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            PLATFORMS
         | 
| 21 | 
            +
              ruby
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            DEPENDENCIES
         | 
| 24 | 
            +
              rest-client (~> 2.0)
         | 
| 25 | 
            +
              ruby-graphviz (~> 1.0)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            BUNDLED WITH
         | 
| 28 | 
            +
               1.16.1
         | 
    
        data/README.md
    ADDED
    
    
    
        data/bin/gremlin2dot
    ADDED
    
    | @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            # vi: set ts=2 sw=2 :
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'optparse'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            def error(message)
         | 
| 7 | 
            +
              $stderr.puts message
         | 
| 8 | 
            +
              exit 2
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            endpoint = nil
         | 
| 12 | 
            +
            query = nil
         | 
| 13 | 
            +
            use_stdin = false
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            json_file = nil
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            canon_file = nil
         | 
| 18 | 
            +
            dot_file = nil
         | 
| 19 | 
            +
            png_file = nil
         | 
| 20 | 
            +
            svg_file = nil
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            opts = OptionParser.new
         | 
| 23 | 
            +
            opts.on('-e', '--endpoint URL', 'The URL of the Gremlin endpoint') {|v| endpoint = v }
         | 
| 24 | 
            +
            opts.on('-q', '--query QUERY', 'The Gremlin query to run') {|v| query = v }
         | 
| 25 | 
            +
            opts.on('--stdin', 'Read Gremlin results as JSON from standard input') { use_stdin = true }
         | 
| 26 | 
            +
            opts.on('--save-json FILE', 'Save the JSON to FILE') {|v| json_file = v }
         | 
| 27 | 
            +
            opts.on('--canon FILE', 'Write the results as canonical DOT to FILE') {|v| canon_file = v }
         | 
| 28 | 
            +
            opts.on('--dot FILE', 'Write the results as placed DOT to FILE') {|v| dot_file = v }
         | 
| 29 | 
            +
            opts.on('--png FILE', 'Write the results as PNG to FILE') {|v| png_file = v }
         | 
| 30 | 
            +
            opts.on('--svg FILE', 'Write the results as SVG to FILE') {|v| svg_file = v }
         | 
| 31 | 
            +
            opts.order!
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            if !canon_file and !dot_file and !png_file and !svg_file
         | 
| 34 | 
            +
              canon_file = "/dev/stdout"
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            if endpoint.nil? != query.nil?
         | 
| 38 | 
            +
              error "Either specify both --endpoint and --query, or specify --stdin 1"
         | 
| 39 | 
            +
            end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            if use_stdin != endpoint.nil?
         | 
| 42 | 
            +
              error "Either specify both --endpoint and --query, or specify --stdin 2"
         | 
| 43 | 
            +
            end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            require 'json'
         | 
| 46 | 
            +
            require 'gremlin2dot'
         | 
| 47 | 
            +
            require 'ruby-graphviz'
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            json_text = if use_stdin
         | 
| 50 | 
            +
                          $stdin.read
         | 
| 51 | 
            +
                        else
         | 
| 52 | 
            +
                          require 'rest-client'
         | 
| 53 | 
            +
                          RestClient.post(
         | 
| 54 | 
            +
                            endpoint,
         | 
| 55 | 
            +
                            { gremlin: query }.to_json,
         | 
| 56 | 
            +
                            { content_type: :json, accept: :json },
         | 
| 57 | 
            +
                          ).body
         | 
| 58 | 
            +
                        end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            if json_file
         | 
| 61 | 
            +
              IO.write(json_file, json_text)
         | 
| 62 | 
            +
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            query_results = JSON.parse(json_text)
         | 
| 65 | 
            +
            unmangled_data = Gremlin2Dot::Unmangler.new.unmangle(query_results)
         | 
| 66 | 
            +
            g = Gremlin2Dot::GraphBuilder.build(unmangled_data)
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            if canon_file
         | 
| 69 | 
            +
              g.output(canon: canon_file)
         | 
| 70 | 
            +
            end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            if dot_file
         | 
| 73 | 
            +
              g.output(dot: dot_file)
         | 
| 74 | 
            +
            end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            if png_file
         | 
| 77 | 
            +
              g.output(png: png_file)
         | 
| 78 | 
            +
            end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            if svg_file
         | 
| 81 | 
            +
              g.output(svg: svg_file)
         | 
| 82 | 
            +
            end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            exit
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            module Gremlin2Dot
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class Edge < Hash
         | 
| 4 | 
            +
                def id ; self['id'] ; end
         | 
| 5 | 
            +
                def label ; self['label'] ; end
         | 
| 6 | 
            +
                def inVLabel ; self['inVLabel'] ; end
         | 
| 7 | 
            +
                def outVLabel ; self['outVLabel'] ; end
         | 
| 8 | 
            +
                def inV ; self['inV'] ; end
         | 
| 9 | 
            +
                def outV ; self['outV'] ; end
         | 
| 10 | 
            +
                def properties ; self['properties'] || {} ; end
         | 
| 11 | 
            +
                def inspect ; "#<#{self.class.name} #{super}>" ; end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              class Vertex < Hash
         | 
| 15 | 
            +
                def id ; self['id'] ; end
         | 
| 16 | 
            +
                def label ; self['label'] ; end
         | 
| 17 | 
            +
                def properties ; self['properties'] || {} ; end
         | 
| 18 | 
            +
                def inspect ; "#<#{self.class.name} #{super}>" ; end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              class VertexProperty < Hash
         | 
| 22 | 
            +
                def id ; self['id'] ; end
         | 
| 23 | 
            +
                def label ; self['label'] ; end
         | 
| 24 | 
            +
                def value ; self['value'] ; end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def inspect
         | 
| 27 | 
            +
                  value.inspect
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def to_s
         | 
| 31 | 
            +
                  value.to_s
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def pretty_print(*args)
         | 
| 35 | 
            +
                  value.pretty_print *args
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              class Property < Hash
         | 
| 40 | 
            +
                def key ; self['key'] ; end
         | 
| 41 | 
            +
                def value ; self['value'] ; end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def inspect
         | 
| 44 | 
            +
                  value.inspect
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def to_s
         | 
| 48 | 
            +
                  value.to_s
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def pretty_print(*args)
         | 
| 52 | 
            +
                  value.pretty_print *args
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              class Tree
         | 
| 57 | 
            +
                attr_accessor :key, :items
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            require 'set'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Gremlin2Dot
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              class GraphBuilder
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def self.build(results)
         | 
| 8 | 
            +
                  self.new().build(results)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def initialize
         | 
| 12 | 
            +
                  @seen = Set.new
         | 
| 13 | 
            +
                  @g = GraphViz.new("G")
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def build(unmangled_data)
         | 
| 17 | 
            +
                  trees = unmangled_data['result']['data']
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  trees.each do |t0|
         | 
| 20 | 
            +
                    t0.each do |t1|
         | 
| 21 | 
            +
                      add_thing t1
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  @g
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def add_thing(thing)
         | 
| 29 | 
            +
                  case thing
         | 
| 30 | 
            +
                  when Vertex
         | 
| 31 | 
            +
                    node = thing
         | 
| 32 | 
            +
                    unless @seen.include? node.id
         | 
| 33 | 
            +
                      label = node.label + node.properties.entries.sort_by(&:first).map {|k, v| "\n#{k}=#{v.first}" }.join("")
         | 
| 34 | 
            +
                      @g.add_nodes(node.id, label: label)
         | 
| 35 | 
            +
                      @seen << node.id
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  when Edge
         | 
| 38 | 
            +
                    edge = thing
         | 
| 39 | 
            +
                    unless @seen.include? edge.id
         | 
| 40 | 
            +
                      label = edge.label + edge.properties.entries.sort_by(&:first).map {|k, v| "\n#{k}=#{v}" }.join("")
         | 
| 41 | 
            +
                      @g.add_edges(edge.outV, edge.inV, label: label)
         | 
| 42 | 
            +
                      @seen << edge.id
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                  when Tree
         | 
| 45 | 
            +
                    add_thing thing.key
         | 
| 46 | 
            +
                    thing.items.each {|child| add_thing child}
         | 
| 47 | 
            +
                  else
         | 
| 48 | 
            +
                    $stderr.puts "Not adding #{thing.class} to the graph"
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            end
         | 
| @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            module Gremlin2Dot
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class Unmangler
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def unmangle(d)
         | 
| 6 | 
            +
                  if d.kind_of?(Hash) and d.has_key?('@type') and d.has_key?('@value') and d.keys.count == 2
         | 
| 7 | 
            +
                    case d['@type']
         | 
| 8 | 
            +
                    when 'g:Map'
         | 
| 9 | 
            +
                      h = Hash.new
         | 
| 10 | 
            +
                      raise unless d['@value'].empty?
         | 
| 11 | 
            +
                      h
         | 
| 12 | 
            +
                    when 'g:List'
         | 
| 13 | 
            +
                      unmangle d['@value']
         | 
| 14 | 
            +
                    when 'g:Tree'
         | 
| 15 | 
            +
                      # array of hashes, where each hash has 'key'=Vertex/Edge, 'value' = ...
         | 
| 16 | 
            +
                      # Array of Hash with 'key' and 'value', where ...
         | 
| 17 | 
            +
                      # – key is a Vertex
         | 
| 18 | 
            +
                      # – value is a Hash of @type/@value
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      d['@value'].map do |item|
         | 
| 21 | 
            +
                        t = Tree.new
         | 
| 22 | 
            +
                        t.key = unmangle item['key']
         | 
| 23 | 
            +
                        t.items = unmangle item['value']
         | 
| 24 | 
            +
                        t
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                    when 'g:Edge'
         | 
| 27 | 
            +
                      unmangle_object(d, Edge)
         | 
| 28 | 
            +
                    when 'g:Vertex'
         | 
| 29 | 
            +
                      unmangle_object(d, Vertex)
         | 
| 30 | 
            +
                    when 'g:VertexProperty'
         | 
| 31 | 
            +
                      unmangle_object(d, VertexProperty)
         | 
| 32 | 
            +
                      # discard the id
         | 
| 33 | 
            +
                      # unmangle d['@value']['value']
         | 
| 34 | 
            +
                    when 'g:Property'
         | 
| 35 | 
            +
                      unmangle_object(d, Property)
         | 
| 36 | 
            +
                      # discard the key
         | 
| 37 | 
            +
                      # unmangle d['@value']['value']
         | 
| 38 | 
            +
                    when 'g:Int32'
         | 
| 39 | 
            +
                      d['@value']
         | 
| 40 | 
            +
                    when 'g:Double'
         | 
| 41 | 
            +
                      d['@value']
         | 
| 42 | 
            +
                    when 'g:Date'
         | 
| 43 | 
            +
                      Time.at(d['@value'] / 1000.0)
         | 
| 44 | 
            +
                    else
         | 
| 45 | 
            +
                      $stderr.puts 'Ignoring unknown type ' + d['@type'] + " with value #{d['@value'].inspect[0..200]}..."
         | 
| 46 | 
            +
                      unmangle d['@value']
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  elsif d.kind_of? Hash
         | 
| 49 | 
            +
                    d.entries.map {|k, v| [k, unmangle(v)]}.to_h
         | 
| 50 | 
            +
                  elsif d.kind_of? Array
         | 
| 51 | 
            +
                    d.map {|v| unmangle v}
         | 
| 52 | 
            +
                  else
         | 
| 53 | 
            +
                    d
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def unmangle_object(d, klass)
         | 
| 58 | 
            +
                  o = klass.new
         | 
| 59 | 
            +
                  d['@value'].entries.each do |k, v|
         | 
| 60 | 
            +
                    o[k] = unmangle v
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                  o
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            end
         | 
    
        data/lib/gremlin2dot.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: gremlin2dot
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Rachel Evans
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2018-06-28 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: rest-client
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '2.0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '2.0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: ruby-graphviz
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '1.0'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '1.0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rspec
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '3.5'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '3.5'
         | 
| 55 | 
            +
            description: "\n"
         | 
| 56 | 
            +
            email:
         | 
| 57 | 
            +
            - rachel@rachelevans.org
         | 
| 58 | 
            +
            executables:
         | 
| 59 | 
            +
            - gremlin2dot
         | 
| 60 | 
            +
            extensions: []
         | 
| 61 | 
            +
            extra_rdoc_files: []
         | 
| 62 | 
            +
            files:
         | 
| 63 | 
            +
            - Gemfile
         | 
| 64 | 
            +
            - Gemfile.lock
         | 
| 65 | 
            +
            - README.md
         | 
| 66 | 
            +
            - bin/gremlin2dot
         | 
| 67 | 
            +
            - lib/gremlin2dot.rb
         | 
| 68 | 
            +
            - lib/gremlin2dot/data_model.rb
         | 
| 69 | 
            +
            - lib/gremlin2dot/graph_builder.rb
         | 
| 70 | 
            +
            - lib/gremlin2dot/unmangler.rb
         | 
| 71 | 
            +
            homepage: http://rve.org.uk/gems/gremlin2dot
         | 
| 72 | 
            +
            licenses:
         | 
| 73 | 
            +
            - Apache-2.0
         | 
| 74 | 
            +
            metadata: {}
         | 
| 75 | 
            +
            post_install_message: 
         | 
| 76 | 
            +
            rdoc_options: []
         | 
| 77 | 
            +
            require_paths:
         | 
| 78 | 
            +
            - lib
         | 
| 79 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 80 | 
            +
              requirements:
         | 
| 81 | 
            +
              - - ">="
         | 
| 82 | 
            +
                - !ruby/object:Gem::Version
         | 
| 83 | 
            +
                  version: '0'
         | 
| 84 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 85 | 
            +
              requirements:
         | 
| 86 | 
            +
              - - ">="
         | 
| 87 | 
            +
                - !ruby/object:Gem::Version
         | 
| 88 | 
            +
                  version: '0'
         | 
| 89 | 
            +
            requirements: []
         | 
| 90 | 
            +
            rubyforge_project: 
         | 
| 91 | 
            +
            rubygems_version: 2.7.6
         | 
| 92 | 
            +
            signing_key: 
         | 
| 93 | 
            +
            specification_version: 4
         | 
| 94 | 
            +
            summary: Run a gremlin query, and visualise using GraphViz
         | 
| 95 | 
            +
            test_files: []
         |