diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 43426a8a..ebac8ea9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: '' -labels: '' +labels: 'bug' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..36014cde 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: '' +labels: 'enhancement' assignees: '' --- diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 52cdd8fa..7366e78c 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,5 +1,6 @@ name-template: '$RESOLVED_VERSION' tag-template: '$RESOLVED_VERSION' +tag-prefix: "" categories: - title: 'πŸš€ Features' labels: @@ -10,8 +11,10 @@ categories: - 'fix' - 'bugfix' - 'bug' - - title: '🧰 Maintenance' - label: 'chore' + - title: 'πŸ“š Documentation' + label: 'documentation' + - title: 'πŸ”’ Security' + label: 'security' change-template: '- $TITLE @$AUTHOR (#$NUMBER)' template: | ## Changes @@ -20,4 +23,38 @@ template: | ## Contributors - $CONTRIBUTORS \ No newline at end of file + $CONTRIBUTORS + +change-title-escapes: '\<*_&"''' +autolabeler: + - label: 'documentation' + files: + - '*.md' + branch: + - '/docs{0,1}\/.+/' + - label: 'bug' + branch: + - '/fix\/.+/' + title: + - '/fix/i' + - label: 'enhancement' + branch: + - '/feature\/.+/' + body: + - '/[A-Z]+-[0-9]+/' + - label: 'documentation' + files: + - '**/*.md' + - 'docs/**/*' + - label: 'security' + branch: + - '/security\/.+/' +replacers: + - search: /"/g + replace: '' + - search: /'/g + replace: '' + - search: /`/g + replace: '' +exclude-labels: + - 'skip-changelog' \ No newline at end of file diff --git a/.github/workflows/cargo-lock.yml b/.github/workflows/cargo-lock.yml new file mode 100644 index 00000000..40c37209 --- /dev/null +++ b/.github/workflows/cargo-lock.yml @@ -0,0 +1,25 @@ +name: Remove Cargo.lock changes + +on: + pull_request: + types: [opened, synchronize] + paths: + - 'Cargo.lock' + +jobs: + remove-cargo-lock: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Remove Cargo.lock changes + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git checkout ${{ github.head_ref }} + git reset origin/${{ github.base_ref }} -- Cargo.lock + git commit -m "Remove changes to Cargo.lock" || echo "No changes to commit" + git push origin ${{ github.head_ref }} --force diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml index 82257d98..5e4b139e 100644 --- a/.github/workflows/pre-release.yaml +++ b/.github/workflows/pre-release.yaml @@ -27,21 +27,12 @@ jobs: - name: Generate Release Notes id: generate_notes - uses: release-drafter/release-drafter@v5 + uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: config-name: release-drafter.yml version: ${{ env.version }} - version-template: '$YEAR.$MONTH.$DAY' - - - name: Prepare Release Body - id: prepare_body - run: | - new_changes="${{ steps.generate_notes.outputs.body }}" - echo "body<> $GITHUB_OUTPUT - echo "$new_changes" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - name: Create and Upload Release id: create_release @@ -50,7 +41,7 @@ jobs: tag_name: ${{ env.version }} name: Pre-Release ${{ env.version }} body: | - ${{ steps.prepare_body.outputs.body }} + ${{ steps.generate_notes.outputs.body }} ![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/linutil/${{ env.version }}/linutil) append_body: false diff --git a/Cargo.lock b/Cargo.lock index 3d3828bf..c3798ede 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -58,43 +58,43 @@ checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" @@ -110,9 +110,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bumpalo" @@ -128,18 +128,18 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "castaway" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" dependencies = [ "rustversion", ] [[package]] name = "cc" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ "shlex", ] @@ -161,14 +161,14 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -200,25 +200,26 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "compact_str" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" dependencies = [ "castaway", "cfg-if", "itoa", + "rustversion", "ryu", "static_assertions", ] @@ -231,15 +232,15 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crossterm" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", - "libc", "mio", "parking_lot", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -262,15 +263,15 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "ego-tree" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" +checksum = "12a0bb14ac04a9fcf170d0bbbef949b44cc492f4452bd20c095636956f653642" [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equivalent" @@ -285,7 +286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -321,13 +322,19 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "home" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -374,14 +381,24 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", ] +[[package]] +name = "instability" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "ioctl-rs" version = "0.1.6" @@ -393,9 +410,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -423,15 +440,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "linutil_core" @@ -479,15 +496,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" dependencies = [ "hashbrown", ] @@ -509,14 +526,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "log", "wasi", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -556,9 +574,9 @@ checksum = "e296cf87e61c9cfc1a61c3c63a0f7f286ed4554e0e22be84e8a38e1d264a2a29" [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -574,7 +592,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -612,18 +630,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -658,18 +676,18 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "ratatui" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16546c5b5962abf8ce6e2881e722b4e0ae3b6f1a08a26ae3573c55853ca68d3" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cassowary", "compact_str", "crossterm", + "instability", "itertools", "lru", "paste", - "stability", "strum", "strum_macros", "unicode-segmentation", @@ -688,11 +706,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -706,15 +724,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -737,18 +755,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.205" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.205" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -840,9 +858,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", @@ -864,16 +882,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "stability" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "static_assertions" version = "1.1.0" @@ -888,9 +896,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] @@ -910,9 +918,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -940,18 +948,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -994,9 +1002,9 @@ dependencies = [ [[package]] name = "tui-term" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac7538a3b9d5e92739253323e169ed25f005669c0e7f9d98f50f697fcada4e8" +checksum = "d07f0233f0d4795d2dc6663cfc3ce56b87bebcee66d6bcc088aa6aff5c072361" dependencies = [ "ratatui", "vt100", @@ -1004,9 +1012,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-segmentation" @@ -1033,15 +1041,15 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vt100" @@ -1068,9 +1076,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -1177,16 +1185,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -1195,129 +1194,72 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -1345,18 +1287,18 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e9d90e64..551f0bc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ license = "MIT" version = "0.1.0" -# Use workspace dependencies for anything public in linutil_core to avoid versioning conflicts [workspace.dependencies] ego-tree = "0.6.2" diff --git a/build/linutil b/build/linutil index 394b056d..25188375 100755 Binary files a/build/linutil and b/build/linutil differ diff --git a/cargo-lock-merge.txt b/cargo-lock-merge.txt new file mode 100644 index 00000000..649a99cf --- /dev/null +++ b/cargo-lock-merge.txt @@ -0,0 +1,5 @@ +What to do when you have a Cargo.lock merge conflict? +1. `git checkout origin/main -- Cargo.lock` to get the original Cargo.lock +2. `cargo build` to update Cargo.lock +3. `git add Cargo.lock` +4. continue the merge as normal \ No newline at end of file diff --git a/docs/KnownIssues.md b/docs/KnownIssues.md index 7632f0f8..0d12097e 100644 --- a/docs/KnownIssues.md +++ b/docs/KnownIssues.md @@ -1 +1,4 @@ -# Known Issues \ No newline at end of file +# Known Issues +--- + +- [Known Issues](https://github.com/ChrisTitusTech/linutil/issues) diff --git a/docs/assets/mainpage.png b/docs/assets/mainpage.png deleted file mode 100644 index c9c7ec51..00000000 Binary files a/docs/assets/mainpage.png and /dev/null differ diff --git a/docs/contribute.md b/docs/contribute.md index 2189c3c0..e47f8172 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -1,2 +1,62 @@ # How to Contribute? +Thank you for considering contributing to Linutil! We appreciate your effort in helping improve this project. To ensure that your contributions align with the goals and quality standards of Linutil, please follow these guidelines: + +## 1. **Install Rust**: + +Make sure you have Rust installed on your machine. You can install it by following the instructions at [rust-lang.org](https://www.rust-lang.org/tools/install). + +## 2. **Fork and Clone the repo** + +1. Make a fork of the repo in GitHub +2. Clone the fork +```bash +git clone https://github.com/YOUR_USERNAME_HERE/linutil.git +cd linutil + ``` + +## 3. Make your changes +- **Edit the files you want to change**: Make your changes to the relevant files. +- **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected. + +## 4. Understand the existing code + +- **Have a clear reason**: Don’t change the way things are done without a valid reason. If you propose an alteration, be prepared to explain why it’s necessary and how it improves the project. +- **Respect existing conventions**: Changes should align with the existing code style, design patterns, and overall project philosophy. If you want to introduce a new way of doing things, justify it clearly. + +## 5. Learn from Past Pull Requests (PRs) + +- **Check merged PRs**: Reviewing merged pull requests can give you an idea of what kind of contributions are accepted and how they are implemented. +- **Study rejected PRs**: This is especially important as it helps you avoid making similar mistakes or proposing changes that have already been considered and declined. + +## 6. Write Clean, Descriptive Commit Messages + +- **Be descriptive**: Your commit messages should clearly describe what the change does and why it was made. +- **Use the imperative mood**: For example, "Add feature X" or "Fix bug in Y", rather than "Added feature X" or "Fixed bug in Y". +- **Keep commits clean**: Avoid committing a change and then immediately following it with a fix for that change. Instead, amend your commit or squash it if needed. + +## 7. Keep Your Pull Requests (PRs) Small and Focused + +- **Make small, targeted PRs**: Focus on one feature or fix per pull request. This makes it easier to review and increases the likelihood of acceptance. +- **Avoid combining unrelated changes**: PRs that tackle multiple unrelated issues are harder to review and might be rejected because of a single problem. + +## 8. Code Review and Feedback + +- **Expect feedback**: PRs will undergo code review. Be open to feedback and willing to make adjustments as needed. +- **Participate in reviews**: If you feel comfortable, review other contributors' PRs as well. Peer review is a great way to learn and ensure high-quality contributions. + +## 9. Contributing Is More Than Just Code + +- **Test the tool**: Running tests and providing feedback on how the tool works in different environments is a valuable contribution. +- **Write well-formed issues**: Clearly describe bugs or problems you encounter, providing as much detail as possible, including steps to reproduce the issue. +- **Propose reasonable feature requests**: When suggesting new features, ensure they fit within the scope, style, and design of the project. Provide clear reasoning and use cases. + +## 10. Documentation + +- **Update the documentation**: If your change affects the functionality, please update the relevant documentation files to reflect this. + +## 11. License + +- **Agree to the license**: By contributing to Linutil, you agree that your contributions will be licensed under the project's MIT license. + +We appreciate your contributions and look forward to collaborating with you to make Linutil better! diff --git a/docs/index.md b/docs/index.md index 91cd803e..2493dc82 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,14 +3,21 @@ [![Version](https://img.shields.io/github/v/release/ChrisTitusTech/linutil?color=%230567ff&label=Latest%20Release&style=for-the-badge)](https://github.com/ChrisTitusTech/linutil/releases/latest) ![GitHub Downloads (specific asset, all releases)](https://img.shields.io/github/downloads/ChrisTitusTech/linutil/start.sh?label=Total%20Downloads&style=for-the-badge) -## Running latest release of LinUtil +## Running the latest release of LinUtil -* You will first need to start a Terminal on your linux machine. -* Now you will need to run following command: - ``` - curl -fsSL https://christitus.com/linux | sh - ``` +To get started, run the following command in your terminal: + +### Stable branch + +``` +curl -fsSL https://christitus.com/linux | sh +``` +--- + +After you've ran the command, you should see a GUI on your screen; It will look something like this: + +![preview](assets/preview.png) !!! info - LinUtil is updated weekly as of the time of writing. Consequently, features and functionalities may evolve, and the documentation may not always reflect the most current images or information. \ No newline at end of file + LinUtil is updated weekly as of the time of writing. Consequently, features and functionalities may evolve, and the documentation may not always reflect the most current images or information. diff --git a/docs/userguide.md b/docs/userguide.md index 15ee5527..8fc385f5 100644 --- a/docs/userguide.md +++ b/docs/userguide.md @@ -1,9 +1,32 @@ # Walkthrough +--- -## How to run LinUtil? -Run the following command in a terminal on your Linux System: -``` -curl -fsSL https://christitus.com/linux | sh -``` -Once you have run that command you will see the following GUI show on your screen: -![Main Page](assets/mainpage.png) \ No newline at end of file +## System Setup + +- **System Update**: Starts a system-wide update. +- **Compile Setup**: Installs tools and dependencies for compiling software. +- **Gaming Setup**: Configures Steam, Lutris, etc. +- **Global Theming**: Sets up and manages global themes. +- **Remove Snaps**: Removes snap packages. + +## Arch Setup + +- **Paru Setup**: Installs the Paru AUR helper. +- **Yay Setup**: Installs the Yay AUR helper. +- **Server Setup**: Installs Arch Linux. + +## Fedora Setup + +- **RPM Fusion Setup**: Adds RPM Fusion repositories. + +## Applications Setup + +- **Alacritty Setup**: Installs and configures Alacritty for you. +- **DwmTitus Setup**: Sets up the Dwm window manager. +- **Kitty Setup**: Installs and configures Kitty for you. +- **Rofi Setup**: Installs the Rofi application/script launcher. +- **Zsh Setup**: Installs and configures Zsh for you. + +## Security Features + +- **Firewall Baselines**: Sets up firewall rules. diff --git a/tabs/applications-setup/dwmtitus-setup.sh b/tabs/applications-setup/dwmtitus-setup.sh index 6a1fb162..8c0fc97a 100644 --- a/tabs/applications-setup/dwmtitus-setup.sh +++ b/tabs/applications-setup/dwmtitus-setup.sh @@ -15,11 +15,11 @@ setupDWM() { $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel libx11 libxinerama libxft imlib2 libxcb ;; apt) - $ESCALATION_TOOL "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev libxcb1-dev + $ESCALATION_TOOL "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev libxcb1-dev libx11-xcb1 ;; dnf) $ESCALATION_TOOL "$PACKAGER" groupinstall -y "Development Tools" - $ESCALATION_TOOL "$PACKAGER" install -y libx11-devel libxinerama-devel libxft-devel imlib2-devel libxcb-devel + $ESCALATION_TOOL "$PACKAGER" install -y libX11-devel libXinerama-devel libXft-devel imlib2-devel libxcb-devel ;; *) echo "Unsupported package manager: $PACKAGER" @@ -302,4 +302,4 @@ setupDWM makeDWM install_nerd_font clone_config_folders -configure_backgrounds \ No newline at end of file +configure_backgrounds diff --git a/tabs/common-script.sh b/tabs/common-script.sh index bfea62f4..aa338ba6 100644 --- a/tabs/common-script.sh +++ b/tabs/common-script.sh @@ -11,6 +11,36 @@ command_exists() { which "$1" >/dev/null 2>&1 } +checkAURHelper() { + ## Check & Install AUR helper + if [ "$PACKAGER" = "pacman" ]; then + if [ -z "$AUR_HELPER_CHECKED" ]; then + AUR_HELPERS="yay paru" + for helper in ${AUR_HELPERS}; do + if command_exists "${helper}"; then + AUR_HELPER=${helper} + echo "Using ${helper} as AUR helper" + AUR_HELPER_CHECKED=true + return 0 + fi + done + + echo "Installing yay as AUR helper..." + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R "$USER":"$USER" ./yay-git + cd yay-git && makepkg --noconfirm -si + + if command_exists yay; then + AUR_HELPER="yay" + AUR_HELPER_CHECKED=true + else + echo -e "${RED}Failed to install AUR helper.${RC}" + exit 1 + fi + fi + fi +} + checkEscalationTool() { ## Check for escalation tools. if [ -z "$ESCALATION_TOOL_CHECKED" ]; then @@ -100,4 +130,5 @@ checkEnv() { checkSuperUser checkDistro checkEscalationTool + checkAURHelper } diff --git a/tabs/system-setup/1-compile-setup.sh b/tabs/system-setup/1-compile-setup.sh index 2e1f644f..1a45d153 100755 --- a/tabs/system-setup/1-compile-setup.sh +++ b/tabs/system-setup/1-compile-setup.sh @@ -15,22 +15,6 @@ installDepend() { else echo "Multilib is already enabled." fi - if ! command_exists yay && ! command_exists paru; then - echo "Installing yay as AUR helper..." - $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel - cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R "$USER":"$USER" ./yay-git - cd yay-git && makepkg --noconfirm -si - else - echo "Aur helper already installed" - fi - if command_exists yay; then - AUR_HELPER="yay" - elif command_exists paru; then - AUR_HELPER="paru" - else - echo "No AUR helper found. Please install yay or paru." - exit 1 - fi $AUR_HELPER -S --needed --noconfirm "$DEPENDENCIES" ;; apt-get|nala) @@ -80,6 +64,7 @@ install_additional_dependencies() { } checkEnv +checkAURHelper checkEscalationTool installDepend -install_additional_dependencies +install_additional_dependencies \ No newline at end of file diff --git a/tabs/system-setup/2-gaming-setup.sh b/tabs/system-setup/2-gaming-setup.sh index 207d7817..ce52aea2 100755 --- a/tabs/system-setup/2-gaming-setup.sh +++ b/tabs/system-setup/2-gaming-setup.sh @@ -13,22 +13,6 @@ installDepend() { else echo "Multilib is already enabled." fi - if ! command_exists yay && ! command_exists paru; then - echo "Installing yay as AUR helper..." - $ESCALATION_TOOL ${PACKAGER} -S --needed --noconfirm base-devel - cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R ${USER}:${USER} ./yay-git - cd yay-git && makepkg --noconfirm -si - else - echo "Aur helper already installed" - fi - if command_exists yay; then - AUR_HELPER="yay" - elif command_exists paru; then - AUR_HELPER="paru" - else - echo "No AUR helper found. Please install yay or paru." - exit 1 - fi $AUR_HELPER -S --needed --noconfirm wine giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls \ mpg123 lib32-mpg123 openal lib32-openal v4l-utils lib32-v4l-utils libpulse lib32-libpulse libgpg-error \ lib32-libgpg-error alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib libjpeg-turbo lib32-libjpeg-turbo \ @@ -109,6 +93,7 @@ install_additional_dependencies() { } checkEnv +checkAURHelper checkEscalationTool installDepend -install_additional_dependencies +install_additional_dependencies \ No newline at end of file diff --git a/tabs/system-setup/system-update.sh b/tabs/system-setup/system-update.sh index 195ddf69..24c5eed2 100755 --- a/tabs/system-setup/system-update.sh +++ b/tabs/system-setup/system-update.sh @@ -5,25 +5,8 @@ fastUpdate() { case ${PACKAGER} in pacman) - if ! command_exists yay && ! command_exists paru; then - echo "Installing yay as AUR helper..." - $ESCALATION_TOOL ${PACKAGER} -S --needed --noconfirm base-devel || { echo -e "${RED}Failed to install base-devel${RC}"; exit 1; } - cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R ${USER}:${USER} ./yay-git - cd yay-git && makepkg --noconfirm -si || { echo -e "${RED}Failed to install yay${RC}"; exit 1; } - else - echo "AUR helper already installed" - fi - if command_exists yay; then - AUR_HELPER="yay" - elif command_exists paru; then - AUR_HELPER="paru" - else - echo "No AUR helper found. Please install yay or paru." - exit 1 - fi - - ${AUR_HELPER} -S --needed --noconfirm rate-mirrors-bin + $AUR_HELPER -S --needed --noconfirm rate-mirrors-bin if [ -s /etc/pacman.d/mirrorlist ]; then $ESCALATION_TOOL cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak @@ -113,7 +96,8 @@ updateFlatpaks() { } checkEnv +checkAURHelper checkEscalationTool fastUpdate updateSystem -updateFlatpaks +updateFlatpaks \ No newline at end of file diff --git a/tui/Cargo.toml b/tui/Cargo.toml index ad4e2d19..383dd154 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -6,11 +6,11 @@ license.workspace = true [dependencies] clap = { version = "4.5.16", features = ["derive"] } -crossterm = "0.27.0" +crossterm = "0.28.1" ego-tree = { workspace = true } oneshot = "0.1.8" portable-pty = "0.8.1" -ratatui = "0.27.0" +ratatui = "0.28.1" tui-term = "0.1.12" unicode-width = "0.1.13" linutil_core = { path = "../core" } diff --git a/tui/src/filter.rs b/tui/src/filter.rs index caf69502..e6ff2cc2 100644 --- a/tui/src/filter.rs +++ b/tui/src/filter.rs @@ -3,7 +3,7 @@ use crossterm::event::{KeyCode, KeyEvent}; use ego_tree::NodeId; use linutil_core::Tab; use ratatui::{ - layout::Rect, + layout::{Position, Rect}, style::Style, text::Span, widgets::{Block, Borders, Paragraph}, @@ -109,7 +109,7 @@ impl Filter { .sum(); let x = area.x + cursor_position as u16 + 1; let y = area.y + 1; - frame.set_cursor(x, y); + frame.set_cursor_position(Position::new(x, y)); } } // Handles key events. Returns true if search must be exited diff --git a/tui/src/float.rs b/tui/src/float.rs index 3b063cae..e60fe464 100644 --- a/tui/src/float.rs +++ b/tui/src/float.rs @@ -4,10 +4,13 @@ use ratatui::{ Frame, }; +use crate::hint::ShortcutList; + pub trait FloatContent { fn draw(&mut self, frame: &mut Frame, area: Rect); fn handle_key_event(&mut self, key: &KeyEvent) -> bool; fn is_finished(&self) -> bool; + fn get_shortcut_list(&self) -> ShortcutList; } pub struct Float { @@ -69,4 +72,8 @@ impl Float { _ => self.content.handle_key_event(key), } } + + pub fn get_shortcut_list(&self) -> ShortcutList { + self.content.get_shortcut_list() + } } diff --git a/tui/src/floating_text.rs b/tui/src/floating_text.rs index 18ea1812..ccf796ee 100644 --- a/tui/src/floating_text.rs +++ b/tui/src/floating_text.rs @@ -1,4 +1,7 @@ -use crate::float::FloatContent; +use crate::{ + float::FloatContent, + hint::{Shortcut, ShortcutList}, +}; use crossterm::event::{KeyCode, KeyEvent}; use linutil_core::Command; use ratatui::{ @@ -104,4 +107,15 @@ impl FloatContent for FloatingText { fn is_finished(&self) -> bool { true } + + fn get_shortcut_list(&self) -> ShortcutList { + ShortcutList { + scope_name: "Floating text", + hints: vec![ + Shortcut::new(vec!["j", "Down"], "Scroll down"), + Shortcut::new(vec!["k", "Up"], "Scroll up"), + Shortcut::new(vec!["Enter", "q"], "Close window"), + ], + } + } } diff --git a/tui/src/hint.rs b/tui/src/hint.rs new file mode 100644 index 00000000..27474ea9 --- /dev/null +++ b/tui/src/hint.rs @@ -0,0 +1,161 @@ +use ratatui::{ + layout::{Margin, Rect}, + style::{Style, Stylize}, + text::{Line, Span}, + widgets::{Block, Borders, Paragraph}, + Frame, +}; + +use crate::state::{AppState, Focus}; + +pub const SHORTCUT_LINES: usize = 2; + +pub struct ShortcutList { + pub scope_name: &'static str, + pub hints: Vec, +} + +pub struct Shortcut { + pub key_sequenses: Vec>, + pub desc: &'static str, +} + +pub fn span_vec_len(span_vec: &[Span]) -> usize { + span_vec.iter().rfold(0, |init, s| init + s.width()) +} +impl ShortcutList { + pub fn draw(&self, frame: &mut Frame, area: Rect) { + let block = Block::default() + .title(self.scope_name) + .borders(Borders::all()); + let inner_area = area.inner(Margin::new(1, 1)); + let mut shortcut_list: Vec> = self.hints.iter().map(|h| h.to_spans()).collect(); + + let mut lines = vec![Line::default(); SHORTCUT_LINES]; + let mut idx = 0; + + while idx < SHORTCUT_LINES - 1 { + let split_idx = shortcut_list + .iter() + .scan(0usize, |total_len, s| { + *total_len += span_vec_len(s); + if *total_len > inner_area.width as usize { + None + } else { + *total_len += 4; + Some(1) + } + }) + .count(); + let new_shortcut_list = shortcut_list.split_off(split_idx); + let line: Vec<_> = shortcut_list + .into_iter() + .flat_map(|mut s| { + s.push(Span::default().content(" ")); + s + }) + .collect(); + shortcut_list = new_shortcut_list; + lines[idx] = line.into(); + idx += 1; + } + lines[idx] = shortcut_list + .into_iter() + .flat_map(|mut s| { + s.push(Span::default().content(" ")); + s + }) + .collect(); + + let p = Paragraph::new(lines).block(block); + frame.render_widget(p, area); + } +} + +impl Shortcut { + pub fn new(key_sequences: Vec<&'static str>, desc: &'static str) -> Self { + Self { + key_sequenses: key_sequences + .iter() + .map(|s| Span::styled(*s, Style::default().bold())) + .collect(), + desc, + } + } + + fn to_spans(&self) -> Vec { + let mut ret: Vec<_> = self + .key_sequenses + .iter() + .flat_map(|seq| { + [ + Span::default().content("["), + seq.clone(), + Span::default().content("] "), + ] + }) + .collect(); + ret.push(Span::styled(self.desc, Style::default().italic())); + ret + } +} + +fn get_list_item_shortcut(state: &AppState) -> Shortcut { + if state.selected_item_is_dir() { + Shortcut::new(vec!["l", "Right", "Enter"], "Go to selected dir") + } else { + Shortcut::new(vec!["l", "Right", "Enter"], "Run selected command") + } +} + +pub fn draw_shortcuts(state: &AppState, frame: &mut Frame, area: Rect) { + match state.focus { + Focus::Search => ShortcutList { + scope_name: "Search bar", + hints: vec![Shortcut::new(vec!["Enter"], "Finish search")], + }, + Focus::List => { + let mut hints = Vec::new(); + hints.push(Shortcut::new(vec!["q", "CTRL-c"], "Exit linutil")); + if state.at_root() { + hints.push(Shortcut::new(vec!["h", "Left", "Tab"], "Focus tab list")); + hints.push(get_list_item_shortcut(state)); + } else { + if state.selected_item_is_up_dir() { + hints.push(Shortcut::new( + vec!["l", "Right", "Enter", "h", "Left"], + "Go to parrent directory", + )); + } else { + hints.push(Shortcut::new(vec!["h", "Left"], "Go to parrent directory")); + hints.push(get_list_item_shortcut(state)); + if state.selected_item_is_cmd() { + hints.push(Shortcut::new(vec!["p"], "Enable preview")); + } + } + hints.push(Shortcut::new(vec!["Tab"], "Focus tab list")); + }; + hints.push(Shortcut::new(vec!["k", "Up"], "Select item above")); + hints.push(Shortcut::new(vec!["j", "Down"], "Select item below")); + hints.push(Shortcut::new(vec!["t"], "Next theme")); + hints.push(Shortcut::new(vec!["T"], "Previous theme")); + ShortcutList { + scope_name: "Item list", + hints, + } + } + Focus::TabList => ShortcutList { + scope_name: "Tab list", + hints: vec![ + Shortcut::new(vec!["q", "CTRL-c"], "Exit linutil"), + Shortcut::new(vec!["l", "Right", "Tab", "Enter"], "Focus action list"), + Shortcut::new(vec!["k", "Up"], "Select item above"), + Shortcut::new(vec!["j", "Down"], "Select item below"), + Shortcut::new(vec!["t"], "Next theme"), + Shortcut::new(vec!["T"], "Previous theme"), + ], + }, + Focus::FloatingWindow(ref float) => float.get_shortcut_list(), + } + .draw(frame, area); +} diff --git a/tui/src/main.rs b/tui/src/main.rs index 49793338..4355a910 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,6 +1,7 @@ mod filter; mod float; mod floating_text; +mod hint; mod running_command; pub mod state; mod theme; @@ -62,7 +63,6 @@ fn main() -> std::io::Result<()> { fn run(terminal: &mut Terminal, state: &mut AppState) -> io::Result<()> { loop { terminal.draw(|frame| state.draw(frame)).unwrap(); - // Wait for an event if !event::poll(Duration::from_millis(10))? { continue; diff --git a/tui/src/running_command.rs b/tui/src/running_command.rs index 44021a4b..d8df3402 100644 --- a/tui/src/running_command.rs +++ b/tui/src/running_command.rs @@ -1,4 +1,7 @@ -use crate::float::FloatContent; +use crate::{ + float::FloatContent, + hint::{Shortcut, ShortcutList}, +}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use linutil_core::Command; use oneshot::{channel, Receiver}; @@ -116,6 +119,20 @@ impl FloatContent for RunningCommand { true } } + + fn get_shortcut_list(&self) -> ShortcutList { + if self.is_finished() { + ShortcutList { + scope_name: "Finished command", + hints: vec![Shortcut::new(vec!["Enter", "q"], "Close window")], + } + } else { + ShortcutList { + scope_name: "Running command", + hints: vec![Shortcut::new(vec!["CTRL-c"], "Kill the command")], + } + } + } } impl RunningCommand { diff --git a/tui/src/state.rs b/tui/src/state.rs index 9bf920f5..267e6769 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -2,6 +2,7 @@ use crate::{ filter::{Filter, SearchAction}, float::{Float, FloatContent}, floating_text::FloatingText, + hint::{draw_shortcuts, SHORTCUT_LINES}, running_command::RunningCommand, theme::Theme, }; @@ -9,10 +10,10 @@ use crossterm::event::{KeyCode, KeyEvent, KeyEventKind}; use ego_tree::NodeId; use linutil_core::{Command, ListNode, Tab}; use ratatui::{ - layout::{Constraint, Direction, Layout}, + layout::{Alignment, Constraint, Direction, Layout}, style::{Style, Stylize}, - text::Line, - widgets::{Block, Borders, List, ListState}, + text::{Line, Span}, + widgets::{Block, Borders, List, ListState, Paragraph}, Frame, }; @@ -20,7 +21,7 @@ pub struct AppState { /// Selected theme theme: Theme, /// Currently focused area - focus: Focus, + pub focus: Focus, /// List of tabs tabs: Vec, /// Current tab @@ -64,12 +65,44 @@ impl AppState { state } pub fn draw(&mut self, frame: &mut Frame) { + let label_block = + Block::default() + .borders(Borders::all()) + .border_set(ratatui::symbols::border::Set { + top_left: " ", + top_right: " ", + bottom_left: " ", + bottom_right: " ", + vertical_left: " ", + vertical_right: " ", + horizontal_top: "*", + horizontal_bottom: "*", + }); + let str1 = "Linutil "; + let str2 = "by Chris Titus"; + let label = Paragraph::new(Line::from(vec![ + Span::styled(str1, Style::default().bold()), + Span::styled(str2, Style::default().italic()), + ])) + .block(label_block) + .alignment(Alignment::Center); + let longest_tab_display_len = self .tabs .iter() .map(|tab| tab.name.len() + self.theme.tab_icon().len()) .max() - .unwrap_or(0); + .unwrap_or(0) + .max(str1.len() + str2.len()); + + let vertical = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage(100), + Constraint::Min(2 + SHORTCUT_LINES as u16), + ]) + .margin(0) + .split(frame.area()); let horizontal = Layout::default() .direction(Direction::Horizontal) @@ -77,11 +110,13 @@ impl AppState { Constraint::Min(longest_tab_display_len as u16 + 5), Constraint::Percentage(100), ]) - .split(frame.size()); + .split(vertical[0]); + let left_chunks = Layout::default() .direction(Direction::Vertical) .constraints([Constraint::Length(3), Constraint::Min(1)]) .split(horizontal[0]); + frame.render_widget(label, left_chunks[0]); let tabs = self .tabs @@ -147,6 +182,8 @@ impl AppState { if let Focus::FloatingWindow(float) = &mut self.focus { float.draw(frame, chunks[1]); } + + draw_shortcuts(self, frame, vertical[1]); } pub fn handle_key(&mut self, key: &KeyEvent) -> bool { match &mut self.focus { @@ -212,7 +249,7 @@ impl AppState { /// Checks ehther the current tree node is the root node (can we go up the tree or no) /// Returns `true` if we can't go up the tree (we are at the tree root) /// else returns `false` - fn at_root(&self) -> bool { + pub fn at_root(&self) -> bool { self.visit_stack.len() == 1 } fn enter_parent_directory(&mut self) { @@ -220,13 +257,10 @@ impl AppState { self.selection.select(Some(0)); self.update_items(); } - fn get_selected_command(&mut self, change_directory: bool) -> Option { + pub fn get_selected_command(&self) -> Option { let mut selected_index = self.selection.selected().unwrap_or(0); if !self.at_root() && selected_index == 0 { - if change_directory { - self.enter_parent_directory(); - } return None; } if !self.at_root() { @@ -236,25 +270,83 @@ impl AppState { if let Some(item) = self.filter.item_list().get(selected_index) { if !item.has_children { return Some(item.node.command.clone()); - } else if change_directory { + } + } + None + } + pub fn go_to_selected_dir(&mut self) { + let mut selected_index = self.selection.selected().unwrap_or(0); + + if !self.at_root() && selected_index == 0 { + self.enter_parent_directory(); + return; + } + + if !self.at_root() { + selected_index = selected_index.saturating_sub(1); + } + + if let Some(item) = self.filter.item_list().get(selected_index) { + if item.has_children { self.visit_stack.push(item.id); self.selection.select(Some(0)); self.update_items(); } } - None + } + pub fn selected_item_is_dir(&self) -> bool { + let mut selected_index = self.selection.selected().unwrap_or(0); + + if !self.at_root() && selected_index == 0 { + return false; + } + + if !self.at_root() { + selected_index = selected_index.saturating_sub(1); + } + + if let Some(item) = self.filter.item_list().get(selected_index) { + item.has_children + } else { + false + } + } + + pub fn selected_item_is_cmd(&self) -> bool { + let mut selected_index = self.selection.selected().unwrap_or(0); + + if !self.at_root() && selected_index == 0 { + return false; + } + + if !self.at_root() { + selected_index = selected_index.saturating_sub(1); + } + + if let Some(item) = self.filter.item_list().get(selected_index) { + !item.has_children + } else { + false + } + } + pub fn selected_item_is_up_dir(&self) -> bool { + let selected_index = self.selection.selected().unwrap_or(0); + + !self.at_root() && selected_index == 0 } fn enable_preview(&mut self) { - if let Some(command) = self.get_selected_command(false) { + if let Some(command) = self.get_selected_command() { if let Some(preview) = FloatingText::from_command(&command) { self.spawn_float(preview, 80, 80); } } } fn handle_enter(&mut self) { - if let Some(cmd) = self.get_selected_command(true) { + if let Some(cmd) = self.get_selected_command() { let command = RunningCommand::new(cmd); self.spawn_float(command, 80, 80); + } else { + self.go_to_selected_dir(); } } fn spawn_float(&mut self, float: T, width: u16, height: u16) {