Skip to content

Commit

Permalink
feat(core): add initial edge-type support (#17)
Browse files Browse the repository at this point in the history
* feat(core): add edge-type support
* feat(core): add support for connections, update config
* feat(core): add external file as input
* docs: add demo gif
* docs: minor wording enhancements
  • Loading branch information
etolbakov authored Jun 13, 2023
1 parent 99459d0 commit 4e64a2a
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 48 deletions.
4 changes: 4 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## key features
- external files as `--input-path` parameter
- add edge-type support for services(rectangles) and connections (arrows)
- minor doc improvements (commands examples, demo)
9 changes: 4 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

env:
RUST_TOOLCHAIN: nightly-2023-05-03
BUILD_VERSION_PREFIX: v0.1.4
BUILD_VERSION_PREFIX: v0.1.5
CARGO_PROFILE: release

permissions:
Expand Down Expand Up @@ -134,6 +134,7 @@ jobs:
run: cargo version ; rustc --version ; gcc --version ; g++ --version

- name: Run cargo build
shell: bash
run: cargo build --profile ${{ env.CARGO_PROFILE }} --target ${{ matrix.arch }}

- name: Calculate checksum and rename binary
Expand All @@ -154,12 +155,11 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.file }}.sha256sum
path: target/${{ matrix.arch }}/${{ env.CARGO_PROFILE }}/${{ matrix.file }}.sha256sum
path: target/${{ matrix.arch }}/${{ env.CARGO_PROFILE }}/${{ matrix.file }}.sha256sum

docker:
name: Build docker image
needs: [build-linux, build-macos]
# needs: [build-linux]
runs-on: ubuntu-latest
steps:
- name: Checkout sources
Expand Down Expand Up @@ -222,9 +222,8 @@ jobs:
etolbakov/excalidocker:${{ env.IMAGE_TAG }}
release:
name: Release artifacts
name: Release artifacts
needs: [build-macos, build-linux, docker]
# needs: [build-linux, docker]
runs-on: ubuntu-latest
steps:
- name: Checkout sources
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "excalidocker"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["Evgeny Tolbakov"]
description = "Utility to convert your docker-compose into excalidraw"
Expand All @@ -19,6 +19,10 @@ serde_yaml = "0.9.21"
clap = {version = "4.0.32", features = ["derive"]}
thiserror = "1.0.40"
rand = "0.8.5"
isahc = "1.7"

# https://github.com/sfackler/rust-openssl/issues/1021
openssl = { version = "0.10", features = ["vendored"] }

[profile.release]
debug = false
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

current_dir = $(shell pwd)
docker_image_tag = latest

##########################################################################################
## Development commands
Expand Down Expand Up @@ -31,6 +32,7 @@ clippy:
## 'o' - provided '--output-path' argument
## 's' - provided '--skip-dependencies' argument
## 'c' - provided '--config-path' argument
## 'r' - provided '--input-path' argument has a link to an external (github) file

e1i:
./target/release/excalidocker --input-path ./data/compose/docker-compose.yaml
Expand All @@ -53,8 +55,10 @@ e4ios:
./target/release/excalidocker --skip-dependencies --input-path ./data/compose/docker-compose-very-large.yaml --output-path $(shell pwd)/docker-compose-very-large.excalidraw

