mirror of https://github.com/deuill/grawkit.git
First version of Grawkit, with simple single-branch test
This version has support for adding commits on a single branch using `git commit`, and enough scaffolding for adding additional commands and accompanying tests easily.
This commit is contained in:
commit
0e5eee146f
|
@ -0,0 +1,14 @@
|
|||
# Code styles for Fawkss.
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2016 Alex Palaistras
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,98 @@
|
|||
# --------------------
|
||||
# Makefile for Grawkit
|
||||
# --------------------
|
||||
|
||||
# Run `make help` for information on available actions.
|
||||
|
||||
# --------------------
|
||||
# Variable definitions
|
||||
# --------------------
|
||||
|
||||
# Default name for Grawkit executable.
|
||||
CMD = $(CURDIR)/grawkit
|
||||
|
||||
# Default executables to use.
|
||||
SHELL = /bin/bash
|
||||
DIFF = $(shell which colordiff || which diff)
|
||||
|
||||
# Test files to execute.
|
||||
TESTS ?= $(shell find tests/*/*)
|
||||
|
||||
# Color & style definitions.
|
||||
BOLD = \033[1m
|
||||
UNDERLINE = \033[4m
|
||||
RED = \033[31m
|
||||
GREEN = \033[32m
|
||||
BLUE = \033[36m
|
||||
RESET = \033[0m
|
||||
|
||||
# ----------------
|
||||
# Other directives
|
||||
# ----------------
|
||||
|
||||
# Make `help` be the default action when no arguments are passed to `make`.
|
||||
.DEFAULT_GOAL = help
|
||||
.PHONY: $(TESTS) test help
|
||||
|
||||
# Awk script for extracting Grawkit documentation as Markdown.
|
||||
define EXTRACT_MARKDOWN
|
||||
/^(#|# .*)$$/ {
|
||||
if (f==1) {f=0; printf "```\n\n"}
|
||||
print substr($$0, 3)
|
||||
}
|
||||
/^[^#]/ {
|
||||
if (f==0) {f=1; printf "\n```awk\n"}
|
||||
print
|
||||
}
|
||||
!NF {
|
||||
print
|
||||
}
|
||||
END {
|
||||
if (f==1) {printf "```\n"}
|
||||
}
|
||||
endef
|
||||
export EXTRACT_MARKDOWN
|
||||
|
||||
# ----------------
|
||||
# Rule definitions
|
||||
# ----------------
|
||||
|
||||
## Build documentation from source file in Markdown format.
|
||||
doc:
|
||||
@awk "$$EXTRACT_MARKDOWN" "$(CMD)"
|
||||
|
||||
## Execute test suite, accepts list of specific files to run.
|
||||
test: test-before $(TESTS) test-after
|
||||
|
||||
test-before:
|
||||
@printf ">> $(BOLD)Executing tests...$(RESET)\n"
|
||||
|
||||
test-after:
|
||||
@printf ">> $(BOLD)Finished executing tests.$(RESET)\n"
|
||||
|
||||
$(TESTS):
|
||||
$(eval TEST_$@ := awk '/<!--/ {f=1;next} /-->/ {exit} f' $@)
|
||||
$(eval EXPECTED_$@ := awk '/-->/ {f=1;getline;next} f' $@)
|
||||
$(eval ACTUAL_$@ := $(CMD) <($(TEST_$@)))
|
||||
|
||||
@printf ">> $(BOLD)Testing file '$@'...$(RESET) "
|
||||
|
||||
# Generate diff between expected and actual results and print back to user.
|
||||
@result=$$($(DIFF) -ud <($(EXPECTED_$@)) <($(ACTUAL_$@)) | tail -n +3); \
|
||||
if [ -z "$$result" ]; then \
|
||||
printf "$(GREEN)OK$(RESET)\n"; \
|
||||
else \
|
||||
printf "$(RED)FAIL$(RESET)\n"; \
|
||||
echo "$$result"; \
|
||||
fi \
|
||||
|
||||
## Show usage information for this Makefile.
|
||||
help:
|
||||
@printf "$(BOLD)Grawkit — The Awksome Git Graph Generator.$(RESET)\n\n"
|
||||
@printf "This Makefile contains tasks for processing auxiliary actions, such as\n"
|
||||
@printf "generating documentation or running test cases against the test suite.\n\n"
|
||||
@printf "$(UNDERLINE)Available Tasks$(RESET)\n\n"
|
||||
@awk -F \
|
||||
':|##' '/^##/ {c=$$2; getline; printf "$(BLUE)%6s$(RESET) %s\n", $$1, c}' \
|
||||
$(MAKEFILE_LIST)
|
||||
@printf "\n"
|
|
@ -0,0 +1,16 @@
|
|||
# Grawkit - The AWKsome Git Graph Toolkit
|
||||
|
||||
Grawkit is a tool that helps build SVG graphs from git command-line descriptions, and is built in Awk.
|
||||
|
||||
## Testing & Documentation
|
||||
|
||||
A `Makefile` is provided for running tests and producing documentation for Grawkit. Run `make help` in the project root for more information.
|
||||
|
||||
A full test-suite is provided (depending only on `make` and `awk`), which should serve as a good example of the existing feature-set.
|
||||
|
||||
## License
|
||||
|
||||
All code in this repository is covered by the terms of the MIT License, the full text of which can be found in the LICENSE file.
|
||||
|
||||
[license-url]: https://github.com/deuill/grawkit/blob/master/LICENSE
|
||||
[license-svg]: https://img.shields.io/badge/license-MIT-blue.svg
|
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/awk -f
|
||||
#
|
||||
# Grawkit — The Awksome Git Graph Generator.
|
||||
# ==========================================
|
||||
#
|
||||
# Grawkit is a tool that helps build SVG graphs from Git command-line descriptions.
|
||||
#
|
||||
# This documentation is built using Markdown syntax, and can be parsed out by
|
||||
# running `make doc` in the project root. Please check the project's README file
|
||||
# for additional information.
|
||||
#
|
||||
# Built-in Functions
|
||||
# ------------------
|
||||
#
|
||||
# This section contains global helper functions, used across different rules, as
|
||||
# defined in the next section below.
|
||||
#
|
||||
# > Function `t` processes the string passed as a template. It's mainly used for
|
||||
# > cleaning up strings with single quotes etc.
|
||||
function t(str) {
|
||||
# Replace single quotes with double quotes.
|
||||
gsub("'", "\"", str)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
# > Function `branch` renders pre-defined branch under a specific name to its
|
||||
# > SVG representation.
|
||||
function branch(name, _, buf, tmp, refs, i, bs, cs) {
|
||||
# Find index of branch.
|
||||
for (n in branches) {
|
||||
if (n == name) break
|
||||
i += 1
|
||||
}
|
||||
|
||||
# Get commit refs.
|
||||
split(branches[name], refs, ",")
|
||||
bs = i * style["branch/spacing"]
|
||||
|
||||
# Add path for branch.
|
||||
tmp = "M" refs[1] * style["commit/spacing"] "," bs
|
||||
tmp = tmp " L" (length(refs) - 1) * style["commit/spacing"] "," bs
|
||||
|
||||
# Print path.
|
||||
buf = sprintf(svg["g"], name)
|
||||
buf = buf "\n" sprintf(svg["path"], tmp)
|
||||
|
||||
# Add commits on path.
|
||||
for (c in refs) {
|
||||
cs = refs[c] * style["commit/spacing"]
|
||||
|
||||
tmp = sprintf(svg["circle"], cs, bs, style["commit/radius"])
|
||||
buf = buf "\n" tmp
|
||||
}
|
||||
|
||||
buf = buf "\n" svg["/g"]
|
||||
return buf
|
||||
}
|
||||
|
||||
# Global Declarations
|
||||
# -------------------
|
||||
#
|
||||
# This block contains logic for initializing global variables used across Grawkit.
|
||||
|
||||
BEGIN {
|
||||
# Rule matching.
|
||||
rule["commit"] = "^git commit"
|
||||
|
||||
# Style definitions.
|
||||
style["branch/spacing"] = "50"
|
||||
style["branch/fill"] = "none"
|
||||
style["branch/stroke"] = "#333"
|
||||
style["branch/stroke-width"] = "10"
|
||||
|
||||
style["commit/spacing"] = "100"
|
||||
style["commit/fill"] = "#fff"
|
||||
style["commit/stroke"] = style["branch/stroke"]
|
||||
style["commit/stroke-width"] = style["branch/stroke-width"] / 2
|
||||
style["commit/radius"] = style["commit/stroke-width"] * 1.5
|
||||
|
||||
# Static SVG templates.
|
||||
svg["svg"] = t("<svg xmlns='http://www.w3.org/2000/svg' viewBox='%d %d %d %d'>")
|
||||
svg["/svg"] = "</svg>"
|
||||
svg["g"] = t("<g id='%s'>")
|
||||
svg["/g"] = "</g>"
|
||||
svg["path"] = t("<path class='branch' d='%s' />")
|
||||
svg["circle"] = t("<circle class='commit' cx='%d' cy='%d' r='%s' />")
|
||||
|
||||
# Branch definitions.
|
||||
branches["master"] = "0"
|
||||
len["branches"] = 1;
|
||||
|
||||
# Commit definitions.
|
||||
commits[0] = "b:master"
|
||||
len["commits"] = 1;
|
||||
|
||||
# Tracks the state across calls.
|
||||
state["branch"] = "master"
|
||||
state["HEAD"] = 0
|
||||
}
|
||||
|
||||
# Rule Definitions
|
||||
# ----------------
|
||||
#
|
||||
# This block contains definitions for line manipulation rules used across Fawkss.
|
||||
# Rules may or may not be exclusive, i.e. the effects of one rule may cascade to
|
||||
# subsequent rules for the same line.
|
||||
#
|
||||
|
||||
# > Match `git commit` declarations.
|
||||
$0 ~ rule["commit"] {
|
||||
# Add new commit with specific message.
|
||||
commits[len["commits"]] = "b:" state["branch"]
|
||||
|
||||
# Update commit references.
|
||||
branches[state["branch"]] = branches[state["branch"]] "," len["commits"]
|
||||
state["HEAD"] = len["commits"]
|
||||
|
||||
len["commits"] += 1
|
||||
}
|
||||
|
||||
# SVG Graph Generation
|
||||
#
|
||||
# This block contains logic for building the final SVG output from Grawkit's
|
||||
# internal state, as defined in the command-line provided.
|
||||
#
|
||||
END {
|
||||
xy = style["branch/stroke-width"] * -1
|
||||
w = (style["commit/spacing"] * (len["commits"] - 1)) + (style["commit/stroke-width"] * 4)
|
||||
h = (style["branch/spacing"] * (len["branches"] - 1)) + (style["branch/stroke-width"] * 2)
|
||||
|
||||
# Print SVG header.
|
||||
printf svg["svg"], xy, xy, w, h
|
||||
printf "\n"
|
||||
|
||||
# Print inline style definitions.
|
||||
print t("<style type='text/css'><![CDATA[")
|
||||
print ".branch {"
|
||||
print " fill: " style["branch/fill"] ";"
|
||||
print " stroke: " style["branch/stroke"] ";"
|
||||
print " stroke-width: " style["branch/stroke-width"] ";"
|
||||
print "}"
|
||||
print ".commit {"
|
||||
print " fill: " style["commit/fill"] ";"
|
||||
print " stroke: " style["commit/stroke"] ";"
|
||||
print " stroke-width: " style["commit/stroke-width"] ";"
|
||||
print "}"
|
||||
print "]]></style>"
|
||||
|
||||
# Print each branch and corresponding commits in turn.
|
||||
for (name in branches) {
|
||||
print branch(name)
|
||||
}
|
||||
|
||||
# Print SVG footer.
|
||||
print svg["/svg"]
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<!--
|
||||
|
||||
# Test a simple scenario of adding a few commits to `master`.
|
||||
|
||||
git commit -m "Adding a new commit"
|
||||
|
||||
-->
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 120 20">
|
||||
<style type="text/css"><![CDATA[
|
||||
.branch {
|
||||
fill: none;
|
||||
stroke: #333;
|
||||
stroke-width: 10;
|
||||
}
|
||||
.commit {
|
||||
fill: #fff;
|
||||
stroke: #333;
|
||||
stroke-width: 5;
|
||||
}
|
||||
]]></style>
|
||||
<g id="master">
|
||||
<path class="branch" d="M0,0 L100,0" />
|
||||
<circle class="commit" cx="0" cy="0" r="7.5" />
|
||||
<circle class="commit" cx="100" cy="0" r="7.5" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 523 B |
Loading…
Reference in New Issue