From 2f7709383f327faf50074cbdb81e53f7ff8525ff Mon Sep 17 00:00:00 2001 From: AXON Date: Sun, 2 Jul 2023 14:46:49 +0600 Subject: [PATCH] Init gitpod.zellij --- .cargo/config.toml.bak | 2 + .github/workflows/release.yaml | 42 ++++ .gitignore | 1 + .gitpod.yml | 8 + Cargo.lock | 415 +++++++++++++++++++++++++++++++++ Cargo.toml | 17 ++ README.md | 45 ++++ install.sh | 23 ++ src/gp_tasks.rs | 98 ++++++++ src/init.rs | 17 ++ src/main.rs | 11 + 11 files changed, 679 insertions(+) create mode 100644 .cargo/config.toml.bak create mode 100644 .github/workflows/release.yaml create mode 100644 .gitignore create mode 100644 .gitpod.yml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100755 install.sh create mode 100644 src/gp_tasks.rs create mode 100644 src/init.rs create mode 100644 src/main.rs diff --git a/.cargo/config.toml.bak b/.cargo/config.toml.bak new file mode 100644 index 0000000..6b77899 --- /dev/null +++ b/.cargo/config.toml.bak @@ -0,0 +1,2 @@ +[build] +target = "wasm32-wasi" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..a61502f --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,42 @@ +name: Release + +permissions: + contents: write + +on: + push: + tags: + - v[0-9]+.* + +jobs: + create-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: taiki-e/create-gh-release-action@v1 + with: + # (required) GitHub token for creating GitHub Releases. + token: ${{ secrets.GITHUB_TOKEN }} + + upload-assets: + strategy: + matrix: + include: + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + build_tool: cross + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: taiki-e/install-action@cross + - uses: taiki-e/upload-rust-binary-action@v1 + with: + # (required) Comma-separated list of binary names (non-extension portion of filename) to build and upload. + # Note that glob pattern is not supported yet. + bin: gitpod_zellij + # (optional) Target triple, default is host triple. + target: ${{ matrix.target }} + # (optional) Tool to build binaries (cargo, or cross) + build_tool: ${{ matrix.build_tool }} + # (required) GitHub token for uploading assets to GitHub Releases. + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..6652a49 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,8 @@ +image: gitpod/workspace-rust:latest + +tasks: + - name: Test plugin + init: cargo build # cache build artifacts using prebuild + command: | + cargo run & + zellij diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a96e693 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,415 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "gitpod_zellij" +version = "0.1.0" +dependencies = [ + "color-eyre", + "regex", + "tracing", + "tracing-error", + "tracing-subscriber", + "which", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "object" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "proc-macro2" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "syn" +version = "2.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f3619c3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "gitpod_zellij" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +color-eyre = "0.6.2" +tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } +tracing = "0.1.37" +tracing-error = "0.2.0" +regex = "1.8.4" +which = "4.4.0" +# dirs = "5.0.1" +# zellij-tile = "0.37.0" + diff --git a/README.md b/README.md new file mode 100644 index 0000000..3cb4386 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +Zellij plugin for Gitpod, with `.gitpod.yml` tasks integration. + + + +# Installation + + + +## Quickstart + +If you want to try it out as is: + +- Go to and scroll down. +- Set as **Dotfiles - Repository URL** and click on `Save`. + +## Custom setup + +If you already have a dotfiles repository that you use on Gitpod, you can copy the contents from [install.sh](./install.sh) and append (while excluding the first shebang line) to your own [installation script](https://www.gitpod.io/docs/configure/user-settings/dotfiles#custom-installation-script). + +# Customization + +## Default editor + +This plugin will spawn an editor in the first tab. It's not necessary for you to specify one, the plugin uses some heuristics to auto detect the available editor. But in case you want to override it, you can do so by creating a variable named `EDITOR` on with a value (e.g. `nvim`) and `*/*` as scope. + +# Roadmap + +This plugin is minimal in its current form. The goal is to have similar features as [gitpod.tmux](https://github.com/axonasif/gitpod.tmux). If you are interested in any of the below features in particular, please [raise an issue](https://github.com/axonasif/gitpod.zellij/issues/new/choose) to let me know. + +- [x] `.gitpod.yml` tasks integration +- [ ] Resource meters: CPU, DISK and MEMORY +- [ ] Custom keybindings +- [ ] Newly opened port notification +- [ ] Functions menu + - [ ] Manage ports + - [ ] Stop workspace +- [ ] Custom Gitpod theme +- [ ] Indicator for dotfiles installation progress +- [ ] Watch `.gitpod.yml` changes for prompting to run `gp validate` + +# Development and contributing + +[![Hack in Gitpod!](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#github.com/axonasif/gitpod.zellij) + +As in [.gitpod.yml](./.gitpod.yml), you will need to run the plugin in the background first and then start zellij: `cargo run & zellij` diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..166e1bd --- /dev/null +++ b/install.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +sudo bash <<'SCRIPT' +# Install latest static zellij +curl -L "https://github.com/zellij-org/zellij/releases/latest/download/zellij-x86_64-unknown-linux-musl.tar.gz" | + tar -C /usr/bin -xzf - zellij + +# Install gitpod.zellij plugin +plugin_path="/usr/bin/gitpod_zellij" +curl -L "https://github.com/axonasif/gitpod.zellij/releases/latest/download/gitpod_zellij-x86_64-unknown-linux-musl.tar.gz" | + tar -C /usr/bin -xzf - gitpod_zellij +SCRIPT + +# Auto start zellij on SSH or xtermjs +cat >>"$HOME/.bashrc" <<'SNIP' +if ! test -v ZELLIJ && ! pgrep -f "$HOME/.vscode-server/bin" 1>/dev/null && (test -v SSH_CONNECTION || test "$PPID" == "$(pgrep -f '/ide/xterm/bin/node /ide/xterm/index.cjs' | head -n1)"); then { + gitpod_zellij & disown + if ! zellij has-sessions 2>/dev/null; then { + exec zellij -s gitpod + } fi + exec zellij attach +} fi +SNIP diff --git a/src/gp_tasks.rs b/src/gp_tasks.rs new file mode 100644 index 0000000..d7d255d --- /dev/null +++ b/src/gp_tasks.rs @@ -0,0 +1,98 @@ +use color_eyre::eyre::{eyre, Report, Result}; +use regex::Regex; +use std::{process::Command, thread::sleep, time::Duration}; +use which::which; + +pub fn attach() -> Result<(), Report> { + // Await for a zellij session + while !Command::new("zellij") + .arg("list-sessions") + .status()? + .success() + { + sleep(Duration::from_secs(1)); + } + + // Rename first tab to editor + let editor_tab_name = "editor"; + Command::new("zellij") + .args(&["action", "rename-tab", editor_tab_name]) + .status()?; + + // Find a usable CLI editor and start it on the first tab + let mut editor: Option = None; + if let Ok(value) = std::env::var("EDITOR") { + if value == "/usr/bin/nano" { + let editors = ["nvim", "vim", "emacs", "helix"]; + for e in editors { + if let Ok(path) = which(e) { + editor = Some(path.to_string_lossy().to_string()); + break; + } + } + } + // In case no match was found (unlikely) + if editor.is_none() { + editor = Some(value); + } + } + Command::new("zellij") + .args(&[ + "action", + "write-chars", + &format!("{}\n", editor.unwrap_or("gp".to_owned())), + ]) + .status()?; + + let gp_tasks_list_raw = Command::new("gp") + .args(&["tasks", "list", "--no-color"]) + .output()?; + if !gp_tasks_list_raw.status.success() { + return Err(eyre!("gp tasks list failed")); + } + let gp_tasks_list_raw = String::from_utf8(gp_tasks_list_raw.stdout)?; + let tasks_re = Regex::new( + r#"\|\s*(?P.{36})\s*\|\s*(?P.*?)\s*\|\s*(?P.*?)\s*\|"#, + )?; + + let mut captures = tasks_re.captures_iter(&gp_tasks_list_raw); + captures.next(); // skip the first capture, which is the header + + for capture in captures { + let task_id = &capture["task_id"]; + let task_name = &capture["task_name"]; + let task_status = &capture["task_status"]; + + if task_status == "stopped" { + continue; + } + + if !Command::new("zellij") + .args(&["action", "new-tab", "--name", task_name]) + .status()? + .success() + { + return Err(eyre!("zellij action new-tab failed for {}", task_name)); + } + + if !Command::new("zellij") + .args(&[ + "action", + "write-chars", + &format!("exec gp tasks attach {task_id}\n"), + ]) + .status()? + .success() + { + return Err(eyre!("zellij action write-chars failed for {}", task_id)); + } + } + + // Switch back to "editor" tab + // NOTE: We could use `zellij action go-to-tab 0` (index) here, but that might not be reliable + Command::new("zellij") + .args(&["action", "go-to-tab-name", editor_tab_name]) + .status()?; + + Ok(()) +} diff --git a/src/init.rs b/src/init.rs new file mode 100644 index 0000000..6b110ee --- /dev/null +++ b/src/init.rs @@ -0,0 +1,17 @@ +use color_eyre::eyre::Result; + +pub fn tracing() -> Result<()> { + use tracing_error::ErrorLayer; + use tracing_subscriber::prelude::*; + use tracing_subscriber::{fmt, EnvFilter}; + + let fmt_layer = fmt::layer().with_target(true).pretty(); + let filter_layer = EnvFilter::try_from_default_env().or_else(|_| EnvFilter::try_new("warn"))?; + + tracing_subscriber::registry() + .with(filter_layer) + .with(fmt_layer) + .with(ErrorLayer::default()) + .init(); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..25b0414 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,11 @@ +use color_eyre::eyre::Result; +mod gp_tasks; +mod init; + +fn main() -> Result<()> { + init::tracing()?; + color_eyre::install()?; + gp_tasks::attach()?; + + Ok(()) +}