Repository: stac-utils/stac-rs (language: python)

Issue:
Take standard input to `stac validate`



Discussion / hints:

Fix patch:
diff --git a/stac-cli/CHANGELOG.md b/stac-cli/CHANGELOG.md
index f0732cf2..90a07adc 100644
--- a/stac-cli/CHANGELOG.md
+++ b/stac-cli/CHANGELOG.md
@@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 
 ## [Unreleased]
 
+### Added
+
+- `stac validate` can take from stdin ([#236](https://github.com/stac-utils/stac-rs/pull/236))
+
 ## [0.0.6] - 2023-10-18
 
 ### Added
diff --git a/stac-cli/Cargo.toml b/stac-cli/Cargo.toml
index d9670b7a..d0a5dbb5 100644
--- a/stac-cli/Cargo.toml
+++ b/stac-cli/Cargo.toml
@@ -26,6 +26,9 @@ tokio = { version = "1.23", features = ["macros", "rt-multi-thread"] }
 tokio-stream = "0.1"
 url = "2"
 
+[dev-dependencies]
+assert_cmd = "2"
+
 [[bin]]
 name = "stac"
 path = "src/main.rs"
diff --git a/stac-cli/data b/stac-cli/data
new file mode 120000
index 00000000..188ec763
--- /dev/null
+++ b/stac-cli/data
@@ -0,0 +1,1 @@
+../spec-examples/v1.0.0
\ No newline at end of file
diff --git a/stac-cli/src/command.rs b/stac-cli/src/command.rs
index 56680a0d..c84d6374 100644
--- a/stac-cli/src/command.rs
+++ b/stac-cli/src/command.rs
@@ -92,7 +92,9 @@ pub enum Command {
         /// or Item, that object will be validated. If its a collections
         /// endpoint from a STAC API, all collections will be validated.
         /// Additional behavior TBD.
-        href: String,
+        ///
+        /// If this is not provided, will read from standard input.
+        href: Option<String>,
     },
 }
 
@@ -135,7 +137,7 @@ impl Command {
                 crate::commands::search(&href, search, max_items, stream, !(compact | stream)).await
             }
             Sort { href, compact } => crate::commands::sort(&href, compact).await,
-            Validate { href } => crate::commands::validate(&href).await,
+            Validate { href } => crate::commands::validate(href.as_deref()).await,
         }
     }
 }
diff --git a/stac-cli/src/commands/validate.rs b/stac-cli/src/commands/validate.rs
index c25d1b3b..c7b49ecb 100644
--- a/stac-cli/src/commands/validate.rs
+++ b/stac-cli/src/commands/validate.rs
@@ -1,8 +1,13 @@
 use crate::{Error, Result};
+use serde_json::Value;
 use stac_validate::{Validate, Validator};
 
-pub async fn validate(href: &str) -> Result<()> {
-    let value: serde_json::Value = stac_async::read_json(href).await?;
+pub async fn validate(href: Option<&str>) -> Result<()> {
+    let value: Value = if let Some(href) = href {
+        stac_async::read_json(href).await?
+    } else {
+        serde_json::from_reader(std::io::stdin())?
+    };
     if let Some(map) = value.as_object() {
         if map.contains_key("type") {
             let value = value.clone();


Test patch:
diff --git a/stac-cli/tests/command.rs b/stac-cli/tests/command.rs
new file mode 100644
index 00000000..a0991a8d
--- /dev/null
+++ b/stac-cli/tests/command.rs
@@ -0,0 +1,29 @@
+use assert_cmd::Command;
+use std::{fs::File, io::Read};
+
+#[test]
+fn help() {
+    let mut command = Command::cargo_bin("stac").unwrap();
+    command.arg("help").assert().success();
+}
+
+#[test]
+fn validate() {
+    let mut command = Command::cargo_bin("stac").unwrap();
+    command
+        .arg("validate")
+        .arg("data/simple-item.json")
+        .assert()
+        .success();
+}
+
+#[test]
+fn validate_stdin() {
+    let mut command = Command::cargo_bin("stac").unwrap();
+    let mut item = String::new();
+    File::open("data/simple-item.json")
+        .unwrap()
+        .read_to_string(&mut item)
+        .unwrap();
+    command.arg("validate").write_stdin(item).assert().success();
+}