Skip to content

Commit

Permalink
Refactoring the ui config to use an enum in preparation for the web ui
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasLYang committed Aug 1, 2024
1 parent 2b0112e commit 3938c06
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 64 deletions.
28 changes: 25 additions & 3 deletions crates/turborepo-lib/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use clap::{
};
use clap_complete::{generate, Shell};
pub use error::Error;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use tracing::{debug, error, log::warn};
use turbopath::AbsoluteSystemPathBuf;
use turborepo_api_client::AnonAPIClient;
Expand All @@ -29,7 +29,6 @@ use crate::{
run::watch::WatchClient,
shim::TurboState,
tracing::TurboSubscriber,
turbo_json::UI as ConfigUI,
};

mod error;
Expand Down Expand Up @@ -183,7 +182,7 @@ pub struct Args {
pub heap: Option<String>,
/// Specify whether to use the streaming UI or TUI
#[clap(long, global = true, value_enum)]
pub ui: Option<ConfigUI>,
pub ui: Option<UIMode>,
/// Override the login endpoint
#[clap(long, global = true, value_parser)]
pub login: Option<String>,
Expand Down Expand Up @@ -2560,3 +2559,26 @@ mod test {
);
}
}

#[derive(Serialize, Deserialize, Debug, Copy, Clone, Deserializable, PartialEq, Eq, ValueEnum)]
#[serde(rename_all = "camelCase")]
pub enum UIMode {
/// Use the terminal user interface
Tui,
/// Use the web user interface (experimental)
Wui,
/// Use the standard output stream
Stream,
}

impl Default for UIMode {
fn default() -> Self {
Self::Tui
}
}

impl UIMode {
pub fn use_tui(&self) -> bool {
matches!(self, Self::Tui)
}
}
4 changes: 2 additions & 2 deletions crates/turborepo-lib/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use turborepo_repository::{
package_graph::PackageGraph, package_json::PackageJson, package_manager::PackageManager,
};

use crate::{cli, commands::CommandBase};
use crate::{cli, cli::UIMode, commands::CommandBase};

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
Expand All @@ -18,7 +18,7 @@ struct ConfigOutput<'a> {
upload_timeout: u64,
enabled: bool,
spaces_id: Option<&'a str>,
ui: bool,
ui: UIMode,
package_manager: PackageManager,
daemon: Option<bool>,
}
Expand Down
5 changes: 3 additions & 2 deletions crates/turborepo-lib/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use turborepo_dirs::config_dir;
use turborepo_ui::UI;

