Repository: AlgebraicJulia/Catlab.jl (julia)

Issue:
Broken Julia LTS v1.0 Support
A recent change (I believe it is the UWD support in Graphviz) to Catlab has broken support of Julia v1.0 LTS. I think as a project we should make sure that code supports not just the latest versions, but make sure it supports whatever the latest LTS is.


stack trace:
```
julia> using Catlab
[ Info: Precompiling Catlab [134e5e36-593f-5add-ad60-77f754baafbe]
ERROR: LoadError: LoadError: LoadError: syntax: invalid function name "Graph <: Expression"
Stacktrace:
 [1] include at ./boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at ./loading.jl:1044
 [3] include at ./sysimg.jl:29 [inlined]
 [4] include(::String) at /home/micah/TEST/env/.julia/packages/Catlab/z8n1h/src/graphics/Graphics.jl:1
 [5] top-level scope at none:0
 [6] include at ./boot.jl:317 [inlined]
 [7] include_relative(::Module, ::String) at ./loading.jl:1044
 [8] include at ./sysimg.jl:29 [inlined]
 [9] include(::String) at /home/micah/TEST/env/.julia/packages/Catlab/z8n1h/src/Catlab.jl:1
 [10] top-level scope at none:0
 [11] include at ./boot.jl:317 [inlined]
 [12] include_relative(::Module, ::String) at ./loading.jl:1044
 [13] include(::Module, ::String) at ./sysimg.jl:29
 [14] top-level scope at none:2
 [15] eval at ./boot.jl:319 [inlined]
 [16] eval(::Expr) at ./client.jl:393
 [17] top-level scope at ./none:3
in expression starting at /home/micah/TEST/env/.julia/packages/Catlab/z8n1h/src/graphics/Graphviz.jl:43
in expression starting at /home/micah/TEST/env/.julia/packages/Catlab/z8n1h/src/graphics/Graphics.jl:7
in expression starting at /home/micah/TEST/env/.julia/packages/Catlab/z8n1h/src/Catlab.jl:7
ERROR: Failed to precompile Catlab [134e5e36-593f-5add-ad60-77f754baafbe] to /home/micah/TEST/env/.julia/compiled/v1.0/Catlab/fBQ1G.ji.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] compilecache(::Base.PkgId, ::String) at ./loading.jl:1203
 [3] _require(::Base.PkgId) at ./loading.jl:960
 [4] require(::Base.PkgId) at ./loading.jl:858
 [5] require(::Module, ::Symbol) at ./loading.jl:853
```

Pull request description:
Resolves #226 and reverts #174.

Patch:
diff --git a/Project.toml b/Project.toml
index d1b3daf8f..85b0e4f42 100644
--- a/Project.toml
+++ b/Project.toml
@@ -18,6 +18,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
 Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
 MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
 MetaGraphs = "626554b9-1ddb-594c-aa3c-2596fe9399a5"
+Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
 Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
 Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
 Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
@@ -38,6 +39,7 @@ LightGraphs = "^1.3"
 LightXML = "^0"
 MLStyle = "^0"
 MetaGraphs = "^0.6"
+Parameters = "^0"
 Reexport = "^0"
 Requires = "^1"
 StaticArrays = "^0"
diff --git a/src/categorical_algebra/Graphs.jl b/src/categorical_algebra/Graphs.jl
index cecae3272..0dd042d00 100644
--- a/src/categorical_algebra/Graphs.jl
+++ b/src/categorical_algebra/Graphs.jl
@@ -11,6 +11,7 @@ export AbstractGraph, Graph, AbstractSymmetricGraph, SymmetricGraph,
   gprops, vprops, eprops, get_gprop, get_vprop, get_eprop,
   set_gprop!, set_vprop!, set_eprop!, set_gprops!, set_vprops!, set_eprops!
 
+using Compat: isnothing
 import LightGraphs
 import LightGraphs: nv, ne, src, dst, edges, vertices, has_edge, has_vertex,
   add_edge!, add_vertex!, add_vertices!,
