Skip to content

Commit fb82456

Browse files
committed
reactor(cli)!: major one
1 parent 2385a4e commit fb82456

29 files changed

+1226
-1034
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
sudo apt-get update
5151
sudo apt-get install libgdal-dev
5252
- name: Test
53-
run: cargo test -p stac -p stac-cli --all-features
53+
run: cargo test -p stac -p stac-duckdb -p stac-cli --all-features -F duckdb/bundled
5454
test-ubuntu-with-pgstac:
5555
runs-on: ubuntu-latest
5656
services:

cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ repository = "https://github.com/stac-utils/stac-rs"
99
license = "MIT OR Apache-2.0"
1010
keywords = ["geospatial", "stac", "metadata", "geo", "raster"]
1111
categories = ["science", "data-structures"]
12+
rust-version = "1.75"
1213

1314
[features]
1415
default = ["gdal", "geoparquet", "pgstac"]
@@ -47,7 +48,6 @@ tokio = { version = "1.23", features = ["macros", "rt-multi-thread"] }
4748
tokio-stream = "0.1"
4849
tracing = "0.1"
4950
tracing-subscriber = "0.3"
50-
url = "2"
5151

5252
[dev-dependencies]
5353
assert_cmd = "2"

cli/README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,25 @@ If you need to use [gdal](../core/README.md#gdal) features, install via `cargo i
3434
**stacrs** provides the following subcommands:
3535

3636
- `stacrs item`: create STAC items and combine them into item collections
37-
- `stacrs search`: search STAC APIs
38-
- `stacrs serve`: serve a STAC API
39-
- `stacrs sort`: sort the fields of STAC items, catalogs, and collections
37+
- `stacrs migrate`: migrate a STAC object to another version
38+
- `stacrs search`: search STAC APIs (and geoparquet, with the experimental `duckdb` feature)
39+
- `stacrs serve`: serve a STAC API (optionally, with a [pgstac](https://github.com/stac-utils/pgstac) backend)
4040
- `stacrs translate`: convert STAC values from one format to another
4141
- `stacrs validate`: validate STAC items, catalogs, and collections using [json-schema](https://json-schema.org/)
4242

4343
Use the `--help` flag to see all available options for the CLI and the subcommands:
4444

4545
## Features
4646

47-
By default, the CLI builds w/ [GDAL](https://gdal.org) support, and will error if GDAL is not installed on your system.
48-
If you don't want to use GDAL, you can disable the default features:
47+
This crate has five features, three of them on by default:
48+
49+
- `duckdb`: experimental support for querying [stac-geoparquet](https://github.com/stac-utils/stac-geoparquet) files using [DuckDB](https://duckdb.org/)
50+
- `gdal`: read geospatial data from rasters (enabled by default)
51+
- `geoparquet`: read and write [stac-geoparquet](https://github.com/stac-utils/stac-geoparquet) (enabled by default)
52+
- `pgstac`: enable a [pgstac](https://github.com/stac-utils/pgstac) backend for `stacrs serve` (enabled by default)
53+
- `python`: create an entrypoint that can be called from Python (used to enable `pip install stacrs-cli`)
54+
55+
If you don't want to use GDAL or any of the other default features:
4956

5057
```shell
5158
cargo install stac-cli --no-default-features

cli/src/args.rs

Lines changed: 0 additions & 270 deletions
This file was deleted.

cli/src/args/item.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use super::{Input, Run};
2+
use crate::{Result, Value};
3+
use stac::{item::Builder, Asset};
4+
use std::path::Path;
5+
use tokio::sync::mpsc::Sender;
6+
7+
/// Arguments for the `item` subcommand.
8+
#[derive(clap::Args, Debug)]
9+
pub struct Args {
10+
/// The item id or asset href
11+
id_or_href: String,
12+
13+
/// The output file, if not provided the item will be printed to standard output
14+
outfile: Option<String>,
15+
16+
/// The asset's key
17+
#[arg(short, long, default_value = "data")]
18+
key: String,
19+
20+
/// Roles to use for the created asset
21+
#[arg(short, long = "role", default_values_t = ["data".to_string()])]
22+
roles: Vec<String>,
23+
24+
/// Don't use GDAL to add geospatial metadata to the item
25+
#[cfg(feature = "gdal")]
26+
#[arg(long)]
27+
disable_gdal: bool,
28+
29+
/// Allow assets to have relative hrefs
30+
#[arg(long)]
31+
allow_relative_hrefs: bool,
32+
}
33+
34+
impl Run for Args {
35+
async fn run(self, _: Input, _: Sender<Value>) -> Result<Option<Value>> {
36+
let (id, href): (Option<String>, Option<String>) = if stac::href_to_url(&self.id_or_href)
37+
.is_none()
38+
&& !Path::new(&self.id_or_href).exists()
39+
{
40+
(Some(self.id_or_href), None)
41+
} else {
42+
(None, Some(self.id_or_href))
43+
};
44+
let id = id
45+
.or_else(|| {
46+
Path::new(href.as_ref().expect("if id is none, href should exist"))
47+
.file_stem()
48+
.map(|s| s.to_string_lossy().to_string())
49+
})
50+
.unwrap_or_else(|| "default".to_string());
51+
let mut builder = Builder::new(id).canonicalize_paths(!self.allow_relative_hrefs);
52+
#[cfg(feature = "gdal")]
53+
{
54+
builder = builder.enable_gdal(!self.disable_gdal);
55+
}
56+
if let Some(href) = href {
57+
let mut asset = Asset::new(href);
58+
asset.roles = self.roles;
59+
builder = builder.asset(self.key, asset);
60+
}
61+
let item = builder.build()?;
62+
Ok(Some(stac::Value::from(item).into()))
63+
}
64+
65+
fn take_outfile(&mut self) -> Option<String> {
66+
self.outfile.take()
67+
}
68+
}

0 commit comments

Comments
 (0)