d5i:
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -e INPUT_PATH=/tmp/docker-compose.yaml etolbakov/excalidocker:latest > produced-by-image.excalidraw
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -e INPUT_PATH=/tmp/docker-compose.yaml etolbakov/excalidocker:$(docker_image_tag) > produced-by-image.excalidraw
d5ir:
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -e INPUT_PATH=https://github.com/apache/pinot/blob/master/docker/images/pinot/docker-compose.yml etolbakov/excalidocker:$(docker_image_tag) > produced-by-image-remote.excalidraw
d5is:
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -e INPUT_PATH=/tmp/docker-compose.yaml -e SKIP_DEPS=true etolbakov/excalidocker:latest > produced-by-image-no-deps.excalidraw
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -e INPUT_PATH=/tmp/docker-compose.yaml -e SKIP_DEPS=true etolbakov/excalidocker:$(docker_image_tag) > produced-by-image-no-deps.excalidraw
d5ic:
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -v "$(current_dir)/excalidocker-config.yaml:/tmp/excalidocker-config.yaml" -e INPUT_PATH=/tmp/docker-compose.yaml -e CONFIG_PATH=/tmp/excalidocker-config.yaml etolbakov/excalidocker:latest > produced-by-image-config-deps.excalidraw
docker run --rm -v "$(current_dir)/data/compose/:/tmp/" -v "$(current_dir)/excalidocker-config.yaml:/tmp/excalidocker-config.yaml" -e INPUT_PATH=/tmp/docker-compose.yaml -e CONFIG_PATH=/tmp/excalidocker-config.yaml etolbakov/excalidocker:$(docker_image_tag) > produced-by-image-config-deps.excalidraw
73 changes: 62 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
# excalidocker-rs
![GitHub release (latest by date)](https://img.shields.io/github/v/release/etolbakov/excalidocker-rs)
![Docker Pulls](https://img.shields.io/docker/pulls/etolbakov/excalidocker?style=plastic)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
![Maintenance](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)

Rust-based utility to convert docker-compose.yaml files into [excalidraw](https://excalidraw.com/) files.
![excalidocker](./data/img/excalidocker-colour.png)
![excalidocker](./data/img/excalidocker-colour-edge.png)

Key features
=================
- Transform your local docker-compose files into excalidraw with just a single `docker run` command. Showcase your infrastructure designs in a visually appealing and engaging format.
- Convert external docker-compose files into excalidraw by simply providing a Github link. Easy to share and collaborate.
- Available for installation on both Linux and MacOS platforms (amd64/arm64).
- Design customization. Tailor your infrastructure diagrams to your specific needs by customizing font, background colours, styles, etc.

Table of contents
=================
<!--ts-->
* [Motivation](#motivation)
* [Usage](#usage)
* [Docker image](#docker-image)
* [Artefact](#artefact)
* [Binaries](#binaries)
* [Config file](#config-file)
* [Demo](#demo)
* [Installation](#installation)
* [Contributing](#contributing)
* [Roadmap](#roadmap)
Expand All @@ -24,20 +35,49 @@ An idea of writing this utility originates from Robin Moffatt's [tweet](https://
## Usage
### Docker image
🐳 `excalidocker` is available as a [docker image](https://hub.docker.com/r/etolbakov/excalidocker/tags).
Convert docker-compose files without hassle. Use it in Github actions for documentation, presentations, ADRs what have you
Convert docker-compose files without hassle. Use as a Github action for documentation, presentations, ADRs what have you.
The sky is the limit. Get the latest image from [docker hub](https://hub.docker.com/r/etolbakov/excalidocker):
```sh
docker pull etolbakov/excalidocker
docker pull etolbakov/excalidocker:latest
```
Usage example:

Convert a local file:
```sh
docker run --rm -v "$(pwd)/data/compose/:/tmp/" -e INPUT_PATH=/tmp/docker-compose.yaml etolbakov/excalidocker:latest > produced-by-image.excalidraw
docker run --rm \
-v "$(pwd)/data/compose/:/tmp/" \
-e INPUT_PATH=/tmp/docker-compose.yaml \
etolbakov/excalidocker:latest > produced-by-image.excalidraw
```

Convert an external file:
```sh
docker run --rm \
-v "$(pwd)/data/compose/:/tmp/" \
-e INPUT_PATH=https://github.com/apache/pinot/blob/master/docker/images/pinot/docker-compose.yml \
etolbakov/excalidocker:latest > produced-by-image-remote.excalidraw
```
The `produced-by-image.excalidraw` file could be opened in [excalidraw](https://excalidraw.com/) and .... hopefully it won't be too scary 👻 😅.

A produced `excalidraw` file could be opened in [excalidraw](https://excalidraw.com/) and .... hopefully it won't be too scary 👻 😅.

<details>
<summary>Convert a local file proving a config</summary>

The command below shows how to pass the config file for additional customization

```sh
docker run --rm \
-v "$(pwd)/data/compose/:/tmp/" \
-v "$(pwd)/excalidocker-config.yaml:/tmp/excalidocker-config.yaml" \
-e INPUT_PATH=/tmp/docker-compose.yaml \
-e CONFIG_PATH=/tmp/excalidocker-config.yaml \
etolbakov/excalidocker:latest > produced-by-image-config-deps.excalidraw
```
</details>

More command examples are in the [Makefile](/Makefile).

### Artefact
📚 Download the latest artifact from [releases](https://github.com/etolbakov/excalidocker-rs/releases) and ungzip it.
### Binaries
📚 Download the latest artifact for your platform/architecture from [releases](https://github.com/etolbakov/excalidocker-rs/releases) and ungzip it.

To get the `help` menu use:
```sh
Expand Down Expand Up @@ -71,9 +111,20 @@ Usage example:
> and you can open it in the future by double-clicking it just as you can any registered app.
>
> ![mac-warning](./data/img/mac-warning.png)
### Config file
`excalidocker` supports basic customization provided via file, for example [excalidocker-config.yaml](./excalidocker-config.yaml).
At the moment it's possible to customize font, fill type ("hachure","cross-hatch", "solid") and backgroud colours for services and ports.
🎨 `excalidocker` supports basic customization provided via file, for example [excalidocker-config.yaml](./excalidocker-config.yaml).
At the moment it's possible to customize:
- font size and type
- fill type (`hachure`, `cross-hatch`, `solid`)
- backgroud colours for services and ports
- edge type (`sharp`, `round`)
- enable/disable connections (has the same effect as `--skip-dependencies` cli option)
### Demo
🎥 This is a small demo to see the `excalidocker` in action
![excalidocker-demo](./data/img/excalidocker.gif)
## Installation
To build `excalidocker` locally, please follow these steps:
Expand Down
Binary file added data/img/excalidocker-colour-edge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed data/img/excalidocker-colour.png
Binary file not shown.
Binary file added data/img/excalidocker.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions excalidocker-config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
font:
size: 16 # recommended S - 16,M - 20,L - 28, XL - 36
family: 1 # 1 - hand-drawn,2 - normal, 3- code
services:
family: 1 # 1 - hand-drawn, 2 - normal, 3 - code
services: # rectangle
background_color: "#b2f2bb"
fill: "hachure" # "hachure","cross-hatch", "solid"
ports:
fill: "hachure" # "hachure", "cross-hatch", "solid"
edge: "round" # "sharp", "round"
ports: # ellipse
background_color: "#a5d8ff"
fill: "hachure" # "hachure","cross-hatch", "solid"
connections: # arrow
visible: true # true / false
edge: "sharp" # "sharp", "round"
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub enum ExcalidockerError {
FileNotFound{path: String, msg: String},
#[error("Failed to read '{}'. Details: {}", path, msg)]
FileFailedRead{path: String, msg: String},
#[error("Failed to parse '{}'. Details: {}", path, msg)]
FileFailedParsing{path: String, msg: String},
#[error("Failed to download '{}'. Details: {}", path, msg)]
RemoteFileFailedRead{path: String, msg: String},
#[error("Failed to parse provided docker-compose '{}'. Details: {}", path, msg)]
InvalidDockerCompose{path: String, msg: String},
}
47 changes: 44 additions & 3 deletions src/exporters/excalidraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub struct ExcalidrawConfig {
pub font: Font,
pub services: Services,
pub ports: Ports,
pub connections: Connections,
}

#[derive(Debug, Deserialize, Clone)]
Expand All @@ -18,6 +19,7 @@ pub struct Font {
pub struct Services {
pub background_color: String,
pub fill: String,
pub edge: String,
}

#[derive(Debug, Deserialize, Clone)]
Expand All @@ -26,6 +28,12 @@ pub struct Ports {
pub fill: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct Connections {
pub visible: bool,
pub edge: String,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BoundElement {
Expand All @@ -42,6 +50,13 @@ pub struct Binding {
pub gap: u16,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Roundness {
#[serde(rename = "type")]
pub roundness_type: i32,
}

pub fn binding(element_id: String) -> Binding {
Binding {
element_id,
Expand All @@ -57,6 +72,13 @@ pub fn arrow_bounded_element(id: String) -> BoundElement{
}
}

pub fn roundness(edge: String) -> Option<Roundness> {
match edge.as_str() {
"round" => Some(Roundness {roundness_type: 3}),
_ => None
}
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ExcalidrawFile {
Expand Down Expand Up @@ -139,6 +161,7 @@ pub enum Element {
fill_style: String,
stroke_width: i32,
stroke_style: String,
roundness: Option<Roundness>,
roughness: i32,
opacity: i32,
start_binding: Binding,
Expand All @@ -163,6 +186,7 @@ pub enum Element {
stroke_width: i32,
stroke_style: String,
roughness: i32,
roundness: Option<Roundness>,
opacity: i32,
stroke_sharpness: String,
locked: bool,
Expand Down Expand Up @@ -313,6 +337,7 @@ impl Element {
fill_style: String,
stroke_width: i32,
stroke_style: String,
roundness: Option<Roundness>,
opacity: i32,
stroke_sharpness: String,
locked: bool,
Expand All @@ -332,6 +357,7 @@ impl Element {
fill_style,
stroke_width,
stroke_style,
roundness,
roughness: 2, // roughness: 0
opacity,
stroke_sharpness,
Expand All @@ -354,6 +380,7 @@ impl Element {
fill_style: String,
stroke_width: i32,
stroke_style: String,
roundness: Option<Roundness>,
opacity: i32,
stroke_sharpness: String,
locked: bool,
Expand All @@ -373,6 +400,7 @@ impl Element {
stroke_width,
stroke_style,
roughness: 2, // roughness: 0, - strict
roundness,
opacity,
stroke_sharpness,
locked,
Expand Down Expand Up @@ -518,9 +546,19 @@ impl Element {
)
}

pub fn simple_arrow(id: String, x: i32, y: i32, width: i32, height: i32, locked: bool, stroke_style: String, points: Vec<[i32; 2]>,
pub fn simple_arrow(
id: String,
x: i32,
y: i32,
width: i32,
height: i32,
locked: bool,
stroke_style: String,
edge: String,
points: Vec<[i32; 2]>,
start_binding: Binding,
end_binding: Binding) -> Self {
end_binding: Binding
) -> Self {
Self::arrow(
id,
x,
Expand All @@ -535,6 +573,7 @@ impl Element {
elements::FILL_STYLE.into(),
elements::STROKE_WIDTH,
stroke_style,
roundness(edge),
elements::OPACITY,
elements::STROKE_SHARPNESS.into(),
locked,
Expand All @@ -551,7 +590,8 @@ impl Element {
group_ids: Vec<String>,
bound_elements: Vec<BoundElement>,
background_color: String,
fill_style: String,
fill_style: String,
edge: String,
locked: bool) -> Self {
Self::rectangle(
id,
Expand All @@ -567,6 +607,7 @@ impl Element {
fill_style, //elements::FILL_STYLE.into(),
elements::STROKE_WIDTH,
elements::STROKE_STYLE.into(),
roundness(edge),
elements::OPACITY,
elements::STROKE_SHARPNESS.into(),
locked,
Expand Down
Loading

0 comments on commit 4e64a2a

Please sign in to comment.