2019-09-10 01:14:38 +02:00
|
|
|
use once_cell::sync::Lazy;
|
2019-07-02 22:12:53 +02:00
|
|
|
use std::io::prelude::*;
|
2019-09-07 19:27:29 +02:00
|
|
|
use std::io::{Error, ErrorKind};
|
2019-07-02 22:12:53 +02:00
|
|
|
use std::path::{Path, PathBuf};
|
2019-09-04 06:20:22 +02:00
|
|
|
use std::process::Command;
|
2019-09-05 18:45:04 +02:00
|
|
|
use std::{env, fs, io, process};
|
2019-06-06 14:18:00 +02:00
|
|
|
|
2019-09-10 01:14:38 +02:00
|
|
|
static MANIFEST_DIR: Lazy<&'static Path> = Lazy::new(|| Path::new(env!("CARGO_MANIFEST_DIR")));
|
|
|
|
static EMPTY_CONFIG: Lazy<PathBuf> = Lazy::new(|| MANIFEST_DIR.join("empty_config.toml"));
|
2019-07-02 22:12:53 +02:00
|
|
|
|
2019-07-28 00:25:13 +02:00
|
|
|
/// Render the full starship prompt
|
|
|
|
pub fn render_prompt() -> process::Command {
|
2019-06-06 14:18:00 +02:00
|
|
|
let mut command = process::Command::new("./target/debug/starship");
|
2019-07-02 22:12:53 +02:00
|
|
|
|
|
|
|
command
|
|
|
|
.arg("prompt")
|
|
|
|
.env_clear()
|
|
|
|
.env("PATH", env!("PATH")) // Provide the $PATH variable so that external programs are runnable
|
|
|
|
.env("STARSHIP_CONFIG", EMPTY_CONFIG.as_os_str());
|
2019-06-06 14:18:00 +02:00
|
|
|
|
|
|
|
command
|
|
|
|
}
|
|
|
|
|
2019-07-28 00:25:13 +02:00
|
|
|
/// Render a specific starship module by name
|
2019-06-06 14:18:00 +02:00
|
|
|
pub fn render_module(module_name: &str) -> process::Command {
|
2019-09-05 18:45:04 +02:00
|
|
|
let binary = fs::canonicalize("./target/debug/starship").unwrap();
|
|
|
|
let mut command = process::Command::new(binary);
|
2019-07-02 22:12:53 +02:00
|
|
|
|
|
|
|
command
|
|
|
|
.arg("module")
|
|
|
|
.arg(module_name)
|
|
|
|
.env_clear()
|
|
|
|
.env("PATH", env!("PATH")) // Provide the $PATH variable so that external programs are runnable
|
|
|
|
.env("STARSHIP_CONFIG", EMPTY_CONFIG.as_os_str());
|
2019-06-06 14:18:00 +02:00
|
|
|
|
|
|
|
command
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a temporary directory with full access permissions (rwxrwxrwt).
|
|
|
|
pub fn new_tempdir() -> io::Result<tempfile::TempDir> {
|
|
|
|
// Using `tempfile::TempDir` directly creates files on macOS within
|
|
|
|
// "/var/folders", which provides us with restricted permissions (rwxr-xr-x)
|
|
|
|
tempfile::tempdir_in("/tmp")
|
|
|
|
}
|
2019-07-02 22:12:53 +02:00
|
|
|
|
2019-09-04 06:20:22 +02:00
|
|
|
/// Create a repo from the fixture to be used in git module tests
|
2019-09-07 19:27:29 +02:00
|
|
|
pub fn create_fixture_repo() -> io::Result<PathBuf> {
|
|
|
|
let fixture_repo_path = new_tempdir()?.path().join("fixture");
|
|
|
|
let repo_path = new_tempdir()?.path().join("rocket");
|
|
|
|
let fixture_path = env::current_dir()?.join("tests/fixtures/rocket.bundle");
|
|
|
|
|
|
|
|
let fixture_repo_dir = path_str(&fixture_repo_path)?;
|
|
|
|
let repo_dir = path_str(&repo_path)?;
|
|
|
|
let fixture = path_str(&fixture_path)?;
|
2019-09-04 06:20:22 +02:00
|
|
|
|
|
|
|
Command::new("git")
|
2019-09-07 19:27:29 +02:00
|
|
|
.args(&["clone", "-b", "master", fixture, fixture_repo_dir])
|
2019-09-04 06:20:22 +02:00
|
|
|
.output()?;
|
|
|
|
|
2019-09-07 19:27:29 +02:00
|
|
|
git2::Repository::clone(fixture_repo_dir, repo_dir).ok();
|
2019-09-07 18:25:01 +02:00
|
|
|
|
|
|
|
Command::new("git")
|
|
|
|
.args(&["config", "--local", "user.email", "starship@example.com"])
|
2019-09-07 19:27:29 +02:00
|
|
|
.current_dir(repo_dir)
|
2019-09-07 18:25:01 +02:00
|
|
|
.output()?;
|
|
|
|
|
|
|
|
Command::new("git")
|
|
|
|
.args(&["config", "--local", "user.name", "starship"])
|
2019-09-07 19:27:29 +02:00
|
|
|
.current_dir(repo_dir)
|
2019-09-07 18:25:01 +02:00
|
|
|
.output()?;
|
|
|
|
|
2019-09-07 19:27:29 +02:00
|
|
|
Ok(repo_path)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn path_str(repo_dir: &PathBuf) -> io::Result<&str> {
|
|
|
|
repo_dir
|
|
|
|
.to_str()
|
|
|
|
.ok_or_else(|| Error::from(ErrorKind::Other))
|
2019-09-04 06:20:22 +02:00
|
|
|
}
|
|
|
|
|
2019-07-02 22:12:53 +02:00
|
|
|
/// Extends `std::process::Command` with methods for testing
|
|
|
|
pub trait TestCommand {
|
|
|
|
fn use_config(&mut self, toml: toml::value::Value) -> &mut process::Command;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestCommand for process::Command {
|
|
|
|
/// Create a configuration file with the provided TOML and use it
|
|
|
|
fn use_config(&mut self, toml: toml::value::Value) -> &mut process::Command {
|
|
|
|
// Create a persistent config file in a tempdir
|
|
|
|
let (mut config_file, config_path) =
|
|
|
|
tempfile::NamedTempFile::new().unwrap().keep().unwrap();
|
|
|
|
write!(config_file, "{}", toml.to_string()).unwrap();
|
|
|
|
|
|
|
|
// Set that newly-created file as the config for the prompt instance
|
|
|
|
self.env("STARSHIP_CONFIG", config_path)
|
|
|
|
}
|
|
|
|
}
|