Skip to content

Latest commit

 

History

History
240 lines (157 loc) · 12.9 KB

README.md

File metadata and controls

240 lines (157 loc) · 12.9 KB

Developer documentation

Quick start

(This is a short version of the official Holochain install instructions.)

Install required binaries

You will need holochain & hc, lair-keystore, cargo, node, pnpm and wasm-opt installed and available on your path.

The easiest way to do this is using the built-in Nix shell. Simply install Nix and run nix develop at the top level of this repository to load most of the necessary dependencies.

Before doing so you may also enable cachix to get faster installations of the Holochain tooling without compiling yourself:

nix profile install github:cachix/cachix/latest
cachix use holochain-ci

Note that once you have entered the repository's Nix environment for the first time you will then be able to run nix develop --offline to skip any checks for refreshed content against remote versions; which can occasionally lead to unexpected long downloads.

If you do not wish to use Nix you can also try your hand at installing everything manually.

Setup the project

  1. Ensure you've loaded the project Nix env, if in doubt run nix-shell from the repository root.
  2. pnpm i to install node packages
  3. npm run build to compile. You'll see some TypeScript errors when building the GraphQL client which can safely be ignored.

Understanding

To get an initial grasp of the project, at an overview level, check out the separate repository structure document.

Running

An npm start will boot up all development services needed to rebuild the project in realtime. The scripts in package.json are self-documenting and can be used as a reference if you wish to run more fine-grained commands.

  • GraphiQL query interface backed by the ValueFlows GraphQL spec at http://localhost:3000
  • Holochain app websocket RPC interface at ws://localhost:4000
  • Holochain admin websocket RPC interface running on a random port, controlled via hc s call
  • TypeScript compiler daemon for rebuilding vf-graphql-holochain browser module upon changes

:TODO: integrate realtime rebuilding of Rust crates

Contributing

If you are interested in contributing to hREA's development we delightedly review all pull requests. For more engaged contributors wishing to make long-term contributions we have a lightweight coordination workflow we practise together.

For other details related to interacting with this codebase at a technical level, read on.

Environment variables

Scripts in this repository respond to the following env vars:

Execution parameters:

  • HOLOCHAIN_APP_PORT sets the websocket port for the app interface when running the conductor in a development sandbox. See the dht:conductor script in package.json.
  • HOLOCHAIN_DNA_UTIL_PATH works similarly to TRYORAMA_HOLOCHAIN_PATH, but for the hc binary that ships with Holochain. It is called to finalise packaging the bundles in bundles/ and to run the dev environment conductor.

Build parameters:

  • RUN_WASM_OPT=0 to disable the WASM optimisation pass during development, as it can be slow and CPU-intensive.

Test parameters:

  • GRAPHQL_DEBUG=1 will enable debug output for the parameters transmitted and received by the GraphQL connection used in tests.
  • WASM_LOG=debug RUST_LOG="debug,wasmer_compiler_cranelift=error,holochain::core::workflow=error" RUST_BACKTRACE=1 are all set when executing the integration test suite.
  • TRYORAMA_LOG_LEVEL=debug is ALSO required in order to view the logs output from your WASM code

Debugging

Most of the time during development, you won't want to run the whole test suite but rather just those tests you're currently working on. The usual workflow when developing a module in isolation is:

  1. npm run build:holochain:dev from the repository root to rebuild the module(s) you are working on.
  2. TRYORAMA_LOG_LEVEL=debug WASM_LOG=debug RUST_LOG="debug,wasmer_compiler_cranelift=error,holochain::core::workflow=error" RUST_BACKTRACE=1 npx tape test/**/*.js from the test directory to run specific tests, substituting a path to an individual file. Note the env vars used here are needed to obtain debug output from the zome code.

Getting debug output printed to the screen depends on where you are logging from.

  • In your Rust code, prefix any debug logging with some format string, or use named arguments-
     debug!("WARGH {:?}", something);
     debug!(named = somethings, work = "too");
  • In JavaScript code, using console.error instead of console.log will make the output visible, even when piping test output into faucet to reduce verbosity. You might also want to get more depth in your output than the built-in serializers provide, especially when interacting with GraphQL result objects-
     console.error(require('util').inspect(something, { depth: null, colors: true }))

Debug output from the Holochain conductor can be noisy, which is why all test scripts coded in package.json pipe the test output to tap-dot). Remember that you can always add nonsense strings to your debug output and pipe things into | grep 'XXXX' instead of | npx tap-dot if you need to locate something specific and the text is overwhelming.

Another way to reduce noice from the Holochain conductor logs, if you want to go down to debug level logs, is to use a config var like the following for RUST_LOG, which holochain will respect:

RUST_LOG="debug,wasmer_compiler_cranelift=error,holochain::core::workflow=error"

You can learn more here.

Advanced execution

