Skip to content

Commit

Permalink
Merge branch 'release/0.15.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
moaxcp committed Jun 3, 2017
2 parents 3cc138b + 09f27e4 commit 2e6a650
Show file tree
Hide file tree
Showing 18 changed files with 680 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ env:
global:
- SONAR_HOST_URL=https://sonarqube.com/
- secure: iuG9LfqDv0DHauFCsSRf6WKvWLwQ0AaEIByypdNPuLrhs87Quhqn/ZapHnU6czY0taldVMefkusu1oBBooXvxMh0FllKXrk0PEFWEn3KtzKbfIsB693vHvYoZQGrdQrOz+1dPixJ7NOMFMHeZYtYvm6ss4MosE2b5uHM8uc1tiS8pNuqHrbxkQSZfWtqe2efFQBiiQUBtV+DWV5He+3nvLjgH3Rr+nKN9hPOOPZZcl/ek4UtjWGKFLSeV85gWekD33WVd1xKOCqS+oTNe5Qu40hrWbqlTke2FGlAEEz4Ub8tjrWqE7+S3yLqzrCHAfnyXA9lUNzieVXrAgIcrZAHcRxkBH2weZIsC6tuwis9lPYI9DvfQsyk3OP0qm4CcIApwXTzwr+NS5ZbpUnLkdjNR9aDtR+r+w9oFrceEJB7ioEskCANfruMLrm0Kv5Wv4QHjENnVNQL9pB7x8NgNw8A06JtO1Y50DSdi+YkiYzgKn4YPaMxTGuVwjCRxBIeD9z50+Ea+oCfBdoubpRM8CYqacDB02wWCzKi1EnvLXdo4Eec+952nmDyMvM5LY6XxveOjiUhsHx3Kl8TlLhPK0VoMMI2PNAh6iTNCAWWlcGmQQf0y+33dmnMJO/k8z3uHiDmT6qK3MOuA3bL1sE3e2BIwfay7tPhqZDo9ELN6LFvNtk=
- secure: vODNTymDcVUjzi0qTDpBRb+nE2obzAA+wafh5RXPk/5ezuUfV7RX8kanW+2ijqI8Zcf83xmBCIWoo1KMQp8rB7HGzIZdcNuTAkM1XaJ64mL7Cg4JEWPXsmVfaN9jXK4bVS/1nzSEfzU4cgd9xdeaoOyx/eVSWEnGdCio7eW/l/CAta12ZjJIUEAnkhkspTHp0paj1dWK8ZbTUNXifXwZr3sSsIvFGvs3eQtC/SP48vTD3rY8Mfp5yulHL3K09meWfnqStHFQjMLS6dUWp3RB9S2/yvQEpwRHswCICgNyFfDmRqvq7itDm1a9Xf9H0LhEPNVKvkg0Mh7R6kRPoug7afBRv1h2NiHyj2vrr5zxAKt5EHpDi0Y1xDcSW+7GycqBJyrlivcm7C87tCnbdboUes2sKeC+mSBcqzqu+VAC1s4+vUBFJIbnjMev/iqEsXj8361hd2HIhaltOnzi6oShF4YNILUoE99+/66bHadN7NsQ7QYJs25+gwl9z5dwHiISKQX9LJa/HmAtSh4yhzNrSkyj0YqxXIEPhprvlwy7ccI9gdZPTVIaBEoQ+HgEpd3BiGBKKmf3k2A7RgQIBsSq7xHvgcxQzgUAEQ/748AbDI6cuOIDHHshBwvMMgrFVU7PY0lidGGI8oSIk54AGmsTlVYQ/9VODacRZqxP0eOKFLk=
- secure: SvDSFrQ5K5M6ChNoKkQr7K6Js98UkIzPali4p/RdmKo0WiA5+KqmUE+OPcHGhkjV+hcThRddoA0GrKNr5OlxeB1yh0idy1qQI3UPD+lPx1mu6Ootf9qOzhDEN9q8W4zkAYnpcN6EjwaqxUSG+jaD6SVfHo84D7CaG8FasfjbGjoe7q8n+IHebsWMuDfTU4f5jM/Vc2vsELX8f7DVpseCkO+hl158tldTTkeRQ0J1xzs2AJ+bViQrpUHFff1IjR5bGXnjr087Dfiw0owcJa90jcC59JhpSVh3Cc2KEO1z0Ww2j34XpwFUmPV0yeYlegEkyfpFXhCQUE4pe1D0RailDg9uWyKHvucxiYIUNNGuYiJ6ipPL7fn44fLzdBB2iaNFFZBMJbcHgrtuQ44W67Fn9bRPCsYbbcLzKqHGijWCzLlZd9ZEFT73uroRNwpN7jTNrloPlThL0Hnc1asY9fd/8y+51PYJgXardqArD5WrMrHMfghwnz8EozpInj+yAngGX3vyxZfc13Kp4g0pOnI508UAxbogZm4ZC39W+8ObmKHNb0ge00YVv3l5iWdPMk41edZYvhXmfuN40hQTcQuvJNHfq/aAxNwfsdR5k/2F3dGocD7qUBYdmsLG9L1VaHtf+0x+qbsL6U5RjzcuewXpD4F3YT2T3pFE8MViWXs/Or8=
- secure: j4xRmR3NcnlimR4HLlq3HfYHokW9RjuVmaUAaICuJ7R6ujoczvwIfOGfa7Y0OqQNcoNeyfAcgdukC+M7nurJHd1Hpb0usKri3yLK40ZVohSMhODAwe80JV6Xp2zgLvhvDdmZ5t8LSMDSRJ8eybaMIHjNBDF3X7mFYrYYfdRpZzfQRhayTGVCuu5fL0Wp6YPA1H5lR6IPuVS9oORD/XgD2TGOR2VuHPZ8F35sx8CKbI6HJq5bTgHAByJhg42EhWYUfqTKd2ULtKVu1ueBb9iXaL6P6lx/E4uVPj6DPqRwK7hkDWBnvgM6+oDt3obzA7VF1lC8hnJG0ebVQetIg/Vmwbro0Cbf2RLLBcoAwwSbdfh1YK/qe3CkjaJ+h5SMMxDAh3OIjwyv5NVklJk4Mhj1cOAIzSho9gLZY7Cm2O/xCBC7o2HZ9DLbsnZnHe4VZSs/xi+0XUR8+XU0mApxi4WJDP4gdJIN4s519pDVD6zpJX/cM1uScuHE2mf4T3LSzqRn9eJK5G2MT54JUDt0Ce11R2rzseTeIxi9X1XPnuOfafxD5P3c+NMNGIlAOdKf1R3DOuKlttmlTcjTCDtM416BiE/ErZuLYznnLimY+hFBbQgL8Af70BGdq4QlkStyxDTXW1Y2IQ3UK6gGO/tkQRqI3FLvKAKoEusocfiPLi4ywKw=
- secure: dqyrAaajNzLuM1jlGfiRtePCpcipqPJFnr3RdR/M6rPMoDttTirJQnfTK5V9QfwbU9QuL0p5svFK5zxk6Utg4QfWCyyjCKs2A1DC7Dd1LYGo3RLP4nsCRU9JGX1bYJHhvymPcnfUbAOXp6JBmQ0qvQ6J+5esVkPiMJMChXPiZg2WpuN/XL7QWOOfvq2eVDN+8tSYTbTgf1D8ezx7xTFze+eax4f66UMZmkB7Xwhx1MGmvuMHjbCBmBfOj/dh02IUOqbfQhf4alzAocrdLQ0AIJj5bPow54AHOuxObgHZFc27/vwyXqDtgKHCtK/XpM2+7mWuegMPb/YubJppyXjKqiYCFkEDiaVkTtI9bJyny5P0Qxa7VojygXkpyjpp/6FLfGhd90BwQCwpVRWTgCl6zF6BCH7PamF6OTQ54xgASLCR2G/46mw4d61Og5Eb4Rd5CTmluAOnFuFWhSP+TFk8pQ1itfGq3Lspe8Nmv3nTP6Yufr3403pkQ+AK7umXQ5sYX8A8DoDsGRv9LO/r9yuT+Vpa6KEz2k1rzhzreXduJtlsKLB1jfzhBvbqmVq4y2aTLUlr4ZtkHV72elnRB/DktIYklJTD5hw0blG2AP3BcP7/Z66JzfTpzcP/0zVJx8OI9b8IhFaXF9sue2XpwGOR6WD0MCdVf6hkBb5v3qaXReg=
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
Expand Down
179 changes: 153 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,168 @@
# graph-dsl

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

