Skip to content

Commit 2e6a650

Browse files
committed
Merge branch 'release/0.15.0'
2 parents 3cc138b + 09f27e4 commit 2e6a650

18 files changed

Lines changed: 680 additions & 91 deletions

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ env:
44
global:
55
- SONAR_HOST_URL=https://sonarqube.com/
66
- secure: iuG9LfqDv0DHauFCsSRf6WKvWLwQ0AaEIByypdNPuLrhs87Quhqn/ZapHnU6czY0taldVMefkusu1oBBooXvxMh0FllKXrk0PEFWEn3KtzKbfIsB693vHvYoZQGrdQrOz+1dPixJ7NOMFMHeZYtYvm6ss4MosE2b5uHM8uc1tiS8pNuqHrbxkQSZfWtqe2efFQBiiQUBtV+DWV5He+3nvLjgH3Rr+nKN9hPOOPZZcl/ek4UtjWGKFLSeV85gWekD33WVd1xKOCqS+oTNe5Qu40hrWbqlTke2FGlAEEz4Ub8tjrWqE7+S3yLqzrCHAfnyXA9lUNzieVXrAgIcrZAHcRxkBH2weZIsC6tuwis9lPYI9DvfQsyk3OP0qm4CcIApwXTzwr+NS5ZbpUnLkdjNR9aDtR+r+w9oFrceEJB7ioEskCANfruMLrm0Kv5Wv4QHjENnVNQL9pB7x8NgNw8A06JtO1Y50DSdi+YkiYzgKn4YPaMxTGuVwjCRxBIeD9z50+Ea+oCfBdoubpRM8CYqacDB02wWCzKi1EnvLXdo4Eec+952nmDyMvM5LY6XxveOjiUhsHx3Kl8TlLhPK0VoMMI2PNAh6iTNCAWWlcGmQQf0y+33dmnMJO/k8z3uHiDmT6qK3MOuA3bL1sE3e2BIwfay7tPhqZDo9ELN6LFvNtk=
7-
- secure: vODNTymDcVUjzi0qTDpBRb+nE2obzAA+wafh5RXPk/5ezuUfV7RX8kanW+2ijqI8Zcf83xmBCIWoo1KMQp8rB7HGzIZdcNuTAkM1XaJ64mL7Cg4JEWPXsmVfaN9jXK4bVS/1nzSEfzU4cgd9xdeaoOyx/eVSWEnGdCio7eW/l/CAta12ZjJIUEAnkhkspTHp0paj1dWK8ZbTUNXifXwZr3sSsIvFGvs3eQtC/SP48vTD3rY8Mfp5yulHL3K09meWfnqStHFQjMLS6dUWp3RB9S2/yvQEpwRHswCICgNyFfDmRqvq7itDm1a9Xf9H0LhEPNVKvkg0Mh7R6kRPoug7afBRv1h2NiHyj2vrr5zxAKt5EHpDi0Y1xDcSW+7GycqBJyrlivcm7C87tCnbdboUes2sKeC+mSBcqzqu+VAC1s4+vUBFJIbnjMev/iqEsXj8361hd2HIhaltOnzi6oShF4YNILUoE99+/66bHadN7NsQ7QYJs25+gwl9z5dwHiISKQX9LJa/HmAtSh4yhzNrSkyj0YqxXIEPhprvlwy7ccI9gdZPTVIaBEoQ+HgEpd3BiGBKKmf3k2A7RgQIBsSq7xHvgcxQzgUAEQ/748AbDI6cuOIDHHshBwvMMgrFVU7PY0lidGGI8oSIk54AGmsTlVYQ/9VODacRZqxP0eOKFLk=
87
- secure: SvDSFrQ5K5M6ChNoKkQr7K6Js98UkIzPali4p/RdmKo0WiA5+KqmUE+OPcHGhkjV+hcThRddoA0GrKNr5OlxeB1yh0idy1qQI3UPD+lPx1mu6Ootf9qOzhDEN9q8W4zkAYnpcN6EjwaqxUSG+jaD6SVfHo84D7CaG8FasfjbGjoe7q8n+IHebsWMuDfTU4f5jM/Vc2vsELX8f7DVpseCkO+hl158tldTTkeRQ0J1xzs2AJ+bViQrpUHFff1IjR5bGXnjr087Dfiw0owcJa90jcC59JhpSVh3Cc2KEO1z0Ww2j34XpwFUmPV0yeYlegEkyfpFXhCQUE4pe1D0RailDg9uWyKHvucxiYIUNNGuYiJ6ipPL7fn44fLzdBB2iaNFFZBMJbcHgrtuQ44W67Fn9bRPCsYbbcLzKqHGijWCzLlZd9ZEFT73uroRNwpN7jTNrloPlThL0Hnc1asY9fd/8y+51PYJgXardqArD5WrMrHMfghwnz8EozpInj+yAngGX3vyxZfc13Kp4g0pOnI508UAxbogZm4ZC39W+8ObmKHNb0ge00YVv3l5iWdPMk41edZYvhXmfuN40hQTcQuvJNHfq/aAxNwfsdR5k/2F3dGocD7qUBYdmsLG9L1VaHtf+0x+qbsL6U5RjzcuewXpD4F3YT2T3pFE8MViWXs/Or8=
98
- secure: j4xRmR3NcnlimR4HLlq3HfYHokW9RjuVmaUAaICuJ7R6ujoczvwIfOGfa7Y0OqQNcoNeyfAcgdukC+M7nurJHd1Hpb0usKri3yLK40ZVohSMhODAwe80JV6Xp2zgLvhvDdmZ5t8LSMDSRJ8eybaMIHjNBDF3X7mFYrYYfdRpZzfQRhayTGVCuu5fL0Wp6YPA1H5lR6IPuVS9oORD/XgD2TGOR2VuHPZ8F35sx8CKbI6HJq5bTgHAByJhg42EhWYUfqTKd2ULtKVu1ueBb9iXaL6P6lx/E4uVPj6DPqRwK7hkDWBnvgM6+oDt3obzA7VF1lC8hnJG0ebVQetIg/Vmwbro0Cbf2RLLBcoAwwSbdfh1YK/qe3CkjaJ+h5SMMxDAh3OIjwyv5NVklJk4Mhj1cOAIzSho9gLZY7Cm2O/xCBC7o2HZ9DLbsnZnHe4VZSs/xi+0XUR8+XU0mApxi4WJDP4gdJIN4s519pDVD6zpJX/cM1uScuHE2mf4T3LSzqRn9eJK5G2MT54JUDt0Ce11R2rzseTeIxi9X1XPnuOfafxD5P3c+NMNGIlAOdKf1R3DOuKlttmlTcjTCDtM416BiE/ErZuLYznnLimY+hFBbQgL8Af70BGdq4QlkStyxDTXW1Y2IQ3UK6gGO/tkQRqI3FLvKAKoEusocfiPLi4ywKw=
9+
- secure: dqyrAaajNzLuM1jlGfiRtePCpcipqPJFnr3RdR/M6rPMoDttTirJQnfTK5V9QfwbU9QuL0p5svFK5zxk6Utg4QfWCyyjCKs2A1DC7Dd1LYGo3RLP4nsCRU9JGX1bYJHhvymPcnfUbAOXp6JBmQ0qvQ6J+5esVkPiMJMChXPiZg2WpuN/XL7QWOOfvq2eVDN+8tSYTbTgf1D8ezx7xTFze+eax4f66UMZmkB7Xwhx1MGmvuMHjbCBmBfOj/dh02IUOqbfQhf4alzAocrdLQ0AIJj5bPow54AHOuxObgHZFc27/vwyXqDtgKHCtK/XpM2+7mWuegMPb/YubJppyXjKqiYCFkEDiaVkTtI9bJyny5P0Qxa7VojygXkpyjpp/6FLfGhd90BwQCwpVRWTgCl6zF6BCH7PamF6OTQ54xgASLCR2G/46mw4d61Og5Eb4Rd5CTmluAOnFuFWhSP+TFk8pQ1itfGq3Lspe8Nmv3nTP6Yufr3403pkQ+AK7umXQ5sYX8A8DoDsGRv9LO/r9yuT+Vpa6KEz2k1rzhzreXduJtlsKLB1jfzhBvbqmVq4y2aTLUlr4ZtkHV72elnRB/DktIYklJTD5hw0blG2AP3BcP7/Z66JzfTpzcP/0zVJx8OI9b8IhFaXF9sue2XpwGOR6WD0MCdVf6hkBb5v3qaXReg=
1010
before_cache:
1111
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
1212
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/