If you look at the commands in package.json you will see that they are namespaced into groups of functionality. You can also see which commands depend on each other. Most of the time it will be more efficient to understand the command structure and run individual commands than it will be to boot the whole system together.

Something you may find painful when debugging is that the react-scripts Webpack configuration used by some UI apps clears the terminal when it is active. To work around this, you can run these commands in separate terminals so that the output is not truncated. Running the system like this would be a case of:

  • Running npm run build first
  • npm run dht in a separate terminal to boot the Holochain conductor
  • npm run dev:graphql:adapter in its own terminal if you plan on editing the GraphQL code & want realtime feedback on your changes
  • npm run dev:graphql:explorer to boot up the GraphiQL app UI to interact with the DNAs, or boot any other UI apps instead

Recommended dev tools

Linters

For Rust, install [Clippy]. rustup component add clippy is executed after setting up the repo, so you should not need to do anything other than setup Rust for your editor:

  • Sublime Text:
    • Rust Enhanced and SublimeLinter-contrib-rustc via Package Control will give you autocomplete and error output upon saving files.
  • VSCode:
    • Install the Rust (rls) extension via the marketplace
    • Set rust-client.disableRustup = false in the editor configuration (Rust versions are managed by Nix)
    • For advanced users you can also setup a language server to get realtime code hinting & errors as you type, for more info, see here.

For JavaScript, install [eslint]. All necessary dependencies should be installed via NPM upon initialising the repository, but you must still configure your editor to show linter output:

  • Sublime Text: - SublimeLinter-eslint and SublimeLinter-tslint are both used, depending on whether editing JS or TS files.
  • VSCode: - Install the ESLint extension via the marketplace.

Editorconfig

This ensures consistency in file formatting. Install a plugin for your editor according to the following:

  • Sublime Text:
    • EditorConfig via Package Control
  • VSCode:
    • EditorConfig for VSCode via the marketplace

File headers

You can configure your editor to automatically add new header comment blocks to files you create.

  • Sublime Text:
    • Install FileHeader via Package Control
    • Go to Preferences > Package Settings > FileHeader > Settings - User to locate your custom_template_header_path
    • Also add this block to your settings:
       "Default": {
       	"author": "YOURNAME",
       	"email": "[email protected]"
       },
      
    • (Note this configuration can also be specified on a per-project basis under settings.FileHeader in your project config JSON file.)
    • Edit files in this folder to set the content to prepend to new files you create.
  • VSCode:
    • :TODO:

Known issues

  • The Visual Studio Code terminal can cause issues with Nix, especially on Windows. Use a standalone terminal instead of the one built in to the editor avoid potential problems.
  • If you get Bad owner or permissions on $HOME/.ssh/config when attempting to use git remote commands or SSH from within the Nix shell, ensure your ~/.ssh/config has 0644 permissions and not 0664.
  • When loading your Nix environment you may encounter the error unknown compression method 'zstd'. If this occurs, ensure you are running Nix v2.4 or above. (See upgrading Nix.)

Gotchas

  • Inconsistent state behaviours in tests:
    • This is most often due to mis-use of await s.consistency() in test code. Ensure that consistency checks are only present after mutation GraphQL operations and JSONRPC calls which modify the source-chain state; i.e. after a GraphQL query one should not perform a consistency wait.
  • Receiving incorrect record IDs when retrieving records:
    • These errors are often encountered when confusing cross-DNA link fields for same-DNA links. Check that you are using the appropriate helpers for the link type (_index vs _remote_index helpers).

Publishing

Publishing Node packages

The JavaScript API client modules are published to NPM with PNPM. You must use PNPM to publish these, since packages contain PNPM-specific workspace metadata that NPM does not know how to deal with.

  • Ensure all packages requiring publication have their version field in package.json updated to reflect the next version to be published.
  • Ensure a successful pnpm run build completes after the version updates are made.
  • Run pnpm -r publish --access public from the root directory to publish all packages with new versions.

Publishing a hApp Release

Publishing a hApp release is actually easy, thanks to the Github Actions automation.

The workflow will automatically create a release on Github, if you tag a commit locally using a correctly formatted string pattern, and push it to github. The string pattern should look similar to happ-0.1.0 or happ-0.0.1-alpha.7.

To do this:

  1. make sure you are on the intended git commit and have no uncommitted changes
  2. make sure your commits are all pushed: git push
  3. perform the git tag: git tag happ-0.0.1
  4. push the git tag: git push --tags
  5. Go to the Github Actions tab and find the latest running workflow named Release. You can track the progress.
  6. Once the build has finished, check the release, and provide release notes and changelog details.
  7. That's it!

TODO: instructions for publishing Rust crates

TODO: instructions for publishing built DNA & zome artifacts to Holochain Devhub

Multi-project setup

For developers who need to work on other ValueFlows-related codebases whilst developing hREA, check out the ValueFlows project metarepo.