mirror of
https://github.com/qdrant/landing_page.git
synced 2026-09-25 14:08:30 +02:00
217 lines
7.7 KiB
Markdown
217 lines
7.7 KiB
Markdown
# Snippet tools
|
|
|
|
This is a tool to work with code snippets.
|
|
|
|
1. Automated CI type checking of snippets.
|
|
2. Writing new snippets and checking/running/testing them locally.
|
|
This tool hides the complexity of setting up every build system/dev env for each client.
|
|
Also, it supports testing snippets against unreleased versions of clients (from git branches/PRs).
|
|
|
|
|
|
## TL;DR
|
|
|
|
```bash
|
|
cd automation/snippets
|
|
|
|
# Fetch the latest clients
|
|
./docker.sh ./sync-clients.py fetch --csharp --java --typescript
|
|
|
|
# Test whether the snippets compile
|
|
./docker.sh ./check.py build snippets/path/to/snippets/*
|
|
|
|
# Generate the Markdown files
|
|
./docker.sh ./generate-md.py
|
|
```
|
|
|
|
## Usage
|
|
|
|
Use this tooling to write snippets as runnable code, test their validity, and generate Markdown files from them.
|
|
|
|
Place your snippets as code files (for example, `python.py`) in the `qdrant-landing/content/documentation/headless/snippets/` directory. You can organize them in subdirectories. Some languages (like Java) require boilerplate code. This boilerplate code is automatically hidden in the generated Markdown files. Refer to existing snippets for examples.
|
|
|
|
After running `generate-md.py`, the generated Markdown files will be placed in the `generated/` subdirectory next to the code files. You can then include these generated Markdown files in your documentation using the `code-snippet` shortcode:
|
|
|
|
```
|
|
{{< code-snippet path="/documentation/headless/snippets/example/" >}}
|
|
```
|
|
|
|
Your code may need some boilerplate code that you don't want to show in the generated Markdown files. You can hide such code by placing `// @hide` (or `# @hide` for Python) at the end of the line. Entire blocks of code can be hidden by placing `// @hide-start` and `// @hide-end` around the block.
|
|
|
|
You can generate multiple code snippets from one source file by defining "blocks" inside the code. This is useful for tutorials, where later code depends on classes and variables defined in earlier code. Each block becomes its own Markdown snippet, and a Markdown snippet is also generated for the entire file. Use `// @block-start block-name` and `// @block-end block-name` to define a block.
|
|
|
|
Include a block in your documentation using the `code-snippet` shortcode with the `block` parameter:
|
|
|
|
```
|
|
{{< code-snippet path="/documentation/headless/snippets/example/" block="block-name" >}}
|
|
```
|
|
|
|
# Example
|
|
|
|
The following Python code:
|
|
|
|
```python
|
|
some_boilerplate_initialization_code() # @hide
|
|
|
|
print("Hello")
|
|
|
|
# @block-start world
|
|
print("World")
|
|
# @block-end world
|
|
|
|
# @hide-start
|
|
some_boilerplate_cleanup_code()
|
|
# @hide-end
|
|
```
|
|
|
|
Results in the following directory structure:
|
|
|
|
```.
|
|
├── generated
|
|
│ └── python.md
|
|
│ └── world
|
|
│ └── python.md
|
|
├── python.py
|
|
```
|
|
|
|
with `generated/python.md` containing:
|
|
|
|
````
|
|
```python
|
|
print("Hello")
|
|
|
|
print("World")
|
|
```
|
|
````
|
|
|
|
and `generated/world/python.md` containing:
|
|
|
|
````
|
|
```python
|
|
print("World")
|
|
```
|
|
````
|
|
|
|
## Dependencies
|
|
|
|
To convert runnable snippets into markdown ([`generate-md.py`](./generate-md.py)) you need only python with no extra dependencies.
|
|
|
|
To typecheck/build snippets, you need a bunch of tools installed.
|
|
The all-in-one [`Dockerfile`](./docker/Dockerfile) and [`shell.nix`](./shell.nix) are provided.
|
|
Run [`./docker.sh`](./docker.sh) to start a shell in the docker container.
|
|
|
|
On ARM-based macOS, ensure that the Docker Desktop setting "General" > "Virtual Machine Options" > "Use Rosetta for x86\_64/amd64 emulation on Apple Silicon" is selected.
|
|
Note: on macOS, if you see Java compile failures related to `protobuf`, re-running the test will often solve those.
|
|
|
|
|
|
## Workflow: typechecking and running
|
|
|
|
Clone and build clients (latest git versions).
|
|
```bash
|
|
./sync-clients.py fetch --csharp --java --typescript
|
|
```
|
|
|
|
(optional) You might specify particular tags/branches/commits instead.
|
|
```bash
|
|
./sync-clients.py fetch --csharp=1.16.0 --java=b290b14892534fc0d76893d41b8f656855cd589b --typescript=main
|
|
```
|
|
|
|
(optional) Update the lockfiles for templates (see ./sync-clients.py lock --help for syntax).
|
|
```bash
|
|
./sync-clients.py lock --go=v1.16.0 --rust=branch=master --python=tag=v1.16.0
|
|
```
|
|
|
|
Typecheck/build all snippets or a particular language/snippet.
|
|
```bash
|
|
./check.py build
|
|
./check.py build -l csharp,java
|
|
./check.py build ./snippets/create-collection/simple
|
|
./check.py build ./snippets/create-collection/simple/go.go
|
|
```
|
|
|
|
Test all testable snippets against localhost Qdrant instance. (you start it yourself).
|
|
Testable snippets are the ones that have `test.py` file in the same directory.
|
|
```bash
|
|
./check.py test
|
|
```
|
|
|
|
Run a particular snippet without running a test.
|
|
```bash
|
|
./check.py run ./snippets/create-collection/simple/go.go
|
|
```
|
|
|
|
|
|
## Workflow: writing new snippets/converting old ones
|
|
|
|
Convert existing old markdown snippets.
|
|
```bash
|
|
./migrate-snippet.py ./snippets/create-collection/simple/go.md
|
|
```
|
|
Or create new snippets from scratch.
|
|
|
|
To reduce noise, you can hide boilerplate code using special comment:
|
|
```go
|
|
if err != nil { panic(err) } // @hide
|
|
```
|
|
The usual wrapping boileplate like `public static void run() throws Exception {` is already hidden by default.
|
|
|
|
Typecheck/build the snippet.
|
|
```bash
|
|
./check.py build ./snippets/create-collection/simple
|
|
```
|
|
|
|
(Optional) Start Qdrant and run the snippet.
|
|
```bash
|
|
./check.py run ./snippets/create-collection/simple/go.go
|
|
```
|
|
|
|
(Optional) Write `test.py` and test it.
|
|
```bash
|
|
./check.py test ./snippets/create-collection/simple
|
|
```
|
|
|
|
Before committing, regenerate markdown files.
|
|
If migrated, also delete old markdown files.
|
|
```bash
|
|
./generate-md.py
|
|
git rm ./snippets/create-collection/simple/go.md # if migrated
|
|
git add ./snippets/create-collection/simple/generated/go.md # made by generate-md.py
|
|
git add ./snippets/create-collection/simple/go.go
|
|
```
|
|
|
|
|
|
## Architecture
|
|
|
|
For each language, the snippet tester collects all code snippets from the [`snippets/`](../../qdrant-landing/content/documentation/headless/snippets) directory and puts them in a single scratch project in a temporary directory.
|
|
Then those projects are compiled/typechecked.
|
|
Putting all snippets in a single project rather than compiling them one by one saves time: some build systems like `gradle` take a lot of time to spin up.
|
|
|
|
Each supported language has:
|
|
- A template project in [`templates/`](./templates) directory.
|
|
- A Python subclass of `Language` in [`lib/languages/`](./lib/languages). It is responsible for:
|
|
- Creating the scratch project from snippets and the template.
|
|
- Building/typechecking the project.
|
|
- Running a particular snippet for testing.
|
|
- A list of build dependencies in [`docker/Dockerfile`](./docker/Dockerfile) and [`shell.nix`](./shell.nix).
|
|
- A handler in [`sync-clients.py`](./sync-clients.py) to fetch the particular git revision of the client.
|
|
- For Java, C#, Typescript it fetches the client sources to the `clients/` directory, and builds them.
|
|
This directory is gitignored.
|
|
- For Go, Rust, Python it updates the lockfile in the [`templates/`](./templates) directory.
|
|
These lockfiles are checked in this repo.
|
|
|
|
|
|
## Quirks
|
|
|
|
- Sometimes `mypy` (python typechecker) complains at valid code.
|
|
Place this comment at the top of the file to silence it:
|
|
```python
|
|
# mypy: disable-error-code="arg-type"
|
|
```
|
|
- On MacOS, if you see Java compile errors like this:
|
|
```
|
|
> java.io.IOException: Cannot run program "/workspace/automation/snippets/cache/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protoc/3.25.5/601137f5367caaf202a28e3844dd6dbbc77b19af/protoc-3.25.5-linux-x86_64.exe": Exec failed, error: 13 (Permission denied)
|
|
```
|
|
Explicitly set the executable bit on the reported file, for example (from `automation/snippets`):
|
|
```bash
|
|
chmod a+x ./cache/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protoc/3.25.5/601137f5367caaf202a28e3844dd6dbbc77b19af/protoc-3.25.5-linux-x86_64.exe
|
|
```
|