chore: merge release-v0.3.0 into main
This commit is contained in:
+12
-14
@@ -1,25 +1,23 @@
|
||||
### 2023-03-13
|
||||
### 2023-03-30
|
||||
|
||||
### Chores
|
||||
+ Rust 1.68.0 clippy linting, [5582c45403413d3355bbcd629cfad559296f5e5b]
|
||||
+ devcontainer use sparse protocol index, [20b79e9cd5bf75bb253158c0b590284139e0291d]
|
||||
+ dependencies updated, [0c07d4b40607a0eba003b6dcd0345ec0543c6264], [601a73d2c830043a25d64922c4d4aa38f8801912], [5aaa3c1ab08b0c85df9bfce18a3e60206556fa58], [7a1563030e48499da7f41033673c70deefe3de8a], [457157755baa1f9e9cfef9315a7940c357b0953d]
|
||||
+ dependencies updated, [7a9bdc9699594532e17a33e044ca0678693c8d3f], [58e03a750fe89b914b9069cb0c6c02a3d0929439], [b246e8c25af0c5136953afca7c694cda66550d9b]
|
||||
|
||||
### Docs
|
||||
+ README.md and screenshot updated, [73ab7580c61dd59c59f10872629111360afb9033]
|
||||
|
||||
### Features
|
||||
+ increase mpsc channel size from 16 to 32 messages, [924f14e998f79f731447a2eded038eab51f2e932]
|
||||
+ KeyEvents send modifier, so can quit on `ctrl + c`, [598f67c6f6a8713102bcc415f0409911763bb914]
|
||||
+ only send relevant mouse events to input handler, [507660d835d0beaa8cd021110401ecc58c0613c6]
|
||||
+ Ability to delete a container, be warned, as this will force delete, closes #27, [937202fe34d1692693c62dd1a7ad19db37651233], [b25f8b18f4f2acd5c9af4a1d40655761d1bd720e]
|
||||
+ Publish images to `ghcr.io` as well as Docker Hub, and correctly tag images with `latest` and the current sermver, [cb1271cf7f21c898020481ad85914a3dcc83ec93]
|
||||
+ Replace `tui-rs` with [ratatui](https://github.com/tui-rs-revival/ratatui), [d431f850219b28af2bc45f3b6917377604596a40]
|
||||
|
||||
### Fixes
|
||||
+ GitHub workflow on SEMEVR tag only, [140773865165bf006e74f9d436fc744220f5eae7]
|
||||
+ out of bound bug in `heading_bar()`, [b9c125da46fe0eb4aae15c354d87ac824e9cb83a]
|
||||
+ `-d` arg error text updated, [e0b49be84062abdfcb636418f57043fad37d06ec]
|
||||
|
||||
### Refactors
|
||||
+ replace `unwrap_or(())` with `.ok()`, [8ba37a165bb89277ab957194da6464bdb35be2e6]
|
||||
+ use `unwrap_or_default()`, [79de92c3921702417bb2df1f44939a7b09cb7fa0]
|
||||
+ Result return, [d9f0bd5566e27218b8c8eaba6ece237907771c1d]
|
||||
|
||||
### Reverts
|
||||
+ temporary devcontainer buildkit fix removed, [d1497a4451f4de54d3cc26c5a3957cd636c29118]
|
||||
+ `popup()` use `saturating_x()` rather than `checked_x()`, [d628e8029942916053b3b7e72d363b1290fc5711]
|
||||
+ button_item() include brackets, [7c92ffef7da20143a31706a310b5e6f2c3e0554f]
|
||||
|
||||
|
||||
see <a href='https://github.com/mrjackwills/oxker/blob/main/CHANGELOG.md'>CHANGELOG.md</a> for more details
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 108 KiB |
@@ -5,6 +5,7 @@ on:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
jobs:
|
||||
deploy:
|
||||
# Change this to latest - or ubuntu 20.04?
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -64,23 +65,39 @@ jobs:
|
||||
- name: compress windows_x86_64 binary
|
||||
run: zip -j ./oxker_windows_x86_64.zip target/x86_64-pc-windows-gnu/release/oxker.exe
|
||||
|
||||
###############################
|
||||
## Build images for Dockerhub #
|
||||
###############################
|
||||
#########################################
|
||||
## Build images for Dockerhub & ghcr.io #
|
||||
#########################################
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Write release version to env
|
||||
run: |
|
||||
CURRENT_SEMVER=${GITHUB_REF_NAME#v}
|
||||
echo "CURRENT_SEMVER=$CURRENT_SEMVER" >> $GITHUB_ENV
|
||||
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
id: buildx
|
||||
with:
|
||||
install: true
|
||||
- name: Build for Docker Hub
|
||||
- name: Build for Dockerhub & ghcr.io
|
||||
run: |
|
||||
docker build --platform linux/arm/v6,linux/arm64,linux/amd64 \
|
||||
-t ${{ secrets.DOCKERHUB_USERNAME }}/oxker:latest \
|
||||
-t ${{ secrets.DOCKERHUB_USERNAME }}/oxker:${{env.CURRENT_SEMVER}} \
|
||||
-t ghcr.io/${{ github.repository_owner }}/oxker:latest \
|
||||
-t ghcr.io/${{ github.repository_owner }}/oxker:${{env.CURRENT_SEMVER}} \
|
||||
--push \
|
||||
-f containerised/Dockerfile .
|
||||
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
# <a href='https://github.com/mrjackwills/oxker/releases/tag/v0.3.0'>v0.3.0</a>
|
||||
### 2023-03-30
|
||||
|
||||
### Chores
|
||||
+ dependencies updated, [7a9bdc96](https://github.com/mrjackwills/oxker/commit/7a9bdc9699594532e17a33e044ca0678693c8d3f), [58e03a75](https://github.com/mrjackwills/oxker/commit/58e03a750fe89b914b9069cb0c6c02a3d0929439), [b246e8c2](https://github.com/mrjackwills/oxker/commit/b246e8c25af0c5136953afca7c694cda66550d9b)
|
||||
|
||||
### Docs
|
||||
+ README.md and screenshot updated, [73ab7580](https://github.com/mrjackwills/oxker/commit/73ab7580c61dd59c59f10872629111360afb9033)
|
||||
|
||||
### Features
|
||||
+ Ability to delete a container, be warned, as this will force delete, closes [#27](https://github.com/mrjackwills/oxker/issues/27), [937202fe](https://github.com/mrjackwills/oxker/commit/937202fe34d1692693c62dd1a7ad19db37651233), [b25f8b18](https://github.com/mrjackwills/oxker/commit/b25f8b18f4f2acd5c9af4a1d40655761d1bd720e)
|
||||
+ Publish images to `ghcr.io` as well as Docker Hub, and correctly tag images with `latest` and the current sermver, [cb1271cf](https://github.com/mrjackwills/oxker/commit/cb1271cf7f21c898020481ad85914a3dcc83ec93)
|
||||
+ Replace `tui-rs` with [ratatui](https://github.com/tui-rs-revival/ratatui), [d431f850](https://github.com/mrjackwills/oxker/commit/d431f850219b28af2bc45f3b6917377604596a40)
|
||||
|
||||
### Fixes
|
||||
+ out of bound bug in `heading_bar()`, [b9c125da](https://github.com/mrjackwills/oxker/commit/b9c125da46fe0eb4aae15c354d87ac824e9cb83a)
|
||||
+ `-d` arg error text updated, [e0b49be8](https://github.com/mrjackwills/oxker/commit/e0b49be84062abdfcb636418f57043fad37d06ec)
|
||||
|
||||
### Refactors
|
||||
+ `popup()` use `saturating_x()` rather than `checked_x()`, [d628e802](https://github.com/mrjackwills/oxker/commit/d628e8029942916053b3b7e72d363b1290fc5711)
|
||||
+ button_item() include brackets, [7c92ffef](https://github.com/mrjackwills/oxker/commit/7c92ffef7da20143a31706a310b5e6f2c3e0554f)
|
||||
|
||||
# <a href='https://github.com/mrjackwills/oxker/releases/tag/v0.2.5'>v0.2.5</a>
|
||||
### 2023-03-13
|
||||
|
||||
|
||||
Generated
+253
-162
@@ -12,10 +12,50 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.69"
|
||||
name = "anstream"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||
checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-wincon",
|
||||
"concolor-override",
|
||||
"concolor-query",
|
||||
"is-terminal",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
@@ -131,42 +171,47 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.8"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
|
||||
checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"unicase",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.8"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0"
|
||||
checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.2"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
@@ -178,28 +223,27 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concolor-override"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
|
||||
|
||||
[[package]]
|
||||
name = "concolor-query"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.26.1"
|
||||
@@ -227,9 +271,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.92"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72"
|
||||
checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
@@ -239,9 +283,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.92"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613"
|
||||
checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
@@ -249,35 +293,35 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.92"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97"
|
||||
checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.92"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
|
||||
checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -307,47 +351,47 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
|
||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
|
||||
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.27"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
|
||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
@@ -493,16 +537,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
version = "0.1.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
|
||||
checksum = "716f12fbcfac6ffab0a5e9ec51d0a0ff70503742bb2dc7b99396394c9dc323f0"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -527,9 +571,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@@ -538,19 +582,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.6"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
|
||||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.4"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857"
|
||||
checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
@@ -596,9 +641,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
@@ -619,12 +664,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.6"
|
||||
@@ -682,12 +721,6 @@ version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
@@ -696,19 +729,19 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "oxker"
|
||||
version = "0.2.5"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bollard",
|
||||
"cansi",
|
||||
"clap",
|
||||
"crossterm 0.26.1",
|
||||
"crossterm",
|
||||
"futures-util",
|
||||
"parking_lot",
|
||||
"ratatui",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tui",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@@ -758,7 +791,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -779,35 +812,11 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.52"
|
||||
version = "1.0.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
|
||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -851,6 +860,19 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"crossterm",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@@ -862,9 +884,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.9"
|
||||
version = "0.37.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
|
||||
checksum = "0e78cc525325c06b4a7ff02db283472f3c042b7ff0c391f96c6d5ac6f4f91b75"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@@ -894,29 +916,29 @@ checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.155"
|
||||
version = "1.0.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71f2b4817415c6d4210bfe1c7bfcf4801b2d904cb4d0e1a8fdb651013c9e86b8"
|
||||
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.155"
|
||||
version = "1.0.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630"
|
||||
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.94"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -925,13 +947,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "395627de918015623b32e7669714206363a7fc00382bf477e72c1f7533e8eafc"
|
||||
checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1042,6 +1064,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
@@ -1053,22 +1086,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1125,14 +1158,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.26.0"
|
||||
version = "1.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
|
||||
checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
@@ -1145,13 +1177,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1194,7 +1226,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1238,19 +1270,6 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "tui"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"crossterm 0.25.0",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
@@ -1262,9 +1281,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.11"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
@@ -1304,6 +1323,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.0"
|
||||
@@ -1363,7 +1388,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -1385,7 +1410,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -1427,13 +1452,22 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2649ff315bee4c98757f15dac226efe3d81927adbb6e882084bb1ee3e0c330a7"
|
||||
dependencies = [
|
||||
"windows-targets 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1442,13 +1476,28 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_gnullvm 0.42.2",
|
||||
"windows_aarch64_msvc 0.42.2",
|
||||
"windows_i686_gnu 0.42.2",
|
||||
"windows_i686_msvc 0.42.2",
|
||||
"windows_x86_64_gnu 0.42.2",
|
||||
"windows_x86_64_gnullvm 0.42.2",
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f8996d3f43b4b2d44327cd71b7b0efd1284ab60e6e9d0e8b630e18555d87d3e"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.47.0",
|
||||
"windows_aarch64_msvc 0.47.0",
|
||||
"windows_i686_gnu 0.47.0",
|
||||
"windows_i686_msvc 0.47.0",
|
||||
"windows_x86_64_gnu 0.47.0",
|
||||
"windows_x86_64_gnullvm 0.47.0",
|
||||
"windows_x86_64_msvc 0.47.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1457,38 +1506,80 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7"
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "oxker"
|
||||
version = "0.2.5"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
authors = ["Jack Wills <email@mrjackwills.com>"]
|
||||
description = "A simple tui to view & control docker containers"
|
||||
@@ -15,14 +15,14 @@ categories = ["command-line-utilities"]
|
||||
anyhow = "1.0"
|
||||
bollard = "0.14"
|
||||
cansi = "2.2"
|
||||
clap={version="4.1", features = ["derive", "unicode", "color"] }
|
||||
clap={version="4.2", features = ["derive", "unicode", "color"] }
|
||||
crossterm = "0.26"
|
||||
futures-util = "0.3"
|
||||
parking_lot = {version= "0.12"}
|
||||
tokio = {version = "1.26", features=["full"]}
|
||||
tokio = {version = "1.27", features=["full"]}
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3"
|
||||
tui = "0.19"
|
||||
ratatui = "0.20"
|
||||
uuid = {version = "1.3", features = ["v4", "fast-rng"]}
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Built in <a href='https://www.rust-lang.org/' target='_blank' rel='noopener noreferrer'>Rust</a>, making heavy use of <a href='https://github.com/fdehau/tui-rs' target='_blank' rel='noopener noreferrer'>tui-rs</a> & <a href='https://github.com/fussybeaver/bollard' target='_blank' rel='noopener noreferrer'>Bollard</a>
|
||||
Built in <a href='https://www.rust-lang.org/' target='_blank' rel='noopener noreferrer'>Rust</a>, making heavy use of <a href='https://github.com/tui-rs-revival/ratatui' target='_blank' rel='noopener noreferrer'>ratatui</a> & <a href='https://github.com/fussybeaver/bollard' target='_blank' rel='noopener noreferrer'>Bollard</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -27,12 +27,21 @@ cargo install oxker
|
||||
```
|
||||
|
||||
### Docker
|
||||
Published on <a href='https://hub.docker.com/r/mrjackwills/oxker' target='_blank' rel='noopener noreferrer'>Docker Hub</a>, with images built for `linux/amd64`, `linux/arm64`, and `linux/arm/v6`
|
||||
|
||||
Published on <a href='https://hub.docker.com/r/mrjackwills/oxker' target='_blank' rel='noopener noreferrer'>Docker Hub</a> and <a href='https://ghcr.io/mrjackwills/oxker' target='_blank' rel='noopener noreferrer'>ghcr.io</a>,
|
||||
with images built for `linux/amd64`, `linux/arm64`, and `linux/arm/v6`
|
||||
|
||||
**via Docker Hub**
|
||||
```shell
|
||||
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock:ro --pull=always mrjackwills/oxker
|
||||
```
|
||||
|
||||
**via ghcr.io**
|
||||
|
||||
```shell
|
||||
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock:ro --pull=always ghcr.io/mrjackwills/oxker
|
||||
```
|
||||
|
||||
### Nix
|
||||
Using nix flakes, oxker can be ran directly with
|
||||
|
||||
@@ -68,7 +77,7 @@ rm oxker_linux_x86_64.tar.gz oxker
|
||||
|
||||
or, for automatic platform selection, download, and installation (to `$HOME/.local/bin`)
|
||||
|
||||
*One should always verify script content before running in a shell*
|
||||
*One should always verify <a href='https://github.com/mrjackwills/oxker/blob/main/install.sh' target='_blank' rel='noopener noreferrer'>script content</a> before running in a shell*
|
||||
|
||||
```shell
|
||||
curl https://raw.githubusercontent.com/mrjackwills/oxker/main/install.sh | bash
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
fmt,
|
||||
};
|
||||
|
||||
use tui::{
|
||||
use ratatui::{
|
||||
style::Color,
|
||||
widgets::{ListItem, ListState},
|
||||
};
|
||||
@@ -207,6 +207,7 @@ pub enum DockerControls {
|
||||
Start,
|
||||
Stop,
|
||||
Unpause,
|
||||
Delete,
|
||||
}
|
||||
|
||||
impl DockerControls {
|
||||
@@ -216,6 +217,7 @@ impl DockerControls {
|
||||
Self::Restart => Color::Magenta,
|
||||
Self::Start => Color::Green,
|
||||
Self::Stop => Color::Red,
|
||||
Self::Delete => Color::Gray,
|
||||
Self::Unpause => Color::Blue,
|
||||
}
|
||||
}
|
||||
@@ -223,11 +225,11 @@ impl DockerControls {
|
||||
/// Docker commands available depending on the containers state
|
||||
pub fn gen_vec(state: State) -> Vec<Self> {
|
||||
match state {
|
||||
State::Dead | State::Exited => vec![Self::Start, Self::Restart],
|
||||
State::Paused => vec![Self::Unpause, Self::Stop],
|
||||
State::Restarting => vec![Self::Stop],
|
||||
State::Running => vec![Self::Pause, Self::Restart, Self::Stop],
|
||||
_ => vec![],
|
||||
State::Dead | State::Exited => vec![Self::Start, Self::Restart, Self::Delete],
|
||||
State::Paused => vec![Self::Unpause, Self::Stop, Self::Delete],
|
||||
State::Restarting => vec![Self::Stop, Self::Delete],
|
||||
State::Running => vec![Self::Pause, Self::Restart, Self::Stop, Self::Delete],
|
||||
_ => vec![Self::Delete],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,6 +238,7 @@ impl fmt::Display for DockerControls {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let disp = match self {
|
||||
Self::Pause => "pause",
|
||||
Self::Delete => "delete",
|
||||
Self::Restart => "restart",
|
||||
Self::Start => "start",
|
||||
Self::Stop => "stop",
|
||||
|
||||
+11
-1
@@ -1,7 +1,7 @@
|
||||
use bollard::models::ContainerSummary;
|
||||
use core::fmt;
|
||||
use ratatui::widgets::{ListItem, ListState};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tui::widgets::{ListItem, ListState};
|
||||
|
||||
mod container_state;
|
||||
|
||||
@@ -456,6 +456,15 @@ impl AppData {
|
||||
self.containers.items.iter_mut().find(|i| &i.id == id)
|
||||
}
|
||||
|
||||
/// return a mutable container by given id
|
||||
pub fn get_container_name_by_id(&mut self, id: &ContainerId) -> Option<String> {
|
||||
self.containers
|
||||
.items
|
||||
.iter_mut()
|
||||
.find(|i| &i.id == id)
|
||||
.map(|i| i.name.clone())
|
||||
}
|
||||
|
||||
/// Find the id of the currently selected container.
|
||||
/// If any containers on system, will always return a ContainerId
|
||||
/// Only returns None when no containers found.
|
||||
@@ -532,6 +541,7 @@ impl AppData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trim a &String and return String
|
||||
let trim_owned = |x: &String| x.trim().to_owned();
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ use crate::app_data::ContainerId;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DockerMessage {
|
||||
Update,
|
||||
Start(ContainerId),
|
||||
Restart(ContainerId),
|
||||
Delete(ContainerId),
|
||||
ConfirmDelete(ContainerId),
|
||||
Pause(ContainerId),
|
||||
Unpause(ContainerId),
|
||||
Stop(ContainerId),
|
||||
Quit,
|
||||
Restart(ContainerId),
|
||||
Start(ContainerId),
|
||||
Stop(ContainerId),
|
||||
Unpause(ContainerId),
|
||||
Update,
|
||||
}
|
||||
|
||||
+31
-2
@@ -1,5 +1,8 @@
|
||||
use bollard::{
|
||||
container::{ListContainersOptions, LogsOptions, StartContainerOptions, Stats, StatsOptions},
|
||||
container::{
|
||||
ListContainersOptions, LogsOptions, RemoveContainerOptions, StartContainerOptions, Stats,
|
||||
StatsOptions,
|
||||
},
|
||||
service::ContainerSummary,
|
||||
Docker,
|
||||
};
|
||||
@@ -335,13 +338,14 @@ impl DockerData {
|
||||
}
|
||||
|
||||
/// Handle incoming messages, container controls & all container information update
|
||||
/// Spawn dowcker commands off into own thread
|
||||
/// Spawn Docker commands off into own thread
|
||||
async fn message_handler(&mut self) {
|
||||
while let Some(message) = self.receiver.recv().await {
|
||||
let docker = Arc::clone(&self.docker);
|
||||
let gui_state = Arc::clone(&self.gui_state);
|
||||
let app_data = Arc::clone(&self.app_data);
|
||||
let uuid = Uuid::new_v4();
|
||||
// TODO need to refactor these
|
||||
match message {
|
||||
DockerMessage::Pause(id) => {
|
||||
tokio::spawn(async move {
|
||||
@@ -397,6 +401,31 @@ impl DockerData {
|
||||
});
|
||||
self.update_everything().await;
|
||||
}
|
||||
DockerMessage::Delete(id) => {
|
||||
tokio::spawn(async move {
|
||||
let loading_spin = Self::loading_spin(uuid, &gui_state).await;
|
||||
if docker
|
||||
.remove_container(
|
||||
id.get(),
|
||||
Some(RemoveContainerOptions {
|
||||
v: false,
|
||||
force: true,
|
||||
link: false,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
Self::set_error(&app_data, DockerControls::Stop, &gui_state);
|
||||
}
|
||||
Self::stop_loading_spin(&gui_state, &loading_spin, uuid);
|
||||
});
|
||||
self.update_everything().await;
|
||||
self.gui_state.lock().set_delete_container(None);
|
||||
}
|
||||
DockerMessage::ConfirmDelete(id) => {
|
||||
self.gui_state.lock().set_delete_container(Some(id));
|
||||
}
|
||||
DockerMessage::Update => self.update_everything().await,
|
||||
DockerMessage::Quit => {
|
||||
self.spawns
|
||||
|
||||
+71
-22
@@ -8,18 +8,18 @@ use crossterm::{
|
||||
execute,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use ratatui::layout::Rect;
|
||||
use tokio::{
|
||||
sync::mpsc::{Receiver, Sender},
|
||||
task::JoinHandle,
|
||||
};
|
||||
use tui::layout::Rect;
|
||||
|
||||
mod message;
|
||||
use crate::{
|
||||
app_data::{AppData, DockerControls, Header},
|
||||
app_error::AppError,
|
||||
docker_data::DockerMessage,
|
||||
ui::{GuiState, SelectablePanel, Status, Ui},
|
||||
ui::{DeleteButton, GuiState, SelectablePanel, Status, Ui},
|
||||
};
|
||||
pub use message::InputMessages;
|
||||
|
||||
@@ -62,13 +62,21 @@ impl InputHandler {
|
||||
match message {
|
||||
InputMessages::ButtonPress(key) => self.button_press(key.0, key.1).await,
|
||||
InputMessages::MouseEvent(mouse_event) => {
|
||||
let error_or_help = self
|
||||
.gui_state
|
||||
.lock()
|
||||
.status_contains(&[Status::Error, Status::Help]);
|
||||
let error_or_help = self.gui_state.lock().status_contains(&[
|
||||
Status::Error,
|
||||
Status::Help,
|
||||
Status::DeleteConfirm,
|
||||
]);
|
||||
if !error_or_help {
|
||||
self.mouse_press(mouse_event);
|
||||
}
|
||||
let delete_confirm = self
|
||||
.gui_state
|
||||
.lock()
|
||||
.status_contains(&[Status::DeleteConfirm]);
|
||||
if delete_confirm {
|
||||
self.button_intersect(mouse_event).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.is_running.load(Ordering::SeqCst) {
|
||||
@@ -133,41 +141,59 @@ impl InputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is executed from the Delete Confirm dialog, and will send an internal message to actually remove the given container
|
||||
async fn confirm_delete(&self) {
|
||||
let id = self.gui_state.lock().get_delete_container();
|
||||
if let Some(id) = id {
|
||||
self.docker_sender
|
||||
.send(DockerMessage::Delete(id))
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// This is executed from the Delete Confirm dialog, and will clear the delete_container information (removes id and closes panel)
|
||||
fn clear_delete(&self) {
|
||||
self.gui_state.lock().set_delete_container(None);
|
||||
}
|
||||
|
||||
/// Handle any keyboard button events
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn button_press(&mut self, key_code: KeyCode, key_modififer: KeyModifiers) {
|
||||
// TODO - refactor this to a single call, maybe return Error, Help or Normal
|
||||
let contains_error = self.gui_state.lock().status_contains(&[Status::Error]);
|
||||
let contains_help = self.gui_state.lock().status_contains(&[Status::Help]);
|
||||
let contains_delete = self
|
||||
.gui_state
|
||||
.lock()
|
||||
.status_contains(&[Status::DeleteConfirm]);
|
||||
|
||||
// Quit on Ctrl + c/C
|
||||
// Always just quit on Ctrl + c/C or q/Q
|
||||
let is_c = || key_code == KeyCode::Char('c') || key_code == KeyCode::Char('C');
|
||||
if key_modififer == KeyModifiers::CONTROL && is_c() {
|
||||
let is_q = || key_code == KeyCode::Char('q') || key_code == KeyCode::Char('Q');
|
||||
if key_modififer == KeyModifiers::CONTROL && is_c() || is_q() {
|
||||
self.quit().await;
|
||||
}
|
||||
|
||||
if contains_error {
|
||||
match key_code {
|
||||
KeyCode::Char('q' | 'Q') => self.quit().await,
|
||||
KeyCode::Char('c' | 'C') => {
|
||||
self.app_data.lock().remove_error();
|
||||
self.gui_state.lock().status_del(Status::Error);
|
||||
}
|
||||
_ => (),
|
||||
if let KeyCode::Char('c' | 'C') = key_code {
|
||||
self.app_data.lock().remove_error();
|
||||
self.gui_state.lock().status_del(Status::Error);
|
||||
}
|
||||
} else if contains_help {
|
||||
match key_code {
|
||||
KeyCode::Char('q' | 'Q') => self.quit().await,
|
||||
KeyCode::Char('h' | 'H') => self.gui_state.lock().status_del(Status::Help),
|
||||
KeyCode::Char('m' | 'M') => self.m_key(),
|
||||
_ => (),
|
||||
}
|
||||
} else {
|
||||
// let abc = KeyEvent::new(KeyCode::Char('d'), KeyModifiers::Ctrl);
|
||||
} else if contains_delete {
|
||||
match key_code {
|
||||
KeyCode::Char('y' | 'Y') => self.confirm_delete().await,
|
||||
KeyCode::Char('n' | 'N') => self.clear_delete(),
|
||||
_ => (),
|
||||
}
|
||||
} else {
|
||||
match key_code {
|
||||
// KeyCode::Ctrl('c') => {
|
||||
// self.quit().await;
|
||||
// }
|
||||
KeyCode::Char('0') => self.app_data.lock().reset_sorted(),
|
||||
KeyCode::Char('1') => self.sort(Header::State),
|
||||
KeyCode::Char('2') => self.sort(Header::Status),
|
||||
@@ -178,7 +204,6 @@ impl InputHandler {
|
||||
KeyCode::Char('7') => self.sort(Header::Image),
|
||||
KeyCode::Char('8') => self.sort(Header::Rx),
|
||||
KeyCode::Char('9') => self.sort(Header::Tx),
|
||||
KeyCode::Char('q' | 'Q') => self.quit().await,
|
||||
KeyCode::Char('h' | 'H') => self.gui_state.lock().status_push(Status::Help),
|
||||
KeyCode::Char('m' | 'M') => self.m_key(),
|
||||
KeyCode::Tab => {
|
||||
@@ -251,6 +276,11 @@ impl InputHandler {
|
||||
};
|
||||
if let Some(id) = option_id {
|
||||
match command {
|
||||
DockerControls::Delete => self
|
||||
.docker_sender
|
||||
.send(DockerMessage::ConfirmDelete(id))
|
||||
.await
|
||||
.ok(),
|
||||
DockerControls::Pause => {
|
||||
self.docker_sender.send(DockerMessage::Pause(id)).await.ok()
|
||||
}
|
||||
@@ -280,6 +310,25 @@ impl InputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a button press interacts with either the yes or no buttons in the delete container confirm window
|
||||
async fn button_intersect(&mut self, mouse_event: MouseEvent) {
|
||||
if mouse_event.kind == MouseEventKind::Down(MouseButton::Left) {
|
||||
let intersect = self.gui_state.lock().button_intersect(Rect::new(
|
||||
mouse_event.column,
|
||||
mouse_event.row,
|
||||
1,
|
||||
1,
|
||||
));
|
||||
|
||||
if let Some(button) = intersect {
|
||||
match button {
|
||||
DeleteButton::Yes => self.confirm_delete().await,
|
||||
DeleteButton::No => self.clear_delete(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle mouse button events
|
||||
fn mouse_press(&mut self, mouse_event: MouseEvent) {
|
||||
match mouse_event.kind {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ use ui::{GuiState, Status, Ui};
|
||||
|
||||
use crate::docker_data::DockerMessage;
|
||||
|
||||
// this is the entry point when running as a Docker Container, and is used, in conjunction with the `CONTAINER_ENV` ENV, to check if we are running as a Docker Container
|
||||
/// This is the entry point when running as a Docker Container, and is used, in conjunction with the `CONTAINER_ENV` ENV, to check if we are running as a Docker Container
|
||||
const ENTRY_POINT: &str = "/app/oxker";
|
||||
const ENV_KEY: &str = "OXKER_RUNTIME";
|
||||
const ENV_VALUE: &str = "container";
|
||||
|
||||
@@ -40,7 +40,7 @@ impl CliArgs {
|
||||
// Quit the program if the docker update argument is 0
|
||||
// Should maybe change it to check if less than 100
|
||||
if args.docker_interval == 0 {
|
||||
error!("docker args needs to be greater than 0");
|
||||
error!("\"-d\" argument needs to be greater than 0");
|
||||
process::exit(1)
|
||||
}
|
||||
Self {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod log_sanitizer {
|
||||
|
||||
use cansi::{v3::categorise_text, Color as CansiColor, Intensity};
|
||||
use tui::{
|
||||
use ratatui::{
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Span, Spans},
|
||||
};
|
||||
|
||||
+144
-42
@@ -1,7 +1,5 @@
|
||||
use parking_lot::Mutex;
|
||||
use std::default::Default;
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
use tui::{
|
||||
use ratatui::{
|
||||
backend::Backend,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
@@ -13,6 +11,8 @@ use tui::{
|
||||
},
|
||||
Frame,
|
||||
};
|
||||
use std::default::Default;
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
|
||||
use crate::app_data::{Header, SortedOrder};
|
||||
use crate::ui::Status;
|
||||
@@ -21,7 +21,7 @@ use crate::{
|
||||
app_error::AppError,
|
||||
};
|
||||
|
||||
use super::gui_state::{BoxLocation, Region};
|
||||
use super::gui_state::{BoxLocation, DeleteButton, Region};
|
||||
use super::{GuiState, SelectablePanel};
|
||||
|
||||
const NAME_TEXT: &str = r#"
|
||||
@@ -43,6 +43,14 @@ const MARGIN: &str = " ";
|
||||
const ARROW: &str = "▶ ";
|
||||
const CIRCLE: &str = "⚪ ";
|
||||
|
||||
/// From a given &str, return the maximum number of chars on a single line
|
||||
fn max_line_width(text: &str) -> usize {
|
||||
text.lines()
|
||||
.map(|i| i.chars().count())
|
||||
.max()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Generate block, add a border if is the selected panel,
|
||||
/// add custom title based on state of each panel
|
||||
fn generate_block<'a>(
|
||||
@@ -53,7 +61,7 @@ fn generate_block<'a>(
|
||||
) -> Block<'a> {
|
||||
gui_state
|
||||
.lock()
|
||||
.update_heading_map(Region::Panel(panel), area);
|
||||
.update_region_map(Region::Panel(panel), area);
|
||||
let current_selected_panel = gui_state.lock().selected_panel;
|
||||
let mut title = match panel {
|
||||
SelectablePanel::Containers => {
|
||||
@@ -424,7 +432,7 @@ pub fn heading_bar<B: Backend>(
|
||||
let info_text = format!("( h ) {suffix} help {MARGIN}",);
|
||||
let info_width = info_text.chars().count();
|
||||
|
||||
let column_width = usize::from(area.width) - info_width;
|
||||
let column_width = usize::from(area.width).saturating_sub(info_width);
|
||||
let column_width = if column_width > 0 { column_width } else { 1 };
|
||||
let splits = if has_containers {
|
||||
vec![
|
||||
@@ -459,7 +467,7 @@ pub fn heading_bar<B: Backend>(
|
||||
let rect = headers_section[index];
|
||||
gui_state
|
||||
.lock()
|
||||
.update_heading_map(Region::Header(header), rect);
|
||||
.update_region_map(Region::Header(header), rect);
|
||||
f.render_widget(paragraph, rect);
|
||||
}
|
||||
}
|
||||
@@ -479,14 +487,6 @@ pub fn heading_bar<B: Backend>(
|
||||
f.render_widget(help_paragraph, split_bar[help_index]);
|
||||
}
|
||||
|
||||
/// From a given &str, return the maximum number of chars on a single line
|
||||
fn max_line_width(text: &str) -> usize {
|
||||
text.lines()
|
||||
.map(|i| i.chars().count())
|
||||
.max()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Help popup box needs these three pieces of information
|
||||
struct HelpInfo {
|
||||
spans: Vec<Spans<'static>>,
|
||||
@@ -500,7 +500,7 @@ impl HelpInfo {
|
||||
spans
|
||||
.iter()
|
||||
.flat_map(|x| x.0.iter())
|
||||
.map(tui::text::Span::width)
|
||||
.map(ratatui::text::Span::width)
|
||||
.max()
|
||||
.unwrap_or(1)
|
||||
}
|
||||
@@ -515,12 +515,12 @@ impl HelpInfo {
|
||||
Span::styled(input.to_owned(), Style::default().fg(color))
|
||||
}
|
||||
|
||||
/// Span to black text span
|
||||
/// &str to black text span
|
||||
fn black_span<'a>(input: &str) -> Span<'a> {
|
||||
Self::span(input, Color::Black)
|
||||
}
|
||||
|
||||
/// Span to white text span
|
||||
/// &str to white text span
|
||||
fn white_span<'a>(input: &str) -> Span<'a> {
|
||||
Self::span(input, Color::White)
|
||||
}
|
||||
@@ -559,7 +559,7 @@ impl HelpInfo {
|
||||
|
||||
/// Generate the button information span + metadata
|
||||
fn gen_button() -> Self {
|
||||
let button_item = |x: &str| Self::white_span(&format!(" {x} "));
|
||||
let button_item = |x: &str| Self::white_span(&format!(" ( {x} ) "));
|
||||
let button_desc = |x: &str| Self::black_span(x);
|
||||
let or = || button_desc("or");
|
||||
let space = || button_desc(" ");
|
||||
@@ -567,52 +567,48 @@ impl HelpInfo {
|
||||
let spans = [
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( tab )"),
|
||||
button_item("tab"),
|
||||
or(),
|
||||
button_item("( shift+tab )"),
|
||||
button_item("shift+tab"),
|
||||
button_desc("to change panels"),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( ↑ ↓ )"),
|
||||
button_item("↑ ↓"),
|
||||
or(),
|
||||
button_item("( j k )"),
|
||||
button_item("j k"),
|
||||
or(),
|
||||
button_item("( PgUp PgDown )"),
|
||||
button_item("PgUp PgDown"),
|
||||
or(),
|
||||
button_item("( Home End )"),
|
||||
button_item("Home End"),
|
||||
button_desc("to change selected line"),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( enter )"),
|
||||
button_item("enter"),
|
||||
button_desc("to send docker container command"),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( h )"),
|
||||
button_item("h"),
|
||||
button_desc("to toggle this help information"),
|
||||
]),
|
||||
Spans::from(vec![space(), button_item("0"), button_desc("to stop sort")]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( 0 )"),
|
||||
button_desc("to stop sort"),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( 1 - 9 )"),
|
||||
button_item("1 - 9"),
|
||||
button_desc("sort by header - or click header"),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( m )"),
|
||||
button_item("m"),
|
||||
button_desc(
|
||||
"to toggle mouse capture - if disabled, text on screen can be selected & copied",
|
||||
),
|
||||
]),
|
||||
Spans::from(vec![
|
||||
space(),
|
||||
button_item("( q )"),
|
||||
button_item("q"),
|
||||
button_desc("to quit at any time"),
|
||||
]),
|
||||
];
|
||||
@@ -636,8 +632,7 @@ impl HelpInfo {
|
||||
Spans::from(vec![Span::styled(
|
||||
REPO.to_owned(),
|
||||
Style::default()
|
||||
.bg(Color::Magenta)
|
||||
.fg(Color::Black)
|
||||
.fg(Color::White)
|
||||
.add_modifier(Modifier::UNDERLINED),
|
||||
)]),
|
||||
];
|
||||
@@ -729,6 +724,117 @@ pub fn help_box<B: Backend>(f: &mut Frame<'_, B>) {
|
||||
f.render_widget(block, area);
|
||||
}
|
||||
|
||||
/// Draw the delete confirm box in the centre of the screen
|
||||
/// take in container id and container name here?
|
||||
pub fn delete_confirm<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
gui_state: &Arc<Mutex<GuiState>>,
|
||||
name: &str,
|
||||
) {
|
||||
let block = Block::default()
|
||||
.title(" Confirm Delete ")
|
||||
.border_type(BorderType::Rounded)
|
||||
.style(Style::default().bg(Color::White).fg(Color::Black))
|
||||
.title_alignment(Alignment::Center)
|
||||
.borders(Borders::ALL);
|
||||
|
||||
let confirm = Spans::from(vec![
|
||||
Span::from("Are you sure you want to delete container: "),
|
||||
Span::styled(
|
||||
name,
|
||||
Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
|
||||
),
|
||||
]);
|
||||
|
||||
let yes_text = " (Y)es ";
|
||||
let no_text = " (N)o ";
|
||||
|
||||
// Find the maximum line width & height, and add some padding
|
||||
let max_line_width = u16::try_from(confirm.width()).unwrap_or(64) + 12;
|
||||
let lines = 8;
|
||||
|
||||
let confirm_para = Paragraph::new(confirm).alignment(Alignment::Center);
|
||||
|
||||
let button_block = || {
|
||||
Block::default()
|
||||
.border_type(BorderType::Rounded)
|
||||
.borders(Borders::ALL)
|
||||
};
|
||||
|
||||
let yes_para = Paragraph::new(yes_text)
|
||||
.alignment(Alignment::Center)
|
||||
.block(button_block());
|
||||
// Need to add some padding for the borders
|
||||
let yes_chars = u16::try_from(yes_text.chars().count() + 2).unwrap_or(9);
|
||||
|
||||
let no_para = Paragraph::new(no_text)
|
||||
.alignment(Alignment::Center)
|
||||
.block(button_block());
|
||||
// Need to add some padding for the borders
|
||||
let no_chars = u16::try_from(no_text.chars().count() + 2).unwrap_or(8);
|
||||
|
||||
let area = popup(
|
||||
lines,
|
||||
max_line_width.into(),
|
||||
f.size(),
|
||||
BoxLocation::MiddleCentre,
|
||||
);
|
||||
|
||||
let split_popup = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Min(2),
|
||||
Constraint::Max(1),
|
||||
Constraint::Max(1),
|
||||
Constraint::Max(3),
|
||||
Constraint::Min(1),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(area);
|
||||
|
||||
// Should maybe have a differenet button_space IF the f.width() is within 2 chars of no_chars + yes_chars?
|
||||
let button_spacing = (max_line_width - no_chars - yes_chars) / 3;
|
||||
|
||||
let button_spacing = if (button_spacing + max_line_width) > f.size().width {
|
||||
1
|
||||
} else {
|
||||
button_spacing
|
||||
};
|
||||
let split_buttons = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Max(button_spacing),
|
||||
Constraint::Min(no_chars),
|
||||
Constraint::Max(button_spacing),
|
||||
Constraint::Min(yes_chars),
|
||||
Constraint::Max(button_spacing),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(split_popup[3]);
|
||||
|
||||
let no_area = split_buttons[1];
|
||||
let yes_area = split_buttons[3];
|
||||
|
||||
// Insert button areas into region map, so can interact with them on click
|
||||
gui_state
|
||||
.lock()
|
||||
.update_region_map(Region::Delete(DeleteButton::No), no_area);
|
||||
|
||||
gui_state
|
||||
.lock()
|
||||
.update_region_map(Region::Delete(DeleteButton::Yes), yes_area);
|
||||
|
||||
f.render_widget(Clear, area);
|
||||
f.render_widget(block, area);
|
||||
f.render_widget(confirm_para, split_popup[1]);
|
||||
f.render_widget(no_para, no_area);
|
||||
f.render_widget(yes_para, yes_area);
|
||||
}
|
||||
|
||||
/// Draw an error popup over whole screen
|
||||
pub fn error<B: Backend>(f: &mut Frame<'_, B>, error: AppError, seconds: Option<u8>) {
|
||||
let block = Block::default()
|
||||
@@ -798,11 +904,7 @@ pub fn info<B: Backend>(f: &mut Frame<'_, B>, text: String) {
|
||||
/// draw a box in the one of the BoxLocations, based on max line width + number of lines
|
||||
fn popup(text_lines: usize, text_width: usize, r: Rect, box_location: BoxLocation) -> Rect {
|
||||
// Make sure blank_space can't be an negative, as will crash
|
||||
let calc = |x: u16, y: usize| {
|
||||
(usize::from(x).checked_sub(y).map_or(1usize, |f| f))
|
||||
.checked_div(2)
|
||||
.map_or(1usize, |f| f)
|
||||
};
|
||||
let calc = |x: u16, y: usize| usize::from(x).saturating_sub(y).saturating_div(2);
|
||||
|
||||
let blank_vertical = calc(r.height, text_lines);
|
||||
let blank_horizontal = calc(r.width, text_width);
|
||||
|
||||
+49
-3
@@ -1,11 +1,11 @@
|
||||
use ratatui::layout::{Constraint, Rect};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt,
|
||||
};
|
||||
use tui::layout::{Constraint, Rect};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::app_data::Header;
|
||||
use crate::app_data::{ContainerId, Header};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub enum SelectablePanel {
|
||||
@@ -43,6 +43,13 @@ impl SelectablePanel {
|
||||
pub enum Region {
|
||||
Panel(SelectablePanel),
|
||||
Header(Header),
|
||||
Delete(DeleteButton),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub enum DeleteButton {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@@ -191,11 +198,13 @@ impl fmt::Display for Loading {
|
||||
|
||||
/// The application gui state can be in multiple of these four states at the same time
|
||||
/// Various functions (e.g input handler), operate differently depending upon current Status
|
||||
// Copy
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||
pub enum Status {
|
||||
Init,
|
||||
Help,
|
||||
DockerConnect,
|
||||
DeleteConfirm,
|
||||
Error,
|
||||
}
|
||||
|
||||
@@ -206,7 +215,9 @@ pub struct GuiState {
|
||||
is_loading: HashSet<Uuid>,
|
||||
loading_icon: Loading,
|
||||
panel_map: HashMap<SelectablePanel, Rect>,
|
||||
delete_map: HashMap<DeleteButton, Rect>,
|
||||
status: HashSet<Status>,
|
||||
delete_container: Option<ContainerId>,
|
||||
pub info_box_text: Option<String>,
|
||||
pub selected_panel: SelectablePanel,
|
||||
}
|
||||
@@ -229,6 +240,16 @@ impl GuiState {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a given Rect (a clicked area of 1x1), interacts with any known delete button
|
||||
pub fn button_intersect(&mut self, rect: Rect) -> Option<DeleteButton> {
|
||||
self.delete_map
|
||||
.iter()
|
||||
.filter(|i| i.1.intersects(rect))
|
||||
.collect::<Vec<_>>()
|
||||
.get(0)
|
||||
.map(|data| *data.0)
|
||||
}
|
||||
|
||||
/// Check if a given Rect (a clicked area of 1x1), interacts with any known panels
|
||||
pub fn header_intersect(&mut self, rect: Rect) -> Option<Header> {
|
||||
self.heading_map
|
||||
@@ -240,7 +261,7 @@ impl GuiState {
|
||||
}
|
||||
|
||||
/// Insert, or updates header area panel into heading_map
|
||||
pub fn update_heading_map(&mut self, region: Region, area: Rect) {
|
||||
pub fn update_region_map(&mut self, region: Region, area: Rect) {
|
||||
match region {
|
||||
Region::Header(header) => self
|
||||
.heading_map
|
||||
@@ -252,9 +273,31 @@ impl GuiState {
|
||||
.entry(panel)
|
||||
.and_modify(|w| *w = area)
|
||||
.or_insert(area),
|
||||
Region::Delete(button) => self
|
||||
.delete_map
|
||||
.entry(button)
|
||||
.and_modify(|w| *w = area)
|
||||
.or_insert(area),
|
||||
};
|
||||
}
|
||||
|
||||
/// Check if an ContainerId is set in the delete_container field
|
||||
pub fn get_delete_container(&self) -> Option<ContainerId> {
|
||||
self.delete_container.clone()
|
||||
}
|
||||
|
||||
/// Set either a ContainerId, or None, to the delete_container field
|
||||
/// If Some, will also insert the DeleteConfirm status into self.status
|
||||
pub fn set_delete_container(&mut self, id: Option<ContainerId>) {
|
||||
if id.is_some() {
|
||||
self.status.insert(Status::DeleteConfirm);
|
||||
} else {
|
||||
self.delete_map.clear();
|
||||
self.status.remove(&Status::DeleteConfirm);
|
||||
}
|
||||
self.delete_container = id;
|
||||
}
|
||||
|
||||
/// Check if the current gui_status contains any of the given status'
|
||||
/// Don't really like this methodology for gui state, needs a re-think
|
||||
pub fn status_contains(&self, status: &[Status]) -> bool {
|
||||
@@ -264,6 +307,9 @@ impl GuiState {
|
||||
/// Remove a gui_status into the current gui_status HashSet
|
||||
pub fn status_del(&mut self, status: Status) {
|
||||
self.status.remove(&status);
|
||||
if status == Status::DeleteConfirm {
|
||||
self.status.remove(&Status::DeleteConfirm);
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a gui_status into the current gui_status HashSet
|
||||
|
||||
+25
-8
@@ -5,6 +5,11 @@ use crossterm::{
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use ratatui::{
|
||||
backend::{Backend, CrosstermBackend},
|
||||
layout::{Constraint, Direction, Layout},
|
||||
Frame, Terminal,
|
||||
};
|
||||
use std::{
|
||||
io::{self, Stdout, Write},
|
||||
sync::{atomic::Ordering, Arc},
|
||||
@@ -13,18 +18,13 @@ use std::{
|
||||
use std::{sync::atomic::AtomicBool, time::Instant};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tracing::error;
|
||||
use tui::{
|
||||
backend::{Backend, CrosstermBackend},
|
||||
layout::{Constraint, Direction, Layout},
|
||||
Frame, Terminal,
|
||||
};
|
||||
|
||||
mod color_match;
|
||||
mod draw_blocks;
|
||||
mod gui_state;
|
||||
|
||||
pub use self::color_match::*;
|
||||
pub use self::gui_state::{GuiState, SelectablePanel, Status};
|
||||
pub use self::gui_state::{DeleteButton, GuiState, SelectablePanel, Status};
|
||||
use crate::{
|
||||
app_data::AppData, app_error::AppError, docker_data::DockerMessage,
|
||||
input_handler::InputMessages,
|
||||
@@ -198,20 +198,23 @@ impl Ui {
|
||||
}
|
||||
|
||||
/// Draw the main ui to a frame of the terminal
|
||||
/// TODO add a single line area for debug message - if not in release mode, maybe with #[cfg(debug_assertions)] ?
|
||||
fn draw_frame<B: Backend>(
|
||||
f: &mut Frame<'_, B>,
|
||||
app_data: &Arc<Mutex<AppData>>,
|
||||
gui_state: &Arc<Mutex<GuiState>>,
|
||||
) {
|
||||
// set max height for container section, needs +4 to deal with docker commands list and borders
|
||||
// set max height for container section, needs +5 to deal with docker commands list and borders
|
||||
let height = app_data.lock().get_container_len();
|
||||
let height = if height < 12 { height + 4 } else { 12 };
|
||||
let height = if height < 12 { height + 5 } else { 12 };
|
||||
|
||||
let column_widths = app_data.lock().get_width();
|
||||
let has_containers = app_data.lock().get_container_len() > 0;
|
||||
let has_error = app_data.lock().get_error();
|
||||
let sorted_by = app_data.lock().get_sorted();
|
||||
|
||||
let delete_confirm = gui_state.lock().get_delete_container();
|
||||
|
||||
let show_help = gui_state.lock().status_contains(&[Status::Help]);
|
||||
let info_text = gui_state.lock().info_box_text.clone();
|
||||
let loading_icon = gui_state.lock().get_loading();
|
||||
@@ -274,6 +277,20 @@ fn draw_frame<B: Backend>(
|
||||
gui_state,
|
||||
);
|
||||
|
||||
if let Some(id) = delete_confirm {
|
||||
let name = app_data.lock().get_container_name_by_id(&id);
|
||||
name.map_or_else(
|
||||
|| {
|
||||
// If a container is deleted outside of oxker but whilst the Delete Confirm dialog is open, it can get caught in kind of a dead lock situation
|
||||
// so if in that unique situation, just clear the delete_container id
|
||||
gui_state.lock().set_delete_container(None);
|
||||
},
|
||||
|name| {
|
||||
draw_blocks::delete_confirm(f, gui_state, &name);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// only draw charts if there are containers
|
||||
if has_containers {
|
||||
draw_blocks::chart(f, lower_main[1], app_data);
|
||||
|
||||
Reference in New Issue
Block a user