From 83ad890535c6e2f2bb12270b98de81ce6f9c8706 Mon Sep 17 00:00:00 2001 From: Tanguy Date: Tue, 26 Jul 2022 12:44:26 +0200 Subject: [PATCH] Documentation site (#745) --- .github/workflows/doc.yml | 36 ++++++++++++++++++++++++ README.md | 8 ++---- examples/README.md | 6 ++++ examples/tutorial_1_connect.md | 26 +++++++++-------- examples/tutorial_2_customproto.md | 17 ++++++----- libp2p.nim | 2 +- mkdocs.yml | 45 ++++++++++++++++++++++++++++++ 7 files changed, 115 insertions(+), 25 deletions(-) create mode 100644 examples/README.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index dca12d5..862c571 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -61,3 +61,39 @@ jobs: git config --global user.name = "${{ github.actor }}" git commit -a -m "update docs for ${GITHUB_REF##*/}" git push origin gh-pages + + update_site: + if: github.ref == 'refs/heads/master' + name: 'Rebuild website' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - uses: actions/setup-python@v2 + with: + python-version: 3.x + + - name: Generate website + run: pip install mkdocs-material && mkdocs build + + - name: Clone the gh-pages branch + uses: actions/checkout@v2 + with: + repository: status-im/nim-libp2p + ref: gh-pages + path: subdoc + fetch-depth: 0 + + - name: Commit & push + run: | + cd subdoc + + rm -rf docs + mv ../site docs + + git add . + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + git config --global user.name = "${{ github.actor }}" + git commit -a -m "update website" + git push origin gh-pages diff --git a/README.md b/README.md index b67b85b..854a2fd 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@

- +

@@ -49,9 +49,7 @@ nimble install libp2p ``` ## Getting Started -You'll find some tutorials [here](examples/tutorial_1_connect.md), or some examples: -- [hello world (ping)](examples/helloworld.nim) -- [direct chat](examples/directchat.nim) +You'll find the documentation [here].(https://status-im.github.io/nim-libp2p/docs/) **Go Daemon:** Please find the installation and usage intructions in [daemonapi.md](examples/go-daemon/daemonapi.md). @@ -114,8 +112,6 @@ nimble install # run all the unit tests nimble test ``` -The code follows the [Status Nim Style Guide](https://status-im.github.io/nim-style-guide/). - ### Contribute diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..18b6ca8 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,6 @@ +# nim-libp2p documentation + +Welcome to the nim-libp2p documentation! + +Here, you'll find [tutorials](tutorial_1_connect.md) to help you get started, as well as [examples](directchat.nim) and +the [full reference](https://status-im.github.io/nim-libp2p/master/libp2p.html). diff --git a/examples/tutorial_1_connect.md b/examples/tutorial_1_connect.md index 65ff473..0dd6543 100644 --- a/examples/tutorial_1_connect.md +++ b/examples/tutorial_1_connect.md @@ -1,15 +1,18 @@ -Hi all, welcome to the first article of the nim-libp2p's tutorial series! +# Simple ping tutorial -_This tutorial is for everyone who is interested in building peer-to-peer chatting applications. No Nim programming experience is needed._ +Hi all, welcome to the first nim-libp2p tutorial! + +!!! tips "" + This tutorial is for everyone who is interested in building peer-to-peer applications. No Nim programming experience is needed. To give you a quick overview, **Nim** is the programming language we are using and **nim-libp2p** is the Nim implementation of [libp2p](https://libp2p.io/), a modular library that enables the development of peer-to-peer network applications. Hope you'll find it helpful in your journey of learning. Happy coding! ;) -# Before you start +## Before you start The only prerequisite here is [Nim](https://nim-lang.org/), the programming language with a Python-like syntax and a performance similar to C. Detailed information can be found [here](https://nim-lang.org/docs/tut1.html). -Install Nim via their official website: [https://nim-lang.org/install.html](https://nim-lang.org/install.html) +Install Nim via their [official website](https://nim-lang.org/install.html). Check Nim's installation via `nim --version` and its package manager Nimble via `nimble --version`. You can now install the latest version of `nim-libp2p`: @@ -17,10 +20,11 @@ You can now install the latest version of `nim-libp2p`: nimble install libp2p@#master ``` -# A simple ping application +## A simple ping application We'll start by creating a simple application, which is starting two libp2p [switch](https://docs.libp2p.io/concepts/stream-multiplexing/#switch-swarm), and pinging each other using the [Ping](https://docs.libp2p.io/concepts/protocols/#ping) protocol. -_TIP: You can extract the code from this tutorial by running `nim c -r tools/markdown_runner.nim examples/tutorial_1_connect.md` in the libp2p folder!_ +!!! tips "" + You can extract the code from this tutorial by running `nim c -r tools/markdown_runner.nim examples/tutorial_1_connect.md` in the libp2p folder! Let's create a `part1.nim`, and import our dependencies: ```nim @@ -58,17 +62,17 @@ proc main() {.async, gcsafe.} = localAddress = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet() pingProtocol = Ping.new(rng=rng) ``` -We created some variables that we'll need for the rest of the application: the global `rng` instance, our `localAddress`, and an instance of the `Ping` protocol. +We created some variables that we'll need for the rest of the application: the global `rng` instance, our `localAddress`, and an instance of the `Ping` protocol. The address is in the [MultiAddress](https://github.com/multiformats/multiaddr) format. The port `0` means "take any port available". -`tryGet` is procedure which is part of the [nim-result](https://github.com/arnetheduck/nim-result/), that will throw an exception if the supplied MultiAddress is not valid. +`tryGet` is procedure which is part of [nim-result](https://github.com/arnetheduck/nim-result/), that will throw an exception if the supplied MultiAddress is invalid. We can now create our two switches: ```nim let switch1 = createSwitch(localAddress, rng) switch2 = createSwitch(localAddress, rng) - + switch1.mount(pingProtocol) await switch1.start() @@ -76,7 +80,7 @@ We can now create our two switches: ``` We've **mounted** the `pingProtocol` on our first switch. This means that the first switch will actually listen for any ping requests coming in, and handle them accordingly. -Now that we've started the nodes, they are listening for incoming peers. +Now that we've started the nodes, they are listening for incoming peers. We can find out which port was attributed, and the resulting local addresses, by using `switch1.peerInfo.addrs`. We'll **dial** the first switch from the second one, by specifying it's **Peer ID**, it's **MultiAddress** and the **`Ping` protocol codec**: @@ -95,7 +99,7 @@ We now have a `Ping` connection setup between the second and the first switch, w And that's it! Just a little bit of cleanup: shutting down the switches, waiting for them to stop, and we'll call our `main` procedure: ```nim await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports - + waitFor(main()) ``` diff --git a/examples/tutorial_2_customproto.md b/examples/tutorial_2_customproto.md index fc950ee..aa3366c 100644 --- a/examples/tutorial_2_customproto.md +++ b/examples/tutorial_2_customproto.md @@ -1,8 +1,9 @@ +# Custom protocol in libp2p + In the [previous tutorial](tutorial_1_connect.md), we've looked at how to create a simple ping program using the `nim-libp2p`. We'll now look at how to create a custom protocol inside the libp2p -# Custom protocol in libp2p Let's create a `part2.nim`, and import our dependencies: ```nim import chronos @@ -21,7 +22,7 @@ type TestProto = ref object of LPProtocol We've set a [protocol ID](https://docs.libp2p.io/concepts/protocols/#protocol-ids), and created a custom `LPProtocol`. In a more complex protocol, we could use this structure to store interesting variables. -A protocol generally has two part: and handling/server part, and a dialing/client part. +A protocol generally has two part: and handling/server part, and a dialing/client part. Theses two parts can be identical, but in our trivial protocol, the server will wait for a message from the client, and the client will send a message, so we have to handle the two cases separately. Let's start with the server part: @@ -29,13 +30,15 @@ Let's start with the server part: proc new(T: typedesc[TestProto]): T = # every incoming connections will in be handled in this closure proc handle(conn: Connection, proto: string) {.async, gcsafe.} = + # Read up to 1024 bytes from this connection, and transform them into + # a string echo "Got from remote - ", string.fromBytes(await conn.readLp(1024)) # We must close the connections ourselves when we're done with it await conn.close() return T(codecs: @[TestCodec], handler: handle) ``` -This is a constructor for our `TestProto`, that will specify our `codecs` and a `handler`, which will be called for each incoming peer asking for this protocol. +This is a constructor for our `TestProto`, that will specify our `codecs` and a `handler`, which will be called for each incoming peer asking for this protocol. In our handle, we simply read a message from the connection and `echo` it. We can now create our client part: @@ -53,12 +56,12 @@ proc main() {.async, gcsafe.} = testProto = TestProto.new() switch1 = newStandardSwitch(rng=rng) switch2 = newStandardSwitch(rng=rng) - + switch1.mount(testProto) - + await switch1.start() await switch2.start() - + let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) await testProto.hello(conn) @@ -69,7 +72,7 @@ proc main() {.async, gcsafe.} = await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports ``` -This is very similar to the first tutorial's `main`, the only noteworthy difference is that we use `newStandardSwitch`, which is similar to `createSwitch` but is bundled directly in libp2p +This is very similar to the first tutorial's `main`, the only noteworthy difference is that we use `newStandardSwitch`, which is similar to the `createSwitch` of the first tutorial, but is bundled directly in libp2p We can now wrap our program by calling our main proc: ```nim diff --git a/libp2p.nim b/libp2p.nim index 3df1b24..46f8023 100644 --- a/libp2p.nim +++ b/libp2p.nim @@ -8,7 +8,7 @@ # those terms. when defined(nimdoc): - ## Welcome to the nim-libp2p documentation! + ## Welcome to the nim-libp2p reference! ## ## On the left, you'll find a switch that allows you to see private ## procedures. By default, you'll only see the public one (marked with `{.public.}`) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..9c4fcbb --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,45 @@ +site_name: nim-libp2p + +repo_url: https://github.com/status-im/nim-libp2p +repo_name: status-im/nim-libp2p +site_url: https://status-im.github.io/nim-libp2p/docs +edit_uri: edit/unstable/examples/ + +docs_dir: examples + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - admonition + - pymdownx.details + - pymdownx.superfences + +theme: + logo: https://docs.libp2p.io/images/logo_small.png + favicon: https://docs.libp2p.io/images/logo_small.png + name: material + features: + - navigation.instant + - search.highlight + palette: + - scheme: default + primary: blue grey + toggle: + icon: material/toggle-switch + name: Switch to dark mode + + - scheme: slate + primary: blue grey + toggle: + icon: material/toggle-switch-off-outline + name: Switch to light mode + +nav: + - Introduction: README.md + - Tutorials: + - 'Part I: Simple connection': tutorial_1_connect.md + - 'Part II: Custom protocol': tutorial_2_customproto.md + - Reference: '/nim-libp2p/master/libp2p.html'