Repository: dathere/qsv (language: rust)

Issue:
Gate the `prompt` command behind a `prompt` feature
### Discussed in https://github.com/jqnatividad/qsv/discussions/2155

<div type='discussions-op-text'>

<sup>Originally posted by **derekmahar** September 20, 2024</sup>
How can I exclude crate [rfd](https://github.com/PolyMeilex/rfd) from the qsv build?  Crate rfd breaks my qsv build on a headless server that has no window manager because it indirectly requires crate [wayland-sys](https://github.com/smithay/wayland-rs) which fails to build because wayland-sys cannot find wayland-client which isn't installed.</div>


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/publish-linux-glibc-231-musl-1124.yml b/.github/workflows/publish-linux-glibc-231-musl-1124.yml
index 31f5273b9..15133e1d4 100644
--- a/.github/workflows/publish-linux-glibc-231-musl-1124.yml
+++ b/.github/workflows/publish-linux-glibc-231-musl-1124.yml
@@ -33,7 +33,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,polars,geocode,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau,polars
@@ -43,7 +43,7 @@ jobs:
             target: x86_64-unknown-linux-musl
             architecture: x86_64
             musl-prep: true
-            addl-build-args: --features=apply,fetch,foreach,self_update,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
diff --git a/.github/workflows/publish-linux-glibc-231-musl-123.yml b/.github/workflows/publish-linux-glibc-231-musl-123.yml
index 1f5651938..b5e1bf00b 100644
--- a/.github/workflows/publish-linux-glibc-231-musl-123.yml
+++ b/.github/workflows/publish-linux-glibc-231-musl-123.yml
@@ -33,7 +33,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,polars,geocode,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau,polars
@@ -43,7 +43,7 @@ jobs:
             target: x86_64-unknown-linux-musl
             architecture: x86_64
             musl-prep: true
-            addl-build-args: --features=apply,fetch,foreach,self_update,polars,geocode,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: polars
diff --git a/.github/workflows/publish-linux-qsvpy-glibc-231-musl-123.yml b/.github/workflows/publish-linux-qsvpy-glibc-231-musl-123.yml
index 4daa50814..abdb22107 100644
--- a/.github/workflows/publish-linux-qsvpy-glibc-231-musl-123.yml
+++ b/.github/workflows/publish-linux-qsvpy-glibc-231-musl-123.yml
@@ -37,7 +37,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,python,polars,geocode,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,python,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -48,7 +48,7 @@ jobs:
             target: x86_64-unknown-linux-musl
             architecture: x86_64
             musl-prep: true
-            addl-build-args: --features=apply,fetch,foreach,self_update,python,polars,geocode,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,python,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
diff --git a/.github/workflows/publish-macOS-x86_64.yml b/.github/workflows/publish-macOS-x86_64.yml
index f09f15099..291ba6340 100644
--- a/.github/workflows/publish-macOS-x86_64.yml
+++ b/.github/workflows/publish-macOS-x86_64.yml
@@ -37,7 +37,7 @@ jobs:
             target: x86_64-apple-darwin
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,fetch,foreach,self_update,luau,polars,to,geocode,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,luau,polars,to,geocode,lens,prompt
             default-features: --no-default-features
             addl-qsvlite-features:
             addl-qsvdp-features: luau
diff --git a/.github/workflows/publish-nightly-glibc-231-musl-1124.yml b/.github/workflows/publish-nightly-glibc-231-musl-1124.yml
index 02765da23..862c4b7c0 100644
--- a/.github/workflows/publish-nightly-glibc-231-musl-1124.yml
+++ b/.github/workflows/publish-nightly-glibc-231-musl-1124.yml
@@ -33,7 +33,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,nightly,self_update,polars,geocode,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,nightly,self_update,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -43,7 +43,7 @@ jobs:
             target: x86_64-unknown-linux-musl
             architecture: x86_64
             musl-prep: true
-            addl-build-args: --features=apply,fetch,foreach,nightly,self_update,polars,lens
+            addl-build-args: --features=apply,fetch,foreach,nightly,self_update,polars,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
diff --git a/.github/workflows/publish-nightly.yml b/.github/workflows/publish-nightly.yml
index 35d8a1947..2b92ea457 100644
--- a/.github/workflows/publish-nightly.yml
+++ b/.github/workflows/publish-nightly.yml
@@ -33,7 +33,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,nightly,self_update,geocode,polars,to,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,nightly,self_update,geocode,polars,to,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau,polars
@@ -49,7 +49,7 @@ jobs:
             os-name: windows
             target: x86_64-pc-windows-msvc
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,nightly,self_update,polars,geocode,to,lens
+            addl-build-args: --features=apply,luau,fetch,nightly,self_update,polars,geocode,to,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -67,7 +67,7 @@ jobs:
             os-name: macos
             target: x86_64-apple-darwin
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,nightly,to,self_update,polars,geocode,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,nightly,to,self_update,polars,geocode,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
diff --git a/.github/workflows/publish-portable.yml b/.github/workflows/publish-portable.yml
index f2b6afc37..1d037484b 100644
--- a/.github/workflows/publish-portable.yml
+++ b/.github/workflows/publish-portable.yml
@@ -36,7 +36,7 @@ jobs:
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau,polars
@@ -47,7 +47,7 @@ jobs:
             architecture: x86_64
             musl-prep: true
             use-cross: false
-            addl-build-args: --features=apply,fetch,foreach,self_update
+            addl-build-args: --features=apply,fetch,foreach,self_update,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
@@ -67,7 +67,7 @@ jobs:
             target: x86_64-pc-windows-msvc
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens
+            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -87,7 +87,7 @@ jobs:
             target: x86_64-pc-windows-gnu
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens
+            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,prompt
             default-features: --no-default-features
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -115,7 +115,7 @@ jobs:
             target: aarch64-unknown-linux-gnu
             architecture: aarch64
             use-cross: true
-            addl-build-args: --features=apply,fetch,foreach,self_update,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
diff --git a/.github/workflows/publish-qsvpy.yml b/.github/workflows/publish-qsvpy.yml
index 0243dc5fa..d8e7922e5 100644
--- a/.github/workflows/publish-qsvpy.yml
+++ b/.github/workflows/publish-qsvpy.yml
@@ -33,7 +33,7 @@ jobs:
             os-name: linux
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,python,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,python,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -49,7 +49,7 @@ jobs:
             os-name: windows
             target: x86_64-pc-windows-msvc
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,self_update,polars,geocode,to,python,lens,foreach
+            addl-build-args: --features=apply,luau,fetch,self_update,polars,geocode,to,python,lens,foreach,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -67,7 +67,7 @@ jobs:
             os-name: macos
             target: x86_64-apple-darwin
             architecture: x86_64
-            addl-build-args: --features=apply,luau,fetch,foreach,to,self_update,polars,geocode,python,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,to,self_update,polars,geocode,python,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 72a4c0964..63e2fb352 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -39,7 +39,7 @@ jobs:
             target: x86_64-unknown-linux-gnu
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,lens
+            addl-build-args: --features=apply,luau,fetch,foreach,self_update,geocode,polars,to,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau,polars
@@ -50,7 +50,7 @@ jobs:
             architecture: x86_64
             musl-prep: true
             use-cross: false
-            addl-build-args: --features=apply,fetch,foreach,self_update,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
@@ -70,7 +70,7 @@ jobs:
             target: x86_64-pc-windows-msvc
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,foreach
+            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,foreach,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -90,7 +90,7 @@ jobs:
             target: x86_64-pc-windows-gnu
             architecture: x86_64
             use-cross: false
-            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,foreach
+            addl-build-args: --features=apply,luau,fetch,self_update,geocode,polars,to,lens,foreach,prompt
             default-features: --no-default-features
             addl-qsvlite-features:
             addl-qsvdp-features: luau
@@ -118,7 +118,7 @@ jobs:
             target: aarch64-unknown-linux-gnu
             architecture: aarch64
             use-cross: true
-            addl-build-args: --features=apply,fetch,foreach,self_update,lens
+            addl-build-args: --features=apply,fetch,foreach,self_update,lens,prompt
             default-features:
             addl-qsvlite-features:
             addl-qsvdp-features:
diff --git a/Cargo.toml b/Cargo.toml
index 9eefcb907..935c89898 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -202,7 +202,7 @@ reqwest = { version = "0.12", features = [
     "stream",
     "zstd",
 ], default-features = false }
-rfd = "0.15"
+rfd = { version = "0.15", optional = true }
 rust_decimal = { version = "1.36", default-features = false }
 ryu = "1"
 sanitize-filename = { version = "0.5", optional = true }
@@ -327,6 +327,7 @@ distrib_features = [
     "lens",
     "luau",
     "polars",
+    "prompt",
     "python",
     "to",
 ]
@@ -367,6 +368,7 @@ geocode = [
     "simple-expand-tilde",
 ]
 luau = ["mlua", "sanitize-filename", "simple-expand-tilde"]
+prompt = ["rfd"]
 python = ["pyo3"]
 to = ["csvs_convert", "xlsxwriter"]
 lens = ["arrow", "csvlens"]
diff --git a/docs/FEATURES.md b/docs/FEATURES.md
index 22b667fdd..9d0943af8 100644
--- a/docs/FEATURES.md
+++ b/docs/FEATURES.md
@@ -10,6 +10,7 @@
 * `geocode` - enable `geocode` command.
 * `luau` - enable `luau` command. Embeds a [Luau](https://luau-lang.org) interpreter into qsv. [Luau has type-checking, sandboxing, additional language operators, increased performance & other improvements](https://luau-lang.org/2022/11/04/luau-origins-and-evolution.html) over Lua.
 * `polars` - enables all [Polars](https://pola.rs)-powered commands (currently, `joinp` and `sqlp`. Also enables polars mode in `count`). Note that Polars is a very powerful library, but it has a lot of dependencies that drastically increases both compile time and binary size.
+* `prompt` - enable `prompt` command.
 * `python` - enable `py` command. Note that qsv will look for the shared library for the Python version (Python 3.7 & above supported) it was compiled against & will abort on startup if the library is not found, even if you're NOT using the `py` command. Check [Python](#python) section for more info.
 * `to` - enables the `to` command.
 * `self_update` - enable self-update engine, checking GitHub for the latest release. Note that if you manually built qsv, `self-update` will only check for new releases.
diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs
index a845044c7..4a18bc51d 100644
--- a/src/cmd/mod.rs
+++ b/src/cmd/mod.rs
@@ -60,7 +60,7 @@ pub mod luau;
 pub mod partition;
 #[cfg(any(feature = "feature_capable", feature = "lite"))]
 pub mod pro;
-#[cfg(any(feature = "feature_capable", feature = "lite"))]
+#[cfg(feature = "prompt")]
 pub mod prompt;
 pub mod pseudo;
 #[cfg(all(feature = "python", feature = "feature_capable"))]
diff --git a/src/main.rs b/src/main.rs
index 9021bdbb8..9eafe4bb1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -155,11 +155,14 @@ fn main() -> QsvExitCode {
 
     enabled_commands.push_str(
         "    partition   Partition CSV data based on a column value
-    pro         Interact with the qsv pro API
-    prompt      Open a file dialog to pick a file
-    pseudo      Pseudonymise the values of a column\n",
+    pro         Interact with the qsv pro API\n",
     );
 
+    #[cfg(all(feature = "prompt", feature = "feature_capable"))]
+    enabled_commands.push_str("    prompt      Open a file dialog to pick a file\n");
+
+    enabled_commands.push_str("    pseudo      Pseudonymise the values of a column\n");
+
     #[cfg(all(feature = "python", feature = "feature_capable"))]
     enabled_commands.push_str("    py          Evaluate a Python expression on CSV data\n");
 
@@ -377,6 +380,7 @@ enum Command {
     Luau,
     Partition,
     Pro,
+    #[cfg(all(feature = "prompt", feature = "feature_capable"))]
     Prompt,
     Pseudo,
     #[cfg(all(feature = "python", feature = "feature_capable"))]
@@ -472,6 +476,7 @@ impl Command {
             Command::Luau => cmd::luau::run(argv),
             Command::Partition => cmd::partition::run(argv),
             Command::Pro => cmd::pro::run(argv),
+            #[cfg(all(feature = "prompt", feature = "feature_capable"))]
             Command::Prompt => cmd::prompt::run(argv),
             Command::Pseudo => cmd::pseudo::run(argv),
             #[cfg(all(feature = "python", feature = "feature_capable"))]
diff --git a/src/mainlite.rs b/src/mainlite.rs
index 709ea5bc5..1445101a1 100644
--- a/src/mainlite.rs
+++ b/src/mainlite.rs
@@ -48,7 +48,6 @@ macro_rules! command_list {
     jsonl       Convert newline-delimited JSON files to CSV
     partition   Partition CSV data based on a column value
     pro         Interact with the qsv pro API
-    prompt      Open a file dialog to pick a file
     pseudo      Pseudonymise the values of a column
     rename      Rename the columns of CSV data efficiently
     replace     Replace patterns in CSV data
@@ -261,7 +260,6 @@ enum Command {
     Jsonl,
     Partition,
     Pro,
-    Prompt,
     Pseudo,
     Rename,
     Replace,
@@ -333,7 +331,6 @@ impl Command {
             Command::Jsonl => cmd::jsonl::run(argv),
             Command::Partition => cmd::partition::run(argv),
             Command::Pro => cmd::pro::run(argv),
-            Command::Prompt => cmd::prompt::run(argv),
             Command::Pseudo => cmd::pseudo::run(argv),
             Command::Rename => cmd::rename::run(argv),
             Command::Replace => cmd::replace::run(argv),
diff --git a/src/util.rs b/src/util.rs
index 38242fcc8..d38991dee 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -216,6 +216,8 @@ pub fn version() -> String {
             Err(e) => enabled_features.push_str(&format!("Luau - cannot retrieve version: {e};")),
         };
     }
+    #[cfg(all(feature = "prompt", feature = "feature_capable"))]
+    enabled_features.push_str("prompt;");
 
     #[cfg(all(feature = "python", not(feature = "lite")))]
     {


Test patch:
diff --git a/tests/tests.rs b/tests/tests.rs
index 412f19261..ea5d0a102 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -89,6 +89,7 @@ mod test_jsonl;
 mod test_luau;
 #[cfg(any(feature = "feature_capable", feature = "lite"))]
 mod test_partition;
+#[cfg(feature = "prompt")]
 mod test_prompt;
 mod test_pseudo;
 #[cfg(feature = "python")]