mini_graph 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f2793e4516fdd7679b69f8ab390e290de4cf03e3dcfb08e483d6aee3c09f6b68
4
+ data.tar.gz: 4399462a5da0cc58eae86e45922a5909cbecf338987f6739b48c67623a62ff82
5
+ SHA512:
6
+ metadata.gz: 328ccffe20e07a980dfd62052a293d759e8ce3b92bed28d941b09e3bbbff8724dcfcd20d6d2c83684f63a620ee8e0383d4ed9bc8b75b432a4907ab7ba79b7ffb
7
+ data.tar.gz: 0b85f02cb695a8d7e5ee5e81cd61ad36dc96917fbbabc91f2517672d039f530ff15d83845d884a32e82107981066be6bd3056f77aba94222a0b7f7b24a79cf5e
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
@@ -0,0 +1 @@
1
+ 2.7.1
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.5
7
+ before_install: gem install bundler -v 1.17.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in mini_graph.gemspec
6
+ gemspec
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mini_graph (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.14.1)
10
+ rake (12.3.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 2.1)
17
+ mini_graph!
18
+ minitest (~> 5.0)
19
+ rake (~> 12.3.3)
20
+
21
+ BUNDLED WITH
22
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2020 Coroutine LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,144 @@
1
+ # MiniGraph
2
+
3
+ [![Build Status](https://travis-ci.org/coroutine/mini_graph.svg?branch=master)](https://travis-ci.org/coroutine/mini_graph)
4
+
5
+ Hi! MiniGraph is a Ruby gem who's name says it all: it is mini--in functionality
6
+ and user experience--and it's a graph implementation. Imagine that!
7
+
8
+ MiniGraph provides a small DSL for defining and searching graphs. Behind the scenes,
9
+ MiniGraph uses a core set of classes to support the DSL. Of course, you are free
10
+ to directly use these classes for defining and searching graphs, if that better
11
+ suits your taste.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'mini_graph'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install mini_graph
28
+
29
+ ## Usage
30
+
31
+ Honestly, there's not a lot to cover here, so we'll keep it brief.
32
+
33
+ First, let's have a look at the DSL. The DSL covers two concerns:
34
+
35
+ 1. Defining graphs: these can be directed or undirected
36
+ 2. Searching graphs: we provide depth-first and breadth-first search functionality, feel free to extend this.
37
+
38
+ Now, let's take a closer look at the graph definition DSL.
39
+
40
+ ### DSL: Defining graphs
41
+
42
+ By default, all graphs created using the graph DSL are undirected. Here's an
43
+ example of a new, undirected graph as created with the DSL:
44
+
45
+ ```ruby
46
+ jim = { name: 'Jim', likes: %w(bears quilts buttermilk) }
47
+ john = { name: 'John', likes: %w(tires mailboxes wombats marshmallows) }
48
+ jill = { name: 'Jill', likes: %w(wind wrappers socks clay) }
49
+ jane = { name: 'Jane', likes: %w(cds parachutes corndogs living) }
50
+
51
+ # Create a new undirected graph, with the 4 vertices: jim, john, jill, jane.
52
+ friends = MiniGraph.create(jim, john, jill, jane) do
53
+
54
+ # create edges from jim, to john, jill and jane.
55
+ edge from: jim, to: [john, jill, jane]
56
+
57
+ # create edges from john, to jill and jane
58
+ edge from: john, to: [jill, jane]
59
+
60
+ # create an edge from jane to jill
61
+ edge from: jane, to: jill
62
+ end
63
+ ```
64
+
65
+ In the previous example, we create our graph to contain a know set of vertices.
66
+ Vertices can only be added to a graph during creation. At no other point in the
67
+ lifecycle of the graph may vertices be added or deleted.
68
+
69
+ Also notice the ability to define edges from a vertex to one or more vertices.
70
+ This is one of the nice little shortcuts provided by the DSL. But wait, there's more!
71
+ We can also easily define edges from many vertices to many vertices. Take, for
72
+ example, this complete, undirected graph:
73
+
74
+ ```ruby
75
+ poker_friends = MiniGraph.create(jim, john, jill, jane) do
76
+ edge from: [jim, john, jill, jane], to: [jim, john, jill, jane]
77
+ end
78
+ ```
79
+
80
+ Dang! That was easy! Ok, enough feigning astonishment!
81
+
82
+ We've now seen undirected graphs, as defined using the MiniGraph DSL, let's
83
+ now take a look at directed graphs. Let's use our first example, but this time
84
+ we'll make the edges directed. Here we go!
85
+
86
+ ```ruby
87
+ # Create a new undirected graph, with the 4 vertices: jim, john, jill, jane.
88
+ friends = MiniGraph.create(jim, john, jill, jane) do
89
+
90
+ # Make this a directed graph.
91
+ directed!
92
+
93
+ # create edges from jim, to john, jill and jane.
94
+ edge from: jim, to: [john, jill, jane]
95
+
96
+ # create edges from john, to jill and jane
97
+ edge from: john, to: [jill, jane]
98
+
99
+ # create an edge from jane to jill
100
+ edge from: jane, to: jill
101
+ end
102
+ ```
103
+
104
+ Did you see that?! We just added `directed!`, and that was it! Smooth and declarative.
105
+
106
+ Did I hear you say you wanted the same declarative syntax for undirected graphs? Boom!
107
+ Just use the `undirected!` declaration, and you're set!
108
+
109
+ Now, let's move on to searching.
110
+
111
+ ### DSL: Searching graphs
112
+
113
+ Now that we know how to define graphs, we should probably be able to find stuff
114
+ in them, right?
115
+
116
+ The MiniGraph search DSL is pretty minimal. You wanna do a depth-first search?
117
+ Check it:
118
+
119
+ ```ruby
120
+ # Searching our previously defined friends graph, and starting our search at the 'john' vertex:
121
+ results = MiniGraph.dfs friends, start_at: john
122
+
123
+ # results implements Enumerable
124
+ results.entries # => [john, jim, jill, jane]
125
+ ```
126
+
127
+ ...and here's breadth-first search on the same graph:
128
+
129
+ ```ruby
130
+ results = MiniGraph.bfs friends, start_at: jill
131
+ results.entries # => [jill, jim, john, jane]
132
+ ```
133
+
134
+ That's it for the DSL! Not much to it, right? You might even call it _Mini_.
135
+
136
+ ## Development
137
+
138
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
139
+
140
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
141
+
142
+ ## Contributing
143
+
144
+ Bug reports and pull requests are welcome on GitHub at https://github.com/coroutine/mini_graph.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mini_graph"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,36 @@
1
+ require "mini_graph/version"
2
+ require "mini_graph/dsl/graph_context"
3
+ require "mini_graph/dsl/search_context"
4
+
5
+ module MiniGraph
6
+
7
+ # Used to construct a new graph.
8
+ #
9
+ # Example usage:
10
+ #
11
+ # jim = Person.new
12
+ # john = Person.new
13
+ # jill = Person.new
14
+ # jane = Person.new
15
+ #
16
+ # friends = MiniGraph.create(jim, john, jill, jane) do
17
+ # # Creates a directed graph
18
+ # directed!
19
+ #
20
+ # edge from: jim, to: [john, jill, jane]
21
+ # edge from: john, to: [jill, jane]
22
+ # edge from: jane, to: jill
23
+ # end
24
+ #
25
+ def self.create(*vertices, &block)
26
+ MiniGraph::DSL::GraphContext.evaluate(*vertices, &block)
27
+ end
28
+
29
+ def self.dfs(graph, start_at: nil)
30
+ MiniGraph::DSL::SearchContext.evaluate(graph, start_at, algorithm: :dfs)
31
+ end
32
+
33
+ def self.bfs(graph, start_at: nil)
34
+ MiniGraph::DSL::SearchContext.evaluate(graph, start_at, algorithm: :bfs)
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ require 'mini_graph/core/error'
2
+
3
+ module MiniGraph
4
+ module Core
5
+ module Edge
6
+
7
+ # -----------------------------------------------------
8
+ # Directed Edge
9
+ # -----------------------------------------------------
10
+
11
+ class Directed
12
+ attr_reader :origin, :destination
13
+
14
+ def initialize(origin, destination)
15
+ @origin = origin
16
+ @destination = destination
17
+ end
18
+
19
+ def eql?(edge)
20
+ origin == edge.origin && destination == edge.destination
21
+ end
22
+
23
+ # cannot use alias or alias_method for this, as subclasses (e.g. UndirectedEdge)
24
+ # do not behave as expected. We'll be explicit.
25
+ def ==(edge)
26
+ eql?(edge)
27
+ end
28
+
29
+ def to_s
30
+ "(#{origin} -> #{destination})"
31
+ end
32
+
33
+ # Another case of not using alias to allow subclasses to behave as expected.
34
+ def inspect
35
+ to_s
36
+ end
37
+
38
+ # Reverses the direction of the edge
39
+ def reverse
40
+ self.class.new(destination, origin)
41
+ end
42
+
43
+ # Indicates a self-looping edge; i.e., an edge that connects a vertex to
44
+ # itself.
45
+ def self_loop?
46
+ origin == destination
47
+ end
48
+ end
49
+
50
+ # -----------------------------------------------------
51
+ # Undirected
52
+ # -----------------------------------------------------
53
+
54
+ class Undirected < Directed
55
+ def eql?(edge)
56
+ super || (origin == edge.destination && destination == edge.origin)
57
+ end
58
+
59
+ def to_s
60
+ "(#{origin} <-> #{destination})"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ module MiniGraph
2
+ module Core
3
+ module Error
4
+ class GraphError < StandardError; end
5
+
6
+ class SelfLoopError < GraphError; end
7
+ class ParallelEdgeError < GraphError; end
8
+ class InvalidIndexError < GraphError; end
9
+ class InvalidEdgeError < GraphError; end
10
+ class InvalidEdgeTypeError < GraphError; end
11
+ class InvalidSearchAlgorithmError < GraphError; end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,119 @@
1
+ require 'forwardable'
2
+ require 'mini_graph/core/edge'
3
+ require 'mini_graph/core/error'
4
+
5
+ module MiniGraph
6
+ module Core
7
+ class Graph
8
+
9
+ include Enumerable
10
+ extend Forwardable
11
+
12
+ def_delegators :@vertices, :each, :size, :[]
13
+
14
+ attr_reader :vertices
15
+
16
+ # Initialize a directed or undirected graph with a list of vertices
17
+ def initialize(vertices, directed: false)
18
+ @directed = !!directed
19
+ @vertices = [vertices].flatten.freeze
20
+ @edges = []
21
+ end
22
+
23
+ def edge_class
24
+ if directed?
25
+ MiniGraph::Core::Edge::Directed
26
+ else
27
+ MiniGraph::Core::Edge::Undirected
28
+ end
29
+ end
30
+
31
+ # Adds an edge from the vertex at origin_index to the vertex at
32
+ # destination_index
33
+ def add_edge(*args)
34
+ edge = args_to_edge(args)
35
+
36
+ # origin must reference a valid index within the graph
37
+ if edge.origin >= size
38
+ raise ::MiniGraph::Core::Error::InvalidIndexError,
39
+ 'origin_index invalid'
40
+ end
41
+
42
+ # destination must reference a valid index within the graph
43
+ if edge.destination >= size
44
+ raise ::MiniGraph::Core::Error::InvalidIndexError,
45
+ 'destination_index invalid'
46
+ end
47
+
48
+ edges << edge
49
+ end
50
+
51
+ def directed?
52
+ @directed
53
+ end
54
+
55
+ def undirected?
56
+ !directed?
57
+ end
58
+
59
+ # Returns an array of vertex indices that have an inbound edge from the vertex
60
+ # at the supplied index
61
+ def adjacent_vertices(index)
62
+ edges.reduce([]) do |adj, edge|
63
+ adj << edge.destination if edge.origin == index
64
+ adj << edge.origin if undirected? && edge.destination == index
65
+ adj
66
+ end
67
+ .uniq
68
+ end
69
+
70
+ # Returns a reversed copy of the digraph.
71
+ def reverse
72
+ self.class.new(vertices, directed: @directed).tap do |dg|
73
+ dg.edges = edges.map(&:reverse)
74
+ end
75
+ end
76
+
77
+ def to_s
78
+ edges.join
79
+ end
80
+
81
+ # -----------------------------------------------------
82
+ # Protected
83
+ # -----------------------------------------------------
84
+
85
+ protected
86
+
87
+ def edges
88
+ @edges
89
+ end
90
+
91
+ def edges=(edges)
92
+ @edges = edges
93
+ end
94
+
95
+ # -----------------------------------------------------
96
+ # Private
97
+ # -----------------------------------------------------
98
+
99
+ private
100
+
101
+ def args_to_edge(args)
102
+ case args.length
103
+ when 1
104
+ args.first.tap do |edge|
105
+ if edge.class != edge_class
106
+ raise MiniGraph::Core::Error::InvalidEdgeTypeError,
107
+ "edge must be instance of #{edge_class.name}"
108
+ end
109
+ end
110
+ when 2
111
+ edge_class.new(*args)
112
+ else
113
+ raise ArgumentError,
114
+ "wrong number of arguments. #{args.length} args were provided. 1 or 2 arguments were expected."
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,73 @@
1
+ module MiniGraph
2
+ module Core
3
+ module Search
4
+
5
+ # -----------------------------------------------------
6
+ # Base Search Implementation
7
+ # -----------------------------------------------------
8
+
9
+ class Base
10
+ include Enumerable
11
+
12
+ attr_reader :graph, :vertex_index
13
+
14
+ def initialize(graph, vertex_index)
15
+ @graph = graph
16
+ @vertex_index = vertex_index
17
+ end
18
+
19
+ def each
20
+ return enum_for(:each) unless block_given?
21
+
22
+ visit(vertex_index) do |vi|
23
+ yield graph[vi]
24
+ end
25
+ end
26
+
27
+ def visit(index, visited=Array.new(graph.size, false), &block)
28
+ raise NotImplementedError, "#visit must be implemented"
29
+ end
30
+ end
31
+
32
+ # -----------------------------------------------------
33
+ # Depth-First Search
34
+ # -----------------------------------------------------
35
+
36
+ class DFS < Base
37
+ def visit(index, visited=Array.new(graph.size, false), &block)
38
+ visited[index] = true
39
+ yield index
40
+
41
+ graph.adjacent_vertices(index).each do |vi|
42
+ visit(vi, visited, &block) unless visited[vi]
43
+ end
44
+ end
45
+ end
46
+
47
+ # -----------------------------------------------------
48
+ # Breadth-First Search
49
+ # -----------------------------------------------------
50
+
51
+ class BFS < Base
52
+ def visit(index, visited=Array.new(graph.size, false), &block)
53
+ queue = []
54
+ visited[index] = true
55
+
56
+ queue.push(index)
57
+
58
+ while !queue.empty?
59
+ next_index = queue.shift
60
+ yield next_index
61
+
62
+ graph.adjacent_vertices(next_index).each do |vi|
63
+ unless visited[vi]
64
+ visited[vi] = true
65
+ queue.push(vi)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,79 @@
1
+ require 'mini_graph/core/edge'
2
+ require 'mini_graph/core/graph'
3
+
4
+ module MiniGraph
5
+ module DSL
6
+ class GraphContext
7
+ def self.evaluate(*vertices, &block)
8
+ unless block_given?
9
+ raise ArgumentError, "cannot call .create without a block"
10
+ end
11
+
12
+ graph_context = new(vertices)
13
+ graph_context.instance_eval(&block)
14
+ graph_context.resolve
15
+ end
16
+
17
+ # -----------------------------------------------------
18
+ # Public Methods
19
+ # -----------------------------------------------------
20
+
21
+ def resolve
22
+ if @edges.any? { |edge| edge.any?(&:nil?) }
23
+ raise MiniGraph::Core::Error::InvalidEdgeError,
24
+ 'One or more invalid edges were specified'
25
+ end
26
+
27
+ MiniGraph::Core::Graph.new(@vertices, directed: @directed).tap do |g|
28
+ @edges.each do |edge|
29
+ g.add_edge(*edge)
30
+ end
31
+ end
32
+ end
33
+
34
+ # -----------------------------------------------------
35
+ # Protected Methods
36
+ # -----------------------------------------------------
37
+
38
+ protected
39
+
40
+ attr_reader :vertex_index
41
+
42
+ def initialize(vertices)
43
+ @vertices = [vertices].flatten
44
+ @vertex_index = @vertices.map.with_index { |v, i| [v, i] }.to_h
45
+ @directed = false
46
+ @edges = []
47
+ end
48
+
49
+ def undirected!
50
+ @directed = false
51
+ end
52
+
53
+ def directed!
54
+ @directed = true
55
+ end
56
+
57
+ def edge(from:, to:)
58
+ from_indices = vertices_to_indices(from)
59
+ to_indices = vertices_to_indices(to)
60
+
61
+ @edges += from_indices.flat_map do |origin|
62
+ to_indices.map do |destination|
63
+ [origin, destination]
64
+ end
65
+ end
66
+ end
67
+
68
+ # -----------------------------------------------------
69
+ # Private Methods
70
+ # -----------------------------------------------------
71
+
72
+ private
73
+
74
+ def vertices_to_indices(vertices)
75
+ [vertices].flatten.map { |v| vertex_index[v] }
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,28 @@
1
+ require 'mini_graph/core/error'
2
+ require 'mini_graph/core/search'
3
+
4
+ module MiniGraph
5
+ module DSL
6
+ class SearchContext
7
+
8
+ ALGORITHM_IMPL = {
9
+ dfs: MiniGraph::Core::Search::DFS,
10
+ bfs: MiniGraph::Core::Search::BFS
11
+ }
12
+
13
+ def self.evaluate(graph, start_at, algorithm:)
14
+ algorithm_impl = ALGORITHM_IMPL[algorithm]
15
+
16
+ unless algorithm_impl
17
+ raise MiniGraph::Core::Error::InvalidSearchAlgorithmError,
18
+ "An unknown algorithm was provided to SearchContext: #{algorithm}"
19
+ end
20
+
21
+ vertex_index = graph.vertices.map.with_index { |v, i| [v, i] }.to_h
22
+ start_index = start_at.nil? ? 0 : vertex_index[start_at]
23
+
24
+ algorithm_impl.new(graph, start_index)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module MiniGraph
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,40 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "mini_graph/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mini_graph"
8
+ spec.version = MiniGraph::VERSION
9
+ spec.authors = ["Tim Lowrimore"]
10
+ spec.email = ["tlowrimore@coroutine.com"]
11
+
12
+ spec.summary = %q{A mini graph library + DSL}
13
+ spec.description = %q{A mini graph library + DSL}
14
+ spec.homepage = "https://github.com/coroutine/mini_graph"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = spec.homepage
22
+ spec.metadata["changelog_uri"] = spec.homepage
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against " \
25
+ "public gem pushes."
26
+ end
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ spec.add_development_dependency "bundler", "~> 2.1"
38
+ spec.add_development_dependency "rake", "~> 12.3.3"
39
+ spec.add_development_dependency "minitest", "~> 5.0"
40
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mini_graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Lowrimore
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-06-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 12.3.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 12.3.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: A mini graph library + DSL
56
+ email:
57
+ - tlowrimore@coroutine.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".ruby-version"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - lib/mini_graph.rb
73
+ - lib/mini_graph/core/edge.rb
74
+ - lib/mini_graph/core/error.rb
75
+ - lib/mini_graph/core/graph.rb
76
+ - lib/mini_graph/core/search.rb
77
+ - lib/mini_graph/dsl/graph_context.rb
78
+ - lib/mini_graph/dsl/search_context.rb
79
+ - lib/mini_graph/version.rb
80
+ - mini_graph.gemspec
81
+ homepage: https://github.com/coroutine/mini_graph
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ homepage_uri: https://github.com/coroutine/mini_graph
86
+ source_code_uri: https://github.com/coroutine/mini_graph
87
+ changelog_uri: https://github.com/coroutine/mini_graph
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.1.2
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: A mini graph library + DSL
107
+ test_files: []