mirror of
https://github.com/starship/starship.git
synced 2024-11-22 16:23:17 +01:00
feat(git_commit): add git tag to module (#950)
This commit is contained in:
parent
c938eac1d6
commit
ea9f803018
@ -1043,17 +1043,19 @@ truncation_symbol = ""
|
||||
|
||||
## Git Commit
|
||||
|
||||
The `git_commit` module shows the current commit hash of the repo in your current directory.
|
||||
The `git_commit` module shows the current commit hash and also the tag (if any) of the repo in your current directory.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Default | Description |
|
||||
| -------------------- | ------------------------ | ----------------------------------------------------- |
|
||||
| `commit_hash_length` | `7` | The length of the displayed git commit hash. |
|
||||
| `format` | `'[\($hash\)]($style) '` | The format for the module. |
|
||||
| `style` | `"bold green"` | The style for the module. |
|
||||
| `only_detached` | `true` | Only show git commit hash when in detached HEAD state |
|
||||
| `disabled` | `false` | Disables the `git_commit` module. |
|
||||
| Option | Default | Description |
|
||||
| -------------------- | ---------------------------------------------- | ----------------------------------------------------- |
|
||||
| `commit_hash_length` | `7` | The length of the displayed git commit hash. |
|
||||
| `format` | `"[\\($hash\\)]($style) [\\($tag\\)]($style)"` | The format for the module. |
|
||||
| `style` | `"bold green"` | The style for the module. |
|
||||
| `only_detached` | `true` | Only show git commit hash when in detached HEAD state |
|
||||
| `tag_disabled` | `true` | Disables showing tag info in `git_commit` module. |
|
||||
| `tag_symbol` | `"🏷 "` | Tag symbol prefixing the info shown |
|
||||
| `disabled` | `false` | Disables the `git_commit` module. |
|
||||
|
||||
### Variables
|
||||
|
||||
@ -1071,6 +1073,7 @@ The `git_commit` module shows the current commit hash of the repo in your curren
|
||||
|
||||
[git_commit]
|
||||
commit_hash_length = 4
|
||||
tag_symbol = "🔖 "
|
||||
```
|
||||
|
||||
## Git State
|
||||
|
@ -9,6 +9,8 @@ pub struct GitCommitConfig<'a> {
|
||||
pub style: &'a str,
|
||||
pub only_detached: bool,
|
||||
pub disabled: bool,
|
||||
pub tag_symbol: &'a str,
|
||||
pub tag_disabled: bool,
|
||||
}
|
||||
|
||||
impl<'a> RootModuleConfig<'a> for GitCommitConfig<'a> {
|
||||
@ -16,10 +18,12 @@ impl<'a> RootModuleConfig<'a> for GitCommitConfig<'a> {
|
||||
GitCommitConfig {
|
||||
// be consistent with git by default, which has DEFAULT_ABBREV set to 7
|
||||
commit_hash_length: 7,
|
||||
format: "[\\($hash\\)]($style) ",
|
||||
format: "[\\($hash$tag\\)]($style) ",
|
||||
style: "green bold",
|
||||
only_detached: true,
|
||||
disabled: false,
|
||||
tag_symbol: "🏷 ",
|
||||
tag_disabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let head_commit = git_head.peel_to_commit().ok()?;
|
||||
let commit_oid = head_commit.id();
|
||||
|
||||
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
let mut parsed;
|
||||
|
||||
parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
.map_style(|variable| match variable {
|
||||
"style" => Some(Ok(config.style)),
|
||||
@ -40,6 +42,48 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
.parse(None)
|
||||
});
|
||||
|
||||
if !config.tag_disabled {
|
||||
// Let's get repo tags names
|
||||
let tag_names = git_repo.tag_names(None).ok()?;
|
||||
let tag_and_refs = tag_names.iter().flat_map(|name| {
|
||||
let full_tag = format!("refs/tags/{}", name.unwrap());
|
||||
git_repo
|
||||
.find_reference(&full_tag)
|
||||
.map(|reference| (String::from(name.unwrap()), reference))
|
||||
});
|
||||
|
||||
let mut tag_name = String::new();
|
||||
// Let's check if HEAD has some tag. If several, only gets first...
|
||||
for (name, reference) in tag_and_refs {
|
||||
if commit_oid == reference.peel_to_commit().ok()?.id() {
|
||||
tag_name = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we have tag...
|
||||
if !tag_name.is_empty() {
|
||||
parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
.map_style(|variable| match variable {
|
||||
"style" => Some(Ok(config.style)),
|
||||
_ => None,
|
||||
})
|
||||
.map(|variable| match variable {
|
||||
"hash" => Some(Ok(id_to_hex_abbrev(
|
||||
commit_oid.as_bytes(),
|
||||
config.commit_hash_length,
|
||||
))),
|
||||
_ => None,
|
||||
})
|
||||
.map(|variable| match variable {
|
||||
"tag" => Some(Ok(format!(" {}{}", &config.tag_symbol, &tag_name))),
|
||||
_ => None,
|
||||
})
|
||||
.parse(None)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.set_segments(match parsed {
|
||||
Ok(segments) => segments,
|
||||
Err(error) => {
|
||||
@ -196,4 +240,99 @@ mod tests {
|
||||
assert_eq!(expected, actual);
|
||||
repo_dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_with_tag_enabled() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
let mut git_commit = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_commit.truncate(7);
|
||||
let commit_output = str::from_utf8(&git_commit).unwrap().trim();
|
||||
|
||||
let git_tag = Command::new("git")
|
||||
.args(&["describe", "--tags", "--exact-match", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
let tag_output = str::from_utf8(&git_tag).unwrap().trim();
|
||||
|
||||
let expected_output = format!("{} {}", commit_output, tag_output);
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.config(toml::toml! {
|
||||
[git_commit]
|
||||
only_detached = false
|
||||
tag_disabled = false
|
||||
tag_symbol = ""
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_output.trim()))
|
||||
.to_string()
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_render_commit_hash_only_detached_on_detached_with_tag_enabled() -> io::Result<()> {
|
||||
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["checkout", "@~1"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.args(&["tag", "tagOnDetached", "-m", "Testing tags on detached"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?;
|
||||
|
||||
let mut git_commit = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
git_commit.truncate(7);
|
||||
let commit_output = str::from_utf8(&git_commit).unwrap().trim();
|
||||
|
||||
let git_tag = Command::new("git")
|
||||
.args(&["describe", "--tags", "--exact-match", "HEAD"])
|
||||
.current_dir(&repo_dir.path())
|
||||
.output()?
|
||||
.stdout;
|
||||
let tag_output = str::from_utf8(&git_tag).unwrap().trim();
|
||||
|
||||
let expected_output = format!("{} {}", commit_output, tag_output);
|
||||
|
||||
let actual = ModuleRenderer::new("git_commit")
|
||||
.config(toml::toml! {
|
||||
[git_commit]
|
||||
tag_disabled = false
|
||||
tag_symbol = ""
|
||||
})
|
||||
.path(&repo_dir.path())
|
||||
.collect();
|
||||
|
||||
let expected = Some(format!(
|
||||
"{} ",
|
||||
Color::Green
|
||||
.bold()
|
||||
.paint(format!("({})", expected_output.trim()))
|
||||
.to_string()
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ pub fn description(module: &str) -> &'static str {
|
||||
"erlang" => "Current OTP version",
|
||||
"gcloud" => "The current GCP client configuration",
|
||||
"git_branch" => "The active branch of the repo in your current directory",
|
||||
"git_commit" => "The active commit of the repo in your current directory",
|
||||
"git_commit" => "The active commit (and tag if any) of the repo in your current directory",
|
||||
"git_state" => "The current git operation, and it's progress",
|
||||
"git_status" => "Symbol representing the state of the repo",
|
||||
"golang" => "The currently installed version of Golang",
|
||||
|
Loading…
Reference in New Issue
Block a user