Skip to content

Assets

Assets are remote or local files that are inputs to a build. All assets have SHA-1 or SHA-256 checksums.

Assets are accessed with the get-asset command described in a later section of the document.

Assets are located with one or more URL or file path mirrors:

SchemeWhat
https://HTTP over TLS web asset
http://HTTP web asset
cell://Cell asset
file://Local asset
noneLocal asset

Assets are also created on-demand:

LocationWhat
dk.uWorkspace asset

Each asset is uniquely identified by its SHA256 checksums. That unique identification means that mirrors for assets can be added at any time (including in the future) without triggering rebuilds.

Examples:

https://example.com/asset1.zip
http://example.com/asset2/

Examples:

cell://root/etc/table/dotnet

Cells are local directories within the project structure. The root cell is predefined to be the working directory that the build system was called from.

For example, cell://root/etc/table/dotnet is the local directory etc/table/dotnet within the cell root.

Assets are created by dk.u workspace script's unified.asset declarations. The module-version in the non-workspace section title becomes the base of the asset.

So:

### CommonsBase_GNU.Make.Apparatus@4.4.1
% unified.asset { name="BuildW32Bat", file="assets/p/patched-make-build_w32.bat" }
\dk.asset(byteSize: "11131", checksum: (sha256: "3f9825744b486bc5413806cccbae36a4d354e944765fba68c26d37884369a06d"))\;

creates an asset CommonsBase_GNU.Make.Apparatus.BuildW32Bat@4.4.1 with path -p assets/p/patched-make-build_w32.bat.

Examples:

selfasset://test-origin

provides access to custom Lua rule assets described in later sections like in the following example:

local M = { id = "OurTest_Exec.PostObject.TestRequest@1.0.0" }
rules = build.newrules(M)
function rules.EchoRequest(command, request)
local path = "a/path"
if command == "submit" then
local file = request.io.open("some/asset/file", "w")
request.io.write(file, "This is my asset!\n")
local origin, asset = request.io.toasset(file, {
path = path, origin_name = "test-origin"
})
return {
submit = {
values = {
schema_version = { major = 1, minor = 0 },
bundles = {
{
id = request.submit.outputid,
listing = {
origins = { origin }
},
assets = { asset }
}
}
}
}
}
end
end
return M

request.io.toasset creates the selfasset URLs on-demand.

Examples:

file://C:/source
C:\source
file:///usr/src/main.tar.gz
/usr/src/main.tar.gz
a/b/c

A local asset may be either:

  • a file
  • a directory

A relative file or directory is relative to the workspace directory.

A local directory path is always zipped into a zip archive file, where the Zip Archive Reproducibility (next section) standards will be followed.

For reproducibility, the generated zip archive file will:

  • have the zip last modification time to the earliest datetime (Jan 1, 1980 00:00:00)
  • have each zip entry with its modification time to the earliest datetime (Jan 1, 1980 00:00:00)
  • have each zip file entry set its external file attribute to a Unix "regular file" with rwxr-x--- permissions (octal 0100750). Every entry is marked with these same permissions because, when a zip is created on a Windows host for a Unix target, the creator cannot reliably tell which files are executable; a uniform attribute keeps the archive bytes reproducible regardless of host. This stored attribute does not by itself make files executable on extraction: an extracting command (get-object, run-object, get-asset, ...) writes non-executable files by default and makes executable only the entries matched by its -e GLOB options (see Options: -f FILE and -d DIR and -x GLOB and -e GLOB).
  • compress every entry with the DEFLATE method (zip compression method 8) at compression level 5, even for tiny file entries (nothing is stored uncompressed)
  • always accompany a zip directory entry with a zip64 directory entry
  • produce the DEFLATE bit stream with the reference encoder: the vendored miniz at the commit pinned in MlFront_ZipFile's notes. RFC 1951 admits many valid DEFLATE encodings of the same data, so byte-for-byte reproducibility across implementations depends on using that same encoder. dk0 and dk1 use the native miniz; a JavaScript implementation (dkjs) uses the same miniz compiled to WebAssembly. The archive bytes, and therefore the Z256 of the archive, are then identical across implementations.

The multi-disk-volume "index" archive format, which lets a single entry be fetched from a large remote archive without downloading the whole archive, is specified in MlFront_ZipFile's notes, and the same reference miniz produces it on every implementation.

The asset key of get-asset:

Terminal window
get-asset MODULE@VERSION -p PATH

has the components:

  1. MODULE: Module ID
  2. VERSION: Module Version
  3. PATH: Asset path

The first two (2) components uniquely identify a bundle while the third component uniquely identifies the asset within a bundle like:

"bundles": [
// This is bundle identified by id = MODULE@VERSION
{
"id": "DkDistribution_Std.Bundle@2.4.202508011516-signed",
"listing": {
"origins": [
{
"name": "github-release",
"mirrors": [
"https://github.com/diskuv/dk/releases/download/2.4.202508011516-signed"
]
}
]
},
"assets": [
// This is the asset identified by path = PATH
{
"origin": "github-release",
"path": "SHA256.sig",
"size": 151,
"checksum": {
"sha256": "0d281c9fe4a336b87a07e543be700e906e728becd7318fa17377d37c33be0f75"
}
}
]
}
]