Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanups #21

Merged
merged 38 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8f02bf0
Separate IsGVGraph and IsGVDigraph
james-d-mitchell May 13, 2024
7357381
Separate file for ErrorFormatted
james-d-mitchell May 13, 2024
bb6572d
Remove redundant funcs
james-d-mitchell May 13, 2024
fbd0390
Reorganise files
james-d-mitchell May 13, 2024
39d0b0c
etc: add code-coverage-test-gap.py
james-d-mitchell May 13, 2024
3e43674
Improve error messages
james-d-mitchell May 13, 2024
2b85ffd
Replace GV with Graphviz in some places
james-d-mitchell May 13, 2024
99c6639
Fix description strings
james-d-mitchell May 13, 2024
e6a7d22
More cleanups
james-d-mitchell May 14, 2024
4dbf0cd
Remove GraphvizGetSubgraph and rename GraphvizFindGraph -> GraphvizFi…
james-d-mitchell May 14, 2024
2eb081b
More cleanups
james-d-mitchell May 14, 2024
61e63b4
Rename GraphvizFilterEnds -> GraphvizRemoveEdges
james-d-mitchell May 14, 2024
7f49516
Rename AsString -> String
james-d-mitchell May 14, 2024
9118809
Add splash.gd
james-d-mitchell May 14, 2024
2e7c27f
Add PrintObj method for graphs and digraphs
james-d-mitchell May 14, 2024
bd99589
Add comment about valid identifiers
james-d-mitchell May 14, 2024
9bef7d5
Add comment to GraphvizSetAttr
james-d-mitchell May 14, 2024
9ba8bc9
IsGraphvizContext does not imply graph or digraph
james-d-mitchell May 14, 2024
6a4c892
Further tweak the categories
james-d-mitchell May 14, 2024
03f5e1e
Fix GraphvizAddSubgraph
james-d-mitchell May 14, 2024
20abb16
Fix tests
james-d-mitchell May 14, 2024
0edd2e6
Fix lint + codespell
james-d-mitchell May 14, 2024
f25ff24
Fixup code coverage script
james-d-mitchell May 15, 2024
6257877
Update desc. strings
james-d-mitchell May 15, 2024
19e0450
More test for code coverage
james-d-mitchell May 15, 2024
737a67f
Revert "Rename AsString -> String"
james-d-mitchell May 15, 2024
7c412f3
More test for code coverage and remove some unreachable code
james-d-mitchell May 15, 2024
6d90950
Correct STOP_TEST strings in tst/examples
james-d-mitchell May 15, 2024
8569f75
Remove GV_EnsureString
james-d-mitchell May 15, 2024
e840460
Fix tests for GAP 4.11
james-d-mitchell May 15, 2024
b78eea9
Remove InstallOtherMethod from gv.gi
james-d-mitchell May 15, 2024
0cee784
Conditionally install GV_Pluralize
james-d-mitchell May 15, 2024
994e1df
More \= method for nodes to dot.gi
james-d-mitchell May 15, 2024
07bf02f
Better error messages in gv.gi
james-d-mitchell May 15, 2024
de8b6ca
Tweak ViewString and rewrite tests
james-d-mitchell May 15, 2024
57f2736
Add comment
james-d-mitchell May 15, 2024
910639c
Fix tests for GAP 4.11 again
james-d-mitchell May 15, 2024
2785ab5
Fix codespell
james-d-mitchell May 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codespellrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[codespell]
skip = ./.git,./doc/*.log,./doc/*.html,./doc/*.txt,./doc/*.six,./doc/*.js,./doc/*.bbl,./doc/*.tex,./doc/*.bib,./doc/_*
ignore-words-list=fille
skip = ./.git,./doc/*.log,./doc/*.html,./doc/*.txt,./doc/*.six,./doc/*.js,./doc/*.bbl,./doc/*.tex,./doc/*.bib,./doc/_*,./tst/*
ignore-words-list=manuel
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
- make it so when duplicates are added to global graph attrs the old values are automatically replaced
- Improve behaviour around ':' syntax - mimic python package

## TODO (ONCE THIS IS EMPTY THEN DONE!)
- Ask about `Pluralize` - think james said to remove for old versions of gap
## TODO
- Update docs
- Add more unit tests
- Thoroughly test the ':' syntax more (might have broke when the quotes were changed)
- PrintObj method is missing for nodes (and probably edges)

## Other
- relates to deadnaut github issue https://www.mankier.com/1/nauty-dretodot
Expand Down
107 changes: 107 additions & 0 deletions etc/code-coverage-test-gap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""
This is a simple script to run code coverage for some test files.
"""
# pylint: disable=invalid-name

import argparse
import os
import re
import subprocess
import sys
import tempfile

from os.path import exists, isdir, isfile
from os import getcwd

_ERR_PREFIX = "\033[31mcode-coverage-test-gap.py: error: "
_INFO_PREFIX = "\033[0m\033[1m"

_PARSER = argparse.ArgumentParser(
prog="code-coverage-test-gap.py", usage="%(prog)s [options]"
)
_PARSER.add_argument(
"tstfiles",
nargs="+",
type=str,
help="the test files you want to check code coverage for"
+ "(must be at least one)",
)
_PARSER.add_argument(
"--gap-root",
nargs="?",
type=str,
help="the gap root directory (default: ~/gap)",
default="~/gap/",
)
_PARSER.add_argument(
"--open",
nargs="?",
type=str,
help=("open the html page for this file (default: None)"),
default=None,
)

_ARGS = _PARSER.parse_args()
if not _ARGS.gap_root[-1] == "/":
_ARGS.gap_root += "/"

if exists("gap") and isdir("gap"):
_PROFILE_DIR = "/gap/"
elif exists("lib") and isdir("lib"):
_PROFILE_DIR = "/lib/"
else:
sys.exit(f"{_ERR_PREFIX}no directory gap or lib to profile!\033[0m")

_ARGS.gap_root = os.path.expanduser(_ARGS.gap_root)
if not (exists(_ARGS.gap_root) and isdir(_ARGS.gap_root)):
sys.exit(f"{_ERR_PREFIX}can't find GAP root directory!\033[0m")

for f in _ARGS.tstfiles:
if not (exists(f) and isfile(f)):
sys.exit(f"{_ERR_PREFIX}{f} does not exist!\033[0m")

_DIR = tempfile.mkdtemp()
print(f"{_INFO_PREFIX}Using temporary directory: {_DIR}\033[0m")

_COMMANDS = 'echo "'
_COMMANDS += "".join(rf"Test(\"{f}\");;\n" for f in _ARGS.tstfiles)
_COMMANDS += rf"""UncoverageLineByLine();;
LoadPackage(\"profiling\", false);;
filesdir := \"{getcwd()}{_PROFILE_DIR}\";;\n"""

_COMMANDS += rf"outdir := \"{_DIR}\";;\n"
_COMMANDS += rf"x := ReadLineByLineProfile(\"{_DIR}/profile.gz\");;\n"
_COMMANDS += 'OutputAnnotatedCodeCoverageFiles(x, filesdir, outdir);"'

_RUN_GAP = f"{_ARGS.gap_root}/gap -A -m 1g -T --cover {_DIR}/profile.gz"

with subprocess.Popen(_COMMANDS, stdout=subprocess.PIPE, shell=True) as pro1:
try:
with subprocess.Popen(_RUN_GAP, stdin=pro1.stdout, shell=True) as pro2:
pro2.wait()
except KeyboardInterrupt:
pro1.terminate()
pro1.wait()
sys.exit("\033[31mKilled!\033[0m")
except (subprocess.CalledProcessError, IOError, OSError):
sys.exit(_ERR_PREFIX + "Something went wrong calling GAP!\033[0m")


def rewrite_fname(fname: str) -> str:
return fname.replace("/", "_")


suffix = ""
if _ARGS.open:
filename = f"{_DIR}/{rewrite_fname(getcwd())}/{rewrite_fname(_ARGS.open)}.html"
p = re.compile(r"<tr class='missed'><td><a name=\"line(\d+)\">")
with open(filename, "r", encoding="utf-8") as f:
m = p.search(f.read())
if m:
suffix += "#line" + m.group(1)
else:
filename = _DIR + "/index.html"
print(f"{_INFO_PREFIX}\nSUCCESS!\033[0m")
print(f"{_INFO_PREFIX}See {filename}")
sys.exit(0)
8 changes: 8 additions & 0 deletions etc/tst-local-vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: tst-local-vars

channels:
- conda-forge

dependencies:
- pyyaml
- bs4
138 changes: 76 additions & 62 deletions gap/dot.gd
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,22 @@
#! @Section Graphviz Categories

#! @BeginGroup Filters
#! @Description Every object in graphviz belongs to the IsGVObject category.
#! The categories following it are for further specificity on the type of
#! objects. These are graphs, digraphs, nodes and edges respectively.
#! All are direct subcategories of IsGVObject excluding IsGVDigraph which is a
#! subcategory of is GVGraph.
DeclareCategory("IsGVObject", IsObject);
DeclareCategory("IsGVGraph", IsGVObject);
# TODO change to IsGVObject below, since digraphs aren't a special kind of
# graph, unless I'm (JDM) mistaken?
DeclareCategory("IsGVDigraph", IsGVGraph);
DeclareCategory("IsGVContext", IsGVGraph);
DeclareCategory("IsGVNode", IsGVObject);
DeclareCategory("IsGVEdge", IsGVObject);
#! @Description Every object in graphviz belongs to the IsGraphvizObject
#! category. The categories following it are for further specificity on the
#! type of objects. These are graphs, digraphs, nodes and edges respectively.
#! All are direct subcategories of IsGraphvizObject excluding IsGraphvizDigraph
#! which is a subcategory of is IsGraphvizGraph.

DeclareCategory("IsGraphvizObject", IsObject);

DeclareCategory("IsGraphvizGraphDigraphOrContext", IsGraphvizObject);
DeclareCategory("IsGraphvizGraph", IsGraphvizGraphDigraphOrContext);
DeclareCategory("IsGraphvizDigraph", IsGraphvizGraphDigraphOrContext);
DeclareCategory("IsGraphvizContext", IsGraphvizGraphDigraphOrContext);

DeclareCategory("IsGraphvizNodeOrEdge", IsGraphvizObject);
DeclareCategory("IsGraphvizNode", IsGraphvizNodeOrEdge);
DeclareCategory("IsGraphvizEdge", IsGraphvizNodeOrEdge);
#! @EndGroup

#! @Section Constructors
Expand Down Expand Up @@ -74,54 +77,61 @@ DeclareOperation("GraphvizDigraph", []);
#! @Arguments obj
#! @Returns the name of the provided graphviz object
#! @Description Gets the name of the provided graphviz object.
DeclareOperation("GraphvizName", [IsGVObject]);
DeclareOperation("GraphvizName", [IsGraphvizObject]);

#! @Arguments obj
#! @Returns the attributes of the provided graphviz object
#! @Description Gets the attributes of the provided graphviz object.
DeclareOperation("GraphvizAttrs", [IsGVObject]);
DeclareOperation("GraphvizAttrs", [IsGraphvizObject]);

#! @Subsection For only graphs and digraphs.

#! @Arguments graph
#! @Returns the nodes of the provided graphviz graph.
#! @Description Gets the nodes of the provided graphviz graph.
#! Node names can only be [a-zA-Z0-9_£] TODO check exact docs.
DeclareOperation("GraphvizNodes", [IsGVGraph]);
DeclareOperation("GraphvizNode", [IsGVGraph, IsObject]);
# From https://graphviz.org/doc/info/lang.html
# An ID is one of the following:
# Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_') or
# digits([0-9]), not beginning with a digit;
# a numeral [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? );
# any double-quoted string ("...") possibly containing escaped quotes (\")¹;
# an HTML string (<...>).
# TODO specify
DeclareOperation("GraphvizNodes", [IsGraphvizGraphDigraphOrContext]);

#! @Arguments graph
#! @Returns the subgraphs of the provided graphviz graph.
#! @Description gets the subgraphs of a provided graphviz graph.
DeclareOperation("GraphvizSubgraphs", [IsGVGraph]);
DeclareOperation("GraphvizGetSubgraph", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizSubgraphs", [IsGraphvizGraphDigraphOrContext]);

#! @Arguments graph, name
#! @Returns a graph with the provided name.
#! @Description
#! Searches through the tree of subgraphs connected to this subgraph for a graph
#! with the provided name.
#! It returns the graph if it exists.
#! If no such graph exists then it will return fail.
DeclareOperation("GraphvizFindGraph", [IsGVGraph, IsObject]);
#! If no such graph exists then it will return <K>fail<K>.
DeclareOperation("GraphvizFindSubgraphRecursive",
[IsGraphvizGraphDigraphOrContext, IsObject]);

#! @Arguments graph
#! @Returns the edges of the provided graphviz graph.
#! @Description Gets the edges of the provided graphviz graph.
DeclareOperation("GraphvizEdges", [IsGVGraph]);
DeclareOperation("GraphvizEdges", [IsGVGraph, IsObject, IsObject]);
DeclareOperation("GraphvizEdges", [IsGraphvizGraphDigraphOrContext]);
DeclareOperation("GraphvizEdges",
[IsGraphvizGraphDigraphOrContext, IsObject, IsObject]);

#! @Subsection For only edges.

#! @Arguments edge
#! @Returns the head of the provided graphviz edge.
#! @Description Gets the head of the provided graphviz graph.
DeclareOperation("GraphvizHead", [IsGVEdge]);
DeclareOperation("GraphvizHead", [IsGraphvizEdge]);

#! @Arguments edge
#! @Returns the head of the provided graphviz tail.
#! @Description Gets the tail of the provided graphviz graph.
DeclareOperation("GraphvizTail", [IsGVEdge]);
DeclareOperation("GraphvizTail", [IsGraphvizEdge]);

#! @Section Set Operations
#! This section covers operations for modifying graphviz objects.
Expand All @@ -131,49 +141,55 @@ DeclareOperation("GraphvizTail", [IsGVEdge]);
#! @Arguments graph, name
#! @Returns the modified graph.
#! @Description Sets the name of a graphviz graph or digraph.
DeclareOperation("GraphvizSetName", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizSetName", [IsGraphvizGraphDigraphOrContext, IsObject]);

#! @Arguments graph, node
#! @Returns the modified graph.
#! @Description Adds a node to the graph.
#! If a node with the same name is already present the operation fails.
DeclareOperation("GraphvizAddNode", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizAddNode", [IsGraphvizGraphDigraphOrContext, IsObject]);

#! @Arguments graph, edge
#! @Returns the modified graph.
#! @Description Adds an edge to the graph.
#! If no nodes with the same name are in the graph then the edge's nodes will be
#! added to the graph. If different nodes with the same name are in the graph
#! then the operation fails.
DeclareOperation("GraphvizAddEdge", [IsGVGraph, IsObject, IsObject]);
DeclareOperation("GraphvizAddEdge",
[IsGraphvizGraphDigraphOrContext, IsObject, IsObject]);

#! @Arguments graph, filter, name
#! @Returns the new subgraph.
#! @Description Adds a subgraph to a graph.
DeclareOperation("GraphvizAddSubgraph", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizAddSubgraph", [IsGVGraph]);
DeclareOperation("GraphvizAddSubgraph",
[IsGraphvizGraphDigraphOrContext, IsObject]);
DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext]);

#! @Arguments graph, filter, name
#! @Returns the new context.
#! @Description Adds a context to a graph.
DeclareOperation("GraphvizAddContext", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizAddContext", [IsGVGraph]);
DeclareOperation("GraphvizAddContext",
[IsGraphvizGraphDigraphOrContext, IsObject]);
DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext]);

#! @Arguments graph, node
#! @Returns the modified graph.
#! @Description Removes the node from the graph.
DeclareOperation("GraphvizRemoveNode", [IsGVGraph, IsObject]);
DeclareOperation("GraphvizRemoveNode",
[IsGraphvizGraphDigraphOrContext, IsObject]);

#! @Arguments graph, predicate
#! @Returns the modified graph.
#! @Description Filters the graph's edges using the provided predicate.
DeclareOperation("GraphvizFilterEdges", [IsGVGraph, IsFunction]);
DeclareOperation("GraphvizFilterEdges",
[IsGraphvizGraphDigraphOrContext, IsFunction]);

#! @Arguments graph, head_name, tail_name
#! @Returns the modified graph.
#! @Description Filters the graph's edges, removing edges between nodes with
#! the specified names.
DeclareOperation("GraphvizFilterEnds", [IsGVGraph, IsObject, IsObject]);
DeclareOperation("GraphvizRemoveEdges",
[IsGraphvizGraphDigraphOrContext, IsObject, IsObject]);

#! @Subsection For modifying object attributes.

Expand All @@ -184,37 +200,19 @@ DeclareOperation("GraphvizFilterEnds", [IsGVGraph, IsObject, IsObject]);
#! All current attributes remain.
#! If an attribute already exists and a new value is provided, the old value
#! will be overwritten.
DeclareOperation("GraphvizSetAttrs", [IsGVObject, IsRecord]);
DeclareOperation("GraphvizSetAttr", [IsGVObject, IsObject, IsObject]);
DeclareOperation("GraphvizSetAttr", [IsGVObject, IsObject]);

#! @Arguments obj, label
#! @Returns the modified object.
#! @Description
#! Updates the label of the object.
#! If a label already exists and a new value is provided, the old value will
#! be overwritten.
# TODO remove
DeclareOperation("GraphvizSetLabel", [IsGVObject, IsObject]);

#! @Arguments obj, color
#! @Returns the modified object.
#! @Description
#! Updates the color of the object.
#! If a color already exists and a new value is provided, the old value will
#! be overwritten.
# TODO remove
DeclareOperation("GraphvizSetColor", [IsGVObject, IsObject]);
DeclareOperation("GraphvizSetAttrs", [IsGraphvizObject, IsRecord]);
DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject, IsObject]);
DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject]);

#! @Arguments obj, attr
#! @Returns the modified object.
#! @Description Removes an attribute from the object provided.
DeclareOperation("GraphvizRemoveAttr", [IsGVObject, IsObject]);
DeclareOperation("GraphvizRemoveAttr", [IsGraphvizObject, IsObject]);

#! @Section Outputting
#! @Arguments graph
#! @Returns the dot representation of the graphviz object.
DeclareOperation("AsString", [IsGVGraph]);
DeclareOperation("AsString", [IsGraphvizGraphDigraphOrContext]);

#! @Arguments obj
#! @Returns the graphviz representation of the object.
Expand All @@ -223,6 +221,22 @@ DeclareOperation("AsString", [IsGVGraph]);
#! Should output the graphviz package representation of the object.
DeclareOperation("Graphviz", [IsObject]);

DeclareOperation("GraphvizSetNodeColors", [IsGVGraph, IsList]);
DeclareOperation("GraphvizSetNodeLabels", [IsGVGraph, IsList]);
DeclareGlobalFunction("ErrorFormatted");
DeclareOperation("GraphvizSetNodeColors",
[IsGraphvizGraphDigraphOrContext, IsList]);
DeclareOperation("GraphvizSetNodeLabels",
[IsGraphvizGraphDigraphOrContext, IsList]);

DeclareGlobalFunction("ErrorIfNotValidColor");

# TODO doc
DeclareOperation("\[\]", [IsGraphvizNode, IsObject]);
# TODO doc
DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]);

# TODO doc
DeclareOperation("\[\]", [IsGraphvizEdge, IsObject]);
# TODO doc
DeclareOperation("\[\]\:\=", [IsGraphvizEdge, IsObject, IsObject]);

# TODO doc
DeclareOperation("\[\]", [IsGraphvizGraphDigraphOrContext, IsObject]);
Loading
Loading