use crate::{
cli::UIMode,
config::{ConfigurationOptions, Error as ConfigError, TurborepoConfigBuilder},
Args,
};
Expand Down Expand Up @@ -69,10 +70,10 @@ impl CommandBase {
.with_token(self.args.token.clone())
.with_timeout(self.args.remote_cache_timeout)
.with_preflight(self.args.preflight.then_some(true))
.with_ui(self.args.ui.map(|ui| ui.use_tui()).or_else(|| {
.with_ui(self.args.ui.map(|ui| ui).or_else(|| {
self.args.execution_args.as_ref().and_then(|args| {
if !args.log_order.compatible_with_tui() {
Some(false)
Some(UIMode::Stream)
} else {
// If the argument is compatible with the TUI this does not mean we should
// override other configs
Expand Down
21 changes: 13 additions & 8 deletions crates/turborepo-lib/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use turborepo_dirs::{config_dir, vercel_config_dir};
use turborepo_errors::TURBO_SITE;

pub use crate::turbo_json::RawTurboJson;
use crate::{commands::CommandBase, turbo_json};
use crate::{cli, cli::UIMode, commands::CommandBase, turbo_json};

#[derive(Debug, Error, Diagnostic)]
#[error("Environment variables should not be prefixed with \"{env_pipeline_delimiter}\"")]
Expand Down Expand Up @@ -207,7 +207,7 @@ pub struct ConfigurationOptions {
pub(crate) enabled: Option<bool>,
pub(crate) spaces_id: Option<String>,
#[serde(rename = "ui")]
pub(crate) ui: Option<bool>,
pub(crate) ui: Option<cli::UIMode>,
#[serde(rename = "dangerouslyDisablePackageManagerCheck")]
pub(crate) allow_no_package_manager: Option<bool>,
pub(crate) daemon: Option<bool>,
Expand Down Expand Up @@ -274,8 +274,12 @@ impl ConfigurationOptions {
self.spaces_id.as_deref()
}

pub fn ui(&self) -> bool {
self.ui.unwrap_or(false) && atty::is(atty::Stream::Stdout)
pub fn ui(&self) -> cli::UIMode {
if atty::is(atty::Stream::Stdout) {
return cli::UIMode::Stream;
}

self.ui.unwrap_or(cli::UIMode::Stream)
}

pub fn allow_no_package_manager(&self) -> bool {
Expand Down Expand Up @@ -317,7 +321,7 @@ impl ResolvedConfigurationOptions for RawTurboJson {
.experimental_spaces
.and_then(|spaces| spaces.id)
.map(|spaces_id| spaces_id.into());
opts.ui = self.ui.map(|ui| ui.use_tui());
opts.ui = self.ui;
opts.allow_no_package_manager = self.allow_no_package_manager;
opts.daemon = self.daemon.map(|daemon| *daemon.as_inner());
Ok(opts)
Expand Down Expand Up @@ -441,7 +445,8 @@ fn get_env_var_config(
let ui = output_map
.get("ui")
.map(|s| s.as_str())
.and_then(truth_env_var);
.and_then(truth_env_var)
.map(|ui| if ui { UIMode::Tui } else { UIMode::Stream });

let allow_no_package_manager = output_map
.get("allow_no_package_manager")
Expand Down Expand Up @@ -517,7 +522,7 @@ fn get_override_env_var_config(
.and_then(|value| {
// If either of these are truthy, then we disable the TUI
if value == "true" || value == "1" {
Some(false)
Some(UIMode::Stream)
} else {
None
}
Expand Down Expand Up @@ -673,7 +678,7 @@ impl TurborepoConfigBuilder {
create_builder!(with_enabled, enabled, Option<bool>);
create_builder!(with_preflight, preflight, Option<bool>);
create_builder!(with_timeout, timeout, Option<u64>);
create_builder!(with_ui, ui, Option<bool>);
create_builder!(with_ui, ui, Option<cli::UIMode>);
create_builder!(
with_allow_no_package_manager,
allow_no_package_manager,
Expand Down
10 changes: 5 additions & 5 deletions crates/turborepo-lib/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use thiserror::Error;
use turborepo_errors::Spanned;
use turborepo_repository::package_graph::{PackageGraph, PackageName};

use crate::{run::task_id::TaskId, task_graph::TaskDefinition};
use crate::{cli::UIMode, run::task_id::TaskId, task_graph::TaskDefinition};

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum TaskNode {
Expand Down Expand Up @@ -383,7 +383,7 @@ impl Engine<Built> {
&self,
package_graph: &PackageGraph,
concurrency: u32,
experimental_ui: bool,
ui_mode: UIMode,
) -> Result<(), Vec<ValidateError>> {
// TODO(olszewski) once this is hooked up to a real run, we should
// see if using rayon to parallelize would provide a speedup
Expand Down Expand Up @@ -480,7 +480,7 @@ impl Engine<Built> {
})
}

validation_errors.extend(self.validate_interactive(experimental_ui));
validation_errors.extend(self.validate_interactive(ui_mode));

match validation_errors.is_empty() {
true => Ok(()),
Expand All @@ -489,10 +489,10 @@ impl Engine<Built> {
}

// Validates that UI is setup if any interactive tasks will be executed
fn validate_interactive(&self, experimental_ui: bool) -> Vec<ValidateError> {
fn validate_interactive(&self, ui_mode: UIMode) -> Vec<ValidateError> {
// If experimental_ui is being used, then we don't need check for interactive
// tasks
if experimental_ui {
if matches!(ui_mode, UIMode::Tui) {
return Vec::new();
}
self.task_definitions
Expand Down
18 changes: 7 additions & 11 deletions crates/turborepo-lib/src/run/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use {
};

use crate::{
cli::DryRunMode,
cli::{DryRunMode, UIMode},
commands::CommandBase,
engine::{Engine, EngineBuilder},
opts::Opts,
Expand All @@ -56,7 +56,7 @@ pub struct RunBuilder {
repo_root: AbsoluteSystemPathBuf,
ui: UI,
version: &'static str,
experimental_ui: bool,
ui_mode: UIMode,
api_client: APIClient,
analytics_sender: Option<AnalyticsSender>,
// In watch mode, we can have a changed package that we want to serve as an entrypoint.
Expand All @@ -77,13 +77,13 @@ impl RunBuilder {
let allow_missing_package_manager = config.allow_no_package_manager();

let version = base.version();
let experimental_ui = config.ui();
let ui_mode = config.ui();
let processes = ProcessManager::new(
// We currently only use a pty if the following are met:
// - we're attached to a tty
atty::is(atty::Stream::Stdout) &&
// - if we're on windows, we're using the UI
(!cfg!(windows) || experimental_ui),
(!cfg!(windows) || matches!(ui_mode, UIMode::Tui)),
);
let CommandBase { repo_root, ui, .. } = base;

Expand All @@ -94,7 +94,7 @@ impl RunBuilder {
repo_root,
ui,
version,
experimental_ui,
ui_mode,
api_auth,
analytics_sender: None,
entrypoint_packages: None,
Expand Down Expand Up @@ -384,7 +384,7 @@ impl RunBuilder {
Ok(Run {
version: self.version,
ui: self.ui,
experimental_ui: self.experimental_ui,
ui_mode: self.ui_mode,
start_at,
processes: self.processes,
run_telemetry,
Expand Down Expand Up @@ -439,11 +439,7 @@ impl RunBuilder {

if !self.opts.run_opts.parallel {
engine
.validate(
pkg_dep_graph,
self.opts.run_opts.concurrency,
self.experimental_ui,
)
.validate(pkg_dep_graph, self.opts.run_opts.concurrency, self.ui_mode)
.map_err(Error::EngineValidation)?;
}

Expand Down
10 changes: 5 additions & 5 deletions crates/turborepo-lib/src/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use turborepo_ui::{cprint, cprintln, tui, tui::AppSender, BOLD_GREY, GREY, UI};

pub use crate::run::error::Error;
use crate::{
cli::EnvMode,
cli::{EnvMode, UIMode},
engine::Engine,
opts::Opts,
process::ProcessManager,
Expand Down Expand Up @@ -69,7 +69,7 @@ pub struct Run {
task_access: TaskAccess,
daemon: Option<DaemonClient<DaemonConnector>>,
should_print_prelude: bool,
experimental_ui: bool,
ui_mode: UIMode,
}

impl Run {
Expand Down Expand Up @@ -172,12 +172,12 @@ impl Run {
self.ui
}

pub fn has_experimental_ui(&self) -> bool {
self.experimental_ui
pub fn has_tui(&self) -> bool {
self.ui_mode.use_tui()
}

pub fn should_start_ui(&self) -> Result<bool, Error> {
Ok(self.experimental_ui
Ok(self.ui_mode.use_tui()
&& self.opts.run_opts.dry_run.is_none()
&& tui::terminal_big_enough()?)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/turborepo-lib/src/run/watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl WatchClient {

let mut events = client.package_changes().await?;

if !self.run.has_experimental_ui() {
if !self.run.has_tui() {
self.run.print_run_prelude();
}

Expand Down
32 changes: 5 additions & 27 deletions crates/turborepo-lib/src/turbo_json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::{

use biome_deserialize_macros::Deserializable;
use camino::Utf8Path;
use clap::ValueEnum;
use miette::{NamedSource, SourceSpan};
use serde::{Deserialize, Serialize};
use struct_iterable::Iterable;
Expand All @@ -17,7 +16,7 @@ use turborepo_repository::{package_graph::ROOT_PKG_NAME, package_json::PackageJs
use turborepo_unescape::UnescapedString;

use crate::{
cli::OutputLogsMode,
cli::{OutputLogsMode, UIMode},
config::{ConfigurationOptions, Error, InvalidEnvPrefixError},
run::{
task_access::{TaskAccessTraceFile, TASK_ACCESS_CONFIG_PATH},
Expand Down Expand Up @@ -125,7 +124,7 @@ pub struct RawTurboJson {
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) remote_cache: Option<RawRemoteCacheOptions>,
#[serde(skip_serializing_if = "Option::is_none", rename = "ui")]
pub ui: Option<UI>,
pub ui: Option<UIMode>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "dangerouslyDisablePackageManagerCheck"
Expand Down Expand Up @@ -167,27 +166,6 @@ impl DerefMut for Pipeline {
}
}

#[derive(Serialize, Debug, Copy, Clone, Deserializable, PartialEq, Eq, ValueEnum)]
#[serde(rename_all = "camelCase")]
pub enum UI {
/// Use the TUI interface
Tui,
/// Use the standard output stream
Stream,
}

impl Default for UI {
fn default() -> Self {
Self::Tui
}
}

impl UI {
pub fn use_tui(&self) -> bool {
matches!(self, Self::Tui)
}
}

#[derive(Serialize, Default, Debug, PartialEq, Clone, Iterable, Deserializable)]
#[serde(rename_all = "camelCase")]
#[deserializable(unknown_fields = "deny")]
Expand Down Expand Up @@ -747,9 +725,9 @@ mod tests {
use turborepo_repository::package_json::PackageJson;
use turborepo_unescape::UnescapedString;

use super::{Pipeline, RawTurboJson, Spanned, UI};
use super::{Pipeline, RawTurboJson, Spanned};
use crate::{
cli::OutputLogsMode,
cli::{OutputLogsMode, UIMode},
run::task_id::TaskName,
task_graph::{TaskDefinition, TaskOutputs},
turbo_json::{RawTaskDefinition, TurboJson},
Expand Down Expand Up @@ -1080,7 +1058,7 @@ mod tests {
#[test_case(r#"{ "ui": "tui" }"#, Some(UI::Tui) ; "tui")]
#[test_case(r#"{ "ui": "stream" }"#, Some(UI::Stream) ; "stream")]
#[test_case(r#"{}"#, None ; "missing")]
fn test_ui(json: &str, expected: Option<UI>) {
fn test_ui(json: &str, expected: Option<UIMode>) {
let json = RawTurboJson::parse(json, AnchoredSystemPath::new("").unwrap()).unwrap();
assert_eq!(json.ui, expected);
}
Expand Down

0 comments on commit 3938c06

Please sign in to comment.