Packages and Modules

The CUE language defines a set of rules for CUE code organization. CUE code can be organized into modules and packages in a way similar to how go code is organized.

A CUE module is a unit of CUE code release, and it can contain multiple CUE packages.

Structuraly CUE modules are recognized because they contain a cue.mod folder and, within that folder, they contain a module.cue file with metadata about the module. So, for all intends and purposes, a CUE module is a folder with a cue.mod/module.cue structure containing module metadata.

CUE requires only that the module.cue contain a field of type string with the name of the module.

module: "kumori.systems/kumori"

CUE imposes rules for module names: they must consist of a root domain name (e.g. "kumori.systems" in the above example) followed by a path of names (simply "/kumori", in the above example).

Packages

Packages in CUE live within modules. A CUE package in Kumori is a folder containing CUE files starting with a line like this:

package mypackge

That is a file in a kumori CUE file must always start with a package declaration.

Importing packages

Packages can be imported in a CUE file. The syntax is similar to that used in go programs:

import (
  k "kumori.systems/kumori:kumori"
)

The above example shows how to import a package named "kumori.systems/kumori" in a CUE file, while at the same time aliasing its name within the file to k. If an alias is not provided, the name of the package is the basename of its name (in the above example it would have been kumori). This is exactly like go behaves.

Notice that the import path of the package in teh above example is ":kumori", this is the actual name of the package that is being imported. This is necessary when the name of the package is different from that of the basename of the import path. When the basename of the path and the package name are the same, it is not necessary to include the suffix with the package name. To avoid mistakes we advise to always specify the package name, as. as we will see when describing the xref-deprecated:developers:kam.adoc[kam] tool, package names do not coincide usually with the basenames of their import paths.

When importing a package, all its top level fields (normal and definitions) are available within the importing file, prefixed with <alias>.' (e.g., `k.#Version, in the previous import example).

Package names in package declarations are simple names, not paths! Paths are used to direct the import machinery find the actual cue files of the package, as we explain below.

How CUE finds imported packages

When CUE encounters an import statement it proceeds as follows to find the contents of the imported package:

  1. It traverses up the folder structure from the folder where the importing file is.

  2. When it finds a root module folder (remember: having a cue.mod/module.cue stucture) then it checks if the name property of the module is a prefix of the imported package name.

  3. If the prefix property is satisfied, it then checks that from the module’s root folder, it can find a folder following the rest of the package name, and it contains indeed, files belonging to (declaring) the package being imported

  4. If the check in (2) fails, it then searches within cue.mod/pkg of the module for a folder with a path equal to the import path.

  5. If the search in (3) or (4) succeeds, it uses the files in the folder, verifying that they indeed are part of the package.

  6. If the search in (3) and (4) fails, CUE continues its search upward the folder structure, looking for another module root folder. If it finds another one it repeats from step (2)

  7. If no root module folder is found, the import fails.

CUE computes the files belonging to a package by merging all files from the package it finds at the import path plus all files in the folders leading to it from the root of its module. This is a very handy property that the xref-deprecated:developers:kam.adoc[kam] tool takes advantage of to organize module workspaces.