diff --git a/src/graphics/ComposeWiringDiagrams.jl b/src/graphics/ComposeWiringDiagrams.jl
index 99aa78be6..c815bc9a2 100644
--- a/src/graphics/ComposeWiringDiagrams.jl
+++ b/src/graphics/ComposeWiringDiagrams.jl
@@ -5,6 +5,7 @@ export ComposePicture, to_composejl, layout_to_composejl
 
 using Compat
 using LinearAlgebra: dot
+using Parameters: @with_kw_noshow
 import Compose
 const C = Compose
 
@@ -39,7 +40,7 @@ const ComposeProperties = AbstractVector{<:Compose.Property}
 
 """ Internal data type for configurable options of Compose.jl wiring diagrams.
 """
-Base.@kwdef struct ComposeOptions
+@with_kw_noshow struct ComposeOptions
   base_unit::Compose.Measure = 4*C.mm
   props::AbstractDict = Dict()
   box_renderer::Function = render_box
diff --git a/src/graphics/Graphviz.jl b/src/graphics/Graphviz.jl
index b825e43c6..871179863 100644
--- a/src/graphics/Graphviz.jl
+++ b/src/graphics/Graphviz.jl
@@ -11,6 +11,7 @@ export Expression, Statement, Attributes, Graph, Digraph, Subgraph,
 
 using Compat
 using DataStructures: OrderedDict
+using Parameters: @with_kw_noshow
 using StaticArrays: StaticVector, SVector
 
 using ...CategoricalAlgebra.Graphs: AbstractPropertyGraph, PropertyGraph,
@@ -41,7 +42,7 @@ as_attributes(d::OrderedDict) = Attributes(Symbol(k) => d[k] for k in keys(d))
 as_attributes(d::AbstractDict) =
   Attributes(Symbol(k) => d[k] for k in sort!(collect(keys(d))))
 
-Base.@kwdef struct Graph <: Expression
+@with_kw_noshow struct Graph <: Expression
   name::String
   directed::Bool
   prog::String="dot"
@@ -60,7 +61,7 @@ Digraph(name::String, stmts::Vector{Statement}; kw...) =
 Digraph(name::String, stmts::Vararg{Statement}; kw...) =
   Graph(; name=name, directed=true, stmts=collect(stmts), kw...)
 
-Base.@kwdef struct Subgraph <: Statement
+@with_kw_noshow struct Subgraph <: Statement
   name::String="" # Subgraphs can be anonymous
   stmts::Vector{Statement}=Statement[]
   graph_attrs::Attributes=Attributes()
diff --git a/src/graphics/GraphvizWiringDiagrams.jl b/src/graphics/GraphvizWiringDiagrams.jl
index ba05928d0..13ff0d938 100644
--- a/src/graphics/GraphvizWiringDiagrams.jl
+++ b/src/graphics/GraphvizWiringDiagrams.jl
@@ -3,6 +3,7 @@
 module GraphvizWiringDiagrams
 export to_graphviz, graphviz_layout
 
+using Compat: isnothing
 import JSON
 using LinearAlgebra: normalize
 using MLStyle: @match
diff --git a/src/graphics/TikZWiringDiagrams.jl b/src/graphics/TikZWiringDiagrams.jl
index 5807992f0..c289a9146 100644
--- a/src/graphics/TikZWiringDiagrams.jl
+++ b/src/graphics/TikZWiringDiagrams.jl
@@ -6,6 +6,7 @@ export to_tikz, layout_to_tikz
 using Compat
 using DataStructures: OrderedDict
 using MLStyle: @match
+using Parameters: @with_kw_noshow
 
 using ...Syntax: GATExpr, show_latex
 using ...WiringDiagrams, ...WiringDiagrams.WiringDiagramSerialization
@@ -20,7 +21,7 @@ import ..TikZ
 
 """ Internal data type for configurable options of Compose.jl wiring diagrams.
 """
-Base.@kwdef struct TikZOptions
+@with_kw_noshow struct TikZOptions
   orientation::LayoutOrientation = LeftToRight
   base_unit::String = "4mm"
   labels::Bool = false
diff --git a/src/graphics/WiringDiagramLayouts.jl b/src/graphics/WiringDiagramLayouts.jl
index 007bbd4a1..89d7dcd35 100644
--- a/src/graphics/WiringDiagramLayouts.jl
+++ b/src/graphics/WiringDiagramLayouts.jl
@@ -14,6 +14,7 @@ using Compat
 import Base: sign
 using LinearAlgebra: dot, normalize
 using Logging
