Validating MCM Arguments

One of MCM's early requirements was that it be possible to specify that an argument should be constrained in some way, for example to specify that a size argument be passed a purely numeric value:

MCM NumericValueExample

define checkMaximumFilesize(filesize path)

(Assume that the body of the above example does the wrong thing if the user passes a filesize of 5M because it is expecting a filesize in bytes.)

A prototype solution was implemented using MCM, and this works so well that MCM itself hasn't yet been changed (and perhaps it need not). It can be used such:

MCM NumericValueExample2

import MCM.Require as Require

define checkMaximumFilesize(filesize path)
	Require.require location> NumericValueExample2.checkMaximumFilesize regex> [0-9]+ str> @filesize

Now should we try to invoke checkMaximumFilesize() with an incorrect argument, then we get a useful error message:

MCM InvokeNumericValueExample2

import MCM.ScriptRegister as ScriptRegister
import NumericValueExample2 as NumericValueExample2

define go()
	ScriptRegister.registerStandardScripts scriptdir> /mcmscripts
	NumericValueExample2.checkMaximumFilesize filesize> 5M path> /var/log/somefile
> mcm -r build -f promptunlessonlyadditions -P .:lib InvokeNumericValueExample2.go
mkdir build
mkdir --mode 700 build/mcmscripts
install --mode 750 build/mcmscripts/01_require
install --mode 750 build/mcmscripts/10_debian-packages
install --mode 750 build/mcmscripts/40_ninja
install --mode 750 build/mcmscripts/50_hooks
mkdir build/mcmscripts/ninja
install build/mcmscripts/ninja/build.ninja
install --mode 750 build/mcmscripts/runall
Enacting...
> build/mcmscripts/runall

01_require
NumericValueExample2.checkMaximumFilesize requires that the given string matches the regex [0-9]+ but it is instead (quoted):
    "5M"
Error: 01_require exited with a non-zero status
Command exited with non-zero status 1
0.00
Exit failure: 1

Require.mcm itself is pleasingly simple and easy to extend and adapt:

MCM MCM.Require

import Admin.Packages as Packages
import MCM.ScriptRegister as ScriptRegister

define require(location regex str
		message = @location requires that the given string matches the regex @regex but it is instead (quoted):
			+     "@str"
	)
	Packages.add package> grep
	Fragment group> require
		content: cat <<"EOF_Require56" | egrep '^@regex$'  >/dev/null || { anerror=1 ; cat <<"EOF_Require72"
			+ @str
			+ EOF_Require56
			+ @message
			+ EOF_Require72
			+ }
	ScriptRegister.register name> 01_require
		content: #!/bin/dash
			+ anerror=0
			+$fragments(require,,@NEWLINE,)
			+ test $anerror -eq 0 || exit 1