We are currently finalizing guidelines called Sane software manifesto (sources). This document consists of chapters and items. An item might be a requirement, a recommendation or an information. In order to get a high-level overview, we generate statistics showing the counts of items of forementioned types in particular chapters. Whole document is built using GNU Make, so we call also Relational pipes commands from the Makefile:
build/statistics.rp: text/ssm.en.xml
mkdir -p build
cat text/ssm.en.xml \
| relpipe-in-xmltable \
--namespace "m" "tag:globalcode.info,2019:sane-software/manifesto" \
--relation "chapter" \
--records "//m:chapter" \
--attribute "name" string "m:name" \
--attribute "requirements" integer "count(descendant::m:item[m:type='requirement'])" \
--attribute "recommendations" integer "count(descendant::m:item[m:type='recommendation'])" \
--attribute "informations" integer "count(descendant::m:item[m:type='information'])" \
--attribute "items_total" integer "count(descendant::m:item)" \
> build/statistics.rp
# Prints a table with number of items in particular chapters:
statistics: build/statistics.rp
cat build/statistics.rp | relpipe-out-tabular
statistics-chart: build/statistics.rp
cat build/statistics.rp | relpipe-tr-cut --relation ".*" --attribute "(name|.*s)" | relpipe-out-gui -title "Sane software manifesto – chart of rule types"
The first Makefile target stores relational data in the file statistics.rp
(which is re/generated only if ssm.en.xml
has been changed).
And then this file is used twice: for terminal output using relpipe-out-tabular
and for visual output with a chart using relpipe-out-gui
.
The relpipe-in-xmltable
simply counts items (requirements, recommendations, informations, totals) in each chapter using XPath expressions.
So we can see how heavy and strict particular chapters are:
chapter:
╭─────────────────────────────────────────┬────────────────────────┬───────────────────────────┬────────────────────────┬───────────────────────╮
│ name (string) │ requirements (integer) │ recommendations (integer) │ informations (integer) │ items_total (integer) │
├─────────────────────────────────────────┼────────────────────────┼───────────────────────────┼────────────────────────┼───────────────────────┤
│ Free software │ 5 │ 1 │ 1 │ 7 │
│ Documented │ 4 │ 0 │ 1 │ 5 │
│ Semantic versioning and upgrades │ 4 │ 2 │ 2 │ 8 │
│ Interfaces, formats and protocols │ 1 │ 3 │ 1 │ 5 │
│ Modular architecture and extensibility │ 2 │ 1 │ 1 │ 4 │
│ Testable │ 0 │ 4 │ 1 │ 5 │
│ Safe code and sustainability │ 2 │ 4 │ 0 │ 6 │
│ Small code footprint │ 0 │ 3 │ 0 │ 3 │
│ Sane dependencies │ 3 │ 7 │ 0 │ 10 │
│ Easily auditable │ 0 │ 2 │ 1 │ 3 │
│ Reproducible builds │ 1 │ 1 │ 0 │ 2 │
│ Trustworthy packages and sources │ 2 │ 4 │ 0 │ 6 │
│ Network interactions │ 4 │ 0 │ 0 │ 4 │
│ Internationalization and localization │ 7 │ 5 │ 0 │ 12 │
│ Communication with users and developers │ 5 │ 5 │ 0 │ 10 │
│ Accept contributions │ 5 │ 3 │ 5 │ 13 │
╰─────────────────────────────────────────┴────────────────────────┴───────────────────────────┴────────────────────────┴───────────────────────╯
Record count: 16
However – for such data – much better than a table is a chart.
So we pipe the raw relational data prepared in the build/statistics.rp
to the relpipe-out-gui
command.
But because this tool counts totals itself and stacks the values in the bar chart,
we remove the items_total
attribute from the relation using relpipe-tr-cut
transformation.
Thanks to regular expressions, it is very concise. But of course, we can make it more explicit:
relpipe-tr-cut --relation "chapter" --attribute "(name|requirements|recommendations|informations)"
# relation name ^ ^ attribute names to be passed through (others are filtered out)
We also set the window title (using the -title
Qt option) and get the chart:
Using these tools we can get statistics and charts from any XML or other supported format like CSV, Recfile or a database. We can also do advanced computations using SQL, Guile or AWK before piping the data to the GUI.
Relational pipes, open standard and free software © 2018-2022 GlobalCode