+using Parameters: @with_kw_noshow
 using StaticArrays: StaticVector, SVector
 using Statistics: mean
 
@@ -47,7 +48,7 @@ svector(orient::LayoutOrientation, first, second) =
 
 """ Internal data type for configurable options of wiring diagram layout.
 """
-Base.@kwdef struct LayoutOptions
+@with_kw_noshow struct LayoutOptions
   orientation::LayoutOrientation = LeftToRight
   default_box_shape::Symbol = :rectangle
   box_shapes::AbstractDict = Dict()
@@ -73,7 +74,7 @@ Specific features of the shape are determined by the graphics backend. For
 example, a rectangle could be rendered with or without rounded corners or even
 as another, similar shape, such as a parallelogram.
 """
-Base.@kwdef mutable struct BoxLayout
+@with_kw_noshow mutable struct BoxLayout
   value::Any = nothing
   shape::Symbol = :rectangle
   position::Vector2D = zeros(Vector2D)
@@ -98,7 +99,7 @@ contents_upper_corner(diagram::WiringDiagram) =
 
 """ Layout for port in a wiring diagram.
 """
-Base.@kwdef struct PortLayout
+@with_kw_noshow struct PortLayout
   value::Any = nothing
   position::Vector2D = zeros(Vector2D) # Position relative to box center.
   normal::Vector2D = zeros(Vector2D)   # Outward unit normal vector.
diff --git a/src/wiring_diagrams/MonoidalUndirected.jl b/src/wiring_diagrams/MonoidalUndirected.jl
index 39271d9c4..c831107dd 100644
--- a/src/wiring_diagrams/MonoidalUndirected.jl
+++ b/src/wiring_diagrams/MonoidalUndirected.jl
@@ -5,6 +5,7 @@ export UndirectedWiringDiagramOb, UndirectedWiringDiagramHom, ObUWD, HomUWD,
   cospan_action, dom_mask, codom_mask
 
 using AutoHashEquals
+using Compat: isnothing
 
 using ...GAT
 using ...Theories: HypergraphCategory
diff --git a/src/wiring_diagrams/Undirected.jl b/src/wiring_diagrams/Undirected.jl
index fbae8c63a..49364a0c9 100644
--- a/src/wiring_diagrams/Undirected.jl
+++ b/src/wiring_diagrams/Undirected.jl
@@ -6,11 +6,12 @@ export UndirectedWiringDiagram, outer_box, box, junction, nboxes, njunctions,
   add_box!, add_junction!, add_junctions!, set_junction!, add_wire!,
   add_wires!, singleton_diagram, cospan_diagram, junction_diagram, ocompose
 
+using Compat: isnothing
+
 using ...CategoricalAlgebra.CSets, ...Present
 using ...CategoricalAlgebra.ShapeDiagrams: Span
 using ...CategoricalAlgebra.FinSets: FinFunction, pushout
 using ...Theories: FreeCategory, dom, codom, compose, ⋅, id
-
 import ..DirectedWiringDiagrams: box, boxes, nboxes, add_box!, add_wire!,
   add_wires!, singleton_diagram, ocompose
 


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 7fe281248..b202c54ee 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -6,7 +6,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        julia-version: ['1.3', '1.4']
+        julia_version: ['1.0', '1.3', '1.4']
         os: [ubuntu-latest]
     
     steps:
@@ -14,6 +14,13 @@ jobs:
       - name: "Set up Julia"
         uses: julia-actions/setup-julia@latest
         with:
-          version: ${{ matrix.julia-version }}
+          version: ${{ matrix.julia_version }}
       - name: "Run tests"
         uses: julia-actions/julia-runtest@master
+        if: matrix.julia_version != '1.0'
+      - name: "Run tests"
+        run: |
+          julia -e 'using Pkg; Pkg.activate("test"); Pkg.develop(PackageSpec(path="."))'
+          julia --color=yes --check-bounds=yes --project=test test/runtests.jl
+        # XXX: Julia 1.0 does not use the Project.toml in `tests` directory.
+        if: matrix.julia_version == '1.0'