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 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
|
# Foundry
This tool aims to extract much of what makes GNOME Builder an IDE into a
library and companion command-line tool.
Why?
Because it seems like there is an opportunity to bring many of the automatic
IDE features of Builder to a command line environment.
To do this, foundry works similar to other developer environments where you
source a bunch of things into your sub-shell. Except, in Foundry's case, there
is a persistent program that lives above that sub-shell which may be interacted
with using the `foundry` commands.
This persistent ancestor process allows for a build manager, LSP management,
SDK tooling, device management and more to run while you are in your shell.
This is born out of the need for me to have much of my Builder tooling
available even when I am not using Builder directly.
Additionally, if/when Builder were to be rebuilt upon Foundry, it can export
the `FOUNDRY_ADDRESS` to a D-Bus socket allowing the use of foundry within
terminal tabs to interact with the Builder instance directly.
A stretch goal is for Ptyxis to be able to have insight into the Foundry
context for new tabs so that multiple tabs can share the same context.
## Documentation
* [Foundry API Documentation](https://gnome.pages.gitlab.gnome.org/foundry/foundry-1/index.html) can be found here.
* [FoundryGtk API Documentation](https://gnome.pages.gitlab.gnome.org/foundry/foundry-gtk-1/index.html) can be found here.
* [FoundryAdw API Documentation](https://gnome.pages.gitlab.gnome.org/foundry/foundry-adw-1/index.html) can be found here.
Foundry heaviy uses Libdex. Knowing how futures work is required. Knowing how fibers work is also useful.
* [Libdex API Documentation](https://gnome.pages.gitlab.gnome.org/libdex/libdex-1/index.html) can be found here.
## Feature Support
Lots of things are in development, but there is some support for the
following tooling:
### Language Servers
* astro-ls
* bash
* blueprint
* clangd
* elixir
* glsl
* gopls
* intelephense
* jdtls
* jedi
* lua
* mesonlsp
* pyrefly
* python-lsp-server
* ruff
* rust-analyzer
* serve-d
* sourcekit
* ts/js
* ty
* vala
* vhdl
* zls
### Build Systems
* Autotools
* BuildStream
* CMake
* Cargo
* Dub
* Go
* Gradle
* Just
* Make
* Maven
* Meson
* Npm
* PHPize
* Waf
### Container Systems
* Flatpak
* JHBuild
* Podman
* Distrobox
* Toolbx
* Host (via sandbox escapes)
* None (current environment)
### Project Configuration Formats
* BuildConfig (simple GKeyFile from Builder)
* Flatpak Manifests (Both JSON and Yaml)
### Device Integration
* Deviced to communicate to remote devices
* Qemu-user-static to run non-native architectures
### Documentation
* Devhelp2 file-format as exposed by gtk-doc and gi-doc
### Version Control Systems
* Git
### Linters
* Codespell
## Design
The foundry library is built heavily upon libdex which is a library I wrote
based on more than 2 decades of writing both concurrent and parallel programs
and libraries. Libdex is my third attempt at doing so (after libgtask and
libiris).
It combines futures and fibers in a way that makes async C programming
significantly less annoying. Imagine if Threading Building Blocks, Grand
Central Dispatch, twisted deferreds, GTask, and Microsoft CCR had a baby.
It supports wait-free work-stealing along with work-queues which do not suffer
from thundering herd problems thanks to `io_uring` and `EFD_SEMAPHORE`.
I wish I had written it before writing Builder, and this is an attempt to
redo the Builder internals on such a design.
## Subsystems
You can find various subsystems in the `lib/` directory.
Most of them are `FoundryService` which are managed by the `FoundryContext`
which is your top-level object for a project. Use `FoundryService` futures
for tracking when they are ready before using. That provides the ability
to remove most "state tracking" code in the associated tooling.
## Complexity and Fibers
Many things do not need fibers and creating them would be unnecessary.
However, whenever you have something complex that needs to manage multiple
concurrent tasks you should use them. The result is much easier to read and
the points where you become concurrent are much more obvious.
## Life-cycle Tracking
Most of the API reflects that we'll be using fibers heavily and thus having
your stack ripped out from under you at some point. To make this safer most
of the API implicitly increments the reference count.
API that does not increment reference counts use the `get()` semantics while
those that do use the `dup()` semantics.
## Testing
Since we have this available as a tool with a sub-shell I expect that we will
be able to do much improved testing over what was possible within Builder.
Trying to unit test a build pipeline inside of a UI application is quite a
difficult endeavor.
## Some Tooling Ideas
```
# If you're inside a foundry environment subshell, FOUNDRY_ADDRESS
# will be set which will let foundry command to connect to the
# long running instance and keep persistence between runs.
# Clone a project (default to GNOME/)
foundry clone gnome:gnome-builder
foundry clone freedesktop:mesa/mesa
# Init foundry from existing project
foundry init
# Add a new configuration
foundry config add --flatpak org.gnome.Builder.Devel.json
foundry config remove org.gnome.Builder.Devel.json
# Change active configuration
foundry config switch org.gnome.Builder.Devel.json
# Enter a PTY/Shell with the environment
foundry enter
foundry devenv
# Run default run command
foundry run
foundry run my-command
foundry run -- bash
# Add a run command
foundry commands add my-command -- MY=env http-server -d ./
foundry commands add my-group -c my-command1 -c my-command2
# Debug a command
foundry debug my-command -p named-command-in-group
# Run within valgrind
foundry valgrind my-command
# Build the project
foundry build
# Rebuild the project
foundry rebuild
# Install the project
foundry install
# Clean the project
foundry clean
# Set environ on a command
foundry commands set my-command --env=FOO=BAR
# List available SDKs
foundry sdk list
# Install an SDK
foundry sdk install org.gnome.Sdk//master
# Change SDK of configuration
foundry sdk org.gnome.Sdk//master
foundry sdk host
# Spawn a language server w/ stdin/stdout transport
foundry lsp python
foundry lsp rust
# Index source code
foundry index
# Search the source code for class Object
foundry search -c Object
# Search and replace
foundry replace -e MyObject OtherObject
# Profile a command
foundry profile [--command my-command]
# List available devices
foundry device list
# Set current device
foundry device switch host
# Add a device
foundry device add ssh://user@remote
# Deploy project to target device
foundry deploy
# Export the project (to a Flatpak)
foundry export
# List available unit tests
foundry test list
# Run a test
foundry test run testname
# Alias of foundry test run
foundry test
# Debug a test
foundry test debug testname
# Create a new release
foundry release 48.alpha --branch gnome-48 --bump=post
# Reload foundry state (parent process)
foundry reload
# Rename a gobject class
foundry refactor rename class IdeObject FoundryObject
# Reformat a file
foundry format file.c
# List symbols in a file
foundry symbols file.c
# Create a new project from template
foundry create --template name --language c --license gpl3 --git
# List diagnostics from last build
foundry diagnostics list [--error --warning]
# List pipeline
foundry pipeline info
# Add a command in the pipeline at position 10
foundry pipeline add 10 my-command
# Allow Builder to attach to this instance
foundry listen
```
|