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
|
This repo is for all subprojects.
# Goals of this project
The Omni project is to leverage automation and asymmetries to create wealth. The
target of the wealth is Bitcoin. The means: write everything down, first
in English, then in code.
Resources defined in the repo can be used to quickly create and release
products. New technology shall be prototyped and developed as needed.
Since Bitcoin always goes up, as long as we are acquiring more Bitcoin, then we
are growing our wealth. There is a limit to the amount of wealth that one person
needs, roughly defined as how much is required to live a modest life and provide
for one's family. Once this is achieved, excess wealth shall be deployed to
improve the world through activist entrepreneurship.
# Developer Guide
Here we define the tools and infrastructure for all dev work.
## Goals of the workflow
- have minimal ceremony
- default to asynchrony, but allow for synchronous work when necessary
- automate the boring stuff
- standardize environments, tooling, and versions to minimize friction
while collaborating
- support the longevity and self-sustainability of the project
Ideally, each contributor should be able to go off grid for a day or a
week or more, continue working offline, submit their work when finished,
and have no or minimal conflicts. This also refers to the resilience of
the production systems.
We should never need "out of office" email auto-replies, or urgent
contact. No pager duty, no daily stand-ups. Yes, this policy will affect
what code we write, not just how we write it; that is by design.
## Source Layout
The source tree maps to the module namespace, and roughly follows the Haskell
namespace hierarchy. This is true of all languages: Python, Scheme, Rust, C,
etc.
Namespaces are formatted either as file paths, like `Omni/Dev`, or
dot-separated, like `Omni.Dev`. Parts of the namespace should always be
capitalized.
The namespace for all products that we own is `Biz`, this includes proprietary
applications, products, and related infrastructure.
The `Omni` namespace is used for internal development tooling and infrastructure
that are shared between all other projects.
Stuff that can be open sourced or otherwise externalized should be outside of
`Biz` or `Omni`.
Related code should be kept close together. This means that you should start
with small namespaces: use `Omni/Thing.hs` before `Omni/Thing/Service.hs`. Try
to keep all related code in one spot for as long as possible.
Re-use code from the `Omni/` namespace as much as possible. For example, use
`Omni/Cli.hs` or `Omni/Test.py` instead of trying to roll your own code for cli
parsing or running test suites. If the the namespace doesn't have the feature
you need, then add the feature.
Boundaries and interfaces between namespaces should be singular and
well-defined. Likewise, the functionality and purpose of a particular
namespace should be singular and well-defined. Follow the unix principle
of "do one thing and do it well."
Namespaces are always capitalized. In Scheme and Python this actually translates
quite well and helps distinguish between types/classes/modules and values.
## Available tools
We provide some tools for working with projects in the omnirepo:
### bild
`bild` is our universal build tool. It can build and test everything in the repo.
#### Examples
`bild --test Omni/Bild.hs` will build and test the `Omni/Bild.hs` namespace. Use
this command to run tests for a namespace.
`bild --time 0 Omni/Cloud.nix` will build the `Omni/Cloud.nix` namespace, which
is our cloud VM instance. The `--time 0` argument disables the timeout (which
defaults to 10 minutes), this is useful for longer builds.
`bild --json Omni/Test.hs` this just does the analysis step, and prints a
description of the build as JSON. It will not build anything.
### lint
The `lint` command is a universal lint and formatting tool. It will error if any
lints fail, or if the code is not formatted properly. Use `lint --fix` to
autofix any lints or autoformat where possible.
#### Examples
`lint Omni/Cli.hs` will lint the `Omni/Cli.hs` namespace and report any errors.
`lint --fix **/*.py` will lint and fix all Python files in the repo.
### repl.sh
This is like `nix-shell` but specific to our repo. It will analyze the given
namespace, pull in all necessary dependencies, and start a bash shell or
language-specific repl.
#### Examples
`repl.sh Omni/Bild.hs` this creates a nix shell for the `Omni/Bild.hs`
namespace, and starts a Haskell repl using `ghci` with the namespace already
loaded.
`repl.sh --bash Omni/Log.py` this creates a nix shell for `Omni/Log.py`, but
starts a bash shell for the namespace instead of a Python repl.
## Setting up remote builds
The `Omni.Dev` machine acts as a remote build server and Nix cache. To use it from
your local machine, your public key must be at `Omni/Keys/$USER.pub` and your
user added to `Omni/Users.nix`, then bild will automatically use your key to run
builds on `Omni.Dev`.
To use distributed builds for all nix commands, add the following to your NixOS
configuration:
nix = {
distributedBuilds = true;
buildMachines = [
{
hostName = "dev.simatime.com";
sshUser = "yourUserName";
sshKey = "/path/to/your/private/key";
system = "x86_64-linux";
supportedFeatures = [
"x86_64-linux"
"big-parallel"
];
}
];
};
|