From 43df7f9da73aec2d3d0bcd289be617ce5f7b7d70 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Mon, 14 Sep 2026 20:32:34 +0300 Subject: [PATCH 1/2] Rename commands per #116: geocoder, static, tilesets Regenerated openapi/ from internal/openapi-command-config/command-config.yaml (#116's decision record in mapbox-cli-private): - geocoder forward-geocode/reverse-geocode/batch-geocode -> forward/reverse/batch - static-images and static-tiles merge into one `static` command group: get-static-image -> get-image, get-static-tile -> get-tile - tilequery, and one operation each from rastertiles, rasterarrays and vectortiles, merge into `tilesets`: get-rastertile -> get-tile, get-mrt-tile -> get-mrt, get-vectortile -> get-mvt, tilequery get -> query Updated docs/commands.md, tests/fixtures/api_command_surface.txt and every test referencing an old command spelling to match. --- docs/commands.md | 462 ++++++++---------- .../api-geocoder/geocoding-v6.production.yaml | 6 +- .../api-gl/static-images.production.v1.yaml | 151 +----- .../api-gl/static-tiles.production.v1.yaml | 4 +- .../rasterarrays.production.v1.yaml | 4 +- .../rastertiles.production.v1.yaml | 2 +- .../tilequery.production.v1.yaml | 4 +- .../vectortiles.production.v1.yaml | 2 +- src/generate_skills.rs | 4 +- src/main.rs | 30 +- src/remedy.rs | 29 +- src/spec.rs | 19 +- tests/docs_contract.rs | 2 +- tests/fixtures/api_command_surface.txt | 20 +- tests/output_contract.rs | 8 +- tests/schema_contract.rs | 8 +- tests/tilesets_cli_proxy.rs | 7 +- 17 files changed, 282 insertions(+), 480 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 7de64d7..c3a4aa9 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -73,12 +73,9 @@ nests, and is typed `mapbox styles draft get`. [fonts.upload](#mapbox-fonts-upload) · [fonts.delete](#mapbox-fonts-delete) **[Geocoder](#geocoder)** — -[geocoder.forward-geocode](#mapbox-geocoder-forward-geocode) · -[geocoder.reverse-geocode](#mapbox-geocoder-reverse-geocode) · -[geocoder.batch-geocode](#mapbox-geocoder-batch-geocode) - -**[Raster arrays](#raster-arrays)** — -[rasterarrays.get-mrt-tile](#mapbox-rasterarrays-get-mrt-tile) +[geocoder.forward](#mapbox-geocoder-forward) · +[geocoder.reverse](#mapbox-geocoder-reverse) · +[geocoder.batch](#mapbox-geocoder-batch) **[Search](#search)** — [search.forward](#mapbox-search-forward) · [search.reverse](#mapbox-search-reverse) · @@ -91,13 +88,8 @@ nests, and is typed `mapbox styles draft get`. [sprites.delete](#mapbox-sprites-delete) · [sprites.delete-batch](#mapbox-sprites-delete-batch) -**[Static images](#static-images)** — -[static-images.get-static-image](#mapbox-static-images-get-static-image) · -[static-images.get-static-image-auto](#mapbox-static-images-get-static-image-auto) · -[static-images.get-static-image-bbox](#mapbox-static-images-get-static-image-bbox) - -**[Static tiles](#static-tiles)** — -[static-tiles.get-static-tile](#mapbox-static-tiles-get-static-tile) +**[Static](#static)** — [static.get-image](#mapbox-static-get-image) · +[static.get-tile](#mapbox-static-get-tile) **[Styles](#styles)** — [styles.list](#mapbox-styles-list) · [styles.get](#mapbox-styles-get) · [styles.create](#mapbox-styles-create) · @@ -107,11 +99,11 @@ nests, and is typed `mapbox styles draft get`. [styles.draft.update](#mapbox-styles-draft-update) · [styles.draft.delete](#mapbox-styles-draft-delete) -**[Tilequery](#tilequery)** — [tilequery.get](#mapbox-tilequery-get) - **[Tilesets](#tilesets)** — -[tilesets.get-rastertile](#mapbox-tilesets-get-rastertile) · -[tilesets.get-vectortile](#mapbox-tilesets-get-vectortile) +[tilesets.get-tile](#mapbox-tilesets-get-tile) · +[tilesets.get-mvt](#mapbox-tilesets-get-mvt) · +[tilesets.get-mrt](#mapbox-tilesets-get-mrt) · +[tilesets.query](#mapbox-tilesets-query) **[Tilesets CLI](#tilesets-cli)** — [tilesets-cli](#mapbox-tilesets-cli-args) @@ -475,7 +467,7 @@ Like `--data`, it goes after the operation name. Two shapes, one with almost nothing and one with most of it: ```sh -mapbox geocoder forward-geocode --q Helsinki +mapbox geocoder forward --q Helsinki mapbox --use-login --profile work styles create --username user \ --data '{"name":"My Style","version":8,"sources":{},"layers":[]}' @@ -886,14 +878,13 @@ All three return GeoJSON, rendered as a numbered list under `-o text` — name and feature type on one line, the full address on the next, `longitude,latitude` on the one after that (the next thing a caller usually wants a result for), never clipped. The response's `attribution`, -the terms the results come under, follows the list — once under a whole -`batch-geocode` batch rather than once under each of up to fifty identical -copies. `batch-geocode` gets one such list per query, under a `Query N:` -header — omitted when the batch held a single query, since there is nothing -to tell it apart from. `tilequery` gets the same list treatment for a -different reason — see its own section. +the terms the results come under, follows the list — once under `batch`'s +whole result rather than once under each of up to fifty identical copies. +`batch` gets one such list per query, under a `Query N:` header — omitted +when the batch held a single query, since there is nothing to tell it apart +from. -### `mapbox geocoder forward-geocode` +### `mapbox geocoder forward` Looks up a location from search text, and returns its standardized address, geographic context and coordinates. @@ -923,9 +914,9 @@ Structured input is an alternative to `--q`: `--address-number`, #### Examples ```sh -mapbox geocoder forward-geocode --q Helsinki --limit 1 -mapbox geocoder forward-geocode --q "1600 Pennsylvania Ave" --country us --types address -mapbox geocoder forward-geocode --street "Kaivokatu" --place Helsinki --country fi +mapbox geocoder forward --q Helsinki --limit 1 +mapbox geocoder forward --q "1600 Pennsylvania Ave" --country us --types address +mapbox geocoder forward --street "Kaivokatu" --place Helsinki --country fi ``` #### Outputs @@ -953,7 +944,7 @@ Tip: `-o json` for the response as the API sent it. -### `mapbox geocoder reverse-geocode` +### `mapbox geocoder reverse` Looks up the features at a pair of coordinates. @@ -966,8 +957,8 @@ the same way they do for forward geocoding. #### Examples ```sh -mapbox geocoder reverse-geocode --longitude 24.94 --latitude 60.16 -mapbox geocoder reverse-geocode --longitude -74.0 --latitude 40.7 --types address +mapbox geocoder reverse --longitude 24.94 --latitude 60.16 +mapbox geocoder reverse --longitude -74.0 --latitude 40.7 --types address ``` A negative coordinate is a value, not a flag. That took a fix — clap read @@ -978,7 +969,7 @@ every coordinate west of Greenwich unusable. The same numbered list as forward geocoding. -### `mapbox geocoder batch-geocode` +### `mapbox geocoder batch` Up to 50 forward or reverse queries in one request. Each query is an object in a JSON array, with what would have been query parameters as its fields. @@ -990,7 +981,7 @@ in a JSON array, with what would have been query parameters as its fields. #### Examples ```sh -mapbox geocoder batch-geocode -d '[ +mapbox geocoder batch -d '[ {"types":["place"],"q":"Helsinki"}, {"types":["place"],"q":"Tampere"}, {"longitude":24.94,"latitude":60.16} @@ -1001,7 +992,7 @@ mapbox geocoder batch-geocode -d '[ A `batch` array, one entry per query, in the order sent. Under `-o text` each query's results render as their own numbered list, same as -`forward-geocode`/`reverse-geocode`, under a `Query N:` header — dropped +`forward`/`reverse`, under a `Query N:` header — dropped when there is only one query, where the header names the only thing on screen: @@ -1044,48 +1035,6 @@ single query. --- -## Raster arrays - -### `mapbox rasterarrays get-mrt-tile` - -One MRT tile from a raster-array job. - -#### Parameters - -`--jobid ` is required and comes from the raster-array job that -produced the tiles. - -#### Examples - -```sh -mapbox rasterarrays get-mrt-tile --jobid 12 2048 1361 > tile.mrt -``` - -#### Outputs - -Not exercised: this account has no raster-array job. A `--jobid` that does -not exist gets a 500 rather than a 404, so the error says nothing useful -about what was wrong: - - - - -
Terminal — -o textAgent — -o json
- -``` -Error: Internal Server Error (HTTP 500) -``` - - - -```json -{"code":"http_500","message":"Internal Server Error","status":500} -``` - -
- ---- - ## Search The public, non-interactive surface of the Search Box API: text search, @@ -1098,7 +1047,7 @@ the vendored specs the way the others do. `suggest` and around a person typing into a search box, not a one-shot CLI invocation — so there is no non-interactive way to use them. -**vs. `geocoder`**: `geocoder reverse-geocode` and `search reverse` take +**vs. `geocoder`**: `geocoder reverse` and `search reverse` take nearly identical coordinates and answer different questions. `geocoder` returns canonical addresses and administrative hierarchy (country, region, postcode, place); `search` returns POIs and businesses with the metadata a @@ -1174,7 +1123,7 @@ becomes a list rather than staying pretty-printed): ### `mapbox search reverse` The POIs and addresses at a coordinate — `search`'s counterpart to -`geocoder reverse-geocode`, answering with business metadata instead of +`geocoder reverse`, answering with business metadata instead of administrative hierarchy. #### Parameters @@ -1680,19 +1629,22 @@ And an object where an array belongs: --- -## Static images +## Static -A rendered map image from a style. All three return image bytes, so -`--output` does not apply — redirect to a file. +A rendered map image or raster tile from a style. Both return image bytes, +so `--output` does not apply — redirect to a file. Static Images and Static +Tiles merged into this one command group (#116); `get-image` and `get-tile` +are what were `static-images get-static-image` and `static-tiles +get-static-tile`. `` takes a **leading dot** — `.png`, `.jpeg`, `.webp`, or `""` for -the style default. `` is `@2x` or `""`. `` is a -marker/path/GeoJSON expression, or `""` for none. +the style default. `` is `@2x` or `""`. `` (`get-image` +only) is a marker/path/GeoJSON expression, or `""` for none. `""` for the overlay drops the segment entirely rather than sending an empty one, so a plain map image needs no overlay expression. -### `mapbox static-images get-static-image` +### `mapbox static get-image` A map image centred on a point. @@ -1714,10 +1666,10 @@ both as integers — pass `0 0` rather than `"" ""`. #### Examples ```sh -mapbox static-images get-static-image streets-v12 "" 24.94 60.16 12 0 0 600 400 "" .png \ +mapbox static get-image streets-v12 "" 24.94 60.16 12 0 0 600 400 "" .png \ --username mapbox > map.png -mapbox static-images get-static-image streets-v12 "pin-s+555555(24.94,60.16)" \ +mapbox static get-image streets-v12 "pin-s+555555(24.94,60.16)" \ 24.94 60.16 12 0 0 600 400 "@2x" .png --username mapbox > pin.png ``` @@ -1736,7 +1688,7 @@ it to a file, e.g. `... > out.png`. ``` -$ mapbox static-images get-static-image … > map.png +$ mapbox static get-image … > map.png $ file map.png map.png: PNG image data, 600 x 400 ``` @@ -1744,58 +1696,9 @@ map.png: PNG image data, 600 x 400 -### `mapbox static-images get-static-image-auto` - -The same image, with the viewport fitted to the overlay instead of given as -a centre and zoom. Six positionals: ` - `. +### `mapbox static get-tile` -`--padding ` insets the fitted view from the edges. Bearing and pitch -cannot be combined with `auto`. `--attribution`, `--logo`, `--addlayer`, -`--before-layer`, `--setfilter` and `--layer-id` are the six -[above](#mapbox-static-images-get-static-image), unchanged — all three -static-image commands take them. - -#### Examples - -```sh -mapbox static-images get-static-image-auto streets-v12 \ - "pin-s+555555(24.94,60.16)" 600 400 "" .png --username mapbox > pin.png -``` - -#### Outputs - -Image bytes, as above. With an empty overlay there is nothing to fit to, and -the API falls back to the style's own default view rather than failing. - -### `mapbox static-images get-static-image-bbox` - -The same image, fitted to a bounding box given as -`[minlon,minlat,maxlon,maxlat]`. Seven positionals: ` - `. - -`--padding ` applies here too, as do `--attribution`, `--logo`, -`--addlayer`, `--before-layer`, `--setfilter` and `--layer-id`. - -#### Examples - -```sh -mapbox static-images get-static-image-bbox streets-v12 "" \ - "[24.9,60.1,25.0,60.2]" 600 400 "" .png --username mapbox > area.png -``` - -#### Outputs - -Image bytes, as above. - ---- - -## Static tiles - -### `mapbox static-tiles get-static-tile` - -One raster tile rendered from a style, rather than from a tileset — the -`maps` command group does the latter. +One raster tile rendered from a style, rather than from a tileset. #### Parameters @@ -1805,15 +1708,15 @@ Seven positionals: ` `. the same ground as 256 px tiles at *z+1*, so 256 needs four times as many requests for the same area. -`` is `@2x` or `""`; `` takes a leading dot, as in static -images. +`` is `@2x` or `""`; `` takes a leading dot, as in +`get-image`. #### Examples ```sh -mapbox static-tiles get-static-tile streets-v12 512 2 1 1 "" .png \ +mapbox static get-tile streets-v12 512 2 1 1 "" .png \ --username mapbox > tile.png -mapbox static-tiles get-static-tile streets-v12 256 12 2048 1361 "@2x" .png \ +mapbox static get-tile streets-v12 256 12 2048 1361 "@2x" .png \ --username mapbox > tile@2x.png ``` @@ -1832,7 +1735,7 @@ it to a file, e.g. `... > out.png`. ``` -$ mapbox static-tiles get-static-tile … > tile.png +$ mapbox static get-tile … > tile.png $ file tile.png tile.png: PNG image data, 512 x 512 ``` @@ -2265,22 +2168,168 @@ beforehand. --- -## Tilequery +## Tilesets + +Tiles by tileset id, plus the raster-array and vector-tile lookups that key +off one: raster from the Raster Tiles API, vector from the Vector Tiles +API, MRT tiles from a raster-array job, and `query` from the Tilequery +API. Four operations, out of four different specs, under one command +group (#116) — a caller asking about a tileset is asking the same kind of +question regardless of which API answers it. + +Not to be confused with [`mapbox tilesets-cli`](#tilesets-cli), which +forwards to the separately installed Python Tilesets CLI and shares +nothing with this but the word. -### `mapbox tilequery get` +The three tile commands return bytes, so `--output` does not apply on +them — redirect to a file. `query` returns GeoJSON. + +### `mapbox tilesets get-tile` + +One raster tile at standard resolution, 256×256. + +#### Parameters + +`` may be several ids separated by commas, composited into one +tile. ` ` are the tile coordinates. + +`` is `png`, `pngraw`, `jpg`, `jpeg` or `webp`. `` is +appended to it rather than being a separate URL segment, so `jpg` with `70` +fetches `.jpg70`; pass `""` for the format's default. Both are positional, +in that order. + +#### Examples + +```sh +mapbox tilesets get-tile mapbox.satellite 2 1 1 png "" > tile.png +mapbox tilesets get-tile mapbox.satellite 12 2048 1361 jpg 70 > tile.jpg70 +``` + +#### Outputs + +Image bytes; redirect to a file. The refusal to print them names an +extension matching what the API sent, which is not always what was asked +for — `mapbox.satellite` is stored as JPEG, so a `png` request still +suggests `out.jpg`. + + + + +
Terminal — refusesRedirected — raw bytes
+ +``` +Error: Response is image/jpeg (9774 bytes). +Refusing to write it to the terminal — redirect +it to a file, e.g. `... > out.jpg`. +``` + + + +``` +$ mapbox tilesets get-tile mapbox.satellite 2 1 1 png "" > tile.png +$ file tile.png +tile.png: JPEG image data +``` + +
+ +### `mapbox tilesets get-mvt` + +One vector tile from one or more Mapbox-hosted tilesets. Up to 15 ids, +comma-separated, composited into a single tile. + +#### Parameters + +`` is `mvt` or `vector.pbf` — the same bytes under two names. + +`--style /[@]` asks the API to filter the tile +to what that style actually draws. + +#### Examples + +```sh +mapbox tilesets get-mvt mapbox.mapbox-streets-v8 12 2048 1361 mvt > tile.mvt +mapbox tilesets get-mvt mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2 \ + 12 2048 1361 mvt > composite.mvt +``` + +#### Outputs + +Protobuf bytes; redirect to a file. + + + + +
Terminal — refusesRedirected — raw bytes
+ +``` +Error: Response is application/vnd.mapbox-vector-tile +(80741 bytes). Refusing to write it to the terminal — +redirect it to a file, e.g. `... > out.mvt`. +``` + + + +``` +$ mapbox tilesets get-mvt … > tile.mvt +$ ls -l tile.mvt +-rw-r--r-- 80741 tile.mvt +``` + +
+ +### `mapbox tilesets get-mrt` + +One MRT tile from a raster-array job. + +#### Parameters + +`--jobid ` is required and comes from the raster-array job that +produced the tiles. + +#### Examples + +```sh +mapbox tilesets get-mrt --jobid 12 2048 1361 > tile.mrt +``` + +#### Outputs + +Not exercised: this account has no raster-array job. A `--jobid` that does +not exist gets a 500 rather than a 404, so the error says nothing useful +about what was wrong: + + + + +
Terminal — -o textAgent — -o json
+ +``` +Error: Internal Server Error (HTTP 500) +``` + + + +```json +{"code":"http_500","message":"Internal Server Error","status":500} +``` + +
+ +### `mapbox tilesets query` What features a vector tileset has at or near a point. -`get` is a hand-picked name, not the one this command would otherwise +`query` is a hand-picked name, not the one this command would otherwise carry: tilequery's own spec spells its one operation's `operationId` after its own URL path (`getV4TilesetsTilequeryLonLatJson`) rather than after what it does, and that spec is not this repo's to rename. The name comes from the maintainer-only decision record instead. -Neither older spelling still runs. `get-v4tilesets-tilequery-lon-lat-json` -and the `get-tilequery` that briefly replaced it were both hidden aliases -of a `COMMAND_ALIASES` row that no longer exists — see the `Breaking` entry -in the changelog. +Neither older spelling still runs. `get-v4tilesets-tilequery-lon-lat-json`, +`tilequery get-tilequery` and `tilequery get` were each replaced in turn, +the last one folding the whole command into this group (#116) — see the +`Breaking` entry in the changelog. #### Parameters @@ -2300,10 +2349,10 @@ the point. #### Examples ```sh -mapbox tilequery get \ +mapbox tilesets query \ mapbox.mapbox-streets-v8 24.94 60.16 --limit 2 -mapbox tilequery get \ +mapbox tilesets query \ mapbox.mapbox-streets-v8 -74.0 40.7 --radius 100 --layers building ``` @@ -2390,115 +2439,6 @@ Tip: `-o json` for the response as the API sent it. --- -## Tilesets - -Tiles by tileset id: raster from the Raster Tiles API, vector from the -Vector Tiles API. Two operations, out of two different specs, under one -command group — a caller asking for a tile is asking the same question -either way, and which API answers it is a detail of the URL. - -Not to be confused with [`mapbox tilesets-cli`](#tilesets-cli), which -forwards to the separately installed Python Tilesets CLI and shares -nothing with this but the word. - -Both return bytes, so `--output` does not apply — redirect to a file. - -### `mapbox tilesets get-rastertile` - -One raster tile at standard resolution, 256×256. - -#### Parameters - -`` may be several ids separated by commas, composited into one -tile. ` ` are the tile coordinates. - -`` is `png`, `pngraw`, `jpg`, `jpeg` or `webp`. `` is -appended to it rather than being a separate URL segment, so `jpg` with `70` -fetches `.jpg70`; pass `""` for the format's default. Both are positional, -in that order. - -#### Examples - -```sh -mapbox tilesets get-rastertile mapbox.satellite 2 1 1 png "" > tile.png -mapbox tilesets get-rastertile mapbox.satellite 12 2048 1361 jpg 70 > tile.jpg70 -``` - -#### Outputs - -Image bytes; redirect to a file. The refusal to print them names an -extension matching what the API sent, which is not always what was asked -for — `mapbox.satellite` is stored as JPEG, so a `png` request still -suggests `out.jpg`. - - - - -
Terminal — refusesRedirected — raw bytes
- -``` -Error: Response is image/jpeg (9774 bytes). -Refusing to write it to the terminal — redirect -it to a file, e.g. `... > out.jpg`. -``` - - - -``` -$ mapbox tilesets get-rastertile mapbox.satellite 2 1 1 png "" > tile.png -$ file tile.png -tile.png: JPEG image data -``` - -
- -### `mapbox tilesets get-vectortile` - -One vector tile from one or more Mapbox-hosted tilesets. Up to 15 ids, -comma-separated, composited into a single tile. - -#### Parameters - -`` is `mvt` or `vector.pbf` — the same bytes under two names. - -`--style /[@]` asks the API to filter the tile -to what that style actually draws. - -#### Examples - -```sh -mapbox tilesets get-vectortile mapbox.mapbox-streets-v8 12 2048 1361 mvt > tile.mvt -mapbox tilesets get-vectortile mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2 \ - 12 2048 1361 mvt > composite.mvt -``` - -#### Outputs - -Protobuf bytes; redirect to a file. - - - - -
Terminal — refusesRedirected — raw bytes
- -``` -Error: Response is application/vnd.mapbox-vector-tile -(80741 bytes). Refusing to write it to the terminal — -redirect it to a file, e.g. `... > out.mvt`. -``` - - - -``` -$ mapbox tilesets get-vectortile … > tile.mvt -$ ls -l tile.mvt --rw-r--r-- 80741 tile.mvt -``` - -
- ---- - ## Agent skills Installs the [Mapbox Agent Skills](https://github.com/mapbox/mapbox-agent-skills) diff --git a/openapi/api-geocoder/geocoding-v6.production.yaml b/openapi/api-geocoder/geocoding-v6.production.yaml index 18f1847..d16e23f 100644 --- a/openapi/api-geocoder/geocoding-v6.production.yaml +++ b/openapi/api-geocoder/geocoding-v6.production.yaml @@ -348,7 +348,7 @@ paths: access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - geocoder - - forward-geocode + - forward /search/geocode/v6/reverse: get: summary: Reverse geocoding @@ -448,7 +448,7 @@ paths: access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - geocoder - - reverse-geocode + - reverse /search/geocode/v6/batch: post: summary: Batch geocoding @@ -670,7 +670,7 @@ paths: access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - geocoder - - batch-geocode + - batch x-mapbox-restrictions-and-limits: | To protect the Geocoding API and maximize service stability, Mapbox rate limits Geocoding API requests. diff --git a/openapi/api-gl/static-images.production.v1.yaml b/openapi/api-gl/static-images.production.v1.yaml index 786c146..8859e6d 100644 --- a/openapi/api-gl/static-images.production.v1.yaml +++ b/openapi/api-gl/static-images.production.v1.yaml @@ -107,155 +107,8 @@ paths: format: '' access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - - static-images - - get-static-image - /styles/v1/{username}/{style_id}/static/{overlay}/auto/{width}x{height}{highRes}{format}: - get: - operationId: getStaticImageAuto - summary: Retrieve a static map image with auto-fit bounds - description: | - Render a static map image that automatically fits the viewport to the - bounding box of the provided overlay. The `auto` keyword replaces the - center, zoom, bearing and pitch segment, and the API calculates the - center and zoom needed to fit all overlay features within the image - dimensions. - - Use the `padding` query parameter to inset the fitted view from the - image edges. - - `bearing` and `pitch` cannot be combined with `auto`; supplying - coordinates alongside `auto` returns `422`. Combining `auto` with - `addlayer` or `setfilter` when there is no overlay also returns `422`, - as does a GeoJSON overlay that contains no features. - tags: - - Static Images - parameters: - - $ref: '#/components/parameters/username' - - $ref: '#/components/parameters/style_id' - - $ref: '#/components/parameters/overlay' - - $ref: '#/components/parameters/width' - - $ref: '#/components/parameters/height' - - $ref: '#/components/parameters/highRes' - - $ref: '#/components/parameters/format' - - $ref: '#/components/parameters/attribution' - - $ref: '#/components/parameters/logo' - - $ref: '#/components/parameters/before_layer' - - $ref: '#/components/parameters/padding' - - $ref: '#/components/parameters/addlayer' - - $ref: '#/components/parameters/setfilter' - - $ref: '#/components/parameters/layer_id' - - $ref: '#/components/parameters/accessToken' - responses: - '200': - $ref: '#/components/responses/ImageSuccess' - content: - image/png: - examples: - staticImageAuto: - summary: Static image auto-fit to a marker overlay - externalValue: https://api.mapbox.com/styles/v1/mapbox/streets-v12/static/pin-s+ff0000(-118.2437,34.0522)/auto/600x400@2x?access_token=MAPBOX_ACCESS_TOKEN - '304': - $ref: '#/components/responses/NotModified' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '403': - $ref: '#/components/responses/Forbidden' - '404': - $ref: '#/components/responses/NotFound' - '422': - $ref: '#/components/responses/InvalidParameters' - '429': - $ref: '#/components/responses/RateLimitExceeded' - x-mapbox-docs-examples: - - example-id: staticImageAuto - title: Get a static map image auto-fit to a marker - request: - username: mapbox - style_id: streets-v12 - overlay: pin-s+ff0000(-118.2437,34.0522) - width: 600 - height: 400 - highRes: '@2x' - format: '' - access_token: YOUR_MAPBOX_ACCESS_TOKEN - x-mapbox-cli-command: - - static-images - - get-static-image-auto - /styles/v1/{username}/{style_id}/static/{overlay}/{bbox}/{width}x{height}{highRes}{format}: - get: - operationId: getStaticImageBbox - summary: Retrieve a static map image for a bounding box - description: | - Render a static map image that fits a specified bounding box, given as - `[minlon,minlat,maxlon,maxlat]` in the path. The API calculates the - center and zoom needed to fit the bounding box within the image - dimensions. - - Use the `padding` query parameter to inset the fitted view from the - image edges. - - `bearing` and `pitch` cannot be combined with a bounding box; supplying - extra coordinates after the bounding box returns `422`. - tags: - - Static Images - parameters: - - $ref: '#/components/parameters/username' - - $ref: '#/components/parameters/style_id' - - $ref: '#/components/parameters/overlay' - - $ref: '#/components/parameters/bbox' - - $ref: '#/components/parameters/width' - - $ref: '#/components/parameters/height' - - $ref: '#/components/parameters/highRes' - - $ref: '#/components/parameters/format' - - $ref: '#/components/parameters/attribution' - - $ref: '#/components/parameters/logo' - - $ref: '#/components/parameters/before_layer' - - $ref: '#/components/parameters/padding' - - $ref: '#/components/parameters/addlayer' - - $ref: '#/components/parameters/setfilter' - - $ref: '#/components/parameters/layer_id' - - $ref: '#/components/parameters/accessToken' - responses: - '200': - $ref: '#/components/responses/ImageSuccess' - content: - image/png: - examples: - staticImageBbox: - summary: Static image fitted to a Washington DC bounding box - externalValue: https://api.mapbox.com/styles/v1/mapbox/streets-v12/static/pin-s+ff0000(-77.0353,38.8895)/[-77.043686,38.892035,-76.933086,38.942035]/600x400@2x?access_token=MAPBOX_ACCESS_TOKEN - '304': - $ref: '#/components/responses/NotModified' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '403': - $ref: '#/components/responses/Forbidden' - '404': - $ref: '#/components/responses/NotFound' - '422': - $ref: '#/components/responses/InvalidParameters' - '429': - $ref: '#/components/responses/RateLimitExceeded' - x-mapbox-docs-examples: - - example-id: staticImageBbox - title: Get a static map image for a bounding box in Washington DC - request: - username: mapbox - style_id: streets-v12 - overlay: pin-s+ff0000(-77.0353,38.8895) - bbox: '[-77.043686,38.892035,-76.933086,38.942035]' - width: 600 - height: 400 - highRes: '@2x' - format: '' - access_token: YOUR_MAPBOX_ACCESS_TOKEN - x-mapbox-cli-command: - - static-images - - get-static-image-bbox + - static + - get-image components: parameters: username: diff --git a/openapi/api-gl/static-tiles.production.v1.yaml b/openapi/api-gl/static-tiles.production.v1.yaml index 0d4c024..159fe43 100644 --- a/openapi/api-gl/static-tiles.production.v1.yaml +++ b/openapi/api-gl/static-tiles.production.v1.yaml @@ -97,8 +97,8 @@ paths: format: '' access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - - static-tiles - - get-static-tile + - static + - get-tile components: parameters: username: diff --git a/openapi/api-rasterarrays/rasterarrays.production.v1.yaml b/openapi/api-rasterarrays/rasterarrays.production.v1.yaml index eef9eab..9f8488d 100644 --- a/openapi/api-rasterarrays/rasterarrays.production.v1.yaml +++ b/openapi/api-rasterarrays/rasterarrays.production.v1.yaml @@ -128,8 +128,8 @@ paths: jobid: clnf3oau5005g08kzhr460vut operationId: getMrtTile x-mapbox-cli-command: - - rasterarrays - - get-mrt-tile + - tilesets + - get-mrt components: securitySchemes: AccessTokenQuery: diff --git a/openapi/api-rastertiles/rastertiles.production.v1.yaml b/openapi/api-rastertiles/rastertiles.production.v1.yaml index 2a84b92..2c5daa8 100644 --- a/openapi/api-rastertiles/rastertiles.production.v1.yaml +++ b/openapi/api-rastertiles/rastertiles.production.v1.yaml @@ -80,7 +80,7 @@ paths: access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - tilesets - - get-rastertile + - get-tile components: parameters: tilesets: diff --git a/openapi/api-tilequery/tilequery.production.v1.yaml b/openapi/api-tilequery/tilequery.production.v1.yaml index ef0068c..467ff24 100644 --- a/openapi/api-tilequery/tilequery.production.v1.yaml +++ b/openapi/api-tilequery/tilequery.production.v1.yaml @@ -213,8 +213,8 @@ paths: '500': $ref: '#/components/responses/ErrorResponse' x-mapbox-cli-command: - - tilequery - - get + - tilesets + - query components: securitySchemes: AccessTokenQuery: diff --git a/openapi/api-vectortiles/vectortiles.production.v1.yaml b/openapi/api-vectortiles/vectortiles.production.v1.yaml index 7e4087f..b0b5ef2 100644 --- a/openapi/api-vectortiles/vectortiles.production.v1.yaml +++ b/openapi/api-vectortiles/vectortiles.production.v1.yaml @@ -92,7 +92,7 @@ paths: access_token: YOUR_MAPBOX_ACCESS_TOKEN x-mapbox-cli-command: - tilesets - - get-vectortile + - get-mvt components: parameters: tileset_id: diff --git a/src/generate_skills.rs b/src/generate_skills.rs index ecc50c9..28eb90f 100644 --- a/src/generate_skills.rs +++ b/src/generate_skills.rs @@ -2038,8 +2038,8 @@ mod tests { let image = schema .commands .iter() - .find(|entry| entry.name == "get-static-image") - .expect("get-static-image is a command"); + .find(|entry| entry.name == "get-image") + .expect("get-image is a command"); let high_res = image .arguments .iter() diff --git a/src/main.rs b/src/main.rs index 9a9b4db..8df2ed6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1194,11 +1194,21 @@ mod tests { let positional = app.clone().try_get_matches_from([ "mapbox", - "tilequery", - "get", - "mapbox.mapbox-streets-v8", + "static", + "get-image", + "--username", + "mapbox", + "streets-v11", + "pin-s+f00(-74,40)", "-74.0", "40.7", + "12", + "0", + "0", + "600", + "400", + "", + "", ]); assert!( positional.is_ok(), @@ -1209,7 +1219,7 @@ mod tests { let flag_value = app.try_get_matches_from([ "mapbox", "geocoder", - "reverse-geocode", + "reverse", "--longitude", "-74.0", "--latitude", @@ -1235,15 +1245,7 @@ mod tests { for argv in [ ["mapbox", "search", "category", "coffee", "--proximity"].as_slice(), ["mapbox", "search", "forward", "--q", "coffee", "--bbox"].as_slice(), - [ - "mapbox", - "geocoder", - "forward-geocode", - "--q", - "x", - "--proximity", - ] - .as_slice(), + ["mapbox", "geocoder", "forward", "--q", "x", "--proximity"].as_slice(), ] { let mut argv = argv.to_vec(); argv.push("-121.90662,37.42827"); @@ -1272,7 +1274,7 @@ mod tests { "mapbox", "search", "forward", "--q", "x", "--types", "--limit", ] .as_slice(), - ["mapbox", "geocoder", "forward-geocode", "--q", "--limit"].as_slice(), + ["mapbox", "geocoder", "forward", "--q", "--limit"].as_slice(), ] { let matches = build_app(&specs).try_get_matches_from(argv); assert!( diff --git a/src/remedy.rs b/src/remedy.rs index e93d174..373113d 100644 --- a/src/remedy.rs +++ b/src/remedy.rs @@ -68,6 +68,11 @@ impl Remedy { /// `every_service_has_a_documentation_page` in `main.rs` fails the build if /// a service is ever added without an entry, which is the only thing keeping /// this list complete. +// `rasterarrays` and `tilequery` are absent on purpose, not by omission: +// #116 folded their one operation each into `tilesets` (see +// command-config.yaml), so neither is a service `bundled_specs()` ever +// returns any more — an entry here for either would fail +// `every_documentation_page_belongs_to_a_service`. const SERVICE_DOCS: &[(&str, &str)] = &[ ("accounts", TOKENS_DOC), ("fonts", "https://docs.mapbox.com/api/maps/fonts/"), @@ -75,27 +80,19 @@ const SERVICE_DOCS: &[(&str, &str)] = &[ "geocoder", "https://docs.mapbox.com/api/search/geocoding-v6/", ), - ( - "rasterarrays", - "https://docs.mapbox.com/api/maps/raster-arrays/", - ), ("search", "https://docs.mapbox.com/api/search/search-box/"), - ( - "static-images", - "https://docs.mapbox.com/api/maps/static-images/", - ), - ( - "static-tiles", - "https://docs.mapbox.com/api/maps/static-tiles/", - ), + // Static Images and Static Tiles merged into one `static` command group + // (#116); neither upstream page covers both, so this points at Static + // Images, the one `getStaticImage` (this group's more-used half) documents. + ("static", "https://docs.mapbox.com/api/maps/static-images/"), // The sprite endpoints are part of the Styles API upstream — the command // group is this CLI's own split, so both point at the same page. ("sprites", "https://docs.mapbox.com/api/maps/styles/"), ("styles", "https://docs.mapbox.com/api/maps/styles/"), - ("tilequery", "https://docs.mapbox.com/api/maps/tilequery/"), - // The index rather than one of the two pages under it: this service - // holds a raster-tiles command and a vector-tiles command, documented - // separately, and picking either page would be wrong for the other. + // The index rather than one of the pages under it: this service now + // holds a raster-tile, an MRT-tile, a tilequery and a vector-tile + // command (#116), documented separately upstream, and picking any one + // of those pages would be wrong for the other three. ("tilesets", "https://docs.mapbox.com/api/maps/"), ]; diff --git a/src/spec.rs b/src/spec.rs index a84496f..e5001bb 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -574,6 +574,10 @@ pub struct SpecEntry { /// a command, and this repo drops it from the running CLI now rather than /// carrying a command group with nothing in it — so the vendoring step no /// longer writes a file for it at all. +/// +/// `maps` and `vectortiles` are listed, but each contributes only one +/// operation, and both now target the merged `tilesets` command group +/// (#116) rather than a group of their own — see [`MERGED_SERVICES`]. pub const MAPBOX_SPEC_ENTRIES: &[SpecEntry] = &[ SpecEntry { name: "accounts", @@ -701,10 +705,12 @@ fn assert_no_duplicate_name(entries: &[SpecEntry], table: &str) { /// /// [`CLI_COMMAND_EXTENSION`] assembles these out of operations that live in /// other files — `sprites` out of five of `styles.yaml`'s, `tilesets` out of -/// one each from `rastertiles.yaml` and `vectortiles.yaml` — so there is no -/// `info.title` left that describes either. Hand-written for that reason and -/// only that reason: a service that still owns a file keeps that file's -/// `info` exactly as before. +/// one each from `rastertiles.yaml`, `rasterarrays.yaml`, `tilequery.yaml` +/// and `vectortiles.yaml` (#116), `static` out of one each from +/// `static-images.yaml` and `static-tiles.yaml` — so there is no +/// `info.title` left that describes any of them. Hand-written for that +/// reason and only that reason: a service that still owns a file keeps that +/// file's `info` exactly as before. const MERGED_SERVICES: &[(&str, &str, &str)] = &[ ( "sprites", @@ -716,6 +722,11 @@ const MERGED_SERVICES: &[(&str, &str, &str)] = &[ "Tiles API", "Raster and vector tiles, by tileset id.", ), + ( + "static", + "Static API", + "Static map images and raster tiles rendered from a Mapbox style.", + ), ]; /// One line of help for an intermediate command group — a path segment diff --git a/tests/docs_contract.rs b/tests/docs_contract.rs index 0f02ad3..c23eb8c 100644 --- a/tests/docs_contract.rs +++ b/tests/docs_contract.rs @@ -163,7 +163,7 @@ fn command_in_heading(line: &str) -> Option { /// /// The whole section counts — table, prose and worked examples alike, not /// only the `#### Parameters` table. The page legitimately introduces a flag -/// in prose (forward-geocode's structured input is a paragraph naming nine of +/// in prose (forward's structured input is a paragraph naming nine of /// them, and `--fresh` is one sentence) or in an example, and a check that /// read only the tables would be enforcing a house style rather than finding /// drift. diff --git a/tests/fixtures/api_command_surface.txt b/tests/fixtures/api_command_surface.txt index 1b006ca..ba4e9a1 100644 --- a/tests/fixtures/api_command_surface.txt +++ b/tests/fixtures/api_command_surface.txt @@ -4,10 +4,9 @@ mapbox accounts retrieve-token | aliases: (none) mapbox fonts delete | aliases: (none) mapbox fonts list | aliases: (none) mapbox fonts upload | aliases: (none) -mapbox geocoder batch-geocode | aliases: (none) -mapbox geocoder forward-geocode | aliases: (none) -mapbox geocoder reverse-geocode | aliases: (none) -mapbox rasterarrays get-mrt-tile | aliases: (none) +mapbox geocoder batch | aliases: (none) +mapbox geocoder forward | aliases: (none) +mapbox geocoder reverse | aliases: (none) mapbox search category | aliases: (none) mapbox search forward | aliases: (none) mapbox search list-category | aliases: (none) @@ -17,10 +16,8 @@ mapbox sprites delete-batch | aliases: (none) mapbox sprites get-json | aliases: (none) mapbox sprites upload | aliases: (none) mapbox sprites upload-batch | aliases: (none) -mapbox static-images get-static-image | aliases: (none) -mapbox static-images get-static-image-auto | aliases: (none) -mapbox static-images get-static-image-bbox | aliases: (none) -mapbox static-tiles get-static-tile | aliases: (none) +mapbox static get-image | aliases: (none) +mapbox static get-tile | aliases: (none) mapbox styles create | aliases: (none) mapbox styles delete | aliases: (none) mapbox styles draft delete | aliases: (none) @@ -29,6 +26,7 @@ mapbox styles draft update | aliases: (none) mapbox styles get | aliases: (none) mapbox styles list | aliases: (none) mapbox styles update | aliases: (none) -mapbox tilequery get | aliases: (none) -mapbox tilesets get-rastertile | aliases: (none) -mapbox tilesets get-vectortile | aliases: (none) +mapbox tilesets get-mrt | aliases: (none) +mapbox tilesets get-mvt | aliases: (none) +mapbox tilesets get-tile | aliases: (none) +mapbox tilesets query | aliases: (none) diff --git a/tests/output_contract.rs b/tests/output_contract.rs index 19bf703..45481dd 100644 --- a/tests/output_contract.rs +++ b/tests/output_contract.rs @@ -252,7 +252,7 @@ fn a_failure_writes_nothing_to_stdout() { #[test] fn a_usage_error_is_json_on_a_pipe_and_keeps_claps_exit_code() { - let out = run(&["geocoder", "forward-geocode", "--nonsense"]); + let out = run(&["geocoder", "forward", "--nonsense"]); let error = &json(&stderr(&out)); assert_eq!(error["code"], "usage"); @@ -272,7 +272,7 @@ fn a_usage_error_is_json_on_a_pipe_and_keeps_claps_exit_code() { /// the case `requested_in_argv` exists for. #[test] fn an_explicit_mode_survives_a_line_clap_could_not_parse() { - let out = run(&["-o", "text", "geocoder", "forward-geocode", "--nonsense"]); + let out = run(&["-o", "text", "geocoder", "forward", "--nonsense"]); let text = stderr(&out); assert!( @@ -539,7 +539,7 @@ fn an_unusable_environment_value_does_not_brick_the_cli() { /// from the first line alone names none of them. #[test] fn a_missing_argument_error_names_the_arguments() { - let out = run(&["static-images", "get-static-image", "mapbox", "streets-v12"]); + let out = run(&["static", "get-image", "mapbox", "streets-v12"]); let message = json(&stderr(&out))["message"] .as_str() @@ -572,7 +572,7 @@ fn an_unauthorized_response_carries_advice_a_caller_can_act_on() { "--token", "pk.bogus", "geocoder", - "forward-geocode", + "forward", "--q", "Helsinki", ]); diff --git a/tests/schema_contract.rs b/tests/schema_contract.rs index c206ab9..b7b6924 100644 --- a/tests/schema_contract.rs +++ b/tests/schema_contract.rs @@ -142,7 +142,7 @@ fn the_root_describes_the_whole_surface() { assert_eq!(value["target"], "mapbox"); for expected in [ "mapbox styles list", - "mapbox geocoder forward-geocode", + "mapbox geocoder forward", "mapbox auth login", "mapbox tilesets-cli", ] { @@ -246,7 +246,7 @@ fn the_values_the_schema_promises_are_the_values_the_cli_takes() { // CLI accepted any number. Both halves are asserted together, because // either one alone can regress into a description that is not true of the // command it describes. - let value = schema(&["static-tiles", "get-static-tile", "--schema"]); + let value = schema(&["static", "get-tile", "--schema"]); let tilesize = commands(&value)[0]["arguments"] .as_array() .expect("arguments") @@ -259,8 +259,8 @@ fn the_values_the_schema_promises_are_the_values_the_cli_takes() { let refused = run(&[ "--username", "u", - "static-tiles", - "get-static-tile", + "static", + "get-tile", "some-style", "300", "1", diff --git a/tests/tilesets_cli_proxy.rs b/tests/tilesets_cli_proxy.rs index 2fa5602..19bc52e 100644 --- a/tests/tilesets_cli_proxy.rs +++ b/tests/tilesets_cli_proxy.rs @@ -242,9 +242,10 @@ fn globals_written_after_the_subcommand_are_forwarded() { } /// `tilesets` was reserved for a command of our own, and is now one: the -/// generated group holding `get-rastertile` and `get-vectortile`. Nothing -/// about it is the proxy, so a line written against the Python CLI's own -/// subcommands has to fail here rather than being forwarded. +/// generated group holding `get-tile`, `get-mvt`, `get-mrt` and `query` +/// (#116). Nothing about it is the proxy, so a line written against the +/// Python CLI's own subcommands has to fail here rather than being +/// forwarded. #[test] fn the_tilesets_name_does_not_reach_the_proxy() { let stub = stub_for("reserved-name"); From 37afc38397bad239b64b7c007a0beda7c4bb3fa6 Mon Sep 17 00:00:00 2001 From: Mofei Zhu <13761509829@163.com> Date: Mon, 14 Sep 2026 21:25:07 +0300 Subject: [PATCH 2/2] Carry clap's suggestion tip into the JSON error's fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit report_parse_result's message only ever took clap's first paragraph, and clap renders a 'did you mean' tip as its second — so -o text showed it and -o json silently dropped it. That's backwards for a rename with no alias: the caller a tip would save is a script or an agent, and that's exactly who's on -o json. Per @mattpodwysocki's review on this PR. --- src/main.rs | 35 ++++++++++++++++++++++++++++++++--- tests/output_contract.rs | 24 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8df2ed6..f4211a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -806,15 +806,44 @@ fn report_parse_result(err: clap::Error, raw_argv: &[std::ffi::OsString]) -> Exi Remedy::default().with_action(help_for_missing_subcommand(message, raw_argv)) } // Clap rejected the line for a reason of its own — a misspelled flag, - // a value that would not parse. There is no command that answers - // that, and inventing one would be worse than the message alone. - _ => Remedy::default(), + // a value that would not parse. There is usually no command that + // answers that, and inventing one would be worse than the message + // alone — but clap's own suggester sometimes already has the answer, + // and `-o text` shows it; carry it over rather than losing it here. + _ => match clap_tip(&rendered) { + Some(tip) => Remedy::default().with_fix(&tip), + None => Remedy::default(), + }, }); output::emit_error(mode, &error.into()); ExitCode::from(code) } +/// The `tip: …` line clap's own suggester renders for an unrecognized +/// subcommand or flag, if there is one. +/// +/// Clap's rendering is an error paragraph, a blank line, then usage and a +/// hint — but for a suggestion it inserts the tip as its own paragraph +/// between the error and the usage line, which is exactly the paragraph +/// `report_parse_result`'s `message` skips past. `-o text` gets it because +/// clap prints the whole rendering there; this is what lets `-o json` carry +/// the same answer instead of silently dropping it — the caller `-o json` +/// is for (a script, an agent) is the one a rename breaks without an alias. +fn clap_tip(rendered: &str) -> Option { + let mut lines = rendered.lines().map(str::trim); + // The first paragraph is the error message; skip to its blank line. + for line in lines.by_ref() { + if line.is_empty() { + break; + } + } + // The next non-blank line is either the tip or, when there is none, + // the usage line — only the former is worth keeping. + let next = lines.find(|line| !line.is_empty())?; + next.strip_prefix("tip:").map(|tip| tip.trim().to_string()) +} + /// The subcommand placeholder clap ends a usage line with when one is still /// required. Nothing here sets `subcommand_value_name`, so this is clap's own /// default spelling. diff --git a/tests/output_contract.rs b/tests/output_contract.rs index 45481dd..7f58bb2 100644 --- a/tests/output_contract.rs +++ b/tests/output_contract.rs @@ -268,6 +268,30 @@ fn a_usage_error_is_json_on_a_pipe_and_keeps_claps_exit_code() { assert_eq!(out.status.code(), Some(2)); } +/// `-o text` prints clap's suggestion for a misspelled subcommand; `-o json` +/// used to drop it, because `report_parse_result`'s `message` only ever +/// takes clap's first paragraph and the tip is clap's second. That is +/// exactly backwards for a rename with no alias: the caller a `tip:` line +/// would save is a script or an agent, and that is the caller on `-o json`. +#[test] +fn an_unrecognized_subcommand_carries_claps_suggestion_into_json() { + let out = run(&["geocoder", "forward-geocode"]); + + let error = &json(&stderr(&out)); + assert_eq!(error["code"], "usage"); + assert!( + error["message"] + .as_str() + .expect("a message") + .contains("forward-geocode"), + "{error}" + ); + assert_eq!( + error["fix"], "a similar subcommand exists: 'forward'", + "{error}" + ); +} + /// `-o` written on a line clap rejects still has to be honoured — that is /// the case `requested_in_argv` exists for. #[test]