Compare two specs#
Diff two spec files so that the diff shows only what the specs state differently. A plain text diff also shows the order of entries, spacing and the order of the terms in a sum. The canonical form is one fixed way to write a spec, and it removes those differences. Comparing two specs lists what the form sorts and what it keeps.
- Write one spec in the canonical form.
The command writes the form to stdout, or to a file with
-o canonical.yaml. A file the language refuses prints its message on
stderr and exits with status 1.
- Diff two files once. Give both files to
diff:
The command writes each spec in the canonical form and prints a unified
diff of the two. It exits with status 0 when the specs are the same, and
with status 1 when they differ, as diff does. A file the language refuses
prints its message on stderr and exits with status 2.
- Make
git diffshow the canonical form. Tell git which files are specs, and which command writes them out:
echo 'specs/*.yaml diff=mathspec' >> .gitattributes
git config diff.mathspec.textconv "python -m mathspec canonical"
The files in the repository stay as you wrote them, and only the diff
changes. A commit that writes sum(dispatch * cost) as
sum(cost * dispatch) then shows no difference, and a commit that changes a
coefficient shows one line:
objective:
sense: minimize
- expression: sum(cost * dispatch)
+ expression: sum((2 * cost) * dispatch)
Match only spec files in .gitattributes, because git runs the command on
every file the pattern matches, and a YAML file that is not a spec fails to
load.
- Check in CI that a change leaves the spec as it was. A change that only moves declarations or reorders the terms of a sum states the same spec. Compare the file on the main branch with the file in the change:
The job fails when the specs differ, and its log shows the lines that changed. The files in the repository stay as you wrote them, with their comments. The same mathspec writes both forms when the job runs, so a new mathspec release does not make the job fail.
- Compare from Python where the comparison is one step of a longer
script.
to_yamlwrites the same text withcanonical=True: