feat: Add `bug-report` sub-command (#725)
This adds a sub command to generate the link. Information, such as operating system and it's version; the current shell's config; and current starship conf, is gathered from the environment and is included in the pre-filled text. The command will also try to open the link in the default browser. Should that fail it will print the link instead and ask the user to copy it.
This commit is contained in:
parent
740b51bd60
commit
76804cc3c8
|
@ -8,6 +8,7 @@ assignees: ''
|
||||||
---
|
---
|
||||||
|
|
||||||
## Bug Report
|
## Bug Report
|
||||||
|
<!-- We recommend running `starship bug-report` in the shell you are experiencing unexpected behavior. The command will automatically pre-fill a report with your system information. -->
|
||||||
|
|
||||||
#### Current Behavior
|
#### Current Behavior
|
||||||
<!-- A clear and concise description of the behavior. -->
|
<!-- A clear and concise description of the behavior. -->
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,6 +46,10 @@ byte-unit = "3.0.3"
|
||||||
starship_module_config_derive = { version = "0.1.0", path = "starship_module_config_derive" }
|
starship_module_config_derive = { version = "0.1.0", path = "starship_module_config_derive" }
|
||||||
yaml-rust = "0.4"
|
yaml-rust = "0.4"
|
||||||
nom = "5.0.1"
|
nom = "5.0.1"
|
||||||
|
os_info = "1.1.3"
|
||||||
|
urlencoding = "1.0.0"
|
||||||
|
open = "1.3.2"
|
||||||
|
reqwest = "0.9.24"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
use crate::utils::exec_cmd;
|
||||||
|
use reqwest;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const GIT_IO_BASE_URL: &str = "https://git.io/";
|
||||||
|
|
||||||
|
pub fn create() {
|
||||||
|
let os_info = os_info::get();
|
||||||
|
|
||||||
|
let environment = Environment {
|
||||||
|
os_type: os_info.os_type(),
|
||||||
|
os_version: os_info.version().to_owned(),
|
||||||
|
shell_info: get_shell_info(),
|
||||||
|
starship_config: get_starship_config(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let link = make_github_issue_link(crate_version!(), environment);
|
||||||
|
|
||||||
|
if open::that(&link).is_ok() {
|
||||||
|
print!("Take a look at your browser. A GitHub issue has been populated with your configuration")
|
||||||
|
} else {
|
||||||
|
let link = reqwest::Client::new()
|
||||||
|
.post(&format!("{}{}", GIT_IO_BASE_URL, "create"))
|
||||||
|
.form(&[("url", &link)])
|
||||||
|
.send()
|
||||||
|
.and_then(|mut response| response.text())
|
||||||
|
.map(|slug| format!("{}{}", GIT_IO_BASE_URL, slug))
|
||||||
|
.unwrap_or(link);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Click this link to create a GitHub issue populated with your configuration:\n\n {}",
|
||||||
|
link
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UNKNOWN_SHELL: &str = "<unknown shell>";
|
||||||
|
const UNKNOWN_VERSION: &str = "<unknown version>";
|
||||||
|
const UNKNOWN_CONFIG: &str = "<unknown config>";
|
||||||
|
|
||||||
|
struct Environment {
|
||||||
|
os_type: os_info::Type,
|
||||||
|
os_version: os_info::Version,
|
||||||
|
shell_info: ShellInfo,
|
||||||
|
starship_config: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_github_issue_link(starship_version: &str, environment: Environment) -> String {
|
||||||
|
let title = urlencoding::encode("Bug Report:");
|
||||||
|
|
||||||
|
let body = urlencoding::encode(&format!("<!--
|
||||||
|
─────────────────────────────────────────────
|
||||||
|
|
||||||
|
This issue has been pre-populated with your system's configuration
|
||||||
|
♥ Thank you for submitting a bug report ♥
|
||||||
|
|
||||||
|
─────────────────────────────────────────────
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Bug Report
|
||||||
|
|
||||||
|
#### Current Behavior
|
||||||
|
<!-- A clear and concise description of the behavior. -->
|
||||||
|
|
||||||
|
#### Expected Behavior
|
||||||
|
<!-- A clear and concise description of what you expected to happen. -->
|
||||||
|
|
||||||
|
#### Additional context/Screenshots
|
||||||
|
<!-- Add any other context about the problem here. If applicable, add screenshots to help explain. -->
|
||||||
|
|
||||||
|
#### Environment
|
||||||
|
- Starship version: {starship_version}
|
||||||
|
- {shell_name} version: {shell_version}
|
||||||
|
- Operating system: {os_name} {os_version}
|
||||||
|
|
||||||
|
#### Relevant Shell Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{shell_config}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Starship Configuration
|
||||||
|
|
||||||
|
```toml
|
||||||
|
{starship_config}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Possible Solution
|
||||||
|
<!--- Only if you have suggestions on a fix for the bug -->",
|
||||||
|
starship_version = starship_version,
|
||||||
|
shell_name = environment.shell_info.name,
|
||||||
|
shell_version = environment.shell_info.version,
|
||||||
|
os_name = environment.os_type,
|
||||||
|
os_version = environment.os_version,
|
||||||
|
shell_config = environment.shell_info.config,
|
||||||
|
starship_config = environment.starship_config,
|
||||||
|
));
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"https://github.com/starship/starship/issues/new?title={}&body={}",
|
||||||
|
title, body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ShellInfo {
|
||||||
|
name: String,
|
||||||
|
version: String,
|
||||||
|
config: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_shell_info() -> ShellInfo {
|
||||||
|
let shell = std::env::var("STARSHIP_SHELL");
|
||||||
|
if shell.is_err() {
|
||||||
|
return ShellInfo {
|
||||||
|
name: UNKNOWN_SHELL.to_string(),
|
||||||
|
version: UNKNOWN_VERSION.to_string(),
|
||||||
|
config: UNKNOWN_CONFIG.to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let shell = shell.unwrap();
|
||||||
|
|
||||||
|
let version = exec_cmd(&shell, &["--version"])
|
||||||
|
.map(|output| output.stdout.trim().to_string())
|
||||||
|
.unwrap_or_else(|| UNKNOWN_VERSION.to_string());
|
||||||
|
|
||||||
|
let config = get_config_path(&shell)
|
||||||
|
.and_then(|config_path| fs::read_to_string(config_path).ok())
|
||||||
|
.map(|config| config.trim().to_string())
|
||||||
|
.unwrap_or_else(|| UNKNOWN_CONFIG.to_string());
|
||||||
|
|
||||||
|
ShellInfo {
|
||||||
|
name: shell,
|
||||||
|
version,
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config_path(shell: &str) -> Option<PathBuf> {
|
||||||
|
dirs::home_dir().and_then(|home_dir| {
|
||||||
|
match shell {
|
||||||
|
"bash" => Some(".bashrc"),
|
||||||
|
"fish" => Some(".config/fish/config.fish"),
|
||||||
|
"ion" => Some("~/.config/ion/initrc"),
|
||||||
|
"powershell" => {
|
||||||
|
if cfg!(windows) {
|
||||||
|
Some("Documents/PowerShell/Microsoft.PowerShell_profile.ps1")
|
||||||
|
} else {
|
||||||
|
Some(".config/powershell/Microsoft.PowerShell_profile.ps1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"zsh" => Some(".zshrc"),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.map(|path| home_dir.join(path))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_starship_config() -> String {
|
||||||
|
dirs::home_dir()
|
||||||
|
.and_then(|home_dir| fs::read_to_string(home_dir.join(".config/starship.toml")).ok())
|
||||||
|
.unwrap_or_else(|| UNKNOWN_CONFIG.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use os_info;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_make_github_issue_link() {
|
||||||
|
let starship_version = "0.1.2";
|
||||||
|
let environment = Environment {
|
||||||
|
os_type: os_info::Type::Linux,
|
||||||
|
os_version: os_info::Version::semantic(1, 2, 3, Some("test".to_string())),
|
||||||
|
shell_info: ShellInfo {
|
||||||
|
name: "test_shell".to_string(),
|
||||||
|
version: "2.3.4".to_string(),
|
||||||
|
config: "No config".to_string(),
|
||||||
|
},
|
||||||
|
starship_config: "No Starship config".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let link = make_github_issue_link(starship_version, environment);
|
||||||
|
|
||||||
|
assert!(link.contains(starship_version));
|
||||||
|
assert!(link.contains("Linux"));
|
||||||
|
assert!(link.contains("1.2.3"));
|
||||||
|
assert!(link.contains("test_shell"));
|
||||||
|
assert!(link.contains("2.3.4"));
|
||||||
|
assert!(link.contains("No%20config"));
|
||||||
|
assert!(link.contains("No%20Starship%20config"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_shell_info() {
|
||||||
|
env::remove_var("STARSHIP_SHELL");
|
||||||
|
let unknown_shell = get_shell_info();
|
||||||
|
assert_eq!(UNKNOWN_SHELL, &unknown_shell.name);
|
||||||
|
|
||||||
|
env::set_var("STARSHIP_SHELL", "fish");
|
||||||
|
|
||||||
|
let fish_shell = get_shell_info();
|
||||||
|
assert_eq!("fish", &fish_shell.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn test_get_config_path() {
|
||||||
|
env::set_var("HOME", "/test/home");
|
||||||
|
|
||||||
|
let config_path = get_config_path("bash");
|
||||||
|
assert_eq!("/test/home/.bashrc", config_path.unwrap().to_str().unwrap());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
|
||||||
|
mod bug_report;
|
||||||
mod config;
|
mod config;
|
||||||
mod configs;
|
mod configs;
|
||||||
mod context;
|
mod context;
|
||||||
|
@ -64,7 +65,8 @@ fn main() {
|
||||||
.long("print-full-init")
|
.long("print-full-init")
|
||||||
.help("Print the main initialization script (as opposed to the init stub)");
|
.help("Print the main initialization script (as opposed to the init stub)");
|
||||||
|
|
||||||
let matches = App::new("starship")
|
let matches =
|
||||||
|
App::new("starship")
|
||||||
.about("The cross-shell prompt for astronauts. ☄🌌️")
|
.about("The cross-shell prompt for astronauts. ☄🌌️")
|
||||||
// pull the version number from Cargo.toml
|
// pull the version number from Cargo.toml
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
|
@ -108,6 +110,9 @@ fn main() {
|
||||||
.arg(&keymap_arg)
|
.arg(&keymap_arg)
|
||||||
.arg(&jobs_arg),
|
.arg(&jobs_arg),
|
||||||
)
|
)
|
||||||
|
.subcommand(SubCommand::with_name("bug-report").about(
|
||||||
|
"Create a pre-populated GitHub issue with information about your configuration",
|
||||||
|
))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
|
@ -132,6 +137,7 @@ fn main() {
|
||||||
print::module(module_name, sub_m.clone());
|
print::module(module_name, sub_m.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
("bug-report", Some(_)) => bug_report::create(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue