1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# Contributing
## Workflow
Before beginning any unit of work, you should ensure you have a GitHub issue
detailing the scope of the work. This could be an issue someone else filed and
has been assigned to you (or you've assigned to yourself) or a new issue you
filed specifically for this unit of work. As much as possible, discussion of the
work should take place in the issue. When this is not possible, please update
the issue with relevant details from any offline conversations. Each issue
should provide a clear and thorough history of the work from inception to
completion.
### Branch Names
Every branch that you intend to put up for review must adhere to the form
`i/<N>/<...>`, where `<N>` is the number of the issue that the branch corresponds
to and `<...>` is an optional short description of the branch to aid in
readability. If `<...>` is omitted, the `/` should be omitted as well, which
makes `i/<N>` a well-formed branch name.
### Commits
Commit messages should be written in an imperative style and include a mandatory
short description and optional long description.
```
Require a short description
Optionally add a long description.
```
### Pull Requests and Merges
When your work is ready for review, open a pull request, making sure to link
to the tracking issue in the description, which should be formatted as follows
(where `<N>` is the number of this work's tracking issue):
```
### Description
Resolves #<N>.
Thoroughly describe the changes made.
### Related
Reference any related issues, links, papers, etc. here.
```
Tests will run automatically via GitHub Actions when you open a pull request or
push new commits to an existing pull request.
With current github permissions, a PR is merge-ready after a single approval
from any member of @urbit/runtime. Although anyone can hit the merge button,
defer to the PR author to merge unless it's an urgent hotfix that needs to be
merged ASAP.
Once you've collected and addressed feedback and are ready to merge, merge the
pull request. Use the default commit message which should default to your PR
title and description. Assuming that you properly included the "Resolves #N."
directive in the pull request description, merging will automatically close the
tracking issue associated with the pull request.
## Development Environment
Although you likely have an identity on the live network, developing on the live
network is high-risk and largely unnecessary. Instead, standard practice is to
work on a fake ship. Fake ships use deterministic keys derived from the ship's
address, don't communicate on the live network, and can communicate with other
fake ships over the local loopback.
### Boot a New Fake Ship
To boot a new fake ship, pass the `-F` flag and a valid Urbit ship name to
`urbit`:
```console
$ bazel build :urbit
$ ln -s bazel-bin/pkg/vere/urbit urbit
$ ./urbit -F <ship>
```
By default, booting a fake ship will use the same pre-compiled kernelspace--
a "pill"-- that livenet ships use, which leads to a non-trivial boot time on the
order of tens of minutes. However, using a development specific pill-- a "solid"
pill-- the time to boot a new fake ship can be reduced to a few minutes.
The solid pill (and other pills) live in the [Urbit repo][urbit]. To boot using
the solid pill, download the pill and then run:
```console
$ ./urbit -F <ship> -B solid.pill
```
Instead of downloading the pill, you can also generate one yourself using
[`dojo`][dojo]:
```console
dojo> .urbit/pill +solid
```
This will write the pill to `<pier>/.urb/put/urbit.pill` (note that `<pier>` is
the ship directory), which you can then use to boot a new ship:
```console
$ ./urbit -F <another-ship> -B <pier>/.urb/put/urbit.pill
```
### Launch an Existing Fake Ship
To launch an existing fake ship, supply the pier (the ship directory), which is
simply the name of the ship[^1], to `urbit`:
```console
$ ./urbit <ship>
```
[^1]: Unless you specify the pier using the `-c` flag.
### Enable Language Server Processing
We support the [`clangd`](https://clangd.llvm.org/installation)
language server, which can be installed directly on your system or
via one of the official editor plugins.
After installing `clangd`, configure it to use the following arguments
(location of these arguments may vary depending on your editor plugin or
if you've installed `clangd` directly on your system).
For example, if you use Visual Studio Code, you can add the following to your
user settings:
```json
{
"clangd.arguments": [
"--header-insertion=never",
"--compile-commands-dir=${workspaceFolder}/",
"--query-driver=**",
],
}
```
For other editors, please refer to the
[editor plugin documentation](https://clangd.llvm.org/installation.html#editor-plugins).
Finally, run the following command to generate a `compile_commands.json` file,
which is used by `clangd` to enable all of its features (e.g. code completion,
jump to definition, cross-references, hovering, symbol renaming, etc.):
```console
bazel run //bazel:refresh_compile_commands
```
### Debugging
Prefer GDB for interactive debugging. You need to compile with the symbol table:
```bash
bazel build :urbit --compilation_mode=dbg
gdb --args ./bazel-bin/pkg/vere/urbit zod
```
In GDB, set the following, and any breakpoints (e.g. `break u3m_bail`):
```gdb
set follow-fork-mode child
handle SIGSEGV nostop noprint
```
Then run the Urbit program as usual with `r`.
|