Skip to content

Commit 1cbce81

Browse files
committed
doc(project): first draft of readme
1 parent e252ca3 commit 1cbce81

1 file changed

Lines changed: 144 additions & 0 deletions

File tree

crates/project/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,147 @@
11
# miden-project
22

33
This crate defines the interfaces for working with `miden-project.toml` files and the corresponding Miden project metadata.
4+
5+
## Terminology
6+
7+
The following document uses some terminology that may be easier to reason about if you understand the specific definitions we're using for those terms in this context:
8+
9+
- *Package*, a single library, program, or component that can be assembled, linked against, and distributed. A package in binary form is considered _assembled_. We also refer to packages as an organizational unit, i.e. before they are assembled, we organize source code into units that correspond to the packages we intend to produce from that source code. Typically the type of package we're referring to will be clear from context, but if we need to distinguish between them, then we use _assembled package_ to refer to the binary form. For an intuition about packages, you can consider a Miden package roughly equivalent to a Rust crate.
10+
- *Project*, refers to the meta-organization of one or more packages into a single unit. See the definition for _Workspace_ for more details on multi-package projects.
11+
- *Workspace*, refers to a project that contains multiple packages, and can share/inherit dependencies and configuration defined at the workspace level. These work just like Cargo workspaces, if you are familiar with their semantics.
12+
- *Version*, refers to the semantic version of a project/package
13+
- *Digest*, refers to the content digest/hash associated with a specific assembled package. Only assembled packages have content digests. When available for a specific package, the content digest becomes an extension of its _version_, and is taken into account during dependency resolution when a specific digest is required by a dependency spec.
14+
15+
## What is a Miden project?
16+
17+
A Miden project, at its most basic, is comprised of two things:
18+
19+
1. A manifest file (i.e. `miden-project.toml`) which describes the project and its dependencies, as well as configuration for tooling in the Miden ecosystem.
20+
2. The source code of the project. This could be any of the following:
21+
- Miden Assembly
22+
- Rust, using an installed `cargo-miden`/`midenc` toolchain
23+
- Any language that can compile to the Miden VM, specifically, are able to produce Miden packages (i.e. `.masp` files).
24+
- Some combination of the above in one project
25+
26+
The above is the simplest form of project, oriented towards building a single Miden package. However, Miden projects may also be organized into workspaces, similar to how Cargo supports organizing Rust crates into workspaces.
27+
28+
## Workspaces
29+
30+
A Miden workspace is a meta-project that consists of one or more sub-projects that correspond to packages. A workspace is comprised of:
31+
32+
* A workspace-level manifest (i.e. `miden-project.toml`), with workspace-specific syntax, that defines configuration and metadata for the workspace, and is shared amongst members of the workspace.
33+
* One or more subdirectories that contain a Miden project corresponding to a single package. These are the "members" of the workspace.
34+
35+
The benefit of using workspaces is when working with multiple package projects that depend on each other, or which share configuration - as opposed to managing them all independently, which would require much more duplication.
36+
37+
### Defining a workspace
38+
39+
To define a workspace, simply create a new directory, and in that directory,
40+
create a `miden-project.toml` file which contains the following:
41+
42+
```toml
43+
[workspace]
44+
members = []
45+
46+
[workspace.package]
47+
version = "0.1.0"
48+
49+
[dependencies]
50+
```
51+
52+
This represents an empty workspace for a new project at version `0.1.0`.
53+
54+
The next step is to create subdirectories for each sub-project, and initialize those as called for by the tooling of the language used in that project.
55+
56+
For examples of Miden Assembly and Rust-based projects, see the section below titled [Defining a project](#defining-a-project).
57+
58+
## Defining a project
59+
60+
To define a new project, all you need is a new directory containing the source code of the project (organization of which is language-specific), and in that directory, create a `miden-project.toml` which contains at least the following:
61+
62+
```toml
63+
[package]
64+
name = "name"
65+
version = "0.1.0" # or whatever semantic version you like
66+
```
67+
68+
This provides the bare minimum metadata needed to construct a basic package. However, in practice you are likely going to want to define [_targets_](#defining-targets), and declare [_dependencies_](#dependency-management).
69+
70+
### Defining targets
71+
72+
A _target_ corresponds to a specific artifact that you want to produce from the project. Most projects will have a single target, but in some cases multiple targets may be useful, particularly for kernels.
73+
74+
Let's add a target to the `miden-project.toml` of the project we created in the previous section:
75+
76+
```toml
77+
[package]
78+
name = "name"
79+
version = "0.1.0"
80+
81+
# The following target is what would be inferred if no targets were declared
82+
# in this file, also known as the _default target_.
83+
[[target]]
84+
kind = "lib" # the type of artifact we're producing
85+
path = "mod.masm" # the relative path to the root module
86+
namespace = "name" # the root namespace of modules parsed for this target
87+
```
88+
89+
As noted above, we've added a target definition that is equivalent to the default target that is inferred if no targets are explicitly declared: a library, whose root module is expected to be found in `mod.masm`, and whose modules will all belong to the `name` namespace (individual modules will have
90+
their path derived from the directory structure).
91+
92+
There are other types of targets though, currently the available kinds are:
93+
94+
* `library`, `lib` - produce a package which exports one or more procedures that can be called from other artifacts, but cannot be executed by the Miden VM without additional setup. Libraries have no implicit dependency on any particular kernel.
95+
* `executable`, `bin`, or `program` - produce a package which has a single entrypoint, and can be executed by the Miden VM directly. Executables have no dependency on any particular kernel.
96+
* `account-component` - produce a package which is a valid account component in the Miden protocol, and contains all metadata needed to construct that component. This type is only valid in conjunction with the Miden transaction kernel.
97+
* `note-script` - produce a package which is a valid note script in the Miden protocol, and exports the necessary metadata and procedures to construct and execute the note. This type is only valid in conjunction with the Miden transaction kernel.
98+
* `tx-script` - produce a package which is a valid transaction script in the Miden protocol, and exports the necessary metadata and procedures to construct and execute the script. This type is only valid in conjunction with the Miden transaction kernel.
99+
100+
As noted earlier, you may define multiple targets in a single Miden project - however you must then request a specific target when assembling the project.
101+
102+
### Dependency management
103+
104+
A key benefit of Miden project manifests is the ability to declare dependencies on Miden packages, and then use those packages in your project, without having to manage the complexity of working with the contents of those packages yourself.
105+
106+
Dependencies are declared in `miden-project.toml` in one of the following forms:
107+
108+
```toml
109+
[dependencies]
110+
# A semantic version constraint
111+
a = "=0.1.0"
112+
# A specific package, given by its content digest
113+
b = "0x......"
114+
# A path dependency
115+
c = { path = "../c" }
116+
d = { path = "../c", version = "~> 0.1.0" }
117+
# A git dependency
118+
e = { git = "https://github.com/example/e", branch = "main" }
119+
f = { git = "https://github.com/example/f", rev = "deadbeef" }
120+
g = { git = "https://github.com/example/g", rev = "deadbeef", version = "~> 0.1.0" }
121+
```
122+
123+
#### Semantics
124+
125+
* `a` specifies a semantic version requirement, these would be evaluated against a package registry implementation
126+
* `b` specifies a package digest, essentially this acts as a stricter SemVer requirement of the form `=MAJ.MIN.PATCH`, where what is required is a version that has exactly the given digest. This form is also evaluated against a package registry implementation.
127+
* `c` specifies that the package sources (or a package artifact) can be found at the given path. The version is inferred from the package at that path, but is essentially equivalent to `version = "*"`.
128+
* `d` is the same as `c`, except it specifies a semantic version requirement that _MUST_ match the package found at `path`
129+
* `e` specifies that the package sources can be found by cloning the `git` repo, and checking out the `main` branch.
130+
* `f` is the same as `e`, except it provides a specific revision in the `git` repo instead
131+
* `g` is the same as `f`, except it specifies a semantic version requirement that _MUST_ match the package found in the cloned repo
132+
133+
In cases where the dependency is resolved to project sources and _not_ an assembled package, the behavior would be to assemble those dependencies first, and then link against them when assembling the current project. This is most useful when linking against packages which are _not_ contracts, or where the contracts are deployed together as a unit.
134+
135+
**NOTE:** Currently there is no canonical package registry, so the resolution of the first two forms described above is dependent on the specific tool that is doing the resolution, namely, how it populates the package index for the resolver provided by this crate.
136+
137+
### Build profiles
138+
139+
TODO
140+
141+
### Custom package metadata
142+
143+
TODO
144+
145+
### Lint configuration
146+
147+
TODO

0 commit comments

Comments
 (0)