From 92e73fa86cec5e9cfc83d0963ff5faa68e860c96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Dec 2022 18:04:11 +0000 Subject: [PATCH 1/7] build(deps): update rust crate once_cell to 1.17.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d89918cf..df169f980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1956,9 +1956,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "opaque-debug" diff --git a/Cargo.toml b/Cargo.toml index 797c3a1ff..30783bc9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ log = { version = "0.4.17", features = ["std"] } # see: https://github.com/NixOS/nixpkgs/issues/160876 notify-rust = { version = "4.6.0", optional = true } nu-ansi-term = "0.46.0" -once_cell = "1.16.0" +once_cell = "1.17.0" open = "3.2.0" # update os module config and tests when upgrading os_info os_info = "3.5.1" From 580113092be6c5f80fb69b7f6775c973b9118432 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:28:56 +0000 Subject: [PATCH 2/7] build(deps): update rust crate shadow-rs to 0.20.0 --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df169f980..6bdef80f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2711,9 +2711,9 @@ dependencies = [ [[package]] name = "shadow-rs" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c401e795850edb4e9fdde5940f856364f0fbab573e8dea58f6ee5f85fcf471d" +checksum = "8da90bd2a722461267a2c5d20b2c6de76dba087348e60484fd6c3fbb48b766d6" dependencies = [ "const_format", "is_debug", diff --git a/Cargo.toml b/Cargo.toml index 30783bc9d..2c724100f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ semver = "1.0.16" serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" sha1 = "0.10.5" -shadow-rs = { version = "0.19.0", default-features = false } +shadow-rs = { version = "0.20.0", default-features = false } # battery is optional (on by default) because the crate doesn't currently build for Termux # see: https://github.com/svartalf/rust-battery/issues/33 starship-battery = { version = "0.7.9", optional = true } @@ -117,7 +117,7 @@ features = [ nix = { version = "0.26.1", default-features = false, features = ["feature", "fs", "user"] } [build-dependencies] -shadow-rs = { version = "0.19.0", default-features = false } +shadow-rs = { version = "0.20.0", default-features = false } dunce = "1.0.3" [target.'cfg(windows)'.build-dependencies] From 69929dd0ac13bf85f0014a3ca40c48655485c5f1 Mon Sep 17 00:00:00 2001 From: cassis163 <42798012+cassis163@users.noreply.github.com> Date: Fri, 30 Dec 2022 18:04:47 +0100 Subject: [PATCH 3/7] docs(nu): Add `-f` flag (#4777) * Add missing -f flag in documentation * Fix Nushell version --- README.md | 4 ++-- docs/README.md | 4 ++-- install/install.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index aee107507..fea32bc76 100644 --- a/README.md +++ b/README.md @@ -332,7 +332,7 @@ Add the following to the end of your Nushell env file (find it by running `$nu.e ```sh mkdir ~/.cache/starship -starship init nu | save ~/.cache/starship/init.nu +starship init nu | save -f ~/.cache/starship/init.nu ``` And add the following to the end of your Nushell configuration (find it by running `$nu.config-path`): @@ -341,7 +341,7 @@ And add the following to the end of your Nushell configuration (find it by runni source ~/.cache/starship/init.nu ``` -Note: Only Nushell v0.61+ is supported +Note: Only Nushell v0.73+ is supported diff --git a/docs/README.md b/docs/README.md index 720a56077..0665a4311 100644 --- a/docs/README.md +++ b/docs/README.md @@ -138,14 +138,14 @@ description: Starship is the minimal, blazing fast, and extremely customizable p ::: warning This will change in the future. - Only Nushell v0.61+ is supported. + Only Nushell v0.73+ is supported. ::: Add the following to the end of your Nushell env file (find it by running `$nu.env-path` in Nushell): ```sh mkdir ~/.cache/starship - starship init nu | save ~/.cache/starship/init.nu + starship init nu | save -f ~/.cache/starship/init.nu ``` And add the following to the end of your Nushell configuration (find it by running `$nu.config-path`): diff --git a/install/install.sh b/install/install.sh index b100b9eb0..65d30422d 100755 --- a/install/install.sh +++ b/install/install.sh @@ -338,10 +338,10 @@ print_install() { # shellcheck disable=SC2088 config_file="${BOLD}your nu config file${NO_COLOR} (find it by running ${BOLD}\$nu.config-path${NO_COLOR} in Nushell)" config_cmd="mkdir ~/.cache/starship - starship init nu | save ~/.cache/starship/init.nu + starship init nu | save -f ~/.cache/starship/init.nu source ~/.cache/starship/init.nu" warning="${warning} This will change in the future. - Only Nushell v0.61 or higher is supported. + Only Nushell v0.73 or higher is supported. Add the following to the end of ${BOLD}your Nushell env file${NO_COLOR} (find it by running ${BOLD}\$nu.env-path${NO_COLOR} in Nushell): \"mkdir ~/.cache/starship; starship init nu | save ~/.cache/starship/init.nu\"" ;; esac From e0590f1669746aab14ef90f25f0edc8ca37fba82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 20:45:23 +0000 Subject: [PATCH 4/7] build(deps): update gitoxide crates --- Cargo.lock | 84 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 4 +-- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bdef80f0..06f642b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -885,9 +885,9 @@ dependencies = [ [[package]] name = "git-actor" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7def29b46f25f95a2e196323cfb336eae9965e0a3c7c35ad9506f295c3a8e234" +checksum = "599cb75eb7c3bf03149b7ab70c66bc0b9a432a092b1154b49d21b49fc7e4bd93" dependencies = [ "bstr", "btoi", @@ -899,9 +899,9 @@ dependencies = [ [[package]] name = "git-attributes" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0affaed361598fdd06b2a184a566c823d0b5817b09f576018248fb267193a96" +checksum = "f8013dfce47c1e29236d732308933e2c77af5355ec5105755d26faf7764d3f7b" dependencies = [ "bstr", "compact_str", @@ -933,18 +933,18 @@ dependencies = [ [[package]] name = "git-command" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6b98a6312fef79b326c0a6e15d576c2bd30f7f9d0b7964998d166049e0d7b9e" +checksum = "215145cc1686a45bc6f9872b153a0d3f3c40a1b94173a928325e1b53dfa5e2af" dependencies = [ "bstr", ] [[package]] name = "git-config" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ff189268cfb19d5151529ac30b6b708072ebfa1075643d785232675456ec320" +checksum = "d1b95089db62159d7d24c13ddfb4bf949c508521d0bb25331744ef500295ceb8" dependencies = [ "bstr", "git-config-value", @@ -976,9 +976,9 @@ dependencies = [ [[package]] name = "git-credentials" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28da3d029be10258007699d002321a3b1ebe45e67b0e140a4cf464ba3ee79b32" +checksum = "97cd6bbe001afd6356b35ef13f2a6b0f0abc0133d1b2ecaec1033bdd769616d6" dependencies = [ "bstr", "git-command", @@ -1004,9 +1004,9 @@ dependencies = [ [[package]] name = "git-diff" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f30011a43908645c492dfbea7b004e10528be6bd667bf5cdc12ff4297fe1e3c" +checksum = "a8ae775956f509fe115b173d79e539f97539d40c1d5c5c63a61d10eaf79c857a" dependencies = [ "git-hash", "git-object", @@ -1016,9 +1016,9 @@ dependencies = [ [[package]] name = "git-discover" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c244b1cf7cf45501116e948506c25324e33ddc613f00557ff5bfded2132009" +checksum = "aab20ca6af631c2bb10d59e63377ca9c9c74908586e6018ab15377967432e68b" dependencies = [ "bstr", "git-hash", @@ -1030,9 +1030,9 @@ dependencies = [ [[package]] name = "git-features" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f98e6ede7b790dfba16bf3c62861ae75c3719485d675b522cf7d7e748a4011c" +checksum = "5ff74064fa007c5beefa89a64bb72834f32b3c497750a56c79c6802bbdb311f9" dependencies = [ "crc32fast", "crossbeam-channel", @@ -1083,9 +1083,9 @@ dependencies = [ [[package]] name = "git-index" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20627f71f3a884b0ae50f9f3abb3a07d9b117d06e16110d25b85da4d71d478c0" +checksum = "430f5d9302a2dd5e50b6b04a3b9d0df6b3423e55908fde18333fe9cd51312027" dependencies = [ "atoi", "bitflags", @@ -1116,9 +1116,9 @@ dependencies = [ [[package]] name = "git-mailmap" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90e3ee2eaeebda8a12d17f4d99dff5b19d81536476020bcebb99ee121820466" +checksum = "396cef08d4ec18ea35fed043f5b003e46957603a01349dd429a4773c146fefca" dependencies = [ "bstr", "git-actor", @@ -1127,9 +1127,9 @@ dependencies = [ [[package]] name = "git-object" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b658f1e3e149d88cb3e0a2234be749bb0cab65887405975dbe6f3190cf6571" +checksum = "fad6c2ddb376b99172dc8b651e11be4cb49cef423de4fad563ebbda4fee3fcf6" dependencies = [ "bstr", "btoi", @@ -1146,9 +1146,9 @@ dependencies = [ [[package]] name = "git-odb" -version = "0.38.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55333419bbb25aa6d39e29155f747ad8e1777fe385f70f447be9d680824d23dd" +checksum = "84ea84e47ae48b95e108664d2991013507694b1b722e4183ed1c9309251b9b10" dependencies = [ "arc-swap", "git-features", @@ -1164,9 +1164,9 @@ dependencies = [ [[package]] name = "git-pack" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed3c9af66949553af9795b9eac9d450a5bdceee9959352cda468997ddce0d2f" +checksum = "692e9c78c57212aa76c71be9a319f80d42fe8191735b3aff5b97b8f034295774" dependencies = [ "bytesize", "clru", @@ -1223,9 +1223,9 @@ dependencies = [ [[package]] name = "git-ref" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c97b7d719e4320179fb64d081016e7faca56fed4a8ee4cf84e4697faad9235a3" +checksum = "b351af399166a5506369e36389d6b9aee744cfa672d0e2ea93d2b01223b1cfbe" dependencies = [ "git-actor", "git-features", @@ -1242,9 +1242,9 @@ dependencies = [ [[package]] name = "git-refspec" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d478e9db0956d60cd386d3348b5ec093e3ae613105a7a75ff6084b886254eba8" +checksum = "fcf699f310ba8530708f599b1ce730eb557ebc0af1a1a57b882ce3d685571092" dependencies = [ "bstr", "git-hash", @@ -1256,9 +1256,9 @@ dependencies = [ [[package]] name = "git-repository" -version = "0.30.2" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1925a65a9fea6587e969a7a85cb239c8e1e438cf6dc520406df1b4c9d0e83bdc" +checksum = "d9e21852e326233c5f3f034a44b66215c166506e5ccf227de7e28ccdfbcfb47a" dependencies = [ "git-actor", "git-attributes", @@ -1299,9 +1299,9 @@ dependencies = [ [[package]] name = "git-revision" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7516b1db551756b4d3176c4b7d18ccc4b79d35dcc5e74f768c90f5bb11bb6c9" +checksum = "8b64c0d2e37eb24c8897d11a2f77371a817c3d40dc744d4a2f048f33236eef6b" dependencies = [ "bstr", "git-date", @@ -1340,9 +1340,9 @@ dependencies = [ [[package]] name = "git-traverse" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5141dde56d0c4861193c760e01fb61c7e03a32d0840ba93a0ac1c597588d4d" +checksum = "43b91ed45b561161ba56b85a83865825b7d17a6b1c6f981e831a78b93cf2cc5f" dependencies = [ "git-hash", "git-hashtable", @@ -1352,9 +1352,9 @@ dependencies = [ [[package]] name = "git-url" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8651924c9692a778f09141ca44d1bf2dada229fe9b240f1ff1bdecd9621a1a93" +checksum = "c85af407ed0dbb8d8da2a7241827d2fd5681186d9dab3570fc8dd8d6152ec48f" dependencies = [ "bstr", "git-features", @@ -1376,9 +1376,9 @@ dependencies = [ [[package]] name = "git-worktree" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d748c54c3d904c914b987654a1416c7abe7cf048fdc83eeae69e6ac3d76f20" +checksum = "ffc45b5ac445d0f8719def12303f037966f810cf399ebe0daf29217865df9a49" dependencies = [ "bstr", "git-attributes", @@ -2318,9 +2318,9 @@ dependencies = [ [[package]] name = "prodash" -version = "22.1.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2b91fcc982d0d8ae5e9d477561c73e09c24c5c19bac4858e202f6f065a13e" +checksum = "5d8c414345b4a98cbcd0e8d8829c8f54b47a7ed4fb771c45b7c5c6c0ae23dc4c" dependencies = [ "bytesize", "dashmap", diff --git a/Cargo.toml b/Cargo.toml index 2c724100f..ba77768f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,9 +48,9 @@ clap_complete = "4.0.7" dirs-next = "2.0.0" dunce = "1.0.3" gethostname = "0.4.1" -git-features = { version = "0.25.1", optional = true } +git-features = { version = "0.26.0", optional = true } # default feature restriction addresses https://github.com/starship/starship/issues/4251 -git-repository = { version = "0.30.2", default-features = false, features = ["max-performance-safe"] } +git-repository = { version = "0.31.0", default-features = false, features = ["max-performance-safe"] } indexmap = { version = "1.9.2", features = ["serde"] } log = { version = "0.4.17", features = ["std"] } # nofity-rust is optional (on by default) because the crate doesn't currently build for darwin with nix From 8a8e09dd507b77194c52bb3f2e1826aed2e13390 Mon Sep 17 00:00:00 2001 From: John Slowik Date: Sat, 31 Dec 2022 05:35:28 -0600 Subject: [PATCH 5/7] docs(preset): Plaintext status added (#4775) * Plaintext status added * One test case --- .../presets/toml/plain-text-symbols.toml | 3 +++ src/modules/status.rs | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml index 66eca654d..e9ee0b95b 100644 --- a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml +++ b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml @@ -180,6 +180,9 @@ symbol = "scala " [spack] symbol = "spack " +[status] +symbol = "[x](bold red) " + [sudo] symbol = "sudo " diff --git a/src/modules/status.rs b/src/modules/status.rs index 8d17ea403..4c33896cf 100644 --- a/src/modules/status.rs +++ b/src/modules/status.rs @@ -337,6 +337,27 @@ mod tests { } } + #[test] + fn failure_plaintext_status() { + let exit_values = [1, 2, 130]; + + for status in &exit_values { + let expected = Some(format!( + "{} ", + Color::Red.bold().paint(format!("x {status}")) + )); + let actual = ModuleRenderer::new("status") + .config(toml::toml! { + [status] + symbol = "[x](bold red) " + disabled = false + }) + .status(*status) + .collect(); + assert_eq!(expected, actual); + } + } + #[test] fn failure_hex_status() { let exit_values = [1, 2, 130, -2_147_467_260, 2_147_500_036]; From 8d2256ab1d0ba288fb6ba9b9248bc2210ca01059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Sat, 31 Dec 2022 15:53:55 +0100 Subject: [PATCH 6/7] feat(hg_branch): Add support for mercurial topics and find hg root dir (#4771) * feat(hg_branch): Add support for mercurial topics and find hg root dir * Fix clippy errors * Use crate::utils::read_file * Update config-schema.json * Extend PathExt to retrieve device ID of Path * Break hg root search when switching to another device * Fix clippy and formatting errors * Update docs/config/README.md Co-authored-by: David Knaack * Update src/modules/utils/path.rs Co-authored-by: David Knaack * Update src/configs/hg_branch.rs Co-authored-by: David Knaack * Update hg_branch description * Revert to lazy loading, use truncate_text from utils and use fake topic * Format code and fix clippy error * Revert to previous test string as topic is optional in the config * Fix doc formatting * Stub device_id for windows * Update config-schema.json * Update src/modules/hg_branch.rs Co-authored-by: David Knaack * Do not use unwrap in device_id * Fix formatter error * Use dev under non linux unixes Co-authored-by: David Knaack --- .github/config-schema.json | 4 +- docs/config/README.md | 29 ++++++------- src/configs/hg_branch.rs | 2 +- src/modules/hg_branch.rs | 86 +++++++++++++++++++++++++------------- src/modules/mod.rs | 2 +- src/modules/utils/path.rs | 25 +++++++++++ 6 files changed, 100 insertions(+), 48 deletions(-) diff --git a/.github/config-schema.json b/.github/config-schema.json index 7924c0cea..e4111cbc3 100644 --- a/.github/config-schema.json +++ b/.github/config-schema.json @@ -750,7 +750,7 @@ "hg_branch": { "default": { "disabled": true, - "format": "on [$symbol$branch]($style) ", + "format": "on [$symbol$branch(:$topic)]($style) ", "style": "bold purple", "symbol": " ", "truncation_length": 9223372036854775807, @@ -3537,7 +3537,7 @@ "type": "string" }, "format": { - "default": "on [$symbol$branch]($style) ", + "default": "on [$symbol$branch(:$topic)]($style) ", "type": "string" }, "truncation_length": { diff --git a/docs/config/README.md b/docs/config/README.md index f8b27bfd1..1fc4968fe 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -2643,26 +2643,27 @@ style = 'bold dimmed green' ## Mercurial Branch -The `hg_branch` module shows the active branch of the repo in your current directory. +The `hg_branch` module shows the active branch and topic of the repo in your current directory. ### Options -| Option | Default | Description | -| ------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- | -| `symbol` | `' '` | The symbol used before the hg bookmark or branch name of the repo in your current directory. | -| `style` | `'bold purple'` | The style for the module. | -| `format` | `'on [$symbol$branch]($style) '` | The format for the module. | -| `truncation_length` | `2^63 - 1` | Truncates the hg branch name to `N` graphemes | -| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. | -| `disabled` | `true` | Disables the `hg_branch` module. | +| Option | Default | Description | +| ------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------- | +| `symbol` | `' '` | The symbol used before the hg bookmark or branch name of the repo in your current directory. | +| `style` | `'bold purple'` | The style for the module. | +| `format` | `'on [$symbol$branch(:$topic)]($style) '` | The format for the module. | +| `truncation_length` | `2^63 - 1` | Truncates the hg branch / topic name to `N` graphemes | +| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. | +| `disabled` | `true` | Disables the `hg_branch` module. | ### Variables -| Variable | Example | Description | -| -------- | -------- | ------------------------------------ | -| branch | `master` | The active mercurial branch | -| symbol | | Mirrors the value of option `symbol` | -| style\* | | Mirrors the value of option `style` | +| Variable | Example | Description | +| -------- | --------- | ------------------------------------ | +| branch | `master` | The active mercurial branch | +| topic | `feature` | The active mercurial topic | +| symbol | | Mirrors the value of option `symbol` | +| style\* | | Mirrors the value of option `style` | *: This variable can only be used as a part of a style string diff --git a/src/configs/hg_branch.rs b/src/configs/hg_branch.rs index 9e45fe5ff..fff150c96 100644 --- a/src/configs/hg_branch.rs +++ b/src/configs/hg_branch.rs @@ -21,7 +21,7 @@ impl<'a> Default for HgBranchConfig<'a> { HgBranchConfig { symbol: " ", style: "bold purple", - format: "on [$symbol$branch]($style) ", + format: "on [$symbol$branch(:$topic)]($style) ", truncation_length: std::i64::MAX, truncation_symbol: "…", disabled: true, diff --git a/src/modules/hg_branch.rs b/src/modules/hg_branch.rs index 3aefd4b65..cb2adecd9 100644 --- a/src/modules/hg_branch.rs +++ b/src/modules/hg_branch.rs @@ -1,20 +1,18 @@ -use unicode_segmentation::UnicodeSegmentation; +use std::io::{Error, ErrorKind}; +use std::path::Path; +use super::utils::truncate::truncate_text; use super::{Context, Module, ModuleConfig}; use crate::configs::hg_branch::HgBranchConfig; use crate::formatter::StringFormatter; +use crate::modules::utils::path::PathExt; +use crate::utils::read_file; /// Creates a module with the Hg bookmark or branch in the current directory /// /// Will display the bookmark or branch name if the current directory is an hg repo pub fn module<'a>(context: &'a Context) -> Option> { - let is_hg_repo = context.try_begin_scan()?.set_folders(&[".hg"]).is_match(); - - if !is_hg_repo { - return None; - } - let mut module = context.new_module("hg_branch"); let config: HgBranchConfig = HgBranchConfig::try_load(module.config); @@ -34,16 +32,16 @@ pub fn module<'a>(context: &'a Context) -> Option> { config.truncation_length as usize }; - let branch_name = - get_hg_current_bookmark(context).unwrap_or_else(|| get_hg_branch_name(context)); + let repo_root = get_hg_repo_root(context).ok()?; + let branch_name = get_hg_current_bookmark(repo_root).unwrap_or_else(|_| { + get_hg_branch_name(repo_root).unwrap_or_else(|_| String::from("default")) + }); - let truncated_graphemes = get_graphemes(&branch_name, len); - // The truncation symbol should only be added if we truncated - let truncated_and_symbol = if len < graphemes_len(&branch_name) { - let truncation_symbol = get_graphemes(config.truncation_symbol, 1); - truncated_graphemes + truncation_symbol.as_str() + let branch_graphemes = truncate_text(&branch_name, len, config.truncation_symbol); + let topic_graphemes = if let Ok(topic) = get_hg_topic_name(repo_root) { + truncate_text(&topic, len, config.truncation_symbol) } else { - truncated_graphemes + String::from("") }; let parsed = StringFormatter::new(config.format).and_then(|formatter| { @@ -57,7 +55,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { _ => None, }) .map(|variable| match variable { - "branch" => Some(Ok(truncated_and_symbol.as_str())), + "branch" => Some(Ok(branch_graphemes.as_str())), + "topic" => Some(Ok(topic_graphemes.as_str())), _ => None, }) .parse(None, Some(context)) @@ -74,26 +73,33 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_hg_branch_name(ctx: &Context) -> String { - std::fs::read_to_string(ctx.current_dir.join(".hg").join("branch")) - .map_or_else(|_| "default".to_string(), |s| s.trim().into()) +fn get_hg_repo_root<'a>(ctx: &'a Context) -> Result<&'a Path, Error> { + let dir = ctx.current_dir.as_path(); + let dev_id = dir.device_id(); + for root_dir in dir.ancestors() { + if dev_id != root_dir.device_id() { + break; + } + if root_dir.join(".hg").is_dir() { + return Ok(root_dir); + } + } + Err(Error::new(ErrorKind::Other, "No .hg found!")) } -fn get_hg_current_bookmark(ctx: &Context) -> Option { - std::fs::read_to_string(ctx.current_dir.join(".hg").join("bookmarks.current")) - .map(|s| s.trim().into()) - .ok() +fn get_hg_branch_name(hg_root: &Path) -> Result { + match read_file(hg_root.join(".hg").join("branch")) { + Ok(b) => Ok(b.trim().to_string()), + Err(e) => Err(e), + } } -fn get_graphemes(text: &str, length: usize) -> String { - UnicodeSegmentation::graphemes(text, true) - .take(length) - .collect::>() - .concat() +fn get_hg_current_bookmark(hg_root: &Path) -> Result { + read_file(hg_root.join(".hg").join("bookmarks.current")) } -fn graphemes_len(text: &str) -> usize { - UnicodeSegmentation::graphemes(text, true).count() +fn get_hg_topic_name(hg_root: &Path) -> Result { + read_file(hg_root.join(".hg").join("topic")) } #[cfg(test)] @@ -186,6 +192,26 @@ mod tests { tempdir.close() } + #[test] + #[ignore] + fn test_hg_topic() -> io::Result<()> { + let tempdir = fixture_repo(FixtureProvider::Hg)?; + let repo_dir = tempdir.path(); + fs::write(repo_dir.join(".hg").join("topic"), "feature")?; + + let actual = ModuleRenderer::new("hg_branch") + .path(repo_dir.to_str().unwrap()) + .config(toml::toml! { + [hg_branch] + format = "$topic" + disabled = false + }) + .collect(); + + assert_eq!(Some(String::from("feature")), actual); + tempdir.close() + } + #[test] #[ignore] fn test_default_truncation_symbol() -> io::Result<()> { diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 64442937f..53c36ec97 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -249,7 +249,7 @@ pub fn description(module: &str) -> &'static str { "haskell" => "The selected version of the Haskell toolchain", "haxe" => "The currently installed version of Haxe", "helm" => "The currently installed version of Helm", - "hg_branch" => "The active branch of the repo in your current directory", + "hg_branch" => "The active branch and topic of the repo in your current directory", "hostname" => "The system hostname", "java" => "The currently installed version of Java", "jobs" => "The current number of jobs running", diff --git a/src/modules/utils/path.rs b/src/modules/utils/path.rs index 2bbb02b51..5f5ad4847 100644 --- a/src/modules/utils/path.rs +++ b/src/modules/utils/path.rs @@ -13,6 +13,8 @@ pub trait PathExt { /// E.g. `\\?\UNC\server\share\foo` => `\foo` /// E.g. `/foo/bar` => `/foo/bar` fn without_prefix(&self) -> &Path; + /// Get device / volume info + fn device_id(&self) -> Option; } #[cfg(windows)] @@ -80,6 +82,11 @@ impl PathExt for Path { let (_, path) = normalize::normalize_path(self); path } + + fn device_id(&self) -> Option { + // Maybe it should use unimplemented! + Some(42u64) + } } // NOTE: Windows path prefixes are only parsed on Windows. @@ -100,6 +107,24 @@ impl PathExt for Path { fn without_prefix(&self) -> &Path { self } + + #[cfg(target_os = "linux")] + fn device_id(&self) -> Option { + use std::os::linux::fs::MetadataExt; + match self.metadata() { + Ok(m) => Some(m.st_dev()), + Err(_) => None, + } + } + + #[cfg(all(unix, not(target_os = "linux")))] + fn device_id(&self) -> Option { + use std::os::unix::fs::MetadataExt; + match self.metadata() { + Ok(m) => Some(m.dev()), + Err(_) => None, + } + } } #[cfg(test)] From 67b6376e2ef0835350e3e856ade6602b6c187c42 Mon Sep 17 00:00:00 2001 From: Lyle Mantooth Date: Sat, 31 Dec 2022 09:55:23 -0500 Subject: [PATCH 7/7] feat: add pijul_channel module (#4765) * feat: Pijul VCS support * Extra bits needed for new module. * Format Markdown table. * Fix lint. * Don't test Pijul module so thoroughly. Installing from source is too expensive, and compiled binaries are only available for Windows (and unofficially as well). Perhaps once Pijul 1.0.0 comes out of beta there will be more binaries available in package repos. * Format! * Bad rebase, remove Pijul install from workflow. * Mock Pijul commands for code coverage. * Make fake .pijul directory in fixture. * Truly mock `pijul` command. * Rename module from `pijul` to `pijul_channel`. * Format! * Fix config-schema.json. * Missed changing module name in docs/ folder. --- .github/config-schema.json | 46 ++++ .../presets/toml/bracketed-segments.toml | 3 + .../presets/toml/nerd-font-symbols.toml | 3 + .../presets/toml/plain-text-symbols.toml | 3 + docs/config/README.md | 16 ++ src/configs/mod.rs | 3 + src/configs/pijul_channel.rs | 30 +++ src/configs/starship_root.rs | 1 + src/module.rs | 1 + src/modules/mod.rs | 3 + src/modules/pijul_channel.rs | 220 ++++++++++++++++++ src/test/mod.rs | 7 + src/utils.rs | 12 + 13 files changed, 348 insertions(+) create mode 100644 src/configs/pijul_channel.rs create mode 100644 src/modules/pijul_channel.rs diff --git a/.github/config-schema.json b/.github/config-schema.json index e4111cbc3..702d57cb8 100644 --- a/.github/config-schema.json +++ b/.github/config-schema.json @@ -1215,6 +1215,21 @@ } ] }, + "pijul_channel": { + "default": { + "disabled": true, + "format": "on [$symbol$channel]($style) ", + "style": "bold purple", + "symbol": " ", + "truncation_length": 9223372036854775807, + "truncation_symbol": "…" + }, + "allOf": [ + { + "$ref": "#/definitions/PijulConfig" + } + ] + }, "pulumi": { "default": { "disabled": false, @@ -4495,6 +4510,37 @@ }, "additionalProperties": false }, + "PijulConfig": { + "type": "object", + "properties": { + "symbol": { + "default": " ", + "type": "string" + }, + "style": { + "default": "bold purple", + "type": "string" + }, + "format": { + "default": "on [$symbol$channel]($style) ", + "type": "string" + }, + "truncation_length": { + "default": 9223372036854775807, + "type": "integer", + "format": "int64" + }, + "truncation_symbol": { + "default": "…", + "type": "string" + }, + "disabled": { + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, "PulumiConfig": { "type": "object", "properties": { diff --git a/docs/.vuepress/public/presets/toml/bracketed-segments.toml b/docs/.vuepress/public/presets/toml/bracketed-segments.toml index deaa6ae8c..98d3cef2c 100644 --- a/docs/.vuepress/public/presets/toml/bracketed-segments.toml +++ b/docs/.vuepress/public/presets/toml/bracketed-segments.toml @@ -130,6 +130,9 @@ format = '\[[$symbol($version)]($style)\]' [php] format = '\[[$symbol($version)]($style)\]' +[pijul_channel] +format = '\[[$symbol$channel]($style)\]' + [pulumi] format = '\[[$symbol$stack]($style)\]' diff --git a/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml b/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml index 18cb47030..49945e1ad 100644 --- a/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml +++ b/docs/.vuepress/public/presets/toml/nerd-font-symbols.toml @@ -108,6 +108,9 @@ Windows = " " [package] symbol = " " +[pijul_channel] +symbol = "🪺 " + [python] symbol = " " diff --git a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml index e9ee0b95b..eb7d43a17 100644 --- a/docs/.vuepress/public/presets/toml/plain-text-symbols.toml +++ b/docs/.vuepress/public/presets/toml/plain-text-symbols.toml @@ -156,6 +156,9 @@ symbol = "pl " [php] symbol = "php " +[pijul_channel] +symbol = "pijul " + [pulumi] symbol = "pulumi " diff --git a/docs/config/README.md b/docs/config/README.md index 1fc4968fe..601b86e94 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -271,6 +271,7 @@ $git_state\ $git_metrics\ $git_status\ $hg_branch\ +$pijul_channel\ $docker_context\ $package\ $c\ @@ -3175,6 +3176,21 @@ By default the module will be shown if any of the following conditions are met: format = 'via [🔹 $version](147 bold) ' ``` +## Pijul Channel + +The `pijul_channel` module shows the active channel of the repo in your current directory. + +### Options + +| Option | Default | Description | +| ------------------- | --------------------------------- | ------------------------------------------------------------------------------------ | +| `symbol` | `' '` | The symbol used before the pijul channel name of the repo in your current directory. | +| `style` | `'bold purple'` | The style for the module. | +| `format` | `'on [$symbol$channel]($style) '` | The format for the module. | +| `truncation_length` | `2^63 - 1` | Truncates the pijul channel name to `N` graphemes | +| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. | +| `disabled` | `true` | Disables the `pijul` module. | + ## Pulumi The `pulumi` module shows the current username, selected [Pulumi Stack](https://www.pulumi.com/docs/intro/concepts/stack/), and version. diff --git a/src/configs/mod.rs b/src/configs/mod.rs index 8a712e5fb..0aee1fe44 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -61,6 +61,7 @@ pub mod os; pub mod package; pub mod perl; pub mod php; +pub mod pijul_channel; pub mod pulumi; pub mod purescript; pub mod python; @@ -221,6 +222,8 @@ pub struct FullConfig<'a> { #[serde(borrow)] php: php::PhpConfig<'a>, #[serde(borrow)] + pijul_channel: pijul_channel::PijulConfig<'a>, + #[serde(borrow)] pulumi: pulumi::PulumiConfig<'a>, #[serde(borrow)] purescript: purescript::PureScriptConfig<'a>, diff --git a/src/configs/pijul_channel.rs b/src/configs/pijul_channel.rs new file mode 100644 index 000000000..031bea6c7 --- /dev/null +++ b/src/configs/pijul_channel.rs @@ -0,0 +1,30 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Deserialize, Serialize)] +#[cfg_attr( + feature = "config-schema", + derive(schemars::JsonSchema), + schemars(deny_unknown_fields) +)] +#[serde(default)] +pub struct PijulConfig<'a> { + pub symbol: &'a str, + pub style: &'a str, + pub format: &'a str, + pub truncation_length: i64, + pub truncation_symbol: &'a str, + pub disabled: bool, +} + +impl<'a> Default for PijulConfig<'a> { + fn default() -> Self { + PijulConfig { + symbol: " ", + style: "bold purple", + format: "on [$symbol$channel]($style) ", + truncation_length: std::i64::MAX, + truncation_symbol: "…", + disabled: true, + } + } +} diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 891e90746..d857ae55f 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -42,6 +42,7 @@ pub const PROMPT_ORDER: &[&str] = &[ "git_metrics", "git_status", "hg_branch", + "pijul_channel", "docker_context", "package", // ↓ Toolchain version modules ↓ diff --git a/src/module.rs b/src/module.rs index 17a345b6b..f678b3129 100644 --- a/src/module.rs +++ b/src/module.rs @@ -68,6 +68,7 @@ pub const ALL_MODULES: &[&str] = &[ "package", "perl", "php", + "pijul_channel", "pulumi", "purescript", "python", diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 53c36ec97..4ca7adea6 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -58,6 +58,7 @@ mod os; mod package; mod perl; mod php; +mod pijul_channel; mod pulumi; mod purescript; mod python; @@ -159,6 +160,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "package" => package::module(context), "perl" => perl::module(context), "php" => php::module(context), + "pijul_channel" => pijul_channel::module(context), "pulumi" => pulumi::module(context), "purescript" => purescript::module(context), "python" => python::module(context), @@ -273,6 +275,7 @@ pub fn description(module: &str) -> &'static str { "package" => "The package version of the current directory's project", "perl" => "The currently installed version of Perl", "php" => "The currently installed version of PHP", + "pijul_channel" => "The current channel of the repo in the current directory", "pulumi" => "The current username, stack, and installed version of Pulumi", "purescript" => "The currently installed version of PureScript", "python" => "The currently installed version of Python", diff --git a/src/modules/pijul_channel.rs b/src/modules/pijul_channel.rs new file mode 100644 index 000000000..c5af4814b --- /dev/null +++ b/src/modules/pijul_channel.rs @@ -0,0 +1,220 @@ +use super::utils::truncate::truncate_text; +use super::{Context, Module, ModuleConfig}; + +use crate::configs::pijul_channel::PijulConfig; +use crate::formatter::StringFormatter; + +/// Creates a module with the Pijul channel in the current directory +/// +/// Will display the channel lame if the current directory is a pijul repo +pub fn module<'a>(context: &'a Context) -> Option> { + let is_repo = context + .try_begin_scan()? + .set_folders(&[".pijul"]) + .is_match(); + + if !is_repo { + return None; + } + + let mut module = context.new_module("pijul_channel"); + let config: PijulConfig = PijulConfig::try_load(module.config); + + // We default to disabled=true, so we have to check after loading our config module. + if config.disabled { + return None; + }; + + let channel_name = get_pijul_current_channel(context)?; + + let truncated_text = truncate_text( + &channel_name, + config.truncation_length as usize, + config.truncation_symbol, + ); + + let parsed = StringFormatter::new(config.format).and_then(|formatter| { + formatter + .map_meta(|variable, _| match variable { + "symbol" => Some(config.symbol), + _ => None, + }) + .map_style(|variable| match variable { + "style" => Some(Ok(config.style)), + _ => None, + }) + .map(|variable| match variable { + "channel" => Some(Ok(&truncated_text)), + _ => None, + }) + .parse(None, Some(context)) + }); + + module.set_segments(match parsed { + Ok(segments) => segments, + Err(error) => { + log::warn!("Error in module `pijul_channel`:\n{}", error); + return None; + } + }); + + Some(module) +} + +fn get_pijul_current_channel(ctx: &Context) -> Option { + let output = ctx.exec_cmd("pijul", &["channel"])?.stdout; + + output + .lines() + .find_map(|l| l.strip_prefix("* ")) + .map(str::to_owned) +} + +#[cfg(test)] +mod tests { + use nu_ansi_term::{Color, Style}; + use std::io; + use std::path::Path; + + use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer}; + + enum Expect<'a> { + ChannelName(&'a str), + Empty, + NoTruncation, + Symbol(&'a str), + Style(Style), + TruncationSymbol(&'a str), + } + + #[test] + fn show_nothing_on_empty_dir() -> io::Result<()> { + let repo_dir = tempfile::tempdir()?; + + let actual = ModuleRenderer::new("pijul_channel") + .path(repo_dir.path()) + .collect(); + + let expected = None; + assert_eq!(expected, actual); + repo_dir.close() + } + + #[test] + fn test_pijul_disabled_per_default() -> io::Result<()> { + let tempdir = fixture_repo(FixtureProvider::Pijul)?; + let repo_dir = tempdir.path(); + expect_pijul_with_config( + repo_dir, + Some(toml::toml! { + [pijul_channel] + truncation_length = 14 + }), + &[Expect::Empty], + ); + tempdir.close() + } + + #[test] + fn test_pijul_autodisabled() -> io::Result<()> { + let tempdir = tempfile::tempdir()?; + expect_pijul_with_config(tempdir.path(), None, &[Expect::Empty]); + tempdir.close() + } + + #[test] + fn test_pijul_channel() -> io::Result<()> { + let tempdir = fixture_repo(FixtureProvider::Pijul)?; + let repo_dir = tempdir.path(); + run_pijul(&["channel", "new", "tributary-48198"], repo_dir)?; + run_pijul(&["channel", "switch", "tributary-48198"], repo_dir)?; + expect_pijul_with_config( + repo_dir, + None, + &[Expect::ChannelName("tributary-48198"), Expect::NoTruncation], + ); + tempdir.close() + } + + #[test] + fn test_pijul_configured() -> io::Result<()> { + let tempdir = fixture_repo(FixtureProvider::Pijul)?; + let repo_dir = tempdir.path(); + run_pijul(&["channel", "new", "tributary-48198"], repo_dir)?; + run_pijul(&["channel", "switch", "tributary-48198"], repo_dir)?; + expect_pijul_with_config( + repo_dir, + Some(toml::toml! { + [pijul_channel] + style = "underline blue" + symbol = "P " + truncation_length = 14 + truncation_symbol = "%" + disabled = false + }), + &[ + Expect::ChannelName("tributary-4819"), + Expect::Style(Color::Blue.underline()), + Expect::Symbol("P"), + Expect::TruncationSymbol("%"), + ], + ); + tempdir.close() + } + + fn expect_pijul_with_config( + repo_dir: &Path, + config: Option, + expectations: &[Expect], + ) { + let actual = ModuleRenderer::new("pijul_channel") + .path(repo_dir.to_str().unwrap()) + .config(config.unwrap_or_else(|| { + toml::toml! { + [pijul_channel] + disabled = false + } + })) + .collect(); + + let mut expect_channel_name = "main"; + let mut expect_style = Color::Purple.bold(); + let mut expect_symbol = "\u{e0a0}"; + let mut expect_truncation_symbol = "…"; + + for expect in expectations { + match expect { + Expect::Empty => { + assert_eq!(None, actual); + return; + } + Expect::Symbol(symbol) => { + expect_symbol = symbol; + } + Expect::TruncationSymbol(truncation_symbol) => { + expect_truncation_symbol = truncation_symbol; + } + Expect::NoTruncation => { + expect_truncation_symbol = ""; + } + Expect::ChannelName(channel_name) => { + expect_channel_name = channel_name; + } + Expect::Style(style) => expect_style = *style, + } + } + + let expected = Some(format!( + "on {} ", + expect_style.paint(format!( + "{expect_symbol} {expect_channel_name}{expect_truncation_symbol}" + )), + )); + assert_eq!(expected, actual); + } + + fn run_pijul(args: &[&str], _repo_dir: &Path) -> io::Result<()> { + crate::utils::mock_cmd("pijul", args).ok_or(io::ErrorKind::Unsupported)?; + Ok(()) + } +} diff --git a/src/test/mod.rs b/src/test/mod.rs index c6320226a..c761bb981 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -7,6 +7,7 @@ use crate::{ }; use log::{Level, LevelFilter}; use once_cell::sync::Lazy; +use std::fs; use std::io; use std::path::{Path, PathBuf}; use tempfile::TempDir; @@ -165,6 +166,7 @@ impl<'a> ModuleRenderer<'a> { pub enum FixtureProvider { Git, Hg, + Pijul, } pub fn fixture_repo(provider: FixtureProvider) -> io::Result { @@ -223,5 +225,10 @@ pub fn fixture_repo(provider: FixtureProvider) -> io::Result { Ok(path) } + FixtureProvider::Pijul => { + let path = tempfile::tempdir()?; + fs::create_dir(path.path().join(".pijul"))?; + Ok(path) + } } } diff --git a/src/utils.rs b/src/utils.rs index 1d035daca..1cbed2e3d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -337,6 +337,18 @@ WebAssembly: unavailable stderr: String::default(), }) }, + "pijul channel" => Some(CommandOutput{ + stdout: String::from(" main\n* tributary-48198"), + stderr: String::default(), + }), + "pijul channel new tributary-48198" => Some(CommandOutput{ + stdout: String::default(), + stderr: String::default(), + }), + "pijul channel switch tributary-48198" => Some(CommandOutput{ + stdout: String::from("Outputting repository ↖"), + stderr: String::default(), + }), "pulumi version" => Some(CommandOutput{ stdout: String::from("1.2.3-ver.1631311768+e696fb6c"), stderr: String::default(),