Skip to content

Commit ac4ec8f

Browse files
Tui feature (#360)
1 parent d757f8a commit ac4ec8f

9 files changed

Lines changed: 75 additions & 21 deletions

File tree

.claude/settings.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"Bash(grep:*)",
3030
"Bash(cargo fmt:*)",
3131
"Bash(./target/release/dft:*)",
32-
"Bash(/Users/matth/OpenSource/datafusion-tui/target/debug/dft:*)"
32+
"Bash(/Users/matth/OpenSource/datafusion-tui/target/debug/dft:*)",
33+
"Bash(./target/debug/dft:*)"
3334
],
3435
"deny": [],
3536
"ask": []

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ jobs:
159159
awslocal s3 mv data/aggregate_test_100.csv s3://test/
160160
awslocal s3 mb s3://tpch-db
161161
echo "Test Execution complete!"
162-
- name: Run CLI tests
162+
- name: Run TUI tests
163163
run: |
164-
cargo test tui_cases
164+
cargo test --features=tui tui_cases
165165
166166
test-s3:
167167
name: Extension / S3

CLAUDE.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1414
# Build the project (default features: functions-parquet, s3)
1515
cargo build
1616

17+
# Build with TUI support
18+
cargo build --features=tui
19+
1720
# Build with all features
1821
cargo build --all-features
1922

20-
# Run the TUI (default interface)
21-
cargo run
23+
# Run the TUI (requires tui feature)
24+
cargo run --features=tui
2225

2326
# Run CLI with a query
2427
cargo run -- -c "SELECT 1 + 2"
@@ -93,8 +96,8 @@ cargo test db
9396
# Run CLI tests
9497
cargo test cli_cases
9598

96-
# Run TUI tests
97-
cargo test tui_cases
99+
# Run TUI tests (requires tui feature)
100+
cargo test --features=tui tui_cases
98101

99102
# Run feature-specific tests
100103
cargo test --features=flightsql extension_cases::flightsql -- --test-threads=1
@@ -196,6 +199,7 @@ Both servers share the same `ExecutionContext` from `datafusion-app`.
196199

197200
The project uses extensive feature flags to keep binary size manageable:
198201