README.md

Lines changed: 153 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,168 @@
11
# graph-dsl
22

3-
A groovy dsl for creating and traversing graphs.
4-
For project build status check the [wiki](https://github.com/moaxcp/graph-dsl/wiki).
3+
A groovy dsl for creating and traversing extensible graphs. The graph can be extended with plugins and traits which
4+
allow developers to create a graph with the desired behavior and values for their algorithm. For project build status
5+
check the [wiki](https://github.com/moaxcp/graph-dsl/wiki).
56

67
# Usage
78

8-
graph-dsl is used to create graphs and algorithms for graphs.
9-
It is designed to be groovy, using closures and metaprogramming for minimal setup.
10-
11-
## Building a graph
12-
139
```groovy
1410
#!/usr/bin/env groovy
1511
@Grab(group='com.github.moaxcp', module='graph-dsl', version='0.11.0')
16-
import static graph.Graph.graph
12+
```
1713

18-
graph {
19-
apply DirectedGraphPlugin
20-
vertex a {
21-
edgesFirst 'b', 'd'
22-
edgesSecond 'd'
14+
## Creating a graph
15+
16+
The basic graph structure is held in a map of named vertices and a set of edges.
17+
18+
All referenced vertices are created if they don't exist.
19+
20+
```groovy
21+
def graph = graph {
22+
edge step1, step2
23+
}
24+
assert graph.vertices.keySet() == ['step1', 'step2'] as Set //vertices were created!
25+
assert graph.edges.size() == 1
26+
assert graph.edges.first() == new Edge(one:'step1', two:'step2') //edge was created!
27+
```
28+
29+
This example of a graph creates two vertices named 'step1' and 'step2' as well as an edge between them. There are many
30+
other methods for creating vertices and edges.
31+
32+
```groovy
33+
graph.with {
34+
edge (A, B) {
35+
traits Mapping, Mapping
36+
queue = new LinkedList()
37+
weight { queue.size() }
2338
}
2439
25-
vertex renameMe {
26-
rename 'b'
27-
edgesFirst 'c', 'd'
40+
vertex A(traits:Mapping) {
41+
action = {
42+
println "processing"
43+
}
2844
}
2945
30-
vertex d([edgesFirst:'c']) {
31-
edgesFirst 'e'
46+
vertex B {
47+
traits Mapping
48+
action = {
49+
println "done processing"
50+
}
3251
}
33-
34-
edge 'f', 'g'
35-
edge g, d
36-
37-
eachBfs {
38-
println it.name
52+
}
53+
```
54+
55+
The Default behavior of a graph is that of an undirected graph. These graphs have a set of edges where only one edge
56+
can connect any two vertices. This behavior can be changed to a directed graph at any time using the DirectedGraphPlugin
57+
58+
```groovy
59+
graph.apply DirectedGraphPlugin
60+
```
61+
62+
Traits can be added to all edges and vertices.
63+
64+
```groovy
65+
graph.edgeTraits Mapping, Weight
66+
graph.vertexTraits Mapping
67+
```
68+
69+
## Traversing a graph
70+
71+
Once a graph is created there is a dsl for depthFirstTraversal and breadthFirstTraversal.
72+
73+
```groovy
74+
graph {
75+
apply DirectedGraphPlugin
76+
vertex A {
77+
edgesFirst 'B', 'D', 'E'
78+
edgesSecond 'D'
3979
}
80+
81+
vertex D {
82+
edgesFirst 'C', 'E'
83+
edgesSecond 'B'
84+
}
85+
86+
edge B, C
87+
depthFirstTraversal {
88+
root = 'A'
89+
preorder { vertex ->
90+
println vertex.name
91+
}
92+
}
93+
94+
breadthFirstTraversal {
95+
root = 'A'
96+
visit { vertex ->
97+
println "bft $vertex.name"
98+
}
99+
}
100+
}
101+
```
102+
103+
## Functional methods
104+
105+
There are functional methods build on the depthFirstTraversal and breadthFirstTraversal method.
106+
107+
```groovy
108+
eachBfs {
109+
println it.name
110+
}
111+
112+
def vertex = findBfs {
113+
it.name == 'A'
114+
}
115+
116+
def bfsOrder = collectBfs {
117+
it.name
40118
}
41119
```
42120

43-
# Getting Started
121+
Note: These methods are not yet implemented for depth first traversal. The depth first traversal methods will be the
122+
defaults for each, find, inject, findAll, and collect.
123+
124+
## Edge Classification
125+
126+
Depth first traversal supports edge classification where an edge is classified as:
127+
128+
* tree-edge - when the destination vertex is white
129+
* back-edge - when the destination vertex is grey
130+
* forward-edge - when the destination vertex is black
131+
* cross-edge - when the destination vertex is black and in a different tree
132+
133+
## EdgeWeightPlugin
134+
135+
This plugin applies Weight to all edges and changes all traversal methods to follow edges in order of their weight.
136+
137+
# Getting Started With Development/Contributing
44138

45139
## install git
46140

141+
Follow this guide to install git.
142+
47143
https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
48144

49145
## install gitflow-avh
50146

147+
This project uses gitflow-avh. It is a plugin for git that provides the `git flow` commands. These commands are used to
148+
follow the gitflow pattern for developing software. For more information see
149+
[Workflow](https://github.com/moaxcp/graph-dsl/wiki/Workflow) in the wiki.
150+
51151
https://github.com/petervanderdoes/gitflow-avh/wiki/Installation
52152

53153
## clone the project
54154

155+
clone the project from github.
156+
55157
git clone https://github.com/moaxcp/graph-dsl.git
56158

57159
## build
58160

161+
The project uses gradle for the build system. Using gradlew, you do not need to install gradle to build the project.
162+
59163
`./gradlew build`
60164

61-
# Contributing
165+
## Contributing
62166

63167
Contributions are welcome. Please submit a pull request to the develop branch in github.
64168

@@ -91,6 +195,29 @@ If there are any issues contact me moaxcp@gmail.com.
91195

92196
# Releases
93197

198+
## 0.15.0
199+
200+
This release combines fixes for a few issues on github.
201+
202+
* [#75](https://github.com/moaxcp/graph-dsl/issues/75) Vertex.name, Edge.one, and Edge.two is now @PackageScope. This only
203+
affects code that is @CompileStatic for now due to [GROOVY-3010](https://issues.apache.org/jira/browse/GROOVY-3010).
204+
* [#74](https://github.com/moaxcp/graph-dsl/issues/74)Vertices and edges may now be deleted. A vertex cannot be deleted if
205+
there are edges referencing it.
206+
* [#73](https://github.com/moaxcp/graph-dsl/issues/73) Added EdgeWeightPlugin. This plugin adds the Weight trait to each
207+
edge. Traversal methods are ordered by edge weight.
208+
209+
There were also several other changes that were not an issue on github:
210+
211+
Updated gradle to 3.5. Refactored gradle script to use the plugins closure when possible. gradle-gitflow does not work
212+
with the closure because it is not in the gradle repository. This is another reason to update the plugin. Spock was also
213+
updated to 1.1.
214+
215+
Added edgeTraits and vertexTraits. These methods will ensure traits are applied to current and future edges and vertices.
216+
217+
Added tests to provide more code coverage in jacoco.
218+
219+
Added more usage details to README.md
220+
94221
## 0.14.0
95222

96223
Just as in 0.13.0, where the config closure was removed from VertexSpec, this release removes the config closure from

build.gradle

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
import static com.github.amkay.gradle.gitflow.version.VersionType.*
22

33
buildscript {
4-
repositories {
5-
maven {
6-
url 'https://plugins.gradle.org/m2/'
7-
}
8-
}
94
dependencies {
105
classpath 'com.github.amkay:gradle-gitflow:0.2.0'
11-
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.3'
12-
classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.8.0'
136
}
147
}
158

9+
plugins {
10+
id 'net.ossindex.audit' version '0.1.1'
11+
id 'io.codearte.nexus-staging' version '0.8.0'
12+
id 'org.sonarqube' version '2.4'
13+
}
14+
1615
apply plugin: 'idea'
1716
apply plugin: 'com.github.amkay.gitflow'
18-
apply plugin: 'org.sonarqube'
1917
apply plugin: 'jacoco'
2018
apply plugin: 'groovy'
2119
apply plugin: 'codenarc'
2220
apply plugin: 'maven'
2321
apply plugin: 'signing'
24-
apply plugin: 'io.codearte.nexus-staging'
2522

2623
group = 'com.github.moaxcp'
2724
description = 'A groovy dsl for creating and traversing graphs.'
@@ -148,7 +145,7 @@ nexusStaging {
148145

149146
dependencies {
150147
compile "org.codehaus.groovy:groovy:$groovyVersion"
151-
testCompile ('org.spockframework:spock-core:1.0-groovy-2.4') {
148+
testCompile ('org.spockframework:spock-core:1.1-groovy-2.4') {
152149
exclude group: 'org.codehaus.groovy', module:'groovy-all'
153150
}
154151
testCompile "org.codehaus.groovy:groovy-all:$groovyVersion"

gradle/wrapper/gradle-wrapper.jar

571 Bytes
Binary file not shown.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Sat Mar 11 14:54:25 EST 2017
1+
#Sat May 13 23:22:59 EDT 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip

src/main/groovy/graph/DirectedGraphPlugin.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class DirectedGraphPlugin implements Plugin {
1818
* @return
1919
*/
2020
void apply(Graph graph) {
21-
graph.@edges = graph.@edges.collect { edge ->
22-
new DirectedEdge(one:edge.one, two:edge.two)
23-
} as LinkedHashSet
21+
graph.replaceEdges { edge ->
22+
new DirectedEdge(one:edge.one, two:edge.two, delegate:edge.delegate)
23+
}
2424

2525
graph.edgeFactory = new DirectedEdgeFactory()
2626

src/main/groovy/graph/Edge.groovy

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
package graph
22

3+
import groovy.transform.PackageScope
4+
35
/**
46
* An edge between two vertices. This class uses a delegate when methods
57
* and properties are missing. Traits should be applied to the delegate
68
* using delegateAs().
79
*/
8-
@SuppressWarnings('NoDef')
910
class Edge {
1011
String one
1112
String two
12-
def delegate = new Object()
13+
Object delegate = new Object()
14+
15+
@PackageScope
16+
void setOne(String one) {
17+
this.one = one
18+
}
19+
20+
@PackageScope
21+
void setTwo(String two) {
22+
this.two = two
23+
}
1324

1425
/**
1526
* applies traits to the delegate.
@@ -55,6 +66,7 @@ class Edge {
5566
* @param args
5667
* @return
5768
*/
69+
@SuppressWarnings('NoDef')
5870
def methodMissing(String name, args) {
5971
delegate.invokeMethod(name, args)
6072
}
@@ -64,6 +76,7 @@ class Edge {
6476
* @param name
6577
* @return
6678
*/
79+
@SuppressWarnings('NoDef')
6780
def propertyMissing(String name) {
6881
delegate[name]
6982
}
@@ -74,6 +87,7 @@ class Edge {
7487
* @param value
7588
* @return
7689
*/
90+
@SuppressWarnings('NoDef')
7791
def propertyMissing(String name, value) {
7892
delegate[name] = value
7993
}

src/main/groovy/graph/EdgeMapPlugin.groovy

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@ class EdgeMapPlugin implements Plugin {
1212
*/
1313
@Override
1414
void apply(Graph graph) {
15-
graph.@edges.each { edge ->
16-
edge.delegateAs(Mapping)
17-
}
18-
19-
graph.edgeFactory = new EdgeFactory() {
20-
EdgeFactory oldFactory = graph.edgeFactory
21-
@Override
22-
Edge newEdge(String one, String two) {
23-
Edge edge = oldFactory.newEdge(one, two)
24-
edge.delegateAs(Mapping)
25-
}
26-
}
15+
graph.edgeTraits(Mapping)
2716
}
2817
}

src/main/groovy/graph/EdgeSpec.groovy

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,12 @@ class EdgeSpec {
8383
}
8484
Edge e = graph.edgeFactory.newEdge(one, two)
8585
Edge edge = graph.edges.find { it == e } ?: e
86+
87+
if (traitsSet) {
88+
edge.delegateAs(this.traitsSet as Class[])
89+
}
8690
graph.addEdge(edge)
91+
8792
graph.vertex(one)
8893
graph.vertex(two)
8994

@@ -95,9 +100,6 @@ class EdgeSpec {
95100
graph.vertex(renameTwo)
96101
edge.two = renameTwo
97102
}
98-
if (traitsSet) {
99-
edge.delegateAs(this.traitsSet as Class[])
100-
}
101103

102104
if (runnerCodeClosure) {
103105
EdgeSpecCodeRunner runner = new EdgeSpecCodeRunner(graph:graph, edge:edge)

0 commit comments

Comments
 (0)