How to setup a Juvix project¶
A juvix project is a collection of juvix modules plus some extra metadata
gathered in a juvix.yaml
file. The most convenient way to create a juvix
project is to run the command:
juvix init
Juvix YAML file¶
A project is rooted in a directory. The root is set by creating a juvix.yaml
,
which contains the following fields, no order is required:
name
version
dependencies
main
The fields are explained below.
- name: This is the name assigned to the project. The name must not be empty
and cannot exceed 100 characters. Lower case letters, digits and hyphen
-
are acceptable characters. The first letter must not be a hyphen. Summarizing, it must match the following regexp:[a-z0-9][a-z0-9-]{0,99}
. - version (optional): The version of the project. It must follow the SemVer specification. If the version is missed then it will be assumed to be 0.0.0.
- main (optional): The main module of the project used as entry point.
- dependencies (optional): The dependencies of the project is given as a list. See below for more information.
Note
As intuition would tell, a Juvix module belongs to a Juvix project if it is placed in the subtree hanging from the root directory. This rule has two exceptions:
- Modules in a hidden (or hanging from a hidden) directory are not part of the
project. E.g., if the root of a project is
dir
, then the moduledir/.d/Lib.juvix
does not belong to the project rooted indir
. - A
juvix.yaml
file shadows otherjuvix.yaml
files in parent directories. E.g. if the root of a project isdir
and the filesdir/juvix.yaml
anddir/nested/juvix.yaml
exist, then the moduledir/nested/Lib.juvix
would belong to the project indir/nested
.
Note
Any Juvix module outside of a project is considered a standalone module and lives in its own (global) project. In other words, there is no need to create a juvix.yaml
file for a standalone module.
Package dependencies¶
In order to specify the list of dependencies for a package, the field
dependencies
has been added to the juvix.yaml
. The dependencies
field is a
list of directories (relative or absolute) or git dependencies. If the
dependency is a directory then its location must contain a juvix.yaml
file. As
expected, if we add a package to the list of dependencies, we will be able to
access its modules through import statements. External dependencies are
supported through git dependencies.
By default, the compiler include the standard library as a dependency, and
therefore a user can use it including the following line in the juvix.yaml
# -- juvix.yaml
dependencies:
- .juvix-build/stdlib/
name: juvix-docs
version: 0.0.0
External dependencies¶
To use external dependencies, it is required to have git
installed. You can
add a git block to the dependencies list:
name: HelloWorld
main: HelloWorld.juvix
dependencies:
- .juvix-build/stdlib
- git:
url: https://my.git.repo
name: myGitRepo
ref: main
version: 0.1.0
Git block required fields:
-
url
: The URL of the git repository -
ref
: The git reference that should be checked out
Note
The values of the name
fields must be unique among the git blocks in the dependencies list.
name
: The name for the dependency. This is used to name the directory of the clone, it is required. Perhaps we could come up with a way to automatically name the clone directory. Current ideas are to somehow encode the URL / ref combination or use a UUID. However, there's some value in having the clone directory named in a friendly way.
Behaviour¶
When dependencies for a package are registered, at the beginning of the compiler pipeline, all remote dependencies are processed:
- If it does not already exist, the remote dependency is cloned to
.juvix-build/deps/$name
git fetch
is run in the clonegit checkout
at the specifiedref
is run in the clone
Note
- Remote dependencies of transitive dependencies are also processed.
- The
git fetch
step is required for the case where the remote is updated.
Lock file
- A lock file is generated in the same directory as for
juvix.yaml
. This file is used to determine if any dependency needs to be updated. If theref
in the lock file does not match theref
in the package file, it is considered out of date.
Fixing errors¶
- Missing fields in the Git dependency block are YAML parse errors
- Duplicate
name
values in the dependencies list is an error thrown when the package file is processed - The
ref
does not exist in the clone or the clone directory is otherwise corrupt. An error with a suggestion tojuvix clean
is given. The package file path is used as the location in the error message. - Other
git
command errors (command not found, etc.), a more verbose error is given with the arguments that were passed to the git command.