202+
- `tui` - Terminal user interface (ratatui-based)
199203
- `s3` - S3 object store integration (default)
200204
- `functions-parquet` - Parquet-specific functions (default)
201205
- `functions-json` - JSON functions

Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ arrow-flight = { features = [
2020
axum = { features = ["macros"], optional = true, version = "0.7.9" }
2121
clap = { features = ["derive"], version = "4.5.27" }
2222
color-eyre = "0.6.3"
23-
crossterm = { features = ["event-stream"], version = "0.28.1" }
23+
crossterm = { features = ["event-stream"], optional = true, version = "0.28.1" }
2424
datafusion = { version = "51" }
2525
datafusion-app = { path = "crates/datafusion-app", version = "0.1.0" }
2626
directories = "5.0.1"
@@ -39,7 +39,7 @@ object_store = "0.12"
3939
parquet = "57"
4040
pin-project-lite = { version = "0.2.14" }
4141
prost = "0.14"
42-
ratatui = "0.28.0"
42+
ratatui = { optional = true, version = "0.28.0" }
4343
serde = { features = ["derive"], version = "1.0.197" }
4444
strum = "0.26.2"
4545
tokio = { features = [
@@ -62,8 +62,10 @@ tpchgen = "2.0"
6262
tpchgen-arrow = "2.0"
6363
tracing = { features = ["log"], version = "0.1.41" }
6464
tracing-subscriber = { features = ["env-filter"], version = "0.3.19" }
65-
tui-logger = { features = ["tracing-support"], version = "0.12" }
66-
tui-textarea = { features = ["search"], version = "0.6.1" }
65+
tui-logger = { features = [
66+
"tracing-support",
67+
], optional = true, version = "0.12" }
68+
tui-textarea = { features = ["search"], optional = true, version = "0.6.1" }
6769
url = { features = ["serde"], version = "2.5.2" }
6870
uuid = { optional = true, version = "1.10.0" }
6971
vortex = { optional = true, version = "0.58" }
@@ -113,6 +115,7 @@ http = [
113115
]
114116
huggingface = ["datafusion-app/huggingface"]
115117
s3 = ["datafusion-app/s3"]
118+
tui = ["dep:crossterm", "dep:ratatui", "dep:tui-logger", "dep:tui-textarea"]
116119
udfs-wasm = ["datafusion-app/udfs-wasm"]
117120
vortex = [
118121
"datafusion-app/vortex",

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ Documentation is undergoing a significant revamp - the new documentation will be
1414

1515
The project offers four complementary interfaces:
1616

17-
1. **Text User Interface (TUI)**: An interactive SQL IDE with real-time query analysis, benchmarking, and catalog exploration
17+
1. **Text User Interface (TUI)**: An interactive SQL IDE with real-time query analysis, benchmarking, and catalog exploration (requires `tui` feature)
1818
2. **Command Line Interface (CLI)**: A scriptable engine for executing queries from files or command line
19-
3. **FlightSQL Server**: A standards-compliant SQL interface for programmatic access
20-
4. **HTTP Server**: A REST API for SQL queries and catalog exploration
19+
3. **FlightSQL Server**: A standards-compliant SQL interface for programmatic access (requires `flightsql` feature)
20+
4. **HTTP Server**: A REST API for SQL queries and catalog exploration (requires `http` feature)
2121

2222
All interfaces share the same execution engine, allowing you to develop locally with the TUI and then seamlessly deploy with the server implementations.
2323

@@ -29,10 +29,13 @@ All interfaces share the same execution engine, allowing you to develop locally
2929

3030
#### From crates.io (Recommended)
3131
```sh
32-
# If you have Rust installed
32+
# Core CLI and server interfaces
3333
cargo install datafusion-dft
3434

35-
# For full functionality with all features
35+
# With TUI interface
36+
cargo install datafusion-dft --features=tui
37+
38+
# For full functionality with all features (including TUI)
3639
cargo install datafusion-dft --all-features
3740
```
3841

@@ -44,19 +47,27 @@ Common feature combinations:
4447
# Core with S3 support
4548
cargo install datafusion-dft --features=s3
4649

50+
# With TUI interface
51+
cargo install datafusion-dft --features=tui
52+
53+
# TUI with S3 and data lake formats
54+
cargo install datafusion-dft --features=tui,s3,deltalake
55+
4756
# Data lake formats
4857
cargo install datafusion-dft --features=deltalake
4958

5059
# With JSON and Parquet functions
51-
cargo install datafusion-dft --features=function-json,functions-parquet
60+
cargo install datafusion-dft --features=functions-json,functions-parquet
5261
```
5362

5463
See the [Features documentation](docs/features.md) for all available features.
5564

65+
**Note**: The TUI (Text User Interface) is optional and requires the `tui` feature flag. The CLI, FlightSQL server, and HTTP server are always available.
66+
5667
### Running the apps
5768

5869
```sh
59-
# Interactive TUI (default)
70+
# Interactive TUI (requires `tui` feature)
6071
dft
6172

6273
# CLI with direct query execution
@@ -155,7 +166,7 @@ LOCATION 's3://bucket/delta_table';
155166

156167
#### Loading DDL
157168

158-
- **TUI**: DDL is automatically loaded at startup
169+
- **TUI** (requires `tui` feature): DDL is automatically loaded at startup
159170
- **CLI**: Add `--run-ddl` flag to execute DDL before your query
160171
- **Custom Path**: Configure a custom DDL path in your config file
161172
```toml

src/config.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub struct CliConfig {
7171
pub execution: ExecutionConfig,
7272
}
7373

74+
#[cfg(feature = "tui")]
7475
#[derive(Clone, Debug, Default, Deserialize)]
7576
pub struct TuiConfig {
7677
#[serde(default = "default_execution_config")]
@@ -170,6 +171,7 @@ pub struct AppConfig {
170171
pub shared: ExecutionConfig,
171172
#[serde(default)]
172173
pub cli: CliConfig,
174+
#[cfg(feature = "tui")]
173175
#[serde(default)]
174176
pub tui: TuiConfig,
175177
#[cfg(feature = "flightsql")]
@@ -189,10 +191,12 @@ fn default_execution_config() -> ExecutionConfig {
189191
ExecutionConfig::default()
190192
}
191193

194+
#[cfg(feature = "tui")]
192195
fn default_display_config() -> DisplayConfig {
193196
DisplayConfig::default()
194197
}
195198

199+
#[cfg(feature = "tui")]
196200
fn default_interaction_config() -> InteractionConfig {
197201
InteractionConfig::default()
198202
}
@@ -229,16 +233,19 @@ fn default_db_path() -> Url {
229233
Url::parse(&with_schema).unwrap()
230234
}
231235

236+
#[cfg(feature = "tui")]
232237
#[derive(Clone, Debug, Deserialize)]
233238
pub struct DisplayConfig {
234239
#[serde(default = "default_frame_rate")]
235240
pub frame_rate: f64,
236241
}
237242

243+
#[cfg(feature = "tui")]
238244
fn default_frame_rate() -> f64 {
239245
30.0
240246
}
241247

248+
#[cfg(feature = "tui")]
242249
impl Default for DisplayConfig {
243250
fn default() -> Self {
244251
Self { frame_rate: 30.0 }
@@ -250,6 +257,7 @@ fn default_benchmark_iterations() -> usize {
250257
10
251258
}
252259

260+
#[cfg(feature = "tui")]
253261
#[derive(Clone, Debug, Default, Deserialize)]
254262
pub struct InteractionConfig {
255263
#[serde(default = "default_mouse")]
@@ -258,10 +266,12 @@ pub struct InteractionConfig {
258266
pub paste: bool,
259267
}
260268

269+
#[cfg(feature = "tui")]
261270
fn default_mouse() -> bool {
262271
false
263272
}
264273

274+
#[cfg(feature = "tui")]
265275
fn default_paste() -> bool {
266276
false
267277
}
@@ -281,11 +291,13 @@ fn default_server_metrics_addr() -> SocketAddr {
281291
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9000)
282292
}
283293

294+
#[cfg(feature = "tui")]
284295
#[derive(Clone, Debug, Default, Deserialize)]
285296
pub struct EditorConfig {
286297
pub experimental_syntax_highlighting: bool,
287298
}
288299

300+
#[cfg(feature = "tui")]
289301
fn default_editor_config() -> EditorConfig {
290302
EditorConfig::default()
291303
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ pub mod db;
2222
pub mod execution;
2323
#[cfg(any(feature = "flightsql", feature = "http"))]
2424
pub mod server;
25+
#[cfg(feature = "tui")]
2526
pub mod telemetry;
2627
pub mod test_utils;
2728
pub mod tpch;
29+
#[cfg(feature = "tui")]
2830
pub mod tui;
2931

3032
pub const APP_NAME: &str = "dft";

src/main.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
// under the License.
1717

1818
use clap::Parser;
19+
#[cfg(not(feature = "tui"))]
20+
use color_eyre::eyre::eyre;
1921
use color_eyre::Result;
2022
use datafusion_dft::args::Command;
2123
#[cfg(any(feature = "flightsql", feature = "http"))]
2224
use datafusion_dft::server;
23-
use datafusion_dft::{args::DftArgs, cli, config::create_config, tpch, tui};
25+
#[cfg(feature = "tui")]
26+
use datafusion_dft::tui;
27+
use datafusion_dft::{args::DftArgs, cli, config::create_config, tpch};
2428
#[cfg(feature = "http")]
2529
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
2630

@@ -129,7 +133,22 @@ async fn app_entry_point(cli: DftArgs) -> Result<()> {
129133
if !cli.files.is_empty() || !cli.commands.is_empty() {
130134
cli::try_run(cli, cfg).await?;
131135
} else {
132-
tui::try_run(cli, cfg).await?;
136+
#[cfg(feature = "tui")]
137+
{
138+
tui::try_run(cli, cfg).await?;
139+
}
140+
#[cfg(not(feature = "tui"))]
141+
{
142+
return Err(eyre!(
143+
"TUI is not enabled in this build.\n\n\
144+
To use the TUI interface, rebuild with:\n \
145+
cargo install datafusion-dft --features=tui\n\n\
146+
Or use the CLI interface:\n \
147+
dft -c \"SELECT 1 + 2\"\n \
148+
dft -f query.sql\n\n\
149+
For more information, run: dft --help"
150+
));
151+
}
133152
}
134153

135154
Ok(())

tests/tui_cases/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
#![cfg(feature = "tui")]
19+
1820
mod ddl;
1921
#[cfg(feature = "flightsql")]
2022
mod flightsql_execution;

0 commit comments

Comments
 (0)