# Usage

graph-dsl is used to create graphs and algorithms for graphs.
It is designed to be groovy, using closures and metaprogramming for minimal setup.

## Building a graph

```groovy
#!/usr/bin/env groovy
@Grab(group='com.github.moaxcp', module='graph-dsl', version='0.11.0')
import static graph.Graph.graph
```

graph {
apply DirectedGraphPlugin
vertex a {
edgesFirst 'b', 'd'
edgesSecond 'd'
## Creating a graph

The basic graph structure is held in a map of named vertices and a set of edges.

All referenced vertices are created if they don't exist.

```groovy
def graph = graph {
edge step1, step2
}
assert graph.vertices.keySet() == ['step1', 'step2'] as Set //vertices were created!
assert graph.edges.size() == 1
assert graph.edges.first() == new Edge(one:'step1', two:'step2') //edge was created!
```

This example of a graph creates two vertices named 'step1' and 'step2' as well as an edge between them. There are many
other methods for creating vertices and edges.

```groovy
graph.with {
edge (A, B) {
traits Mapping, Mapping
queue = new LinkedList()
weight { queue.size() }
}
vertex renameMe {
rename 'b'
edgesFirst 'c', 'd'
vertex A(traits:Mapping) {
action = {
println "processing"
}
}
vertex d([edgesFirst:'c']) {
edgesFirst 'e'
vertex B {
traits Mapping
action = {
println "done processing"
}
}
edge 'f', 'g'
edge g, d
eachBfs {
println it.name
}
```

The Default behavior of a graph is that of an undirected graph. These graphs have a set of edges where only one edge
can connect any two vertices. This behavior can be changed to a directed graph at any time using the DirectedGraphPlugin

```groovy
graph.apply DirectedGraphPlugin
```

Traits can be added to all edges and vertices.

```groovy
graph.edgeTraits Mapping, Weight
graph.vertexTraits Mapping
```

## Traversing a graph

Once a graph is created there is a dsl for depthFirstTraversal and breadthFirstTraversal.

```groovy
graph {
apply DirectedGraphPlugin
vertex A {
edgesFirst 'B', 'D', 'E'
edgesSecond 'D'
}
vertex D {
edgesFirst 'C', 'E'
edgesSecond 'B'
}
edge B, C
depthFirstTraversal {
root = 'A'
preorder { vertex ->
println vertex.name
}
}
breadthFirstTraversal {
root = 'A'
visit { vertex ->
println "bft $vertex.name"
}
}
}
```

## Functional methods

There are functional methods build on the depthFirstTraversal and breadthFirstTraversal method.

```groovy
eachBfs {
println it.name
}
def vertex = findBfs {
it.name == 'A'
}
def bfsOrder = collectBfs {
it.name
}
```

# Getting Started
Note: These methods are not yet implemented for depth first traversal. The depth first traversal methods will be the
defaults for each, find, inject, findAll, and collect.

## Edge Classification

Depth first traversal supports edge classification where an edge is classified as:

* tree-edge - when the destination vertex is white
* back-edge - when the destination vertex is grey
* forward-edge - when the destination vertex is black
* cross-edge - when the destination vertex is black and in a different tree

## EdgeWeightPlugin

This plugin applies Weight to all edges and changes all traversal methods to follow edges in order of their weight.

# Getting Started With Development/Contributing

## install git

Follow this guide to install git.

https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

## install gitflow-avh

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

https://github.com/petervanderdoes/gitflow-avh/wiki/Installation

## clone the project

clone the project from github.

git clone https://github.com/moaxcp/graph-dsl.git

## build

The project uses gradle for the build system. Using gradlew, you do not need to install gradle to build the project.

`./gradlew build`

# Contributing
## Contributing

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

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

# Releases

## 0.15.0

This release combines fixes for a few issues on github.

* [#75](https://github.com/moaxcp/graph-dsl/issues/75) Vertex.name, Edge.one, and Edge.two is now @PackageScope. This only
affects code that is @CompileStatic for now due to [GROOVY-3010](https://issues.apache.org/jira/browse/GROOVY-3010).
* [#74](https://github.com/moaxcp/graph-dsl/issues/74)Vertices and edges may now be deleted. A vertex cannot be deleted if
there are edges referencing it.
* [#73](https://github.com/moaxcp/graph-dsl/issues/73) Added EdgeWeightPlugin. This plugin adds the Weight trait to each
edge. Traversal methods are ordered by edge weight.

There were also several other changes that were not an issue on github:

Updated gradle to 3.5. Refactored gradle script to use the plugins closure when possible. gradle-gitflow does not work
with the closure because it is not in the gradle repository. This is another reason to update the plugin. Spock was also
updated to 1.1.

Added edgeTraits and vertexTraits. These methods will ensure traits are applied to current and future edges and vertices.

Added tests to provide more code coverage in jacoco.

Added more usage details to README.md

## 0.14.0

Just as in 0.13.0, where the config closure was removed from VertexSpec, this release removes the config closure from
Expand Down
17 changes: 7 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import static com.github.amkay.gradle.gitflow.version.VersionType.*

buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'com.github.amkay:gradle-gitflow:0.2.0'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.3'
classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.8.0'
}
}

plugins {
id 'net.ossindex.audit' version '0.1.1'
id 'io.codearte.nexus-staging' version '0.8.0'
id 'org.sonarqube' version '2.4'
}

apply plugin: 'idea'
apply plugin: 'com.github.amkay.gitflow'
apply plugin: 'org.sonarqube'
apply plugin: 'jacoco'
apply plugin: 'groovy'
apply plugin: 'codenarc'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'io.codearte.nexus-staging'

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

dependencies {
compile "org.codehaus.groovy:groovy:$groovyVersion"
testCompile ('org.spockframework:spock-core:1.0-groovy-2.4') {
testCompile ('org.spockframework:spock-core:1.1-groovy-2.4') {
exclude group: 'org.codehaus.groovy', module:'groovy-all'
}
testCompile "org.codehaus.groovy:groovy-all:$groovyVersion"
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Sat Mar 11 14:54:25 EST 2017
#Sat May 13 23:22:59 EDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
6 changes: 3 additions & 3 deletions src/main/groovy/graph/DirectedGraphPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class DirectedGraphPlugin implements Plugin {
* @return
*/
void apply(Graph graph) {
graph.@edges = graph.@edges.collect { edge ->
new DirectedEdge(one:edge.one, two:edge.two)
} as LinkedHashSet
graph.replaceEdges { edge ->
new DirectedEdge(one:edge.one, two:edge.two, delegate:edge.delegate)
}

graph.edgeFactory = new DirectedEdgeFactory()

Expand Down
18 changes: 16 additions & 2 deletions src/main/groovy/graph/Edge.groovy
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package graph

import groovy.transform.PackageScope

/**
* An edge between two vertices. This class uses a delegate when methods
* and properties are missing. Traits should be applied to the delegate
* using delegateAs().
*/
@SuppressWarnings('NoDef')
class Edge {
String one
String two
def delegate = new Object()
Object delegate = new Object()

@PackageScope
void setOne(String one) {
this.one = one
}

@PackageScope
void setTwo(String two) {
this.two = two
}

/**
* applies traits to the delegate.
Expand Down Expand Up @@ -55,6 +66,7 @@ class Edge {
* @param args
* @return
*/
@SuppressWarnings('NoDef')
def methodMissing(String name, args) {
delegate.invokeMethod(name, args)
}
Expand All @@ -64,6 +76,7 @@ class Edge {
* @param name
* @return
*/
@SuppressWarnings('NoDef')
def propertyMissing(String name) {
delegate[name]
}
Expand All @@ -74,6 +87,7 @@ class Edge {
* @param value
* @return
*/
@SuppressWarnings('NoDef')
def propertyMissing(String name, value) {
delegate[name] = value
}
Expand Down
13 changes: 1 addition & 12 deletions src/main/groovy/graph/EdgeMapPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ class EdgeMapPlugin implements Plugin {
*/
@Override
void apply(Graph graph) {
graph.@edges.each { edge ->
edge.delegateAs(Mapping)
}

graph.edgeFactory = new EdgeFactory() {
EdgeFactory oldFactory = graph.edgeFactory
@Override
Edge newEdge(String one, String two) {
Edge edge = oldFactory.newEdge(one, two)
edge.delegateAs(Mapping)
}
}
graph.edgeTraits(Mapping)
}
}
8 changes: 5 additions & 3 deletions src/main/groovy/graph/EdgeSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ class EdgeSpec {
}
Edge e = graph.edgeFactory.newEdge(one, two)
Edge edge = graph.edges.find { it == e } ?: e

if (traitsSet) {
edge.delegateAs(this.traitsSet as Class[])
}
graph.addEdge(edge)

graph.vertex(one)
graph.vertex(two)

Expand All @@ -95,9 +100,6 @@ class EdgeSpec {
graph.vertex(renameTwo)
edge.two = renameTwo
}
if (traitsSet) {
edge.delegateAs(this.traitsSet as Class[])
}

if (runnerCodeClosure) {
EdgeSpecCodeRunner runner = new EdgeSpecCodeRunner(graph:graph, edge:edge)
Expand Down
Loading

0 comments on commit 2e6a650

Please sign in to comment.