Skip to content

The dawn package tool

Dawn is the package tool for Dusk, and like the compiler it is written in Dusk: the compiler/dawn.dusk root sits over the same compiler tree. It fetches external code from git repositories the way Go does: there is no central registry, a package is just a repository you can read, and the import path tells you where the code lives. Dawn installs alongside the dusk compiler; the AUR package builds and installs the two binaries together (see the dusk CLI).

A dusk program pulls in the standard library and local modules with a dotted path, and an external package with its git path in quotes:

@import std.io
@import "github.com/user/repo/module"

The first three segments of a git path, host/user/repo, name the repository. The rest, module, names a file inside it. The import string carries no version yet. Dawn fetches the repository, and the dusk compiler resolves the module from the local cache.

Because the source is the package, there is no registry to run or trust. The same gaps come with that model, and later work will close them: version pinning, a lock file for repeatable builds, and a way to vendor code you do not want to refetch. See limitations below and the roadmap.

Dawn has four commands:

Terminal window
dawn get <file.dusk> # clone the git packages a file imports into the cache
dawn build <file.dusk> # fetch packages, then compile
dawn run <file.dusk> # fetch packages, compile, and run
dawn version # print version

build and run are wrappers: they fetch every git package the file imports, then hand the program to the dusk compiler pipeline. build prints the path of the produced binary, which lands under target/dawn-out. run builds and then executes the binary, and Dawn’s exit code is the program’s exit code. You can also fetch with dawn get and then call dusk directly.

get parses the file’s @import directives, treats every import containing a / as a git package, and shallow-clones each repository it has not already cached. It reports how many packages are ready, printing cached for repositories already present and fetching for new clones.

Any other invocation, including bare dawn, prints the help text. dawn version, --version, and -V all print the version.

Without a built binary, you can build Dawn from a source checkout with the Dusk compiler, or run it straight from source:

Terminal window
dusk build compiler/dawn.dusk # build the dawn binary
dusk run compiler/dawn.dusk get examples/app.dusk # or run straight from source
dusk run compiler/dawn.dusk run examples/app.dusk

Dawn clones each repository into a content cache, and the dusk loader resolves git imports from there. The cache root is $DAWN_CACHE, or ~/.dawn/cache when that is unset. The layout mirrors the import path:

~/.dawn/cache/
github.com/user/repo/ a shallow clone of the repository
module.dusk a module inside it, resolved by an import

An import github.com/user/repo/module resolves to ~/.dawn/cache/github.com/user/repo/module.dusk, or falls back to repo.dusk as a leaf, the same way the stdlib resolves a dotted path. The loader merges the modules it finds, the same as a stdlib import.

Setting $DAWN_CACHE points a build at a clean cache. This is also how Dawn’s own tests check resolution without touching a real home directory.

Dawn shells out to the system git to fetch, so git has to be on your path. Each fetch is a shallow clone (git clone --depth 1) of https://<host>/<user>/<repo> into the cache. If the clone fails or git cannot be spawned, Dawn reports the error and exits nonzero.

The fetch-and-resolve path runs end to end, and it is minimal on purpose. As of v1.4.0:

  • No version selection. The import string carries no version, and an import resolves against the latest clone in the cache. A repository already in the cache is never refetched by get.
  • No lock file. There is no manifest recording resolved versions, so a fresh machine may fetch different bytes than the one that last built the project.
  • No graph fetch. Dawn fetches only the root file’s direct imports, not the imports of the packages it fetches.
  • No integrity check. Fetched modules are not hashed or verified on use.
  • HTTPS only, public repositories. Fetch URLs are constructed as https:// plus the repository path; private repositories with authentication are future work, along with vendoring and offline builds.

The planned order of work (version pinning by git tag or commit, a lock file, graph fetch, integrity hashes, then vendoring and private repositories) is covered on the roadmap.