The nitrile.yml
reference¶
This page documents the nitrile.yml
file. For a large example, see the
Nitrile package file.
actions
¶
In this key a list of actions can be specified. Actions are simple scripts that
can be run with nitrile do
. The following example defines an
action run
:
actions:
run:
script: [...]
actions:script
¶
A list of strings, which will be joined by newlines and executed as a shell
script (/bin/sh
, on Unix systems) or a PowerShell script (on Windows
systems). This script is run in a single process (which is useful if you use
variables or change directory).
The script can take arguments using $@
(Shell) or $args
(PowerShell). For
usage details, see the documentation on nitrile do
.
build
¶
In this key a list of build goals can be specified. The content of this key
should be a mapping from goal names to build specifications. The following
example defines the build goals tools
and library
:
build:
tools:
script: [...]
library:
depends: [tools]
required_dependencies: [json]
script: [...]
nitrile build
builds the build goals, taking
depends
into account.
build:depends
¶
A list of build goals that should be built before building this goal.
build:required_dependencies
¶
A list of names of optional dependencies that are required for this specific build job.
Info
Requires format_version
>= 0.4.11.
build:script
¶
This is the actual specification of the build. It consists of a list of build commands.
Currently, the following types of build commands are available:
The list of build commands is converted to a shell script (/bin/sh
, on Unix
systems) or a PowerShell script (on Windows systems). This script is run in a
single process (which is useful if you use variables or change directory).
System commands¶
A system command is a simple shell command:
build:
goal:
script:
- make -C src
On Unix systems, this command is run with /bin/sh
. On Windows, this command
is run with PowerShell.
build:script:clm
¶
With the clm
build type, the clm
make tool can be used to build an
application. This requires base-clm
(or base
) in the
dependencies
.
For example:
dependencies:
base:
version: ^1.0.0
scope: Build
build:
goal:
script:
- clm:
main: app
target: bin/app
For the possible options in the clm
mapping, see
clm_options
. Some additional keys are accepted only here:
main
: the main module of the application to build (without file extension).target
: the file path for the executable. Defaults to the value ofmain
.
build:script:test-runner
¶
This runs the test-runner tool (which is assumed to be installed in
dependencies
or otherwise available). This is mainly useful
in tests:script
, not in build:script
.
For example:
tests:
test-case-1:
script:
- test-runner:
junit_xml: case-1.xml
tests: [./test.sh]
The options are:
output_format
:JSON
to output JSON test events instead of human-readable messages.junit_xml
: the file path to a file to write a JUnit-style report to. This file can then be parsed by GitLab to give test reports on commits and merge requests.tests
: these are the actual tests. A test can be simply the name of an executable. If arguments need to be given, use a mapping, e.g.:{executable: ./test.sh, options: [--my-option]}
.
clm_options
¶
This sets global options for:
They can be overridden there.
General options:
src
: a list of file paths included for just this build goal (seesrc
for the global option).compiler
: the name of a different binary thancocl
(from base-compiler) to use as a compiler (e.g.cocl-itasks
from base-compiler-itasks). This binary should be provided by some package in theexe
directory. On Windows,.exe
is appended to the filename if it does not already end with.exe
.compiler_options
: a list of command line arguments to be passed to the compiler.
Compilation options:
-
undecidable_instances
:true
to allow undecidable instances. This lifts some restrictions (e.g. the coverage condition1) that ensure instance resolution terminates and setting this totrue
may therefore result in non-termination of the compiler.Info
Requires
format_version
>= 0.4.10. -
check_indices
:false
to not generate code to check for out-of-bounds array indexing.Info
The default is
false
withformat_version
<= 0.4.21. -
partial_functions
:Ignore
to ignore partial functions;Warning
to generate warnings;Error
to generate errors. profiling
:NoProfiling
(default),StackTracing
,TimeProfiling
, orCallgraphProfiling
. See here for a description of the different profiling options.generate_descriptors
:true
to generate all descriptors.export_local_labels
:true
to export local labels.bytecode
:true
to enable bytecode generation for the ABC interpreter;null
to disable bytecode generation (the default);prelinked
to enable bytecode generation as well as prelinking for the WebAssembly interpreter. By default, optimized ABC code is used when bytecode generation is turned on. To use unoptimized ABC code, give a mapping:bytecode: {optimize_abc: false, prelink: true}
.list_types
:None
(default),Inferred
,LackingStrictness
, orAll
to either list no function types, list the inferred function types, list the types of functions for which not all strictness information has been exported, or list all function types.warnings
:false
to disable compiler warnings.fusion
:NoFusion
to disable fusion (the default);PlainFusion
to enable fusion on normal functions only;GenericFusion
to enable fusion on generic functions;AllFusion
to enable fusion on both normal and generic functions. Generic fusion may require you to increase the compiler heap size usingcompiler_options: [-h, 512m]
(for instance).
Linker options:
strip
:false
to disable stripping of the final executable.link
: a list of object files that should be linked with the application.post_link
: a file name for a post link step, ornull
to disable the post link step (the default). This should be an executable in aexe
directory of one of the dependencies. On Windows,.exe
is appended to the filename if it does not already end with.exe
. As its arguments it gets the object files that are being linked (except special files like_startup.o
) and-o
followed by the output file path.
Application options:
heap
: a memory size for the maximum heap size of the application. This can be an integer (number of bytes), or the suffixesk
andm
can be used for kilobytes and megabytes.stack
: a memory size for the maximum stack size of the application. This takes the same format as theheap
.print_constructors
:false
to disable printing of constructors of the result by the application.print_result
:false
to disable printing of the result by the application.print_time
:false
to disable printing execution and garbage collection time after termination of the application.wait_for_key_press
:true
to wait for a key press before exiting the program (Windows only).garbage_collector
: can beCopyingCollector
orMarkingCollector
. See this page for a description of the two garbage collectors.
contact_email
¶
An email address where the maintainer can be reached. This field is required to publish a package.
dependencies
¶
The dependencies of the project. This should be specified as a mapping from package names to version constraints, for example:
dependencies:
base: ^2.0
containers: ^1.0
There is also a more verbose format in which other options related to dependencies can be set, such as optionality and scope:
dependencies:
containers:
version: ^1.0
scope: Build
optional: true
When several dependencies have the same options, a shorthand is possible. In
the following example, the last two dependencies have scope: Test
:
dependencies:
base: ^2.0
{scope: Test}:
gast: ^0.4
test-runner: ^2.0
Note
The shorthand syntax requires format_version
>= 0.4.13.
dependencies:optional
¶
Dependencies can be marked as optional when they are not necessary for the package to work. This allows a package to specify a constraint on another package without requiring a user to install that package.
A possible use case is a package that defines types and functions to deal with
some application domain. It may be useful to define common instances for
serialization or testing in the library. However, if an end user does not use
the same serialization or testing methods, it should not be required to install
the corresponding packages. In this case the library can define the instances
in separate modules (e.g., Data.MyDomain.Gast
), and specify the related
dependencies (e.g., gast
) as optional.
In this case, if a project depends on this domain library but not on gast
,
gast
will not be installed:
name: my-domain-library
dependencies:
gast:
version: ^0.2
optional: true
---
name: my-application
dependencies:
my-domain-library: ^1.0
However, if a project depends on the domain library and gast
, the
constraint will be used:
name: my-application
dependencies:
my-domain-library: ^1.0
gast:
version: ^0.2
scope: Test
The benefit is that if the depending project tries to use an incompatible
version of the optional dependency, nitrile fetch
will fail:
name: my-application
dependencies:
my-domain-library: ^1.0
gast:
version: ^0.3
scope: Test
dependencies:scope
¶
Dependencies that are only needed for building or testing the package can be
given scope: Build
or scope: Test
:
dependencies:
base:
version: ^1.0.0
scope: Build
property-tester:
version: ^3.0
scope: Test
By default, the scope is Build
for packages with the type
Application
and Use
for libraries and miscellaneous packages.
The difference between Build
and Use
is that dependencies with the Use
scope propagate, i.e. are required by all packages using this package.
dependencies:version
¶
This key gives the version constraint for a dependency. If there are no other keys, only the version constraint needs to be given:
dependencies:
base: ^1.0 # shorthand for {version: ^1.0}
property-tester:
version: ^3.0
scope: Test
A version constraint has the following syntax, based on
that of npm
:
<Constraint> ::= <ConstraintPart> '||' <Constraint> -- disjunction
| <ConstraintPart>
<ConstraintPart> ::= <ConstraintPart> ' ' <ConstraintPart> -- conjunction
| <Version> '-' <Version> -- inclusive range
| <Limiter> <Version>
<Limiter> ::= '^' -- keep first non-zero
| '~' -- keep minor version
| '>' | '>=' | '<' | '<=' | '='
<Version> ::= <Integer> '.' <Integer> '.' <Integer>
| <Integer> '.' <Integer>
| <Integer>
description
¶
A short description of the project. This field is required to publish a package.
It is advised that the description starts with a capital and ends with a period.
format_version
¶
The version of the nitrile.yml
format used. This allows projects to continue
using an old version of the nitrile.yml
format with a newer version of
Nitrile. When Nitrile encounters a nitrile.yml
in an older format, it will
attempt to migrate the configuration automatically (without writing the new
configuration to nitrile.yml
).
The format_version
increases with the version of Nitrile itself. Therefore, a
format_version
of x.y
is guaranteed to work with Nitrile x.*
, but not
with z.*
. (As long as Nitrile is in the 0.x range, backwards incompatible
changes may be introduced in the minor version).
format_version
defaults to 0.4.4, the version in which the field was
introduced. It is not possible to specify a format version below this version,
as no migrations for these older versions are defined.
Before upgrading the format_version
, the changelog should be
consulted to check for backwards incompatible changes.
license
¶
The SPDX identifier of the license under which the package is distributed. This field is required to publish a package.
maintainer
¶
The name of the project maintainer. This field is required to publish a package.
name
¶
The name of the application or library. This field is required to package or publish a package.
The name may contain only lowercase letters, digits, and hyphens (-
). It must
start with a letter and may not end with a hyphen.
package
¶
This key allows for additional options for the
nitrile package
command.
package:core_modules
¶
For packages that include library modules, this key may contain a list of module name patterns that should be considered ‘core’ modules. This is used by Cloogle, as described here.
This key should contain a list of patterns. Patterns are matched using simple
string equality, but a wildcard (*
) can be used to match any substring. For
example: Lib.Internal.*
.
Info
Note that Internal*
will match Internal
and Internal.X
, but also
InternalX
. On the other hand, Internal.*
will not match InternalX
but
also not match Internal
. To match Internal
and Internal.*
to the
exclusion of Internal*
, use two patterns: Internal
and Internal.*
.
package:exclude
¶
A list of files to exclude from the package. The pattern format is inspired by
that of .gitignore
:
/
is used as a directory separator. Directory separators may occur at the beginning, middle, or end of a pattern.- If there is a separator at a non-final position, the pattern is interpreted as relative to the root directory. Otherwise the pattern may match any leaf in the directory tree.
- If there is a separator at a final position the pattern only matches directories.
- Asterisk (
*
) matches any number of characters except/
; question mark (?
) matches any one character except/
. Character ranges (e.g.[a-z]
) are not supported. **/
at the start,/**
at the end, or/**/
in the middle of a pattern can be used to match any number of directories.
package:extra_files
¶
A list of files that should be included in the package. For example:
package:
extra_files:
- LICENSE
- README.md
Files can be just a file path, in which case the source and destination path
are the same. When they are not the same, a mapping with src
and dst
fields
can be given:
package:
extra_files:
- src: doc/documentation.pdf
dst: documentation.pdf
package:include
¶
By default, only *.icl
and *.dcl
are included in libraries when running
nitrile package
. With this key a list of filename
patterns can be specified that should also be included. This is useful if the
package should include some ABC or object files. For example:
package:
include:
- systemProcessSupport.o
The patterns have the same syntax as in package:exclude
.
rules
¶
This key allows you to specify settings that are only used under certain circumstances. The value should be a mapping from rule conditions to settings. For example:
src:
- src/lib
rules:
posix:
extra_src:
- src/lib-posix
windows:
extra_src:
- src/lib-windows
In this example, we have a directory src/lib
for platform-independent code,
and two additional directories src/lib-posix
and src/lib-windows
, which are
used only on POSIX and Windows systems, respectively.
For a real-world example, see Nitrile’s own package file.
Rule conditions¶
There are a number of basic conditions. These can be conjuncted using and
.
For example, posix and 64bit
matches only 64-bit POSIX platforms.
There is currently no support for disjunctions (i.e., or
) or parentheses.
The basic conditions are:
- For architectures:
arm
andintel
- For bitwidths:
32bit
and64bit
- For platforms:
linux
,mac
, andwindows
There are some shorthands:
arm64
forarm and 64bit
(there is noarm32
)x64
forintel and 64bit
x86
forintel and 32bit
posix
forlinux
ormac
Rule settings¶
The following settings are allowed in rules:
rules:extra_actions
¶
Defines extra actions. See actions
for details.
rules:extra_build
¶
Defines extra build steps. See build
for details.
rules:extra_dependencies
¶
Defines extra dependencies. See dependencies
for details.
rules:extra_package
¶
Defines extra package options. See package
for details.
rules:extra_src
¶
Defines extra source directories. See src
for details.
rules:extra_tests
¶
Defines extra tests. See tests
for details.
src
¶
A list of source directories, for example:
src:
- src
Source directories are available in the include path of build tools like
clm
.
src:path
¶
This key gives the path of the source directory. If there are no other keys, only the path needs to be given:
src:
- src # shorthand for {path: src}
- path: test
scope: Test
src:scope
¶
Source directories that are only needed for building or testing the package can
be given scope: Build
or scope: Test
:
src:
- path: src
scope: Build
- path: test
scope: Test
By default, the scope is Build
for applications and Use
for libraries and
miscellaneous packages (see type
). Directories with scope: Use
are
included when running nitrile package
on a library
package.
tests
¶
A mapping of test cases. Each entry has a name (the key) and a number of options (the value). For example:
builds:
library:
{...}
src:
- path: test
scope: Test
tests:
test case 1:
depends: [library]
script:
- clm:
main: test_case_1
- ./test/test_case_1
expected_result: test/test_case_1.expected_result
Globally, there are three kinds of tests:
-
Those using
script
: thescript
should be an array of commands, similar to thescript
inbuild
sections. The test passes if all steps return exit code 0. It may be useful to usetest-runner
commands in thescript
to use the test-runner tool. -
Those using
expected_result
. There should also be ascript
. The test passes if the output last command in thescript
matches the contents of the file mentioned inexpected_result
. -
Those using
compilation
. This simply checks that each module insrc
can be compiled. -
Those using
properties
. This uses the property-tester tool to collect Gast properties from definition modules and generate test modules for them, which are then run using test-runner.
tests:compilation
¶
A compilation
test simply checks that each module in the src
directories can be compiled.
tests:
compilation:
compilation:
clm_options: { ... }
#only_modules: [ ... ]
#except_modules: [ ... ]
When no options are needed, an empty record can be given:
tests:
compilation:
compilation: {}
Note
Compilation tests are intended as a basic check that code exported to library
users compiles. For this reason, compilation tests only cover modules in directories with
scope: Use
and can only use dependencies with
scope: Use
.
If there is a need to test compilation of modules from other directories,
they can be added to the src
option in
clm_options
.
tests:compilation:clm_options
¶
Allows to specify clm
options for this test only. The record takes the same
form as the global clm_options
setting.
tests:compilation:except_modules
¶
A list of module names that should not be tested. This option is incompatible
with only_modules
.
Note
Requires format_version
>= 0.4.13.
tests:compilation:only_modules
¶
A list of module names that should be tested. Other modules will not be tested.
This option is incompatible with
except_modules
.
Note
Requires format_version
>= 0.4.13.
tests:depends
¶
A list of build goals that should be built before running the test. This takes
the same form as build:depends
.
tests:expected_result
¶
This field can contain a file path. When present, the test only passes if the
output of the last script
command matches the content of this
file.
For a real-world example, see Gast.
Info
On Windows, the output of the script will be forcefully encoded in UTF-8
before checking the result (instead of UTF-16, which is used by default in
PowerShell). Also, \r\n
will be replaced by \n
in both the program output
and the expected_result
file. On other systems, the output of the program
is used as-is.
tests:properties
¶
This allows you to use property-tester to collect Gast properties from
definition modules and generate test modules, which are then run by
test-runner. property-tester and test-runner are assumed to be in
your dependencies
.
property-tester will search for properties in definition modules in
src
.
The execution of property tests may be parallelized over multiple processes by providing the parallel test runner option.
The following options are accepted:
clm_options
: allows setting compilation options for the property modules. The same options as inclm_options
are accepted.junit_xml
: seebuild:script:test-runner
for details.output_format
: seebuild:script:test-runner
for details.test_options
: a list of options for running the tests. These are defined in Gast’sTestoption
type, and can be found when running one of the tests with--help
. For example,Tests 10000
will run 10,000 tests.
Info
The tests are generated in ./nitrile-tests
, so that you can inspect the
generated modules and/or use the generated executables as well.
tests:required_dependencies
¶
A list of names of optional dependencies that are required for this specific
test. This takes the same form as
build:required_dependencies
.
Info
Requires format_version
>= 0.4.11.
tests:script
¶
This field contains a list of commands that are run by the test runner. The exit code of the commands should be 0 for the test to pass.
The same commands are supported as in build:script
.
type
¶
Required. This must be one of Application
, Library
, or Miscellaneous
.
The type influences the way
nitrile package
works, as well as the
default dependency scope
and source directory
scope
.
Other than that, it is just there to indicate to users what kind of project they are dealing with.
url
¶
The URL to the repository of the project.
To publish a package, this field is required and must be a GitLab.com URL, e.g. https://gitlab.com/clean-and-itasks/nitrile. This is because the registry only integrates with GitLab.com.
version
¶
A SemVer 2.0.0-compatible version. (Currently, additional labels for pre-releases are not supported.) This field is required to package or publish a package.
To start, 0.1.0 is a good value. For more details on versioning, see the packaging and publishing checklist.
watch
¶
This key allows for additional options for the
nitrile watch
command.
watch:exclude
¶
A list of strings, which are interpreted as PCRE regular expressions.
nitrile watch
will ignore changes on any file of which the whole name matches
any of these patterns.
iTasks developers may want to use exclude: ['-www/']
.
-
See e.g. Definition 7 in Sulzmann, Martin, et al. “Understanding functional dependencies via constraint handling rules.” Journal of Functional Programming 17.1 (2007): 83-129. ↩