chore: merge release-v0.6.1 into main

This commit is contained in:
Jack Wills
2024-02-14 14:39:44 +00:00
16 changed files with 533 additions and 262 deletions
+13 -11
View File
@@ -1,23 +1,25 @@
### 2024-01-18 ### 2024-02-14
### Chores ### Chores
+ dependencies updated, [53b4bafbe53312fe41608ddf33e865d474222aaa], [58ef151600e362048a607c8ae61a5edfe80ab1dd], [b6fd35022a99ec0e982ddb154b0450d49c4840e9], [0438c108bdd9815d7eae1b89c47c4e6438f358d6] + create_release v0.5.5, [616338b7107036e968f51c3ff80739f9ffb40fbd]
+ files formatted, [1806165c3e266876b2d1806f7b662d09705f3aad] + update dependencies, [10180d2e0817c00a198e27f7d71080c502639a6b]
+ create_release.sh check for unused lint, [d0b27211928f93f8455e1ee5a6a6485c6a21d382] + update to ratatui v0.26.0, [d33dce3eec4c19cc3c3668dab77f7d25d6970c3c]
+ GitHub workflow dependency bump, [0314eac9df6cf9fea1943dcd06bd6a0b27131c16]
### Docs ### Docs
= Readme updated, screenshot added, [7561a93415c1e1f596b15edba95e7b32a939cd90], [4069e5572f81cb689dbb9f735db919e4636cdccc] + screenshot updated, [fe5ec4f5dd25f11817be37f3f1867a6a2b0afc42]
### Features
+ Ports section added, closes #21, [65a1afcb0605604ede350a5630c775f94ebb74ee], [7a096a65c40924021fe643fe0aa1067095832df9]
### Fixes ### Fixes
+ sort arrow now on left of header, [40ddcb727d2c1758d6dd26a58507b85b219f51e2] + ports all listed in white, [d3b23585b38045eb3bc827367eca90eb7f7a7dd5]
+ use long container name in delete popup, [6202b7bbfdfb04a94959b5143dac3f1aa59cd336]
+ memory display, closes #33, [a182d40a7463164ef5dcac379d1a1768d77209d2]
### Refactors ### Refactors
+ rename string_wrapper > unit_struct, [27cf53e41f8b379f606c1c27620ee08e79bac57e] + use &[T] instead of &Vec<T>, [76cd08ab2f98687a866a6bbb4fa93bbdedaa7699], [1f62bb50210f2d66bb7215e42e8b21a3c1a6ec06]
+ draw_block constraints into consts, [0436ff1b7356c80532048c7d497c66d331092b01]
### Tests ### Tests
+ Finally have tests, currently for layout and associated methods, at the moment running the tests will not interfere with any running Docker containers, [4bcf77db776a36e0a8151ecfbda722a66c4ba46c] + update port test with new colour, [f74ae3f5c34d74b78822078291fed401427c4cba]
+ color match tests updated, [5b287416315942b19c62f8c66348ce28462d894c]
see <a href='https://github.com/mrjackwills/oxker/blob/main/CHANGELOG.md'>CHANGELOG.md</a> for more details 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: 34 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@@ -56,7 +56,7 @@ jobs:
# Upload output for release page # Upload output for release page
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
if-no-files-found: error if-no-files-found: error
name: ${{ matrix.target }} name: ${{ matrix.target }}
@@ -75,7 +75,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup | Artifacts - name: Setup | Artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
- name: Update Release - name: Update Release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
+25
View File
@@ -1,3 +1,28 @@
# <a href='https://github.com/mrjackwills/oxker/releases/tag/v0.6.1'>v0.6.1</a>
### 2024-02-14
### Chores
+ create_release v0.5.5, [616338b7](https://github.com/mrjackwills/oxker/commit/616338b7107036e968f51c3ff80739f9ffb40fbd)
+ update dependencies, [10180d2e](https://github.com/mrjackwills/oxker/commit/10180d2e0817c00a198e27f7d71080c502639a6b)
+ update to ratatui v0.26.0, [d33dce3e](https://github.com/mrjackwills/oxker/commit/d33dce3eec4c19cc3c3668dab77f7d25d6970c3c)
+ GitHub workflow dependency bump, [0314eac9](https://github.com/mrjackwills/oxker/commit/0314eac9df6cf9fea1943dcd06bd6a0b27131c16)
### Docs
+ screenshot updated, [fe5ec4f5](https://github.com/mrjackwills/oxker/commit/fe5ec4f5dd25f11817be37f3f1867a6a2b0afc42)
### Fixes
+ ports all listed in white, [d3b23585](https://github.com/mrjackwills/oxker/commit/d3b23585b38045eb3bc827367eca90eb7f7a7dd5)
+ use long container name in delete popup, [6202b7bb](https://github.com/mrjackwills/oxker/commit/6202b7bbfdfb04a94959b5143dac3f1aa59cd336)
+ memory display, closes [#33](https://github.com/mrjackwills/oxker/issues/33), [a182d40a](https://github.com/mrjackwills/oxker/commit/a182d40a7463164ef5dcac379d1a1768d77209d2)
### Refactors
+ use &[T] instead of &Vec<T>, [76cd08ab](https://github.com/mrjackwills/oxker/commit/76cd08ab2f98687a866a6bbb4fa93bbdedaa7699), [1f62bb50](https://github.com/mrjackwills/oxker/commit/1f62bb50210f2d66bb7215e42e8b21a3c1a6ec06)
+ draw_block constraints into consts, [0436ff1b](https://github.com/mrjackwills/oxker/commit/0436ff1b7356c80532048c7d497c66d331092b01)
### Tests
+ update port test with new colour, [f74ae3f5](https://github.com/mrjackwills/oxker/commit/f74ae3f5c34d74b78822078291fed401427c4cba)
+ color match tests updated, [5b287416](https://github.com/mrjackwills/oxker/commit/5b287416315942b19c62f8c66348ce28462d894c)
# <a href='https://github.com/mrjackwills/oxker/releases/tag/v0.6.0'>v0.6.0</a> # <a href='https://github.com/mrjackwills/oxker/releases/tag/v0.6.0'>v0.6.0</a>
### 2024-01-18 ### 2024-01-18
Generated
+126 -88
View File
@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.7" version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@@ -66,9 +66,9 @@ dependencies = [
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.4" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]] [[package]]
name = "anstyle-parse" name = "anstyle-parse"
@@ -207,6 +207,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "castaway"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
dependencies = [
"rustversion",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.83" version = "1.0.83"
@@ -224,22 +233,22 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.31" version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
dependencies = [ dependencies = [
"android-tzdata", "android-tzdata",
"iana-time-zone", "iana-time-zone",
"num-traits", "num-traits",
"serde", "serde",
"windows-targets 0.48.5", "windows-targets 0.52.0",
] ]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.18" version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -247,9 +256,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.4.18" version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -261,9 +270,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.4.7" version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -273,9 +282,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
@@ -283,6 +292,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "compact_str"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
dependencies = [
"castaway",
"cfg-if",
"itoa",
"ryu",
"static_assertions",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.6" version = "0.8.6"
@@ -347,9 +369,9 @@ dependencies = [
[[package]] [[package]]
name = "either" name = "either"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]] [[package]]
name = "equivalent" name = "equivalent"
@@ -453,7 +475,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http", "http",
"indexmap 2.1.0", "indexmap 2.2.3",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@@ -484,9 +506,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.4" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
[[package]] [[package]]
name = "hex" name = "hex"
@@ -567,9 +589,9 @@ dependencies = [
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.59" version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [ dependencies = [
"android_system_properties", "android_system_properties",
"core-foundation-sys", "core-foundation-sys",
@@ -611,9 +633,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.1.0" version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.14.3", "hashbrown 0.14.3",
@@ -628,9 +650,9 @@ checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.12.0" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [ dependencies = [
"either", "either",
] ]
@@ -643,9 +665,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.67" version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@@ -658,9 +680,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.152" version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]] [[package]]
name = "libredox" name = "libredox"
@@ -691,9 +713,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]] [[package]]
name = "lru" name = "lru"
version = "0.12.1" version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22"
dependencies = [ dependencies = [
"hashbrown 0.14.3", "hashbrown 0.14.3",
] ]
@@ -706,9 +728,9 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.1" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [ dependencies = [
"adler", "adler",
] ]
@@ -736,10 +758,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "num-traits" name = "num-conv"
version = "0.2.17" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@@ -783,7 +811,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]] [[package]]
name = "oxker" name = "oxker"
version = "0.6.0" version = "0.6.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bollard", "bollard",
@@ -837,18 +865,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.3" version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal",
] ]
[[package]] [[package]]
name = "pin-project-internal" name = "pin-project-internal"
version = "1.1.3" version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -881,9 +909,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.76" version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -929,12 +957,13 @@ dependencies = [
[[package]] [[package]]
name = "ratatui" name = "ratatui"
version = "0.25.0" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb" checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8"
dependencies = [ dependencies = [
"bitflags 2.4.2", "bitflags 2.4.2",
"cassowary", "cassowary",
"compact_str",
"crossterm", "crossterm",
"indoc", "indoc",
"itertools", "itertools",
@@ -992,18 +1021,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.195" version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.195" version = "1.0.196"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1012,9 +1041,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.111" version = "1.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@@ -1046,16 +1075,17 @@ dependencies = [
[[package]] [[package]]
name = "serde_with" name = "serde_with"
version = "3.4.0" version = "3.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270"
dependencies = [ dependencies = [
"base64", "base64",
"chrono", "chrono",
"hex", "hex",
"indexmap 1.9.3", "indexmap 1.9.3",
"indexmap 2.1.0", "indexmap 2.2.3",
"serde", "serde",
"serde_derive",
"serde_json", "serde_json",
"time", "time",
] ]
@@ -1110,9 +1140,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.13.0" version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]] [[package]]
name = "socket2" name = "socket2"
@@ -1135,25 +1165,31 @@ dependencies = [
] ]
[[package]] [[package]]
name = "strsim" name = "static_assertions"
version = "0.10.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]] [[package]]
name = "strum" name = "strum"
version = "0.25.0" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f"
dependencies = [ dependencies = [
"strum_macros", "strum_macros",
] ]
[[package]] [[package]]
name = "strum_macros" name = "strum_macros"
version = "0.25.3" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -1186,18 +1222,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.56" version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.56" version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1216,12 +1252,13 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.31" version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
"num-conv",
"powerfmt", "powerfmt",
"serde", "serde",
"time-core", "time-core",
@@ -1236,10 +1273,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.2.16" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
dependencies = [ dependencies = [
"num-conv",
"time-core", "time-core",
] ]
@@ -1260,9 +1298,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.35.1" version = "1.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@@ -1403,9 +1441,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.10.1" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
@@ -1432,9 +1470,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.6.1" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"rand", "rand",
@@ -1469,9 +1507,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.90" version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@@ -1479,9 +1517,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.90" version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"log", "log",
@@ -1494,9 +1532,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.90" version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -1504,9 +1542,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.90" version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1517,9 +1555,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.90" version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
[[package]] [[package]]
name = "winapi" name = "winapi"
+6 -6
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "oxker" name = "oxker"
version = "0.6.0" version = "0.6.1"
edition = "2021" edition = "2021"
authors = ["Jack Wills <email@mrjackwills.com>"] authors = ["Jack Wills <email@mrjackwills.com>"]
description = "A simple tui to view & control docker containers" description = "A simple tui to view & control docker containers"
@@ -29,16 +29,16 @@ similar_names = "allow"
anyhow = "1.0" anyhow = "1.0"
bollard = "0.15" bollard = "0.15"
cansi = "2.2" cansi = "2.2"
clap = { version = "4.4", features = ["color", "derive", "unicode"] } clap = { version = "4.5", features = ["color", "derive", "unicode"] }
crossterm = "0.27" crossterm = "0.27"
directories = "5.0"
futures-util = "0.3" futures-util = "0.3"
parking_lot = { version = "0.12" } parking_lot = { version = "0.12" }
tokio = { version = "1.35", features = ["full"] } ratatui = "0.26"
tokio = { version = "1.36", features = ["full"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
ratatui = "0.25" uuid = { version = "1.7", features = ["fast-rng", "v4"] }
uuid = { version = "1.6", features = ["fast-rng", "v4"] }
directories = "5.0"
[dev-dependencies] [dev-dependencies]
+112 -32
View File
@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# rust create_release # rust create_release v0.5.5
# v0.4.1
STAR_LINE='****************************************' STAR_LINE='****************************************'
CWD=$(pwd) CWD=$(pwd)
@@ -18,6 +17,11 @@ error_close() {
exit 1 exit 1
} }
# Check that dialog is installed
if ! [ -x "$(command -v dialog)" ]; then
error_close "dialog is not installed"
fi
# $1 string - question to ask # $1 string - question to ask
ask_yn() { ask_yn() {
printf "%b%s? [y/N]:%b " "${GREEN}" "$1" "${RESET}" printf "%b%s? [y/N]:%b " "${GREEN}" "$1" "${RESET}"
@@ -29,21 +33,34 @@ user_input() {
echo "$data" echo "$data"
} }
# ask continue, or quit
ask_continue() {
ask_yn "continue"
if [[ ! "$(user_input)" =~ ^y$ ]]; then
exit
fi
}
# semver major update
update_major() { update_major() {
local bumped_major local bumped_major
bumped_major=$((MAJOR + 1)) bumped_major=$((MAJOR + 1))
echo "${bumped_major}.0.0" echo "${bumped_major}.0.0"
} }
# semver minor update
update_minor() { update_minor() {
local bumped_minor local bumped_minor
bumped_minor=$((MINOR + 1)) bumped_minor=$((MINOR + 1))
MINOR=bumped_minor
echo "${MAJOR}.${bumped_minor}.0" echo "${MAJOR}.${bumped_minor}.0"
} }
# semver patch update
update_patch() { update_patch() {
local bumped_patch local bumped_patch
bumped_patch=$((PATCH + 1)) bumped_patch=$((PATCH + 1))
PATCH=bumped_patch
echo "${MAJOR}.${MINOR}.${bumped_patch}" echo "${MAJOR}.${MINOR}.${bumped_patch}"
} }
@@ -153,14 +170,6 @@ check_tag() {
done done
} }
# ask continue, or quit
ask_continue() {
ask_yn "continue"
if [[ ! "$(user_input)" =~ ^y$ ]]; then
exit
fi
}
# run all tests # run all tests
cargo_test() { cargo_test() {
cargo test -- --test-threads=1 cargo test -- --test-threads=1
@@ -169,31 +178,55 @@ cargo_test() {
# Simulate publishing to crates.io # Simulate publishing to crates.io
cargo_publish() { cargo_publish() {
echo -e "${PURPLE}cargo publish --dry-run${RESET}"
cargo publish --dry-run cargo publish --dry-run
ask_continue ask_continue
} }
# Build all releases that GitHub workflow would # Check to see if cross is installed - if not then install
# This will download GB's of docker images check_cross() {
cargo_build() { if ! [ -x "$(command -v cross)" ]; then
cargo install cross echo -e "${GREEN}cargo install cross${RESET}"
cargo_clean cargo install cross
fi
}
cargo_build_x86_linux() {
check_cross
echo -e "${YELLOW}cross build --target x86_64-unknown-linux-musl --release${RESET}" echo -e "${YELLOW}cross build --target x86_64-unknown-linux-musl --release${RESET}"
cross build --target x86_64-unknown-linux-musl --release cross build --target x86_64-unknown-linux-musl --release
ask_continue }
cargo_clean
cargo_build_aarch64_linux() {
check_cross
echo -e "${YELLOW}cross build --target aarch64-unknown-linux-musl --release${RESET}" echo -e "${YELLOW}cross build --target aarch64-unknown-linux-musl --release${RESET}"
cross build --target aarch64-unknown-linux-musl --release cross build --target aarch64-unknown-linux-musl --release
ask_continue }
cargo_clean
cargo_build_armv6_linux() {
check_cross
echo -e "${YELLOW}cross build --target arm-unknown-linux-musleabihf --release${RESET}" echo -e "${YELLOW}cross build --target arm-unknown-linux-musleabihf --release${RESET}"
cross build --target arm-unknown-linux-musleabihf --release cross build --target arm-unknown-linux-musleabihf --release
ask_continue }
cargo_clean
cargo_build_x86_windows() {
check_cross
echo -e "${YELLOW}cross build --target x86_64-pc-windows-gnu --release${RESET}" echo -e "${YELLOW}cross build --target x86_64-pc-windows-gnu --release${RESET}"
cross build --target x86_64-pc-windows-gnu --release cross build --target x86_64-pc-windows-gnu --release
}
# Build all releases that GitHub workflow would
# This will download GB's of docker images
cargo_build_all() {
cargo clean
cargo_build_armv6_linux
ask_continue
cargo_build_aarch64_linux
ask_continue
cargo_build_x86_linux
ask_continue
cargo_build_x86_windows
ask_continue ask_continue
cargo_clean
} }
# $1 text to colourise # $1 text to colourise
@@ -202,11 +235,6 @@ release_continue() {
ask_continue ask_continue
} }
# Clean/remove builds, due to issue with cross-rs
cargo_clean() {
echo -e "${YELLOW}cargo clean${RESET}"
cargo clean
}
# Check repository for typos # Check repository for typos
check_typos() { check_typos() {
echo -e "\n${PURPLE}check typos${RESET}" echo -e "\n${PURPLE}check typos${RESET}"
@@ -214,14 +242,16 @@ check_typos() {
ask_continue ask_continue
} }
# Make sure the unused lint isn't used # Make sure the unused lint isn't used
check_allow_unused() { check_allow_unused() {
matches_any=$(find . -type d \( -name .git -o -name target \) -prune -o -type f -exec grep -lE '^#!\[allow\(unused\)\]$' {} +) matches_any=$(find . -type d \( -name .git -o -name target \) -prune -o -type f -exec grep -lE '^#!\[allow\(unused\)\]$' {} +)
matches_cargo=$(grep "^unused = \"allow\"" ./Cargo.toml) matches_cargo=$(grep "^unused = \"allow\"" ./Cargo.toml)
if [ -n "$matches_any" ]; then if [ -n "$matches_any" ]; then
error_close "\"#[allow(unused)]\" in ${matches_any}" echo "\"#[allow(unused)]\" in ${matches_any}"
ask_continue
elif [ -n "$matches_cargo" ]; then elif [ -n "$matches_cargo" ]; then
error_close "\"unused = \"allow\"\" in Cargo.toml" echo "\"unused = \"allow\"\" in Cargo.toml"
ask_continue
fi fi
} }
@@ -234,7 +264,7 @@ release_flow() {
get_git_remote_url get_git_remote_url
cargo_test cargo_test
cargo_build cargo_build_all
cargo_publish cargo_publish
cd "${CWD}" || error_close "Can't find ${CWD}" cd "${CWD}" || error_close "Can't find ${CWD}"
@@ -255,6 +285,7 @@ release_flow() {
echo -e "\ncargo fmt" echo -e "\ncargo fmt"
cargo fmt cargo fmt
echo -e "\n${PURPLE}cargo check${RESET}\n" echo -e "\n${PURPLE}cargo check${RESET}\n"
cargo check cargo check
@@ -267,8 +298,12 @@ release_flow() {
release_continue "git checkout main" release_continue "git checkout main"
git checkout main git checkout main
echo -e "${PURPLE}git pull origin main${RESET}"
git pull origin main
echo -e "${PURPLE}git merge --no-ff \"${RELEASE_BRANCH}\" -m \"chore: merge ${RELEASE_BRANCH} into main\"${RESET}" echo -e "${PURPLE}git merge --no-ff \"${RELEASE_BRANCH}\" -m \"chore: merge ${RELEASE_BRANCH} into main\"${RESET}"
git merge --no-ff "$RELEASE_BRANCH" -m "chore: merge ${RELEASE_BRANCH} into main" git merge --no-ff "$RELEASE_BRANCH" -m "chore: merge ${RELEASE_BRANCH} into main"
echo -e "\n${PURPLE}cargo check${RESET}\n" echo -e "\n${PURPLE}cargo check${RESET}\n"
cargo check cargo check
@@ -291,6 +326,51 @@ release_flow() {
git branch -d "$RELEASE_BRANCH" git branch -d "$RELEASE_BRANCH"
} }
build_choice() {
cmd=(dialog --backtitle "Choose option" --radiolist "choose" 14 80 16)
options=(
1 "x86 musl linux" off
2 "aarch64 musl linux" off
3 "armv6 musl linux" off
4 "x86 windows" off
5 "all" off
)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
exitStatus=$?
clear
if [ $exitStatus -ne 0 ]; then
exit
fi
for choice in $choices; do
case $choice in
0)
exit
;;
1)
cargo_build_x86_linux
exit
;;
2)
cargo_build_aarch64_linux
exit
;;
3)
cargo_build_armv6_linux
exit
;;
4)
cargo_build_x86_windows
exit
;;
5)
cargo_build_all
exit
;;
esac
done
}
main() { main() {
cmd=(dialog --backtitle "Choose option" --radiolist "choose" 14 80 16) cmd=(dialog --backtitle "Choose option" --radiolist "choose" 14 80 16)
options=( options=(
@@ -319,7 +399,7 @@ main() {
break break
;; ;;
3) 3)
cargo_build build_choice
main main
break break
;; ;;
-2
View File
@@ -11,8 +11,6 @@ services:
ipc: private ipc: private
restart: always restart: always
shm_size: 256MB shm_size: 256MB
ports:
- "127.0.0.1:4040:4040"
networks: networks:
- oxker-example-net - oxker-example-net
deploy: deploy:
+2 -4
View File
@@ -48,7 +48,6 @@ impl PartialOrd for ContainerId {
} }
} }
/// TODO - use string_wrapper for ContainerId?
/// ContainerName and ContainerImage are simple structs, used so can implement custom fmt functions to them /// ContainerName and ContainerImage are simple structs, used so can implement custom fmt functions to them
macro_rules! unit_struct { macro_rules! unit_struct {
($name:ident) => { ($name:ident) => {
@@ -537,7 +536,6 @@ pub struct ContainerItem {
pub mem_limit: ByteStats, pub mem_limit: ByteStats,
pub mem_stats: VecDeque<ByteStats>, pub mem_stats: VecDeque<ByteStats>,
pub name: ContainerName, pub name: ContainerName,
// todo remove option, can be empty vec
pub ports: Vec<ContainerPorts>, pub ports: Vec<ContainerPorts>,
pub rx: ByteStats, pub rx: ByteStats,
pub state: State, pub state: State,
@@ -691,7 +689,7 @@ mod tests {
use super::{ByteStats, ContainerName, CpuStats, LogsTz}; use super::{ByteStats, ContainerName, CpuStats, LogsTz};
#[test] #[test]
// Display CpuStats as a string /// Display CpuStats as a string
fn test_container_state_cpustats_to_string() { fn test_container_state_cpustats_to_string() {
let test = |f: f64, s: &str| { let test = |f: f64, s: &str| {
assert_eq!(CpuStats::new(f).to_string(), s); assert_eq!(CpuStats::new(f).to_string(), s);
@@ -704,7 +702,7 @@ mod tests {
} }
#[test] #[test]
// Display bytestats as a string, convert into correct data unit (Kb, MB, GB) /// Display bytestats as a string, convert into correct data unit (Kb, MB, GB)
fn test_container_state_bytestats_to_string() { fn test_container_state_bytestats_to_string() {
let test = |u: u64, s: &str| { let test = |u: u64, s: &str| {
assert_eq!(ByteStats::new(u).to_string(), s); assert_eq!(ByteStats::new(u).to_string(), s);
+11 -10
View File
@@ -212,7 +212,7 @@ impl AppData {
} }
/// Get all the ContainerItems /// Get all the ContainerItems
pub const fn get_container_items(&self) -> &Vec<ContainerItem> { pub fn get_container_items(&self) -> &[ContainerItem] {
&self.containers.items &self.containers.items
} }
@@ -383,6 +383,7 @@ impl AppData {
} }
/// Get mutable Option of the currently selected container DockerControls items /// Get mutable Option of the currently selected container DockerControls items
/// TODO command or control, need a uniform name across the application
pub fn get_control_items(&mut self) -> Option<&mut Vec<DockerControls>> { pub fn get_control_items(&mut self) -> Option<&mut Vec<DockerControls>> {
self.get_mut_selected_container() self.get_mut_selected_container()
.map(|i| &mut i.docker_controls.items) .map(|i| &mut i.docker_controls.items)
@@ -1229,7 +1230,7 @@ mod tests {
} }
#[test] #[test]
// Get the currently selected container /// Get the currently selected container
fn test_app_data_get_selected_container() { fn test_app_data_get_selected_container() {
let (_ids, mut containers) = gen_containers(); let (_ids, mut containers) = gen_containers();
let mut app_data = gen_appdata(&containers); let mut app_data = gen_appdata(&containers);
@@ -1249,7 +1250,7 @@ mod tests {
} }
#[test] #[test]
// Get mut container by id /// Get mut container by id
fn test_app_data_get_container_by_id() { fn test_app_data_get_container_by_id() {
let (_ids, mut containers) = gen_containers(); let (_ids, mut containers) = gen_containers();
let mut app_data = gen_appdata(&containers); let mut app_data = gen_appdata(&containers);
@@ -1259,7 +1260,7 @@ mod tests {
} }
#[test] #[test]
// Get just the containers name by id /// Get just the containers name by id
fn test_app_data_get_container_name_by_id() { fn test_app_data_get_container_name_by_id() {
let (_ids, containers) = gen_containers(); let (_ids, containers) = gen_containers();
let mut app_data = gen_appdata(&containers); let mut app_data = gen_appdata(&containers);
@@ -1269,7 +1270,7 @@ mod tests {
} }
#[test] #[test]
// Get the id of the currently selected container /// Get the id of the currently selected container
fn test_app_data_get_selected_container_id() { fn test_app_data_get_selected_container_id() {
let (_ids, containers) = gen_containers(); let (_ids, containers) = gen_containers();
let mut app_data = gen_appdata(&containers); let mut app_data = gen_appdata(&containers);
@@ -1383,7 +1384,7 @@ mod tests {
"Up 1 hour".to_owned(), "Up 1 hour".to_owned(),
) )
}; };
let mut app_data = gen_appdata(&vec![gen_item_state(state)]); let mut app_data = gen_appdata(&[gen_item_state(state)]);
app_data.containers_start(); app_data.containers_start();
app_data.docker_controls_start(); app_data.docker_controls_start();
@@ -1832,15 +1833,15 @@ mod tests {
fn test_app_data_update_containers() { fn test_app_data_update_containers() {
let (_ids, containers) = gen_containers(); let (_ids, containers) = gen_containers();
let mut app_data = gen_appdata(&containers); let mut app_data = gen_appdata(&containers);
let result_pre = app_data.get_container_items().clone(); let result_pre = app_data.get_container_items().to_owned();
let mut input = vec![ let mut input = [
gen_container_summary(1, "paused"), gen_container_summary(1, "paused"),
gen_container_summary(2, "dead"), gen_container_summary(2, "dead"),
]; ];
app_data.update_containers(&mut input); app_data.update_containers(&mut input);
let result_post = app_data.get_container_items(); let result_post = app_data.get_container_items().to_owned();
assert_ne!(&result_pre, result_post); assert_ne!(result_pre, result_post);
assert_eq!(result_post[0].state, State::Paused); assert_eq!(result_post[0].state, State::Paused);
assert_eq!(result_post[1].state, State::Dead); assert_eq!(result_post[1].state, State::Dead);
} }
+15 -4
View File
@@ -1,7 +1,7 @@
use bollard::{ use bollard::{
container::{ container::{
ListContainersOptions, LogsOptions, RemoveContainerOptions, StartContainerOptions, Stats, ListContainersOptions, LogsOptions, MemoryStatsStats, RemoveContainerOptions,
StatsOptions, StartContainerOptions, Stats, StatsOptions,
}, },
service::ContainerSummary, service::ContainerSummary,
Docker, Docker,
@@ -71,7 +71,7 @@ pub struct DockerData {
impl DockerData { impl DockerData {
/// Use docker stats to calculate current cpu usage /// Use docker stats to calculate current cpu usage
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
// FIX: this can overflow // TODO FIX: this can overflow
fn calculate_usage(stats: &Stats) -> f64 { fn calculate_usage(stats: &Stats) -> f64 {
let mut cpu_percentage = 0.0; let mut cpu_percentage = 0.0;
let previous_cpu = stats.precpu_stats.cpu_usage.total_usage; let previous_cpu = stats.precpu_stats.cpu_usage.total_usage;
@@ -121,8 +121,19 @@ impl DockerData {
.take(1); .take(1);
while let Some(Ok(stats)) = stream.next().await { while let Some(Ok(stats)) = stream.next().await {
// Memory stats are only collected if the container is alive - is this the behaviour we want?
let mem_stat = if state.is_alive() { let mem_stat = if state.is_alive() {
Some(stats.memory_stats.usage.unwrap_or_default()) let mem_cache = stats.memory_stats.stats.map_or(0, |i| match i {
MemoryStatsStats::V1(x) => x.inactive_file,
MemoryStatsStats::V2(x) => x.inactive_file,
});
Some(
stats
.memory_stats
.usage
.unwrap_or_default()
.saturating_sub(mem_cache),
)
} else { } else {
None None
}; };
-1
View File
@@ -150,7 +150,6 @@ async fn main() {
let containers = app_data let containers = app_data
.lock() .lock()
.get_container_items() .get_container_items()
.clone()
.iter() .iter()
.map(|i| format!("{i}")) .map(|i| format!("{i}"))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
+5 -2
View File
@@ -98,12 +98,13 @@ mod tests {
}] }]
.to_vec(), .to_vec(),
alignment: None, alignment: None,
style: Style::default(),
}]; }];
assert_eq!(result, expected); assert_eq!(result, expected);
} }
#[test] #[test]
// Use the escape codes to colorize the text /// Use the escape codes to colorize the text
fn color_match_colorize() { fn color_match_colorize() {
let result = log_sanitizer::colorize_logs(INPUT); let result = log_sanitizer::colorize_logs(INPUT);
let expected = vec![Line { let expected = vec![Line {
@@ -130,12 +131,13 @@ mod tests {
}, },
], ],
alignment: None, alignment: None,
style: Style::default(),
}]; }];
assert_eq!(result, expected); assert_eq!(result, expected);
} }
#[test] #[test]
// Remove all escape ansi codes from given input /// Remove all escape ansi codes from given input
fn color_match_remove_ansi() { fn color_match_remove_ansi() {
let result = log_sanitizer::remove_ansi(INPUT); let result = log_sanitizer::remove_ansi(INPUT);
let expected = vec![Line { let expected = vec![Line {
@@ -143,6 +145,7 @@ mod tests {
content: std::borrow::Cow::Borrowed("oxker"), content: std::borrow::Cow::Borrowed("oxker"),
style: Style::default(), style: Style::default(),
}], }],
style: Style::default(),
alignment: None, alignment: None,
}]; }];
assert_eq!(result, expected); assert_eq!(result, expected);
+206 -91
View File
@@ -44,6 +44,24 @@ const MARGIN: &str = " ";
const RIGHT_ARROW: &str = ""; const RIGHT_ARROW: &str = "";
const CIRCLE: &str = ""; const CIRCLE: &str = "";
const CONSTRAINT_50_50: [Constraint; 2] = [Constraint::Percentage(50), Constraint::Percentage(50)];
const CONSTRAINT_100: [Constraint; 1] = [Constraint::Percentage(100)];
const CONSTRAINT_POPUP: [Constraint; 5] = [
Constraint::Min(2),
Constraint::Max(1),
Constraint::Max(1),
Constraint::Max(3),
Constraint::Min(1),
];
const CONSTRAINT_BUTTONS: [Constraint; 5] = [
Constraint::Percentage(10),
Constraint::Percentage(35),
Constraint::Percentage(10),
Constraint::Percentage(35),
Constraint::Percentage(10),
];
/// From a given &str, return the maximum number of chars on a single line /// From a given &str, return the maximum number of chars on a single line
fn max_line_width(text: &str) -> usize { fn max_line_width(text: &str) -> usize {
text.lines() text.lines()
@@ -94,8 +112,7 @@ pub fn commands(
fd: &FrameData, fd: &FrameData,
gui_state: &Arc<Mutex<GuiState>>, gui_state: &Arc<Mutex<GuiState>>,
) { ) {
let block = || generate_block(app_data, area, fd, gui_state, SelectablePanel::Commands); let block = generate_block(app_data, area, fd, gui_state, SelectablePanel::Commands);
// let block = block();
let items = app_data.lock().get_control_items().map_or(vec![], |i| { let items = app_data.lock().get_control_items().map_or(vec![], |i| {
i.iter() i.iter()
.map(|c| { .map(|c| {
@@ -108,18 +125,14 @@ pub fn commands(
.collect::<Vec<_>>() .collect::<Vec<_>>()
}); });
let items = List::new(items)
.block(block())
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol(RIGHT_ARROW);
if let Some(i) = app_data.lock().get_control_state() { if let Some(i) = app_data.lock().get_control_state() {
let items = List::new(items)
.block(block)
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol(RIGHT_ARROW);
f.render_stateful_widget(items, area, i); f.render_stateful_widget(items, area, i);
} else { } else {
let block = || generate_block(app_data, area, fd, gui_state, SelectablePanel::Commands); let paragraph = Paragraph::new("").block(block).alignment(Alignment::Center);
let paragraph = Paragraph::new("")
.block(block())
.alignment(Alignment::Center);
f.render_widget(paragraph, area); f.render_widget(paragraph, area);
} }
} }
@@ -241,11 +254,11 @@ pub fn logs(
fd: &FrameData, fd: &FrameData,
gui_state: &Arc<Mutex<GuiState>>, gui_state: &Arc<Mutex<GuiState>>,
) { ) {
let block = || generate_block(app_data, area, fd, gui_state, SelectablePanel::Logs); let block = generate_block(app_data, area, fd, gui_state, SelectablePanel::Logs);
if fd.init { if fd.init {
let paragraph = Paragraph::new(format!("parsing logs {}", fd.loading_icon)) let paragraph = Paragraph::new(format!("parsing logs {}", fd.loading_icon))
.style(Style::default()) .style(Style::default())
.block(block()) .block(block)
.alignment(Alignment::Center); .alignment(Alignment::Center);
f.render_widget(paragraph, area); f.render_widget(paragraph, area);
} else { } else {
@@ -253,12 +266,12 @@ pub fn logs(
if logs.is_empty() { if logs.is_empty() {
let paragraph = Paragraph::new("no logs found") let paragraph = Paragraph::new("no logs found")
.block(block()) .block(block)
.alignment(Alignment::Center); .alignment(Alignment::Center);
f.render_widget(paragraph, area); f.render_widget(paragraph, area);
} else { } else {
let items = List::new(logs) let items = List::new(logs)
.block(block()) .block(block)
.highlight_symbol(RIGHT_ARROW) .highlight_symbol(RIGHT_ARROW)
.highlight_style(Style::default().add_modifier(Modifier::BOLD)); .highlight_style(Style::default().add_modifier(Modifier::BOLD));
// This should always return Some, as logs is not empty // This should always return Some, as logs is not empty
@@ -307,12 +320,8 @@ pub fn ports(
)) ))
.fg(Color::Yellow), .fg(Color::Yellow),
)]; )];
for (index, item) in ports.0.iter().enumerate() { for item in &ports.0 {
let fg = if index % 2 == 0 { let fg = Color::White;
Color::White
} else {
Color::Magenta
};
let strings = item.print(); let strings = item.print();
let line = vec![ let line = vec![
@@ -333,7 +342,7 @@ pub fn chart(f: &mut Frame, area: Rect, app_data: &Arc<Mutex<AppData>>) {
if let Some((cpu, mem)) = app_data.lock().get_chart_data() { if let Some((cpu, mem)) = app_data.lock().get_chart_data() {
let area = Layout::default() let area = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) .constraints(CONSTRAINT_50_50)
.split(area); .split(area);
let cpu_dataset = vec![Dataset::default() let cpu_dataset = vec![Dataset::default()
@@ -423,7 +432,7 @@ pub fn heading_bar(
let mut color = Color::Black; let mut color = Color::Black;
let mut prefix = ""; let mut prefix = "";
let mut prefix_margin = 0; let mut prefix_margin = 0;
if let Some((a, b)) = data.sorted_by.as_ref() { if let Some((a, b)) = &data.sorted_by {
if x == a { if x == a {
match b { match b {
SortedOrder::Asc => prefix = "", SortedOrder::Asc => prefix = "",
@@ -505,12 +514,12 @@ pub fn heading_bar(
let column_width = if column_width > 0 { column_width } else { 1 }; let column_width = if column_width > 0 { column_width } else { 1 };
let splits = if data.has_containers { let splits = if data.has_containers {
vec![ vec![
Constraint::Min(2), Constraint::Max(2),
Constraint::Min(column_width.try_into().unwrap_or_default()), Constraint::Min(column_width.try_into().unwrap_or_default()),
Constraint::Min(info_width.try_into().unwrap_or_default()), Constraint::Max(info_width.try_into().unwrap_or_default()),
] ]
} else { } else {
vec![Constraint::Percentage(100)] CONSTRAINT_100.to_vec()
}; };
let split_bar = Layout::default() let split_bar = Layout::default()
@@ -756,15 +765,12 @@ pub fn help_box(f: &mut Frame) {
let split_popup = Layout::default() let split_popup = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints( .constraints([
[ Constraint::Max(name_info.height.try_into().unwrap_or_default()),
Constraint::Max(name_info.height.try_into().unwrap_or_default()), Constraint::Max(description_info.height.try_into().unwrap_or_default()),
Constraint::Max(description_info.height.try_into().unwrap_or_default()), Constraint::Max(button_info.height.try_into().unwrap_or_default()),
Constraint::Max(button_info.height.try_into().unwrap_or_default()), Constraint::Min(final_info.height.try_into().unwrap_or_default()),
Constraint::Max(final_info.height.try_into().unwrap_or_default()), ])
]
.as_ref(),
)
.split(area); .split(area);
let name_paragraph = Paragraph::new(name_info.lines) let name_paragraph = Paragraph::new(name_info.lines)
@@ -815,7 +821,7 @@ pub fn delete_confirm(f: &mut Frame, gui_state: &Arc<Mutex<GuiState>>, name: &Co
let confirm = Line::from(vec![ let confirm = Line::from(vec![
Span::from("Are you sure you want to delete container: "), Span::from("Are you sure you want to delete container: "),
Span::styled( Span::styled(
name.to_string(), name.get(),
Style::default() Style::default()
.fg(Color::Red) .fg(Color::Red)
.bg(Color::White) .bg(Color::White)
@@ -843,16 +849,10 @@ pub fn delete_confirm(f: &mut Frame, gui_state: &Arc<Mutex<GuiState>>, name: &Co
.alignment(Alignment::Center) .alignment(Alignment::Center)
.block(button_block()); .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) let no_para = Paragraph::new(no_text)
.alignment(Alignment::Center) .alignment(Alignment::Center)
.block(button_block()); .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( let area = popup(
lines, lines,
max_line_width.into(), max_line_width.into(),
@@ -862,30 +862,12 @@ pub fn delete_confirm(f: &mut Frame, gui_state: &Arc<Mutex<GuiState>>, name: &Co
let split_popup = Layout::default() let split_popup = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints( .constraints(CONSTRAINT_POPUP)
[
Constraint::Min(2),
Constraint::Max(1),
Constraint::Max(1),
Constraint::Max(3),
Constraint::Min(1),
]
.as_ref(),
)
.split(area); .split(area);
let split_buttons = Layout::default() let split_buttons = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints( .constraints(CONSTRAINT_BUTTONS)
[
Constraint::Percentage(10),
Constraint::Percentage(35),
Constraint::Percentage(10),
Constraint::Percentage(35),
Constraint::Percentage(10),
]
.as_ref(),
)
.split(split_popup[3]); .split(split_popup[3]);
let no_area = split_buttons[1]; let no_area = split_buttons[1];
@@ -951,6 +933,7 @@ pub fn error(f: &mut Frame, error: AppError, seconds: Option<u8>) {
} }
/// Draw info box in one of the 9 BoxLocations /// Draw info box in one of the 9 BoxLocations
// TODO is this broken?
pub fn info(f: &mut Frame, text: &str, instant: Instant, gui_state: &Arc<Mutex<GuiState>>) { pub fn info(f: &mut Frame, text: &str, instant: Instant, gui_state: &Arc<Mutex<GuiState>>) {
let block = Block::default() let block = Block::default()
.title("") .title("")
@@ -1085,7 +1068,7 @@ mod tests {
// ******************** // // ******************** //
#[test] #[test]
// Test that when DockerCommands are available, they are drawn correctly, dependant on container state /// Test that when DockerCommands are available, they are drawn correctly, dependant on container state
fn test_draw_blocks_commands_none() { fn test_draw_blocks_commands_none() {
let (w, h) = (12, 6); let (w, h) = (12, 6);
let mut setup = test_setup(w, h, false, false); let mut setup = test_setup(w, h, false, false);
@@ -1236,7 +1219,7 @@ mod tests {
} }
#[test] #[test]
// When control panel is selected, the border is blue, if not then white, selected text is highlighted /// When control panel is selected, the border is blue, if not then white, selected text is highlighted
fn test_draw_blocks_commands_panel_selected_color() { fn test_draw_blocks_commands_panel_selected_color() {
let (w, h) = (12, 6); let (w, h) = (12, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1326,7 +1309,7 @@ mod tests {
} }
#[test] #[test]
// No containers, panel unselected, then selected, border color changes correctly /// No containers, panel unselected, then selected, border color changes correctly
fn test_draw_blocks_containers_none() { fn test_draw_blocks_containers_none() {
let (w, h) = (25, 6); let (w, h) = (25, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1387,7 +1370,7 @@ mod tests {
} }
#[test] #[test]
// Containers panel drawn, selected line is bold, border is blue /// Containers panel drawn, selected line is bold, border is blue
fn test_draw_blocks_containers_some() { fn test_draw_blocks_containers_some() {
let (w, h) = (130, 6); let (w, h) = (130, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1746,7 +1729,7 @@ mod tests {
// ********** // // ********** //
#[test] #[test]
// No logs, panel unselected, then selected, border color changes correctly /// No logs, panel unselected, then selected, border color changes correctly
fn test_draw_blocks_logs_none() { fn test_draw_blocks_logs_none() {
let (w, h) = (25, 6); let (w, h) = (25, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1808,7 +1791,7 @@ mod tests {
} }
#[test] #[test]
// Parsing logs, spinner visible, and then animates by one frame /// Parsing logs, spinner visible, and then animates by one frame
fn test_draw_blocks_logs_parsing() { fn test_draw_blocks_logs_parsing() {
let (w, h) = (25, 6); let (w, h) = (25, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1874,7 +1857,7 @@ mod tests {
} }
#[test] #[test]
// Logs correct displayed, changing log state also draws correctly /// Logs correct displayed, changing log state also draws correctly
fn test_draw_blocks_logs_some() { fn test_draw_blocks_logs_some() {
let (w, h) = (25, 6); let (w, h) = (25, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -1943,7 +1926,7 @@ mod tests {
} }
#[test] #[test]
// Full (long) name displayed in logs border /// Full (long) name displayed in logs border
fn test_draw_blocks_logs_long_name() { fn test_draw_blocks_logs_long_name() {
let (w, h) = (80, 6); let (w, h) = (80, 6);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2032,7 +2015,7 @@ mod tests {
} }
} }
#[test] #[test]
// When status is Running, but not data, charts drawn without dots etc /// When status is Running, but not data, charts drawn without dots etc
fn test_draw_blocks_charts_running_none() { fn test_draw_blocks_charts_running_none() {
let (w, h) = (80, 10); let (w, h) = (80, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2087,7 +2070,7 @@ mod tests {
} }
#[test] #[test]
// When status is Running, charts correctly drawn /// When status is Running, charts correctly drawn
fn test_draw_blocks_charts_running_some() { fn test_draw_blocks_charts_running_some() {
let (w, h) = (80, 10); let (w, h) = (80, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2140,7 +2123,7 @@ mod tests {
} }
#[test] #[test]
// Whens status paused, some text is now Yellow /// Whens status paused, some text is now Yellow
fn test_draw_blocks_charts_paused() { fn test_draw_blocks_charts_paused() {
let (w, h) = (80, 10); let (w, h) = (80, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2188,7 +2171,7 @@ mod tests {
} }
#[test] #[test]
// When dead, text is read /// When dead, text is read
fn test_draw_blocks_charts_dead() { fn test_draw_blocks_charts_dead() {
let (w, h) = (80, 10); let (w, h) = (80, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2335,7 +2318,6 @@ mod tests {
let result = &setup.terminal.backend().buffer().content; let result = &setup.terminal.backend().buffer().content;
for (index, expected_char) in expected.chars().enumerate() { for (index, expected_char) in expected.chars().enumerate() {
let result_cell = &result[index]; let result_cell = &result[index];
assert_eq!(result_cell.symbol(), expected_char.to_string()); assert_eq!(result_cell.symbol(), expected_char.to_string());
assert_eq!(result_cell.bg, Color::Magenta); assert_eq!(result_cell.bg, Color::Magenta);
assert_eq!( assert_eq!(
@@ -2383,8 +2365,8 @@ mod tests {
test(" name state status cpu memory/limit id image ▼ ↓ rx ↑ tx ( h ) show help ", 99..=108, (Header::Rx, SortedOrder::Desc)); test(" name state status cpu memory/limit id image ▼ ↓ rx ↑ tx ( h ) show help ", 99..=108, (Header::Rx, SortedOrder::Desc));
// tx // tx
test(" name state status cpu memory/limit id image ↓ rx ▲ ↑ tx ( h ) show help ", 109..=122, (Header::Tx, SortedOrder::Asc)); test(" name state status cpu memory/limit id image ↓ rx ▲ ↑ tx ( h ) show help ", 109..=118, (Header::Tx, SortedOrder::Asc));
test(" name state status cpu memory/limit id image ↓ rx ▼ ↑ tx ( h ) show help ", 109..=122, (Header::Tx, SortedOrder::Desc)); test(" name state status cpu memory/limit id image ↓ rx ▼ ↑ tx ( h ) show help ", 109..=118, (Header::Tx, SortedOrder::Desc));
} }
#[test] #[test]
@@ -2425,7 +2407,7 @@ mod tests {
// Help popup // // Help popup //
// ********** // // ********** //
#[test] #[test]
// This will cause issues once the version has more than the current 5 chars (0.5.0) /// This will cause issues once the version has more than the current 5 chars (0.5.0)
// Help popup is drawn correctly // Help popup is drawn correctly
fn test_draw_blocks_help() { fn test_draw_blocks_help() {
let (w, h) = (87, 30); let (w, h) = (87, 30);
@@ -2525,7 +2507,7 @@ mod tests {
// ************ // // ************ //
#[test] #[test]
// Delete container popup is drawn correctly /// Delete container popup is drawn correctly
fn test_draw_blocks_delete() { fn test_draw_blocks_delete() {
let (w, h) = (82, 10); let (w, h) = (82, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2587,6 +2569,70 @@ mod tests {
} }
} }
#[test]
/// Delete container popup is drawn correctly
fn test_draw_blocks_delete_long_name() {
let (w, h) = (106, 10);
let mut setup = test_setup(w, h, true, true);
let name = ContainerName::from("container_1_container_1_container_1");
setup.app_data.lock().containers.items[0].name = name.clone();
let expected = [
" ",
" ╭──────────────────────────────────── Confirm Delete ────────────────────────────────────╮ ",
" │ │ ",
" │ Are you sure you want to delete container: container_1_container_1_container_1 │ ",
" │ │ ",
" │ ╭──────────────────────────────╮ ╭─────────────────────────────╮ │ ",
" │ │ (N)o │ │ (Y)es │ │ ",
" │ ╰──────────────────────────────╯ ╰─────────────────────────────╯ │ ",
" ╰────────────────────────────────────────────────────────────────────────────────────────╯ ",
" ",
];
setup
.terminal
.draw(|f| {
super::delete_confirm(f, &setup.gui_state, &name);
})
.unwrap();
let result = &setup.terminal.backend().buffer().content;
for (row_index, row) in expected.iter().enumerate() {
for (char_index, expected_char) in row.chars().enumerate() {
let index = row_index * usize::from(w) + char_index;
let result_cell = &result[index];
assert_eq!(result_cell.symbol(), expected_char.to_string());
if row_index == 0
|| row_index == usize::from(h - 1)
|| char_index < 8
|| char_index > usize::from(w - 9)
{
assert_eq!(result_cell.fg, Color::Reset);
assert_eq!(result_cell.bg, Color::Reset);
} else {
assert_eq!(result_cell.bg, Color::White);
}
// Borders are black
if BORDER_CHARS.contains(&result_cell.symbol()) {
assert_eq!(result_cell.fg, Color::Black);
// Container name is red
} else if row_index == 3 && (57..=82).contains(&char_index) {
assert_eq!(result_cell.fg, Color::Red);
// All other text is black
} else if !row_index == 0
&& !row_index == usize::from(h - 1)
&& !char_index < 8
&& !char_index > usize::from(w - 9)
{
assert_eq!(result_cell.fg, Color::Black);
}
}
}
}
// ***** // // ***** //
// popup // // popup //
// ***** // // ***** //
@@ -2617,13 +2663,13 @@ mod tests {
.unwrap(); .unwrap();
let result = &setup.terminal.backend().buffer().content; let result = &setup.terminal.backend().buffer().content;
for (row_index, row) in expected.iter().enumerate() { for (row_index, row) in expected.iter().enumerate() {
for (char_index, expected_char) in row.chars().enumerate() { for (char_index, expected_char) in row.chars().enumerate() {
let index = row_index * usize::from(w) + char_index; let index = row_index * usize::from(w) + char_index;
let result_cell = &result[index]; let result_cell = &result[index];
assert_eq!(expected_char.to_string(), result_cell.symbol()); assert_eq!(expected_char.to_string(), result_cell.symbol());
let (fg, bg) = if row_index >= 6 && char_index >= 32 { let (fg, bg) = if row_index >= 6 && char_index >= 32 {
(Color::White, Color::Blue) (Color::White, Color::Blue)
} else { } else {
@@ -2641,7 +2687,7 @@ mod tests {
// *********** // // *********** //
#[test] #[test]
// Test that the error popup is centered, red background, white border, white text, and displays the correct text /// Test that the error popup is centered, red background, white border, white text, and displays the correct text
fn test_draw_blocks_docker_connect_error() { fn test_draw_blocks_docker_connect_error() {
let (w, h) = (46, 9); let (w, h) = (46, 9);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2692,7 +2738,7 @@ mod tests {
} }
#[test] #[test]
// Test that the clearable error popup is centered, red background, white border, white text, and displays the correct text /// Test that the clearable error popup is centered, red background, white border, white text, and displays the correct text
fn test_draw_blocks_clearable_error() { fn test_draw_blocks_clearable_error() {
let (w, h) = (39, 10); let (w, h) = (39, 10);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2744,7 +2790,7 @@ mod tests {
} }
#[test] #[test]
// Port section when container has no ports /// Port section when container has no ports
fn test_draw_blocks_ports_no_ports() { fn test_draw_blocks_ports_no_ports() {
let (w, h) = (30, 8); let (w, h) = (30, 8);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2824,7 +2870,7 @@ mod tests {
} }
#[test] #[test]
// Port section when container has multiple ports /// Port section when container has multiple ports
fn test_draw_blocks_ports_multiple_ports() { fn test_draw_blocks_ports_multiple_ports() {
let (w, h) = (32, 8); let (w, h) = (32, 8);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2883,12 +2929,9 @@ mod tests {
if row_index == 1 && result_cell_as_char { if row_index == 1 && result_cell_as_char {
assert_eq!(result_cell.fg, Color::Yellow); assert_eq!(result_cell.fg, Color::Yellow);
} }
if row_index == 2 && result_cell_as_char { if (2..=3).contains(&row_index) && result_cell_as_char {
assert_eq!(result_cell.fg, Color::White); assert_eq!(result_cell.fg, Color::White);
} }
if row_index == 3 && result_cell_as_char {
assert_eq!(result_cell.fg, Color::Magenta);
}
if row_index == 4 && result_cell_as_char { if row_index == 4 && result_cell_as_char {
assert_eq!(result_cell.fg, Color::White); assert_eq!(result_cell.fg, Color::White);
} }
@@ -2897,7 +2940,7 @@ mod tests {
} }
#[test] #[test]
// Port section title color correct dependant on state /// Port section title color correct dependant on state
fn test_draw_blocks_ports_container_state() { fn test_draw_blocks_ports_container_state() {
let (w, h) = (32, 8); let (w, h) = (32, 8);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -2951,6 +2994,7 @@ mod tests {
}) })
.unwrap(); .unwrap();
// This is wrong - why?
let expected = [ let expected = [
"╭─────────── ports ────────────╮", "╭─────────── ports ────────────╮",
"│ ip private public │", "│ ip private public │",
@@ -2988,7 +3032,7 @@ mod tests {
// The whole layout // // The whole layout //
// **************** // // **************** //
#[test] #[test]
// Check that the whole layout is drawn correctly /// Check that the whole layout is drawn correctly
fn test_draw_blocks_whole_layout() { fn test_draw_blocks_whole_layout() {
let (w, h) = (160, 30); let (w, h) = (160, 30);
let mut setup = test_setup(w, h, true, true); let mut setup = test_setup(w, h, true, true);
@@ -3028,7 +3072,7 @@ mod tests {
"│ │", "│ │",
"│ │", "│ │",
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯", "╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯",
"╭───────────────────────── cpu 03.00% ──────────────────────────╮╭─────────────────────── memory 30.00 kB ───────────────────────╮╭────────── ports ───────────╮", "╭───────────────────────── cpu 03.00% ──────────────────────────╮╭─────────────────────── memory 30.00 kB ───────────────────────╮╭────────── ports ───────────╮",
"│10.00%│ •••• ││100.00 kB│ ••• ││ ip private public│", "│10.00%│ •••• ││100.00 kB│ ••• ││ ip private public│",
"│ │ ••• • ││ │ ••• • ││ 8001 │", "│ │ ••• • ││ │ ••• • ││ 8001 │",
"│ │•• ••• ││ │•• ••• ││127.0.0.1 8003 8003│", "│ │•• ••• ││ │•• ••• ││127.0.0.1 8003 8003│",
@@ -3052,4 +3096,75 @@ mod tests {
} }
} }
} }
#[test]
/// Check that the whole layout is drawn correctly when have long container name and long image name
fn test_draw_blocks_whole_layout_long_name() {
let (w, h) = (190, 30);
let mut setup = test_setup(w, h, true, true);
insert_chart_data(&setup);
insert_logs(&setup);
setup.app_data.lock().containers.items[0]
.ports
.push(ContainerPorts {
ip: Some("127.0.0.1".to_owned()),
private: 8003,
public: Some(8003),
});
setup.app_data.lock().containers.items[0].name =
ContainerName::from("a_long_container_name_for_the_purposes_of_this_test");
setup.app_data.lock().containers.items[0].image =
ContainerImage::from("a_long_image_name_for_the_purposes_of_this_test");
let expected = [
" name state status cpu memory/limit id image ↓ rx ↑ tx ( h ) show help ",
"╭ Containers 1/3 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮╭─────────────────╮",
"│⚪ a_long_container_name_for_the… ✓ running Up 1 hour 03.00% 30.00 kB / 30.00 kB 1 a_long_image_name_for_the_pur… 0.00 kB 0.00 kB ││▶ pause │",
"│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB ││ restart │",
"│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB ││ stop │",
"│ ││ delete │",
"│ ││ │",
"│ ││ │",
"╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰─────────────────╯",
"╭ Logs 3/3 - a_long_container_name_for_the_purposes_of_this_test ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮",
"│ line 1 │",
"│ line 2 │",
"│▶ line 3 │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"│ │",
"╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯",
"╭───────────────────────────────── cpu 03.00% ─────────────────────────────────╮╭────────────────────────────── memory 30.00 kB ───────────────────────────────╮╭────────── ports ───────────╮",
"│10.00%│ •••• ││100.00 kB│ ••••• ││ ip private public│",
"│ │ •••• • ││ │ ••• • ││ 8001 │",
"│ │••• •••• ││ │••• ••• ││127.0.0.1 8003 8003│",
"│ │ ││ │ ││ │",
"╰──────────────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────────────╯╰────────────────────────────╯",
];
setup
.terminal
.draw(|f| {
draw_frame(f, &setup.app_data, &setup.gui_state);
})
.unwrap();
let result = &setup.terminal.backend().buffer().content;
for (row_index, row) in expected.iter().enumerate() {
for (char_index, expected_char) in row.chars().enumerate() {
let index = row_index * usize::from(w) + char_index;
let result_cell = &result[index];
assert_eq!(result_cell.symbol(), expected_char.to_string(),);
}
}
}
} }
+6 -6
View File
@@ -109,19 +109,19 @@ impl BoxLocation {
) -> [Constraint; 3] { ) -> [Constraint; 3] {
match self { match self {
Self::TopLeft | Self::MiddleLeft | Self::BottomLeft => [ Self::TopLeft | Self::MiddleLeft | Self::BottomLeft => [
Constraint::Max(text_width), Constraint::Min(text_width),
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
], ],
Self::TopCentre | Self::MiddleCentre | Self::BottomCentre => [ Self::TopCentre | Self::MiddleCentre | Self::BottomCentre => [
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
Constraint::Max(text_width), Constraint::Min(text_width),
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
], ],
Self::TopRight | Self::MiddleRight | Self::BottomRight => [ Self::TopRight | Self::MiddleRight | Self::BottomRight => [
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
Constraint::Max(blank_horizontal), Constraint::Max(blank_horizontal),
Constraint::Max(text_width), Constraint::Min(text_width),
], ],
} }
} }
@@ -133,19 +133,19 @@ impl BoxLocation {
) -> [Constraint; 3] { ) -> [Constraint; 3] {
match self { match self {
Self::TopLeft | Self::TopCentre | Self::TopRight => [ Self::TopLeft | Self::TopCentre | Self::TopRight => [
Constraint::Max(number_lines), Constraint::Min(number_lines),
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
], ],
Self::MiddleLeft | Self::MiddleCentre | Self::MiddleRight => [ Self::MiddleLeft | Self::MiddleCentre | Self::MiddleRight => [
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
Constraint::Max(number_lines), Constraint::Min(number_lines),
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
], ],
Self::BottomLeft | Self::BottomCentre | Self::BottomRight => [ Self::BottomLeft | Self::BottomCentre | Self::BottomRight => [
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
Constraint::Max(blank_vertical), Constraint::Max(blank_vertical),
Constraint::Max(number_lines), Constraint::Min(number_lines),
], ],
} }
} }
+4 -3
View File
@@ -265,13 +265,14 @@ fn draw_frame(f: &mut Frame, app_data: &Arc<Mutex<AppData>>, gui_state: &Arc<Mut
let whole_layout = Layout::default() let whole_layout = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([Constraint::Min(1), Constraint::Min(100)].as_ref()) .constraints([Constraint::Max(1), Constraint::Min(1)].as_ref())
.split(f.size()); .split(f.size());
// Split into 3, containers+controls, logs, then graphs // Split into 3, containers+controls, logs, then graphs
// This one is the issue!
let upper_main = Layout::default() let upper_main = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([Constraint::Max(fd.height), Constraint::Percentage(50)].as_ref()) .constraints([Constraint::Max(fd.height), Constraint::Min(1)].as_ref())
.split(whole_layout[1]); .split(whole_layout[1]);
let top_split = if fd.has_containers { let top_split = if fd.has_containers {
@@ -286,7 +287,7 @@ fn draw_frame(f: &mut Frame, app_data: &Arc<Mutex<AppData>>, gui_state: &Arc<Mut
.split(upper_main[0]); .split(upper_main[0]);
let lower_split = if fd.has_containers { let lower_split = if fd.has_containers {
vec![Constraint::Percentage(70), Constraint::Percentage(20)] vec![Constraint::Percentage(70), Constraint::Percentage(30)]
} else { } else {
vec![Constraint::Percentage(100)] vec![Constraint::Percentage(100)]
}; };