Repository: dcs4cop/xcube
Pull request #173 (2019-09-17 11:35:21)

Alicja 91 removing cli inconsistencies
When accepting this PR the CLI commands will change and saved commands might not work anymore. (eg. `xcube serve - v` is now `xcube serve --verbose` only because `-v` is already used by other CLI commands like `xcube gen ` for variables. 

This PR partly adresses #91 

**- Different names for similar options across tools** - are now consistent
**- Inconsistent use of CLI metavars across tools** - should now be consistent
**- Inconsistent use of CLI shortcuts across tools (e.g. uppcase/lowercase or same letter for different options)** - are now consistent and not double for different tools



Patch:
diff --git a/CHANGES.md b/CHANGES.md
index bb42dad6..0b53d168 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,28 @@
 ## Changes in 0.2.0.dev2 (in dev)
 
-* Reorganisation of the Documentation and Examples Section (partly adressing #106)
+* Making CLI parameters consistent and removing or changing parameter abbreviations in case they were used twice for different params. (partly addressing #91)
+  For every CLI command which is generating an output a path must be provided by the option `-o`, `--output`. If not provided by the user, a default output_path is generated.
+  The following CLI parameter have changed and their abbreviation is not enabled anymore : 
+
+    - `xcube gen -v` is now only `xcube gen --vars` or `xcube gen --variables` 
+    - `xcube gen -p` is now  `xcube gen -P` 
+    - `xcube gen -i` is now  `xcube gen -I` 
+    - `xcube gen -r` is now  `xcube gen -R`
+    - `xcube gen -s` is now  `xcube gen -S` 
+    - `xcube chunk -c`  is now  `xcube chunk -C`
+    - `xcube level -l` is now `xcube level -L`
+    - `xcube dump -v` is now `xcube dump --variable` or `xcube dump --var`
+    - `xcube dump -e` is now `xcube dump -E` 
+    - `xcube vars2dim -v` is now `xcube vars2dim --variable` or `xcube vars2dim --var`
+    - `xcube vars2dim --var_name` is now `xcube vars2dim --variable` or `xcube vars2dim --var`
+    - `xcube vars2dim -d` is now `xcube vars2dim -D` 
+    - `xcube grid res -d` is now `xcube grid res -D`
+    - `xcube grid res -c` is now `xcube grid res --cov` or `xcube grid res --coverage` 
+    - `xcube grid res -n` is now `xcube grid res -N` or `xcube grid res --num_results` 
+    - `xcube serve -p` is now `xcube serve -P` 
+    - `xcube serve -a` is now `xcube serve -A` 
+    
+* Reorganisation of the Documentation and Examples Section (partly addressing #106)
 
 ### Enhancements
 
@@ -51,7 +73,7 @@
      see AWS docs [HEAD](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html) 
      and [GET](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html)
 * `xcube serve` now verifies that a configured cube is valid once it is opened. (#107)
-* Added new CLI command `xcube verify` performing data cube verification. (#19)
+* Added new CLI command `xcube verify` performing xcube dataset verification. (#19)
 * Reworked `xcube extract` to be finally useful and effective for point data extraction. (#102) 
 * `xcube server`can now filter datasets by point coordinate, e.g. `/datasets?point=12.5,52.8`. (#50) 
 * `xcube server`can now limit time series to a maximum number of 
@@ -75,7 +97,7 @@
   for backward compatibility. (#79)
 * Added new CLI command `xcube resample` that is used to generate temporarily up- or downsampled
   data cubes from other data cubes.
-* `xcube serve` can now be run with data cube paths and styling information given via the CLI rather 
+* `xcube serve` can now be run with xcube dataset paths and styling information given via the CLI rather 
   than a configuration file. For example `xcube serve --styles conc_chl=(0,20,"viridis") /path/to/my/chl-cube.zarr`.
   This allows for quick inspection of newly generated cubes via `xcube gen`.
   Also added option `--show` that starts the Xcube viewer on desktop environments in a browser. 
@@ -85,7 +107,7 @@
 * Added new `xcube timeit` command that can be used to measure the time required for 
   parameterized command invocations. 
   The command is still in development and therefore hidden.
-* Added global `xcube --scheduler <scheduler>` option for Dask distributed computing (#58)
+* Added global `xcube --scheduler SCHEDULER` option for Dask distributed computing (#58)
 * Added global `xcube --traceback` option, removed local `xcube gen --traceback` option
 * Completed version 1 of an xcube developer guide.
 * Added `xcube serve` command (#43) 
diff --git a/docs/source/cli.rst b/docs/source/cli.rst
index 80ddeaf6..e90ffa38 100644
--- a/docs/source/cli.rst
+++ b/docs/source/cli.rst
@@ -5,7 +5,7 @@ Command-line Interface
 The xcube command-line interface is a single executable ``xcube`` with several sub-commands comprising
 functions ranging from cube generation, over cube analysis and manipulation, to cube publication.
 
-Most of the commands operate on datasets that conform to the xcube definition (:doc:`cubedef`) a data cube.
+Most of the commands operate on datasets that conform to the xcube definition (:doc:`cubedef`) of a data cube.
 Such inputs are consistently named ``CUBE`` and provided as command argument(s). You may pass a path into the
 local file system or a path into some object storage bucket, e.g. in AWS S3.
 Command inputs of other type are usually called ``INPUT``.
diff --git a/docs/source/cli/xcube.md b/docs/source/cli/xcube.md
index cd9070de..accaa980 100644
--- a/docs/source/cli/xcube.md
+++ b/docs/source/cli/xcube.md
@@ -13,9 +13,8 @@ $ xcube --help
       --traceback              Enable tracing back errors by dumping the Python
                                call stack. Pass as very first option to also trace
                                back error during command-line validation.
-    
-      --scheduler <scheduler>  Enable distributed computing using the Dask
-                               scheduler identified by <scheduler>. <scheduler>
+      --scheduler SCHEDULER    Enable distributed computing using the Dask
+                               scheduler identified by SCHEDULER. SCHEDULER
                                can have the form <address>?<keyword>=<value>,...
                                where <address> is <host> or <host>:<port> and
                                specifies the scheduler's address in your network.
@@ -27,12 +26,13 @@ $ xcube --help
       --help                   Show this message and exit.
     
     Commands:
-      chunk     (Re-)chunk dataset.
-      dump      Dump contents of a dataset.
-      extract   Extract cube time series.
-      gen       Generate data cube.
-      grid      Find spatial data cube resolutions and adjust bounding boxes.
+      chunk     (Re-)chunk xcube dataset.
+      dump      Dump contents of an input dataset.
+      extract   Extract cube points.
+      gen       Generate xcube dataset.
+      grid      Find spatial xcube dataset resolutions and adjust bounding boxes.
       level     Generate multi-resolution levels.
+      optimize  Optimize xcube dataset for faster access.
       prune     Delete empty chunks.
       resample  Resample data along the time dimension.
       serve     Serve data cubes via web service.
diff --git a/docs/source/cli/xcube_chunk.md b/docs/source/cli/xcube_chunk.md
index 32237d72..056bab8c 100644
--- a/docs/source/cli/xcube_chunk.md
+++ b/docs/source/cli/xcube_chunk.md
@@ -6,21 +6,22 @@
 $ xcube chunk --help
 ```
     
-    Usage: xcube chunk [OPTIONS] <input> <output>
+    Usage: xcube chunk [OPTIONS] CUBE
     
-      (Re-)chunk dataset. Changes the external chunking of all variables of
-      <input> according to <chunks> and writes the result to <output>.
+      (Re-)chunk xcube dataset. Changes the external chunking of all variables of
+      CUBE according to CHUNKS and writes the result to OUTPUT.
     
     Options:
-      -f, --format <format>  Format of the output. If not given, guessed from
-                             <output>.
-      -p, --params <params>  Parameters specific for the output format. Comma-
+      -o, --output OUTPUT    Output path. Defaults to 'out.zarr'
+      -f, --format FORMAT    Format of the output. If not given, guessed from
+                             OUTPUT.
+      -p, --params PARAMS    Parameters specific for the output format. Comma-
                              separated list of <key>=<value> pairs.
-      -c, --chunks <chunks>  Chunk sizes for each dimension. Comma-separated list
+      -C, --chunks CHUNKS    Chunk sizes for each dimension. Comma-separated list
                              of <dim>=<size> pairs, e.g. "time=1,lat=270,lon=270"
       --help                 Show this message and exit.
 
 
 Example:
 
-    $ xcube chunk input_not_chunked.zarr output_rechunked.zarr --chunks "time=1,lat=270,lon=270"
+    $ xcube chunk input_not_chunked.zarr -o output_rechunked.zarr --chunks "time=1,lat=270,lon=270"
diff --git a/docs/source/cli/xcube_dump.md b/docs/source/cli/xcube_dump.md
index c8c05fda..d68955fb 100644
--- a/docs/source/cli/xcube_dump.md
+++ b/docs/source/cli/xcube_dump.md
@@ -3,18 +3,19 @@
 Dump contents of a dataset.
 
 ```bash
-    $ xcube dump --help
+$ xcube dump --help
 ```
 
     
-    Usage: xcube dump [OPTIONS] <path>
+    Usage: xcube dump [OPTIONS] INPUT
     
-    Dump contents of a dataset.
+      Dump contents of an input dataset.
     
-    optional arguments:
-      --help                Show this help message and exit
-      --variable, -v        Name of a variable (multiple allowed).
-      --encoding, -e        Dump also variable encoding information.
+    Options:
+      --variable, --var VARIABLE
+                                      Name of a variable (multiple allowed).
+      -E, --encoding                  Dump also variable encoding information.
+      --help                          Show this message and exit.
 
 
 Example:
diff --git a/docs/source/cli/xcube_extract.md b/docs/source/cli/xcube_extract.md
index 01658a9a..e3e1bbe8 100644
--- a/docs/source/cli/xcube_extract.md
+++ b/docs/source/cli/xcube_extract.md
@@ -3,36 +3,33 @@
 Extract cube points.
 
 ```bash
-$ xcube dump --help
+$ xcube extract --help
 ```
 
     Usage: xcube extract [OPTIONS] CUBE POINTS
-
-      Extract cube points.
-
+    
+      Extract data points from an xcube dataset.
+    
       Extracts data cells from CUBE at coordinates given in each POINTS record
       and writes the resulting values to given output path and format.
-
-      <points> must be a CSV file that provides at least the columns "lon",
-      "lat", and "time". The "lon" and "lat" columns provide a point's location
-      in decimal degrees. The "time" column provides a point's date or date-
-      time. Its format should preferably be ISO, but other formats may work as
-      well.
-
+    
+      POINTS must be a CSV file that provides at least the columns "lon", "lat",
+      and "time". The "lon" and "lat" columns provide a point's location in
+      decimal degrees. The "time" column provides a point's date or date-time.
+      Its format should preferably be ISO, but other formats may work as well.
+    
     Options:
-      -o, --output TEXT             Output file. If omitted, output is written to
-                                    stdout.
-      -f, --format [csv|json|xlsx]  Output format. Currently, only 'csv' is
-                                    supported.
-      -C, --coords                  Include cube cell coordinates in output.
-      -B, --bounds                  Include cube cell coordinate boundaries (if
-                                    any) in output.
-      -I, --indexes                 Include cube cell indexes in output.
-      -R, --refs                    Include point values as reference in output.
-      --help                        Show this message and exit.
+      -o, --output OUTPUT    Output path. If omitted, output is written to stdout.
+      -f, --format FORMAT    Output format. Currently, only 'csv' is supported.
+      -C, --coords           Include cube cell coordinates in output.
+      -B, --bounds           Include cube cell coordinate boundaries (if any) in
+                             output.
+      -I, --indexes              Include cube cell indexes in output.
+      -R, --refs                 Include point values as reference in output.
+      --help                 Show this message and exit.
 
 
 Example:  
     
-    $ xcube extract xcube_cube.zarr point_data.csv -CBIR
+    $ xcube extract xcube_cube.zarr -o point_data.csv -Cb --indexes --refs
     
diff --git a/docs/source/cli/xcube_gen.md b/docs/source/cli/xcube_gen.md
index fd78ca73..c02016d1 100644
--- a/docs/source/cli/xcube_gen.md
+++ b/docs/source/cli/xcube_gen.md
@@ -1,14 +1,14 @@
 # `xcube gen`
 
-Generate data cube.
+Generate xcube dataset.
 
 ```bash
 $ xcube gen --help
 ```
 
-    Usage: xcube gen [OPTIONS] [INPUTS]...
+    Usage: xcube gen [OPTIONS] [INPUT]...
     
-      Generate data cube. Data cubes may be created in one go or successively in
+      Generate xcube dataset. Data cubes may be created in one go or successively in
       append mode, input by input. The input paths may be one or more input
       files or a pattern that may contain wildcards '?', '*', and '**'. The
       input paths can also be passed as lines of a text file. To do so, provide
@@ -16,7 +16,7 @@ $ xcube gen --help
       input paths to be used.
     
     Options:
-      -p, --proc TEXT                 Input processor name. The available input
+      -P, --proc INPUT-PROCESSOR      Input processor name. The available input
                                       processor names and additional information
                                       about input processors can be accessed by
                                       calling xcube gen --info . Defaults to
@@ -24,21 +24,22 @@ $ xcube gen --help
                                       with simple datasets whose variables have
                                       dimensions ("lat", "lon") and conform with
                                       the CF conventions.
-      -c, --config TEXT               Data cube configuration file in YAML format.
+      -c, --config CONFIG             xcube dataset configuration file in YAML format.
                                       More than one config input file is
                                       allowed.When passing several config files,
                                       they are merged considering the order passed
                                       via command line.
-      -o, --output TEXT               Output path. Defaults to 'out.zarr'
-      -f, --format TEXT               Output format. Information about output
+      -o, --output OUTPUT             Output path. Defaults to 'out.zarr'
+      -f, --format FORMAT             Output format. Information about output
                                       formats can be accessed by calling xcube gen
                                       --info. If omitted, the format will be
                                       guessed from the given output path.
-      -s, --size TEXT                 Output size in pixels using format
+      -S, --size SIZE                 Output size in pixels using format
                                       "<width>,<height>".
-      -r, --region TEXT               Output region using format "<lon-min>,<lat-
+      -R, --region REGION             Output region using format "<lon-min>,<lat-
                                       min>,<lon-max>,<lat-max>"
-      -v, --variables, --vars TEXT    Variables to be included in output. Comma-
+      --variables, --vars VARIABLES
+                                      Variables to be included in output. Comma-
                                       separated list of names which may contain
                                       wildcard characters "*" and "?".
       --resampling [Average|Bilinear|Cubic|CubicSpline|Lanczos|Max|Median|Min|Mode|Nearest|Q1|Q3]
@@ -55,10 +56,10 @@ $ xcube gen --help
       --prof                          Collect profiling information and dump
                                       results after processing.
       --sort                          The input file list will be sorted before
-                                      creating the data cube. If --sort parameter
+                                      creating the xcube dataset. If --sort parameter
                                       is not passed, order of input list will be
                                       kept.
-      -i, --info                      Displays additional information about format
+      -I, --info                      Displays additional information about format
                                       options or about input processors.
       --dry_run                       Just read and process inputs, but don't
                                       produce any outputs.
@@ -88,7 +89,7 @@ Below is the `xcube gen --info` call with 5 input processors installed via plugi
 
 Example:
 
-    $ xcube gen -a -s 2000,1000 -r 0,50,5,52.5 -v conc_chl,conc_tsm,kd489,c2rcc_flags,quality_flags -n hiroc-cube -t -p default D:\OneDrive\BC\EOData\HIGHROC\2017\01\*.nc
+    $ xcube gen -S 2000,1000 -R 0,50,5,52.5 --vars conc_chl,conc_tsm,kd489,c2rcc_flags,quality_flags -o hiroc-cube.zarr -P default D:\OneDrive\BC\EOData\HIGHROC\2017\01\*.nc
 
 
 Some input processors have been developed for specific EO data sources 
diff --git a/docs/source/cli/xcube_grid.md b/docs/source/cli/xcube_grid.md
index 647c7b50..d24ec76f 100644
--- a/docs/source/cli/xcube_grid.md
+++ b/docs/source/cli/xcube_grid.md
@@ -2,15 +2,15 @@
 
 Warning: this tool will likely change in the near future.
 
-Find spatial data cube resolutions and adjust bounding boxes.
+Find spatial xcube dataset resolutions and adjust bounding boxes.
 
 ```bash
-    $ xcube grid --help
+$ xcube grid --help
 ```
 
     Usage: xcube grid [OPTIONS] COMMAND [ARGS]...
     
-      Find spatial data cube resolutions and adjust bounding boxes.
+      Find spatial xcube dataset resolutions and adjust bounding boxes.
     
       We find suitable resolutions with respect to a possibly regional fixed
       Earth grid and adjust regional spatial bounding boxes to that grid. We
@@ -47,7 +47,7 @@ Find spatial data cube resolutions and adjust bounding boxes.
 Example: Find suitable target resolution for a ~300m (Sentinel 3 OLCI FR resolution) 
 fixed Earth grid within a deviation of 5%.
 
-    $ xcube grid res 300m -d 5%
+    $ xcube grid res 300m -D 5%
     
     TILE    LEVEL   HEIGHT  INV_RES RES (deg)       RES (m), DELTA_RES (%)
     540     7       69120   384     0.0026041666666666665   289.9   -3.4
@@ -73,7 +73,7 @@ We want to see if the resolution pyramid also supports a resolution close to 10m
 
 This indicates we have a resolution of 9.1m at level 12.
 
-Lets assume we have data cube region with longitude from 0 to 5 degrees
+Lets assume we have xcube dataset region with longitude from 0 to 5 degrees
 and latitudes from 50 to 52.5 degrees. What is the adjusted bounding box 
 on a fixed Earth grid with the inverse resolution 384?
 
diff --git a/docs/source/cli/xcube_level.md b/docs/source/cli/xcube_level.md
index d427b745..5eb39f40 100644
--- a/docs/source/cli/xcube_level.md
+++ b/docs/source/cli/xcube_level.md
@@ -6,34 +6,35 @@ Generate multi-resolution levels.
 $ xcube level --help
 ```
     
-    Usage: xcube level [OPTIONS] <input>
+    Usage: xcube level [OPTIONS] INPUT
     
-      Generate multi-resolution levels. Transform the given dataset by <input>
+      Generate multi-resolution levels. Transform the given dataset by INPUT
       into the levels of a multi-level pyramid with spatial resolution
       decreasing by a factor of two in both spatial dimensions and write the
-      result to directory <output>.
+      result to directory OUTPUT.
     
     Options:
-      -o, --output <output>           Output directory. If omitted,
-                                      "<input>.levels" will be used.
-      -l, --link                      Link the <input> instead of converting it to
-                                      a level zero dataset. Use with care, as the
-                                      <input>'s internal spatial chunk sizes may
-                                      be inappropriate for imaging purposes.
-      -t, --tile-size <tile-size>     Tile size, given as single integer number or
+      -o, --output OUTPUT             Output path. If omitted, "INPUT.levels"
+                                      will be used.
+      -L, --link                          Link the INPUT instead of converting it to a
+                                      level zero dataset. Use with care, as the
+                                      INPUT's internal spatial chunk sizes may be
+                                      inappropriate for imaging purposes.
+      -t, --tile-size TILE-SIZE       Tile size, given as single integer number or
                                       as <tile-width>,<tile-height>. If omitted,
                                       the tile size will be derived from the
-                                      <input>'s internal spatial chunk sizes. If
-                                      the <input> is not chunked, tile size will
+                                      INPUT's internal spatial chunk sizes. If
+                                      the INPUT is not chunked, tile size will
                                       be 512.
-      -n, --num-levels-max <num-levels-max>
+      -n, --num-levels-max NUM-LEVELS-MAX
                                       Maximum number of levels to generate. If not
                                       given, the number of levels will be derived
                                       from spatial dimension and tile sizes.
       --help                          Show this message and exit.
 
+
     
 Example:
 
-    $ xcube level -l -t 720 data/cubes/test-cube.zarr
+    $ xcube level --link -t 720 data/cubes/test-cube.zarr
 
diff --git a/docs/source/cli/xcube_optimize.md b/docs/source/cli/xcube_optimize.md
index e9c3fa73..8b95cf1c 100644
--- a/docs/source/cli/xcube_optimize.md
+++ b/docs/source/cli/xcube_optimize.md
@@ -1,17 +1,17 @@
 # `xcube optimize`
 
-Optimize data cube for faster access.
+Optimize xcube dataset for faster access.
 
-```
+```bash
 $ xcube optimize --help
 ```
 
-    Usage: xcube optimize [OPTIONS] INPUT
+    Usage: xcube optimize [OPTIONS] CUBE
     
-      Optimize data cube for faster access.
+      Optimize xcube dataset for faster access.
     
-      Reduces the number of metadata and coordinate data files in data cube
-      given by INPUT. Consolidated cubes open much faster especially from remote
+      Reduces the number of metadata and coordinate data files in xcube dataset
+      given by CUBE. Consolidated cubes open much faster especially from remote
       locations, e.g. in object storage, because obviously much less HTTP
       requests are required to fetch initial cube meta information. That is, it
       merges all metadata files into a single top-level JSON file ".zmetadata".
@@ -22,15 +22,15 @@ $ xcube optimize --help
       format.
     
     Options:
-      -o, --output TEXT  Output path. The placeholder "<built-in function input>"
-                         will be replaced by the input's filename without
-                         extension (such as ".zarr"). Defaults to
-                         "{input}-optimized.zarr".
-      -I, --in-place     Optimize cube in place. Ignores output path.
-      -C, --coords       Also optimize coordinate variables by converting any
-                         chunked arrays into single, non-chunked, contiguous
-                         arrays.
-      --help             Show this message and exit.
+      -o, --output OUTPUT    Output path. The placeholder "<built-in function
+                             input>" will be replaced by the input's filename
+                             without extension (such as ".zarr"). Defaults to
+                             "{INPUT}-optimized.zarr".
+      -I, --in-place         Optimize cube in place. Ignores output path.
+      -C, --coords           Also optimize coordinate variables by converting any
+                             chunked arrays into single, non-chunked, contiguous
+                             arrays.
+      --help                 Show this message and exit.
 
 
 Examples:
diff --git a/docs/source/cli/xcube_prune.md b/docs/source/cli/xcube_prune.md
index ca3fd1fb..ae49af95 100644
--- a/docs/source/cli/xcube_prune.md
+++ b/docs/source/cli/xcube_prune.md
@@ -10,10 +10,10 @@ the near future.
 $ xcube prune --help
 ```
 
-    Usage: xcube prune [OPTIONS] INPUT
+    Usage: xcube prune [OPTIONS] CUBE
     
-      Delete empty chunks. Deletes all block files associated with empty (NaN-
-      only) chunks in given INPUT cube, which must have ZARR format.
+      Delete empty chunks. Deletes all data files associated with empty (NaN-
+      only) chunks in given CUBE, which must have ZARR format.
     
     Options:
       --dry-run  Just read and process input, but don't produce any outputs.
diff --git a/docs/source/cli/xcube_resample.md b/docs/source/cli/xcube_resample.md
index 4392d142..6bb30f80 100644
--- a/docs/source/cli/xcube_resample.md
+++ b/docs/source/cli/xcube_resample.md
@@ -6,21 +6,22 @@ Resample data along the time dimension.
 $ xcube resample --help
 ```
     
-    Usage: xcube resample [OPTIONS] INPUT
+    Usage: xcube resample [OPTIONS] CUBE
     
       Resample data along the time dimension.
     
     Options:
-      -c, --config TEXT               Data cube configuration file in YAML format.
+      -c, --config CONFIG             xcube dataset configuration file in YAML format.
                                       More than one config input file is
                                       allowed.When passing several config files,
                                       they are merged considering the order passed
                                       via command line.
-      -o, --output TEXT               Output path.
+      -o, --output OUTPUT             Output path. Defaults to 'out.zarr'.
       -f, --format [zarr|netcdf4|mem]
                                       Output format. If omitted, format will be
                                       guessed from output path.
-      --variables, --vars TEXT        Comma-separated list of names of variables
+      --variables, --vars VARIABLES
+                                      Comma-separated list of names of variables
                                       to be included.
       -M, --method TEXT               Temporal resampling method. Available
                                       downsampling methods are 'count', 'first',
diff --git a/docs/source/cli/xcube_serve.md b/docs/source/cli/xcube_serve.md
index e8f67378..0627c19b 100644
--- a/docs/source/cli/xcube_serve.md
+++ b/docs/source/cli/xcube_serve.md
@@ -46,7 +46,7 @@ The SwaggerHub allows to choose the xcube-server project and therefore the datas
 $ xcube serve --help
 ```
 
-    Usage: xcube serve [OPTIONS] CUBE...
+    Usage: xcube serve [OPTIONS] [CUBE]...
     
       Serve data cubes via web service.
     
@@ -55,8 +55,8 @@ $ xcube serve --help
       https://app.swaggerhub.com/apis/bcdev/xcube-server.
     
     Options:
-      -a, --address ADDRESS  Service address. Defaults to 'localhost'.
-      -p, --port PORT        Port number where the service will listen on.
+      -A, --address ADDRESS  Service address. Defaults to 'localhost'.
+      -P --port PORT            Port number where the service will listen on.
                              Defaults to 8080.
       --prefix PREFIX        Service URL prefix. May contain template patterns
                              such as "${version}" or "${name}". For example
@@ -77,7 +77,7 @@ $ xcube serve --help
       --tilemode MODE        Tile computation mode. This is an internal option
                              used to switch between different tile computation
                              implementations. Defaults to 0.
-      -s, --show             Run viewer app. Requires setting the environment
+      -s, --show                 Run viewer app. Requires setting the environment
                              variable XCUBE_VIEWER_PATH to a valid xcube-viewer
                              deployment or build directory. Refer to
                              https://github.com/dcs4cop/xcube-viewer for more
diff --git a/docs/source/cli/xcube_vars2dim.md b/docs/source/cli/xcube_vars2dim.md
index 0d50f35b..28fb5af1 100644
--- a/docs/source/cli/xcube_vars2dim.md
+++ b/docs/source/cli/xcube_vars2dim.md
@@ -3,23 +3,26 @@
 Convert cube variables into new dimension.
 
 ```bash
-    $ xcube vars2dim --help
+$ xcube vars2dim --help
 ```
     
-    Usage: xcube vars2dim [OPTIONS] <cube>
+    Usage: xcube vars2dim [OPTIONS] CUBE
     
-      Convert cube variables into new dimension. Moves all variables of <cube>
-      into into a single new variable <var-name> with a new dimension <dim-name>
-      and writes the results to <output>.
+      Convert cube variables into new dimension. Moves all variables of CUBE
+      into into a single new variable VARIABLE with a new dimension DIM-NAME
+      and writes the results to OUTPUT.
     
     Options:
-      -d, --dim_name <dim-name>  Name of the new dimension into variables.
-                                 Defaults to "var".
-      -v, --var_name <var-name>  Name of the new variable that includes all
-                                 variables. Defaults to "data".
-      -o, --output <output>      Output file.
-      -f, --format <format>      Format of the output. If not given, guessed from
-                                 <output>.
-      --help                     Show this message and exit.
+      --variable, --var VARIABLE
+                                      Name of the new variable that includes all
+                                      variables. Defaults to "data".
+      -D, --dim_name DIM-NAME         Name of the new dimension into variables.
+                                      Defaults to "var".
+      -o, --output OUTPUT             Output path. If omitted,
+                                      'INPUT-vars2dim.INPUT-FORMAT' will be
+                                      used.
+      -f, --format FORMAT             Format of the output. If not given, guessed
+                                      from OUTPUT.
+      --help                          Show this message and exit.
 
 
diff --git a/docs/source/cli/xcube_verify.md b/docs/source/cli/xcube_verify.md
index 10906151..257ab11b 100644
--- a/docs/source/cli/xcube_verify.md
+++ b/docs/source/cli/xcube_verify.md
@@ -3,23 +3,23 @@
 Perform cube verification.
 
 ```bash
-xcube verify --help
+$ xcube verify --help
 ```
 
-    Usage: xcube verify [OPTIONS] INPUT
+    Usage: xcube verify [OPTIONS] CUBE
     
       Perform cube verification.
     
-      The tool verifies that INPUT
+      The tool verifies that CUBE
       * defines the dimensions "time", "lat", "lon";
       * has corresponding "time", "lat", "lon" coordinate variables and that they
         are valid, e.g. 1-D, non-empty, using correct units;
-      * has valid bounds variables for "time", "lat", "lon" coordinate
+      * has valid  bounds variables for "time", "lat", "lon" coordinate
         variables, if any;
       * has any data variables and that they are valid, e.g. min. 3-D, all have
         same dimensions, have at least dimensions "time", "lat", "lon".
     
-      If INPUT is a valid data cube, the tool returns exit code 0. Otherwise a
+      If INPUT is a valid xcube dataset, the tool returns exit code 0. Otherwise a
       violation report is written to stdout and the tool returns exit code 3.
     
     Options:
diff --git a/docs/source/devguide.md b/docs/source/devguide.md
index 26251cda..0e744c33 100644
--- a/docs/source/devguide.md
+++ b/docs/source/devguide.md
@@ -91,30 +91,31 @@ In the following common arguments and options are listed.
 
 Input argument:
 
-    @click.argument('input', metavar='<input>')
+    @click.argument('input')
 
-Output argument:
+If input argument is restricted to a xcube dataset:
+
+    @click.argument('cube')
 
-    @click.argument('output', metavar='<output>')
 
 Output (directory) option:
 
-    @click.option('--output', '-o', metavar='<output>',
-                  help='Output directory. If omitted, "<input>.levels" will be used.')
+    @click.option('--output', '-o', metavar='OUTPUT',
+                  help='Output directory. If omitted, "INPUT.levels" will be used.')
 
 Output format:
 
-    @click.option('--format', '-f', metavar='<format>', type=click.Choice(['zarr', 'netcdf']),
-                  help="Format of the output. If not given, guessed from <output>.")
+    @click.option('--format', '-f', metavar='FORMAT', type=click.Choice(['zarr', 'netcdf']),
+                  help="Format of the output. If not given, guessed from OUTPUT.")
 
 Output parameters:
 
-    @click.option('--param', '-p', metavar='<param>', multiple=True,
+    @click.option('--param', metavar='PARAM', multiple=True,
                   help="Parameter specific for the output format. Multiple allowed.")
 
 Variable names:
 
-    @click.option('--var', '-v', metavar='<variable>', multiple=True,
+    @click.option('--variable',--var', metavar='VARIABLE', multiple=True,
                   help="Name of a variable. Multiple allowed.")
 
 
@@ -156,10 +157,10 @@ keyword parameter `cube_asserted: bool = False`.
 Otherwise name the primary dataset argument `dataset`.
 
 Reflect the fact, that a certain API method or function operates only 
-on datasets that conform with the xcube data cube specifications by
+on datasets that conform with the xcube dataset specifications by
 using `cube` in its name rather than `dataset`. For example `compute_dataset` 
 can operate on any xarray datasets, while `get_cube_values_for_points` expects a 
-data cube as input or `read_cube` ensures it will return valid data cubes only. 
+xcube dataset as input or `read_cube` ensures it will return valid data cubes only. 
 
 In the implementation, if `not cube_asserted`, 
 we must assert and verify the `cube` is a cube. 
diff --git a/docs/source/examples/xcube_gen.rst b/docs/source/examples/xcube_gen.rst
index 8602b909..61bebbc2 100644
--- a/docs/source/examples/xcube_gen.rst
+++ b/docs/source/examples/xcube_gen.rst
@@ -2,12 +2,12 @@
 Generating a cube
 =================
 
-In this example we show how to generate a (toy) data cube from a set of EO source files.
+In this example we show how to generate a (toy) xcube dataset from a set of EO source files.
 
 Preparation
 ===========
 
-In order to create a suitable data cube for your needs,
+In order to create a suitable xcube dataset for your needs,
 there are some questions which need to be answered before hand.
 
 1. Find appropriate grid for cube:
@@ -66,7 +66,7 @@ The output format (``output_writer_name``) are defined as well.
 The chunking of the dimensions can be set by the output writer parameter (``output_writer_params``) called chunksizes,
 and here the chunking is set for latitude and longitude. If the chunking is not set, a automatic chunking is appllied.
 The spatial resampling method (output_resampling) is set to 'nearest' and the confguration file contains only one 
-variable which will be included into the data cube - 'analysed-sst'.
+variable which will be included into the xcube dataset - 'analysed-sst'.
 
 The Analysed Sea Surface Temperature data set contains the variable already as needed. This means no pixel 
 masking needs to be applied. However, this might differ depending on the input data. You can take a look at a 
diff --git a/docs/source/examples/xcube_serve.rst b/docs/source/examples/xcube_serve.rst
index 03dd6011..c9717b96 100644
--- a/docs/source/examples/xcube_serve.rst
+++ b/docs/source/examples/xcube_serve.rst
@@ -9,9 +9,9 @@ Running the server
 
 To run the server on default port 8080 using the demo configuration:::
 
-    $ xcube serve -v -c examples/serve/demo/config.yml
+    $ xcube serve --verbose -c examples/serve/demo/config.yml
 
-To run the server using a particular data cube path and styling information for a variable:::
+To run the server using a particular xcube dataset path and styling information for a variable:::
 
     $ xcube serve --styles conc_chl=(0,20,"viridis") examples/serve/demo/cube-1-250-250.zarr
 
diff --git a/xcube/api/api.py b/xcube/api/api.py
index 4ee9d0a0..5015170d 100644
--- a/xcube/api/api.py
+++ b/xcube/api/api.py
@@ -91,7 +91,7 @@ class XCubeDatasetAccessor:
     @classmethod
     def read(cls, input_path: str, format_name: str = None, **kwargs) -> xr.Dataset:
         """
-        Read a data cube from *input_path*.
+        Read a xcube dataset from *input_path*.
         If *format* is not provided it will be guessed from *input_path*.
 
         :param input_path: input path
@@ -238,7 +238,7 @@ class XCubeDatasetAccessor:
         Convert data variables into a dimension
 
         :param dim_name: The name of the new dimension ['vars']
-        :return: A new data cube with the new dimension.
+        :return: A new xcube dataset with the new dimension.
         """
         return vars_to_dim(self._dataset, dim_name)
 
@@ -258,9 +258,9 @@ class XCubeDatasetAccessor:
 
     def verify(self) -> List[str]:
         """
-        Verify that this dataset is a valid data cube.
+        Verify that this dataset is a valid xcube dataset.
 
-        Returns a list of issues, which is empty if this dataset is a valid data cube.
+        Returns a list of issues, which is empty if this dataset is a valid xcube dataset.
 
         :return: List of issues or empty list.
         """
diff --git a/xcube/api/gen/gen.py b/xcube/api/gen/gen.py
index 074db5f8..16b93ff9 100644
--- a/xcube/api/gen/gen.py
+++ b/xcube/api/gen/gen.py
@@ -60,7 +60,7 @@ def gen_cube(input_paths: Sequence[str] = None,
              dry_run: bool = False,
              monitor: Callable[..., None] = None) -> bool:
     """
-    Generate a data cube from one or more input files.
+    Generate a xcube dataset from one or more input files.
 
     :param sort_mode:
     :param input_paths: The input paths.
@@ -194,13 +194,13 @@ def _process_input(input_processor: InputProcessor,
         input_dataset = input_reader.read(input_file, **input_reader_params)
         monitor(f'Dataset read:\n{input_dataset}')
     except Exception as e:
-        monitor(f'ERROR: cannot read input: {e}: skipping...')
+        monitor(f'Error: cannot read input: {e}: skipping...')
         traceback.print_exc()
         return False
 
     time_range = input_processor.get_time_range(input_dataset)
     if time_range[0] > time_range[1]:
-        monitor('ERROR: start time is greater than end time: skipping...')
+        monitor('Error: start time is greater than end time: skipping...')
         return False
 
     if output_variables:
@@ -312,7 +312,7 @@ def _process_input(input_processor: InputProcessor,
         total_t2 = time.perf_counter()
         monitor(f'{num_steps} steps took {total_t2 - total_t1} seconds to complete')
     except RuntimeError as e:
-        monitor(f'ERROR: something went wrong during processing, skipping input slice: {e}')
+        monitor(f'Error: something went wrong during processing, skipping input slice: {e}')
         traceback.print_exc()
         return False
     finally:
diff --git a/xcube/api/readwrite.py b/xcube/api/readwrite.py
index 3d7009fa..3ec1af37 100644
--- a/xcube/api/readwrite.py
+++ b/xcube/api/readwrite.py
@@ -16,7 +16,7 @@ def open_cube(input_path: str,
     :param input_path: input path
     :param format_name: format, e.g. "zarr" or "netcdf4"
     :param kwargs: format-specific keyword arguments
-    :return: data cube
+    :return: xcube dataset
     """
     dataset = read_cube(input_path, format_name, **kwargs)
     try:
@@ -29,13 +29,13 @@ def read_cube(input_path: str,
               format_name: str = None,
               **kwargs) -> xr.Dataset:
     """
-    Read a data cube from *input_path*.
+    Read a xcube dataset from *input_path*.
     If *format* is not provided it will be guessed from *input_path*.
 
     :param input_path: input path
     :param format_name: format, e.g. "zarr" or "netcdf4"
     :param kwargs: format-specific keyword arguments
-    :return: data cube
+    :return: xcube dataset
     """
     return read_dataset(input_path, format_name=format_name, is_cube=True, **kwargs)
 
@@ -46,15 +46,15 @@ def write_cube(cube: xr.Dataset,
                cube_asserted: bool = False,
                **kwargs) -> xr.Dataset:
     """
-    Write a data cube to *output_path*.
+    Write a xcube dataset to *output_path*.
     If *format* is not provided it will be guessed from *output_path*.
 
-    :param cube: Data cube to be written.
+    :param cube: xcube dataset to be written.
     :param output_path: output path
     :param format_name: format, e.g. "zarr" or "netcdf4"
     :param kwargs: format-specific keyword arguments
     :param cube_asserted: If False, *cube* will be verified, otherwise it is expected to be a valid cube.
-    :return: data cube *cube*
+    :return: xcube dataset *cube*
     """
     if not cube_asserted:
         assert_cube(cube)
@@ -71,7 +71,7 @@ def open_dataset(input_path: str,
 
     :param input_path: input path
     :param format_name: format, e.g. "zarr" or "netcdf4"
-    :param is_cube: Whether a ValueError will be raised, if the dataset read from *input_path* is not a data cube.
+    :param is_cube: Whether a ValueError will be raised, if the dataset read from *input_path* is not a xcube dataset.
     :param kwargs: format-specific keyword arguments
     :return: dataset object
     """
@@ -92,7 +92,7 @@ def read_dataset(input_path: str,
 
     :param input_path: input path
     :param format_name: format, e.g. "zarr" or "netcdf4"
-    :param is_cube: Whether a ValueError will be raised, if the dataset read from *input_path* is not a data cube.
+    :param is_cube: Whether a ValueError will be raised, if the dataset read from *input_path* is not a xcube dataset.
     :param kwargs: format-specific keyword arguments
     :return: dataset object
     """
diff --git a/xcube/api/resample.py b/xcube/api/resample.py
index 7ac30203..ab52917f 100644
--- a/xcube/api/resample.py
+++ b/xcube/api/resample.py
@@ -36,9 +36,9 @@ def resample_in_time(cube: xr.Dataset,
                      var_names: Sequence[str] = None,
                      metadata: Dict[str, Any] = None):
     """
-    Resample a data cube in the time dimension.
+    Resample a xcube dataset in the time dimension.
 
-    :param cube: The data cube.
+    :param cube: The xcube dataset.
     :param frequency: Resampling frequency.
     :param method: Resampling method or sequence of resampling methods.
     :param offset: Offset used to adjust the resampled time labels. Some pandas date offset strings are supported.
@@ -47,7 +47,7 @@ def resample_in_time(cube: xr.Dataset,
     :param tolerance: Time tolerance for selective upsampling methods. Defaults to *frequency*.
     :param interp_kind: Kind of interpolation if *method* is 'interpolation'.
     :param metadata: Output metadata.
-    :return: A new data cube resampled in time.
+    :return: A new xcube dataset resampled in time.
     """
     if var_names:
         cube = select_vars(cube, var_names)
diff --git a/xcube/api/ts.py b/xcube/api/ts.py
index 0f204f3f..cd2d3ca1 100644
--- a/xcube/api/ts.py
+++ b/xcube/api/ts.py
@@ -59,7 +59,7 @@ def get_time_series(cube: xr.Dataset,
     If the given *geometry* does not overlap the cube's boundaries, or if not output variables remain,
     the function returns ``None``.
 
-    :param cube: The data cube
+    :param cube: The xcube dataset
     :param geometry: Optional geometry
     :param var_names: Optional sequence of names of variables to be included.
     :param start_date: Optional start date.
diff --git a/xcube/api/vars_to_dim.py b/xcube/api/vars_to_dim.py
index 104c5ad5..60a9660b 100644
--- a/xcube/api/vars_to_dim.py
+++ b/xcube/api/vars_to_dim.py
@@ -31,11 +31,11 @@ def vars_to_dim(cube: xr.Dataset,
     """
     Convert data variables into a dimension.
 
-    :param cube: The data cube.
+    :param cube: The xcube dataset.
     :param dim_name: The name of the new dimension and coordinate variable. Defaults to 'var'.
     :param var_name: The name of the new, single data variable. Defaults to 'data'.
     :param cube_asserted: If False, *cube* will be verified, otherwise it is expected to be a valid cube.
-    :return: A new data cube with data variables turned into a new dimension.
+    :return: A new xcube dataset with data variables turned into a new dimension.
     """
 
     if not cube_asserted:
diff --git a/xcube/api/verify.py b/xcube/api/verify.py
index 9d02c4f7..0a6e6312 100644
--- a/xcube/api/verify.py
+++ b/xcube/api/verify.py
@@ -27,16 +27,16 @@ import xarray as xr
 
 def assert_cube(dataset: xr.Dataset, name=None) -> xr.Dataset:
     """
-    Assert that the given *dataset* is a valid data cube.
+    Assert that the given *dataset* is a valid xcube dataset.
 
     :param dataset: The dataset to be validated.
     :param name: Optional parameter name.
-    :raise: ValueError, if dataset is not a valid data cube
+    :raise: ValueError, if dataset is not a valid xcube dataset
     """
     report = verify_cube(dataset)
     if report:
         message = f"Dataset" + (name + " " if name else " ")
-        message += "is not a valid data cube, because:\n"
+        message += "is not a valid xcube dataset, because:\n"
         message += "- " + ";\n- ".join(report) + "."
         raise ValueError(message)
 
@@ -45,7 +45,7 @@ def assert_cube(dataset: xr.Dataset, name=None) -> xr.Dataset:
 
 def verify_cube(dataset: xr.Dataset) -> List[str]:
     """
-    Verify the given *dataset* for being a valid data cube.
+    Verify the given *dataset* for being a valid xcube dataset.
 
     The tool verifies that *dataset*
     * defines the dimensions "time", "lat", "lon";
@@ -56,7 +56,7 @@ def verify_cube(dataset: xr.Dataset) -> List[str]:
     * has any data variables and that they are valid, e.g. min. 3-D, all have
       same dimensions, have at least dimensions "time", "lat", "lon".
 
-    Returns a list of issues, which is empty if *dataset* is a valid data cube.
+    Returns a list of issues, which is empty if *dataset* is a valid xcube dataset.
 
     :param dataset: A dataset to be verified.
     :return: List of issues or empty list.
diff --git a/xcube/cli/apply.py b/xcube/cli/apply.py
index d48afea7..1526591e 100644
--- a/xcube/cli/apply.py
+++ b/xcube/cli/apply.py
@@ -20,36 +20,37 @@
 # SOFTWARE.
 
 import click
-
+from xcube.api.gen.defaults import DEFAULT_OUTPUT_PATH
 __author__ = "Norman Fomferra (Brockmann Consult GmbH)"
 
 
 # noinspection PyShadowingBuiltins
 @click.command(name='apply', hidden=True)
-@click.argument('output', metavar='<output>')
-@click.argument('script', metavar='<script>')
-@click.argument('input', metavar='<input>...', nargs=-1)
-@click.option('--params', metavar='<params>',
+@click.argument('script')
+@click.argument('cube', nargs=-1)
+@click.option('--output', '-o', metavar='OUTPUT', default=DEFAULT_OUTPUT_PATH,
+              help=f'Output path. Defaults to {DEFAULT_OUTPUT_PATH!r}')
+@click.option('--params', '-p', metavar='PARAMS',
               help="Keyword arguments passed to apply() and init() functions in <script>.")
-@click.option('--vars', metavar='<vars>',
+@click.option('--variables', '--vars', metavar='VARIABLES',
               help="Comma-separated list of variable names.")
-@click.option('--dask', metavar='<dask>',
+@click.option('--dask', metavar='DASK',
               default='forbidden',
               type=click.Choice(['forbidden', 'allowed', 'parallelized']),
               help="Mode of operation for the Dask library.")
-@click.option('--format', metavar='<format>',
+@click.option('--format', '-f', metavar='FORMAT',
               default='zarr',
               type=click.Choice(['zarr', 'nc']),
               help="Output format.")
-@click.option('--dtype', metavar='<dtype>',
+@click.option('--dtype', metavar='DTYPES',
               default='float64',
               type=click.Choice(["uint8", "int8", "uint16", "int16", "uint32", "int32", "float32", "float64"]),
               help="Output data type.")
-def apply(output: str,
-          script: str,
-          input: str,
+def apply(script: str,
+          cube: str,
+          output: str,
           params: str,
-          vars: str,
+          variables: str,
           dask: str,
           format: str,
           dtype: str):
@@ -58,23 +59,23 @@ def apply(output: str,
     The function is used to transform N chunks of equal shape to a new chunk of same shape.
     N is the number of variables from all data cubes.
 
-    Uses the Python program <script> to transform data cubes
-    given by <inputs> into a new data cube given by <output>.
+    Uses the Python program SCRIPT to transform data cubes
+    given by CUBEs into a new xcube dataset given by OUTPUT.
 
     The <script> must define a function ``apply(*variables, **params)`` where variables
-    are numpy arrays (chunks) in the order given by <vars> or given by the variables returned by
-    an optional ``init()`` function that my be defined in <script>.
-    If neither <vars> nor an ``init()`` function is defined, all variables are passed in arbitrary order.
+    are numpy arrays (chunks) in the order given by VARIABLES or given by the variables returned by
+    an optional ``init()`` function that my be defined in SCRIPT.
+    If neither VARIABLES nor an ``init()`` function is defined, all variables are passed in arbitrary order.
 
     The optional ``init(*cubes, **params)`` function can be used to validate the data cubes,
     extract the desired variables in desired order and to provide some extra processing parameters passed to
     the ``apply()`` function. The ``init()`` argument *cubes* are the ``xarray.Dataset`` objects
-    according to <input> and *params* are according to <params>. The return value of ``init()`` is
+    according to CUBEs and *params* are according to PARAMS. The return value of ``init()`` is
     a tuple (*variables*, *new_params*) where *variables* is a list of ``xarray.DataArray`` objects and
     *new_params* are newly computed parameters passed to ``apply()``.
     """
 
-    input_paths = input
+    input_paths = cube
     output_path = output
     apply_function_name = "apply"
     init_function_name = "init"
@@ -85,7 +86,7 @@ def apply(output: str,
     locals_dict = dict()
     exec(code, globals(), locals_dict)
 
-    var_names = list(map(lambda s: s.strip(), vars.split(","))) if vars else None
+    var_names = list(map(lambda s: s.strip(), variables.split(","))) if variables else None
 
     init_function = locals_dict.get(init_function_name)
     if init_function is not None and not callable(init_function):
@@ -101,7 +102,7 @@ def apply(output: str,
     from xcube.util.cliutil import parse_cli_kwargs
     from xcube.util.dsio import guess_dataset_format, find_dataset_io
 
-    kwargs = parse_cli_kwargs(params, "<params>")
+    kwargs = parse_cli_kwargs(params, "PARAMS")
     input_cube_0 = None
     input_cubes = []
     for input_path in input_paths:
diff --git a/xcube/cli/cli.py b/xcube/cli/cli.py
index 2b99f02b..57710f6c 100644
--- a/xcube/cli/cli.py
+++ b/xcube/cli/cli.py
@@ -2,6 +2,7 @@ import sys
 
 import click
 
+from xcube.api.gen.defaults import DEFAULT_OUTPUT_PATH
 from xcube.cli.apply import apply
 from xcube.cli.extract import extract
 from xcube.cli.gen import gen
@@ -12,52 +13,53 @@ from xcube.cli.resample import resample
 from xcube.cli.serve import serve
 from xcube.cli.timeit import timeit
 from xcube.cli.verify import verify
-from xcube.util.cliutil import parse_cli_kwargs, new_cli_ctx_obj, handle_cli_exception, cli_option_traceback, \
-    cli_option_scheduler
+from xcube.util.cliutil import cli_option_scheduler, cli_option_traceback, handle_cli_exception, new_cli_ctx_obj, \
+    parse_cli_kwargs
 from xcube.version import version
 
 
 # noinspection PyShadowingBuiltins
 @click.command(name="chunk")
-@click.argument('input', metavar='<input>')
-@click.argument('output', metavar='<output>')
-@click.option('--format', '-f', metavar='<format>', type=click.Choice(['zarr', 'netcdf']),
-              help="Format of the output. If not given, guessed from <output>.")
-@click.option('--params', '-p', metavar='<params>',
+@click.argument('cube')
+@click.option('--output', '-o', metavar='OUTPUT', default=DEFAULT_OUTPUT_PATH,
+              help=f'Output path. Defaults to {DEFAULT_OUTPUT_PATH!r}')
+@click.option('--format', '-f', metavar='FORMAT', type=click.Choice(['zarr', 'netcdf']),
+              help="Format of the output. If not given, guessed from OUTPUT.")
+@click.option('--params', '-p', metavar='PARAMS',
               help="Parameters specific for the output format."
                    " Comma-separated list of <key>=<value> pairs.")
-@click.option('--chunks', '-c', metavar='<chunks>', nargs=1, default=None,
+@click.option('--chunks','-C', metavar='CHUNKS', nargs=1, default=None,
               help='Chunk sizes for each dimension.'
                    ' Comma-separated list of <dim>=<size> pairs,'
                    ' e.g. "time=1,lat=270,lon=270"')
-def chunk(input, output, format=None, params=None, chunks=None):
+def chunk(cube, output, format=None, params=None, chunks=None):
     """
-    (Re-)chunk dataset.
-    Changes the external chunking of all variables of <input> according to <chunks> and writes
-    the result to <output>.
+    (Re-)chunk xcube dataset.
+    Changes the external chunking of all variables of CUBE according to CHUNKS and writes
+    the result to OUTPUT.
     """
     chunk_sizes = None
     if chunks:
-        chunk_sizes = parse_cli_kwargs(chunks, metavar="<chunks>")
+        chunk_sizes = parse_cli_kwargs(chunks, metavar="CHUNKS")
         for k, v in chunk_sizes.items():
             if not isinstance(v, int) or v <= 0:
-                raise click.ClickException("Invalid value for <chunks>, "
+                raise click.ClickException("Invalid value for CHUNKS, "
                                            f"chunk sizes must be positive integers: {chunks}")
 
     write_kwargs = dict()
     if params:
-        write_kwargs = parse_cli_kwargs(params, metavar="<params>")
+        write_kwargs = parse_cli_kwargs(params, metavar="PARAMS")
 
     from xcube.util.dsio import guess_dataset_format
     format_name = format if format else guess_dataset_format(output)
 
     from xcube.api import open_dataset, chunk_dataset, write_dataset
 
-    with open_dataset(input_path=input) as ds:
+    with open_dataset(input_path=cube) as ds:
         if chunk_sizes:
             for k in chunk_sizes:
                 if k not in ds.dims:
-                    raise click.ClickException("Invalid value for <chunks>, "
+                    raise click.ClickException("Invalid value for CHUNKS, "
                                                f"{k!r} is not the name of any dimension: {chunks}")
 
         chunked_dataset = chunk_dataset(ds, chunk_sizes=chunk_sizes, format_name=format_name)
@@ -69,27 +71,27 @@ DEFAULT_TILE_SIZE = 512
 
 # noinspection PyShadowingBuiltins
 @click.command(name="level")
-@click.argument('input', metavar='<input>')
-@click.option('--output', '-o', metavar='<output>',
-              help='Output directory. If omitted, "<input>.levels" will be used.')
-@click.option('--link', '-l', is_flag=True, flag_value=True,
-              help='Link the <input> instead of converting it to a level zero dataset. '
-                   'Use with care, as the <input>\'s internal spatial chunk sizes may be inappropriate '
+@click.argument('input')
+@click.option('--output', '-o', metavar='OUTPUT',
+              help='Output path. If omitted, "INPUT.levels" will be used.')
+@click.option('--link', '-L', is_flag=True, flag_value=True,
+              help='Link the INPUT instead of converting it to a level zero dataset. '
+                   'Use with care, as the INPUT\'s internal spatial chunk sizes may be inappropriate '
                    'for imaging purposes.')
-@click.option('--tile-size', '-t', metavar='<tile-size>',
+@click.option('--tile-size', '-t', metavar='TILE-SIZE',
               help=f'Tile size, given as single integer number or as <tile-width>,<tile-height>. '
-                   f'If omitted, the tile size will be derived from the <input>\'s '
+                   f'If omitted, the tile size will be derived from the INPUT\'s '
                    f'internal spatial chunk sizes. '
-                   f'If the <input> is not chunked, tile size will be {DEFAULT_TILE_SIZE}.')
-@click.option('--num-levels-max', '-n', metavar='<num-levels-max>', type=int,
+                   f'If the INPUT is not chunked, tile size will be {DEFAULT_TILE_SIZE}.')
+@click.option('--num-levels-max', '-n', metavar='NUM-LEVELS-MAX', type=int,
               help=f'Maximum number of levels to generate. '
                    f'If not given, the number of levels will be derived from '
                    f'spatial dimension and tile sizes.')
 def level(input, output, link, tile_size, num_levels_max):
     """
     Generate multi-resolution levels.
-    Transform the given dataset by <input> into the levels of a multi-level pyramid with spatial resolution
-    decreasing by a factor of two in both spatial dimensions and write the result to directory <output>.
+    Transform the given dataset by INPUT into the levels of a multi-level pyramid with spatial resolution
+    decreasing by a factor of two in both spatial dimensions and write the result to directory OUTPUT.
     """
     import time
     import os
@@ -100,7 +102,7 @@ def level(input, output, link, tile_size, num_levels_max):
     link_input = link
 
     if num_levels_max is not None and num_levels_max < 1:
-        raise click.ClickException(f"<num-levels-max> must be a positive integer")
+        raise click.ClickException(f"NUM-LEVELS-MAX must be a positive integer")
 
     if not output_path:
         basename, ext = os.path.splitext(input_path)
@@ -119,7 +121,7 @@ def level(input, output, link, tile_size, num_levels_max):
             if tile_size != 2:
                 raise click.ClickException("Expected a pair of positive integers <tile-width>,<tile-height>")
         if tile_size[0] < 1 or tile_size[1] < 1:
-            raise click.ClickException("<tile-size> must comprise positive integers")
+            raise click.ClickException("TILE-SIZE must comprise positive integers")
         spatial_tile_shape = tile_size[1], tile_size[0]
 
     start_time = t0 = time.perf_counter()
@@ -140,39 +142,39 @@ def level(input, output, link, tile_size, num_levels_max):
 
 
 @click.command(name="dump")
-@click.argument('dataset', metavar='<path>')
-@click.option('--variable', '-v', metavar='<variable>', multiple=True,
+@click.argument('input')
+@click.option('--variable', '--var', metavar='VARIABLE', multiple=True,
               help="Name of a variable (multiple allowed).")
-@click.option('--encoding', '-e', is_flag=True, flag_value=True,
+@click.option('--encoding', '-E', is_flag=True, flag_value=True,
               help="Dump also variable encoding information.")
-def dump(dataset, variable, encoding):
+def dump(input, variable, encoding):
     """
-    Dump contents of a dataset.
+    Dump contents of an input dataset.
     """
     from xcube.api import open_dataset, dump_dataset
-    with open_dataset(dataset) as ds:
+    with open_dataset(input) as ds:
         text = dump_dataset(ds, var_names=variable, show_var_encoding=encoding)
         print(text)
 
 
 # noinspection PyShadowingBuiltins,PyUnusedLocal
 @click.command(name="vars2dim")
-@click.argument('cube', metavar='<cube>')
-@click.option('--var_name', '-v', metavar='<var-name>',
+@click.argument('cube')
+@click.option('--variable', '--var', metavar='VARIABLE',
               default='data',
               help='Name of the new variable that includes all variables. Defaults to "data".')
-@click.option('--dim_name', '-d', metavar='<dim-name>',
+@click.option('--dim_name', '-D', metavar='DIM-NAME',
               default='var',
               help='Name of the new dimension into variables. Defaults to "var".')
-@click.option('--output', '-o', metavar='<output>',
-              help="Output file.")
-@click.option('--format', '-f', metavar='<format>', type=click.Choice(['zarr', 'netcdf']),
-              help="Format of the output. If not given, guessed from <output>.")
-def vars2dim(cube, var_name, dim_name, output=None, format=None):
+@click.option('--output', '-o', metavar='OUTPUT',
+              help="Output path. If omitted, 'INPUT-vars2dim.INPUT-FORMAT' will be used.")
+@click.option('--format', '-f', metavar='FORMAT', type=click.Choice(['zarr', 'netcdf']),
+              help="Format of the output. If not given, guessed from OUTPUT.")
+def vars2dim(cube, variable, dim_name, output=None, format=None):
     """
     Convert cube variables into new dimension.
-    Moves all variables of <cube> into into a single new variable <var-name>
-    with a new dimension <dim-name> and writes the results to <output>.
+    Moves all variables of CUBE into into a single new variable <var-name>
+    with a new dimension DIM-NAME and writes the results to OUTPUT.
     """
 
     from xcube.util.dsio import guess_dataset_format
@@ -188,7 +190,7 @@ def vars2dim(cube, var_name, dim_name, output=None, format=None):
     format_name = format if format else guess_dataset_format(output)
 
     with open_dataset(input_path=cube) as ds:
-        converted_dataset = vars_to_dim(ds, dim_name=dim_name, var_name=var_name)
+        converted_dataset = vars_to_dim(ds, dim_name=dim_name, var_name=variable)
         write_dataset(converted_dataset, output_path=output, format_name=format_name)
 
 
diff --git a/xcube/cli/extract.py b/xcube/cli/extract.py
index 80df88b0..dc631c97 100644
--- a/xcube/cli/extract.py
+++ b/xcube/cli/extract.py
@@ -7,9 +7,9 @@ import click
 @click.command(name="extract")
 @click.argument('cube')
 @click.argument('points')
-@click.option('--output', '-o',
-              help="Output file. If omitted, output is written to stdout.")
-@click.option('--format', '-f', type=click.Choice(['csv', 'json', 'xlsx']),
+@click.option('--output', '-o', metavar='OUTPUT',
+              help="Output path. If omitted, output is written to stdout.")
+@click.option('--format', '-f', metavar='FORMAT', type=click.Choice(['csv', 'json', 'xlsx']),
               help="Output format. Currently, only 'csv' is supported.", default='csv')
 @click.option('--coords', '-C', is_flag=True,
               help="Include cube cell coordinates in output.")
@@ -34,7 +34,7 @@ def extract(cube,
     Extracts data cells from CUBE at coordinates given in each POINTS record and writes the resulting values to given
     output path and format.
 
-    <points> must be a CSV file that provides at least the columns "lon", "lat", and "time". The "lon" and "lat"
+    POINTS must be a CSV file that provides at least the columns "lon", "lat", and "time". The "lon" and "lat"
     columns provide a point's location in decimal degrees. The "time" column provides a point's date or
     date-time. Its format should preferably be ISO, but other formats may work as well.
     """
diff --git a/xcube/cli/gen.py b/xcube/cli/gen.py
index 299ebbbf..cdaee5a6 100644
--- a/xcube/cli/gen.py
+++ b/xcube/cli/gen.py
@@ -29,27 +29,27 @@ resampling_methods = sorted(RESAMPLING_METHOD_NAMES)
 
 # noinspection PyShadowingBuiltins
 @click.command(name='gen', context_settings={"ignore_unknown_options": True})
-@click.argument('inputs', nargs=-1)
-@click.option('--proc', '-p', default='default',
+@click.argument('input', nargs=-1)
+@click.option('--proc', '-P', metavar='INPUT-PROCESSOR', default='default',
               help=f'Input processor name. '
                    f'The available input processor names and additional information about input processors '
                    'can be accessed by calling xcube gen --info . Defaults to "default", an input processor '
                    'that can deal with simple datasets whose variables have dimensions ("lat", "lon") and '
                    'conform with the CF conventions.')
-@click.option('--config', '-c', multiple=True,
-              help='Data cube configuration file in YAML format. More than one config input file is allowed.'
+@click.option('--config', '-c', metavar='CONFIG', multiple=True,
+              help='xcube dataset configuration file in YAML format. More than one config input file is allowed.'
                    'When passing several config files, they are merged considering the order passed via command line.')
-@click.option('--output', '-o', default=DEFAULT_OUTPUT_PATH,
+@click.option('--output', '-o', metavar='OUTPUT', default=DEFAULT_OUTPUT_PATH,
               help=f'Output path. Defaults to {DEFAULT_OUTPUT_PATH!r}')
-@click.option('--format', '-f',
+@click.option('--format', '-f', metavar='FORMAT',
               help=f'Output format. '
                    'Information about output formats can be accessed by calling '
                    'xcube gen --info. If omitted, the format will be guessed from the given output path.')
-@click.option('--size', '-s',
+@click.option('--size', '-S', metavar='SIZE',
               help='Output size in pixels using format "<width>,<height>".')
-@click.option('--region', '-r',
+@click.option('--region', '-R', metavar='REGION',
               help='Output region using format "<lon-min>,<lat-min>,<lon-max>,<lat-max>"')
-@click.option('--variables', '--vars', '-v',
+@click.option('--variables', '--vars', metavar='VARIABLES',
               help='Variables to be included in output. '
                    'Comma-separated list of names which may contain wildcard characters "*" and "?".')
 @click.option('--resampling', type=click.Choice(resampling_methods),
@@ -62,13 +62,13 @@ resampling_methods = sorted(RESAMPLING_METHOD_NAMES)
 @click.option('--prof', is_flag=True,
               help='Collect profiling information and dump results after processing.')
 @click.option('--sort', is_flag=True,
-              help='The input file list will be sorted before creating the data cube. '
+              help='The input file list will be sorted before creating the xcube dataset. '
                    'If --sort parameter is not passed, order of input list will be kept.')
-@click.option('--info', '-i', is_flag=True,
+@click.option('--info', '-I', is_flag=True,
               help='Displays additional information about format options or about input processors.')
 @click.option('--dry_run', is_flag=True,
               help='Just read and process inputs, but don\'t produce any outputs.')
-def gen(inputs: str,
+def gen(input: str,
         proc: str,
         config: tuple,
         output: str,
@@ -83,13 +83,13 @@ def gen(inputs: str,
         info: bool,
         sort: bool):
     """
-    Generate data cube.
+    Generate xcube dataset.
     Data cubes may be created in one go or successively in append mode, input by input.
     The input paths may be one or more input files or a pattern that may contain wildcards '?', '*', and '**'.
     The input paths can also be passed as lines of a text file. To do so, provide exactly one input file with
     ".txt" extension which contains the actual input paths to be used.
     """
-    input_paths = inputs
+    input_paths = input
     input_processor_name = proc
     config_file = config
     output_path = output
diff --git a/xcube/cli/grid.py b/xcube/cli/grid.py
index 26ef6594..37fbdaf5 100644
--- a/xcube/cli/grid.py
+++ b/xcube/cli/grid.py
@@ -166,21 +166,21 @@ def factor_out_two(x: int) -> Tuple[int, int]:
 
 
 @click.command(name="res")
-@click.argument('target_res', metavar="TARGET_RES")
-@click.option('--delta_res', '-d', metavar='DELTA_RES', default=_DEFAULT_RES_DELTA,
+@click.argument('target_res', metavar='TARGET_RES')
+@click.option('--delta_res', '-D', metavar='DELTA_RES', default=_DEFAULT_RES_DELTA,
               help=f'Maximum resolution delta. Defaults to {_DEFAULT_RES_DELTA}.')
-@click.option('--coverage', '-c', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
+@click.option('--coverage', '--cov', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
               help=f'The vertical coverage in degrees. Defaults to {_DEFAULT_LAT_COVERAGE} degrees.')
-@click.option('--tile_max', '-t', metavar='TILE_MAX', default=_DEFAULT_MAX_TILE, type=int,
+@click.option('--tile_max', metavar='TILE_MAX', default=_DEFAULT_MAX_TILE, type=int,
               help=f'Maximum tile size. Defaults to {_DEFAULT_MAX_TILE}.')
 @click.option('--level_min', '-l', metavar='LEVEL_MIN', default=_DEFAULT_MIN_LEVEL, type=int,
               help=f'Minimum resolution level. Defaults to {_DEFAULT_MIN_LEVEL}.')
-@click.option('--int_inv_res', '-i', metavar='INT_INV_RES', is_flag=True,
+@click.option('--int_inv_res', metavar='INT_INV_RES', is_flag=True,
               help=f'Find only resolutions whose inverse are integers.')
-@click.option('--sort_by', '-s', metavar='SORT_BY',
+@click.option('--sort_by', metavar='SORT_BY',
               type=click.Choice(_SORT_BY_KEYS), default=_DEFAULT_SORT_BY,
               help='Sort output by column name.')
-@click.option('--num_results', '-n', metavar='NUM_RESULTS',
+@click.option('--num_results', '-N', metavar='NUM_RESULTS',
               type=int, default=_DEFAULT_NUM_RESULTS,
               help=f'Maximum number of results to list. Defaults to {_DEFAULT_NUM_RESULTS}')
 @click.option('--sep', metavar='SEP', default='\t',
@@ -241,11 +241,11 @@ def list_resolutions(target_res: str,
 
 
 @click.command(name="levels")
-@click.option('--res', '-r', metavar="RES",
+@click.option('--res', '-R', metavar="RES",
               help='Resolution in degrees. Can also be a rational number of form RES_NOM/RES_DEN.')
 @click.option('--height', '-h', metavar="HEIGHT", type=int,
               help='Height in grid cells.')
-@click.option('--coverage', '-c', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
+@click.option('--coverage', '--cov', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
               help=f'The vertical coverage in degrees. Defaults to {_DEFAULT_LAT_COVERAGE} degrees.')
 @click.option('--level_min', '-l', metavar="LEVEL_MIN", type=int,
               help="List at least up to this level.")
@@ -271,13 +271,13 @@ def list_levels(res: str, height: int, coverage: str, level_min: Optional[int],
 
 @click.command(name="abox", context_settings={"ignore_unknown_options": True})
 @click.argument('geom', metavar="GEOM")
-@click.option('--res', '-r', metavar="RES",
+@click.option('--res', '-R', metavar="RES",
               help='The parent grid\'s resolution in degrees. Can also be a rational number of form A/B.')
 @click.option('--height', '-h', metavar="HEIGHT", type=int,
               help='The parent grid\'s height in grid cells.')
-@click.option('--coverage', '-c', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
+@click.option('--coverage', '--cov', metavar="COVERAGE", default=str(_DEFAULT_LAT_COVERAGE),
               help=f'The parent grid\'s coverage in degrees. Defaults to {_DEFAULT_LAT_COVERAGE} degrees.')
-@click.option('--tile_factor', '-t', metavar="TILE_FACTOR", type=int,
+@click.option('--tile_factor', metavar="TILE_FACTOR", type=int,
               help='A tile factor to compute tile sizes from height at level zero: TILE = TILE_FACTOR * HEIGHT_0.'
                    'Usually TILE_FACTOR = 2^N. If not given, TILE = 1.')
 def adjust_box(geom: str, res: Optional[str], height: Optional[int], coverage: str, tile_factor: Optional[int]):
@@ -377,7 +377,7 @@ def _fetch_coverage_from_option(coverage_str: str) -> fractions.Fraction:
 @click.group()
 def grid():
     """
-    Find spatial data cube resolutions and adjust bounding boxes.
+    Find spatial xcube dataset resolutions and adjust bounding boxes.
 
     We find suitable resolutions with respect to a possibly regional fixed Earth grid and adjust regional spatial
     bounding boxes to that grid. We also try to select the resolutions such
diff --git a/xcube/cli/optimize.py b/xcube/cli/optimize.py
index e49ba2cc..3c56c9b2 100644
--- a/xcube/cli/optimize.py
+++ b/xcube/cli/optimize.py
@@ -26,8 +26,8 @@ DEFAULT_OUTPUT_PATH = '{input}-optimized.zarr'
 
 # noinspection PyShadowingBuiltins
 @click.command(name='optimize')
-@click.argument('input')
-@click.option('--output', '-o', 'output_path',
+@click.argument('CUBE')
+@click.option('--output', '-o', metavar='OUTPUT',
               help=f'Output path. The placeholder "{input}" will be replaced by the input\'s filename '
                    f'without extension (such as ".zarr"). Defaults to "{DEFAULT_OUTPUT_PATH}".',
               default=DEFAULT_OUTPUT_PATH)
@@ -38,14 +38,14 @@ DEFAULT_OUTPUT_PATH = '{input}-optimized.zarr'
               help="Also optimize coordinate variables by converting any chunked arrays "
                    "into single, non-chunked, contiguous arrays.",
               is_flag=True)
-def optimize(input,
-             output_path,
+def optimize(cube,
+             output,
              in_place,
              unchunk_coords):
     """
-    Optimize data cube for faster access.
+    Optimize xcube dataset for faster access.
 
-    Reduces the number of metadata and coordinate data files in data cube given by INPUT.
+    Reduces the number of metadata and coordinate data files in xcube dataset given by CUBE.
     Consolidated cubes open much faster especially from remote locations, e.g. in object storage,
     because obviously much less HTTP requests are required to fetch initial cube meta
     information. That is, it merges all metadata files into a single top-level JSON file ".zmetadata".
@@ -55,7 +55,7 @@ def optimize(input,
     The command currently works only for data cubes using ZARR format.
     """
     from xcube.api import optimize_dataset
-    optimize_dataset(input,
-                     output_path=output_path,
+    optimize_dataset(cube,
+                     output_path=output,
                      in_place=in_place,
                      unchunk_coords=unchunk_coords)
diff --git a/xcube/cli/prune.py b/xcube/cli/prune.py
index b0469c6e..ee418035 100644
--- a/xcube/cli/prune.py
+++ b/xcube/cli/prune.py
@@ -29,16 +29,16 @@ from xcube.util.constants import FORMAT_NAME_ZARR
 
 # noinspection PyShadowingBuiltins
 @click.command(name='prune')
-@click.argument('input')
+@click.argument('cube')
 @click.option('--dry-run', is_flag=True,
               help='Just read and process input, but don\'t produce any outputs.')
-def prune(input, dry_run):
+def prune(cube, dry_run):
     """
     Delete empty chunks.
-    Deletes all data files associated with empty (NaN-only) chunks in given INPUT cube,
+    Deletes all data files associated with empty (NaN-only) chunks in given CUBE,
     which must have ZARR format.
     """
-    _prune(input_path=input, dry_run=dry_run, monitor=print)
+    _prune(input_path=cube, dry_run=dry_run, monitor=print)
     return 0
 
 
diff --git a/xcube/cli/resample.py b/xcube/cli/resample.py
index 37785eda..65e176ae 100644
--- a/xcube/cli/resample.py
+++ b/xcube/cli/resample.py
@@ -43,17 +43,17 @@ DEFAULT_INTERPOLATION_KIND = 'linear'
 
 # noinspection PyShadowingBuiltins
 @click.command(name='resample')
-@click.argument('input')
-@click.option('--config', '-c', multiple=True,
-              help='Data cube configuration file in YAML format. More than one config input file is allowed.'
+@click.argument('cube')
+@click.option('--config', '-c', metavar='CONFIG', multiple=True,
+              help='xcube dataset configuration file in YAML format. More than one config input file is allowed.'
                    'When passing several config files, they are merged considering the order passed via command line.')
-@click.option('--output', '-o',
+@click.option('--output', '-o', metavar='OUTPUT',
               default=DEFAULT_OUTPUT_PATH,
-              help="Output path.")
+              help=f"Output path. Defaults to {DEFAULT_OUTPUT_PATH!r}.")
 @click.option('--format', '-f',
               type=click.Choice(OUTPUT_FORMAT_NAMES),
               help="Output format. If omitted, format will be guessed from output path.")
-@click.option('--variables', '--vars',
+@click.option('--variables', '--vars', metavar='VARIABLES',
               help="Comma-separated list of names of variables to be included.")
 @click.option('--method', '-M', multiple=True,
               help=f"Temporal resampling method. "
@@ -93,7 +93,7 @@ DEFAULT_INTERPOLATION_KIND = 'linear'
                    'Defaults to the given frequency.')
 @click.option('--dry-run', default=False, is_flag=True,
               help='Just read and process inputs, but don\'t produce any outputs.')
-def resample(input,
+def resample(cube,
              config,
              output,
              format,
@@ -109,7 +109,7 @@ def resample(input,
     Resample data along the time dimension.
     """
 
-    input_path = input
+    input_path = cube
     config_files = config
     output_path = output
     output_format = format
diff --git a/xcube/cli/serve.py b/xcube/cli/serve.py
index f798cb48..9df97260 100644
--- a/xcube/cli/serve.py
+++ b/xcube/cli/serve.py
@@ -31,15 +31,15 @@ VIEWER_ENV_VAR = 'XCUBE_VIEWER_PATH'
 
 
 @click.command(name='serve')
-@click.argument('cubes', metavar='CUBE...', nargs=-1)
-@click.option('--address', '-a', metavar='ADDRESS', default=DEFAULT_ADDRESS,
+@click.argument('cube', nargs=-1)
+@click.option('--address', '-A', metavar='ADDRESS', default=DEFAULT_ADDRESS,
               help=f'Service address. Defaults to {DEFAULT_ADDRESS!r}.')
-@click.option('--port', '-p', metavar='PORT', default=DEFAULT_PORT, type=int,
+@click.option('--port', '-P', metavar='PORT', default=DEFAULT_PORT, type=int,
               help=f'Port number where the service will listen on. Defaults to {DEFAULT_PORT}.')
 @click.option('--prefix', metavar='PREFIX',
               help='Service URL prefix. May contain template patterns such as "${version}" or "${name}". '
                    'For example "${name}/api/${version}".')
-@click.option('--name', '-n', metavar='NAME', hidden=True,
+@click.option('--name', metavar='NAME', hidden=True,
               help='Service name. Deprecated, use prefix option instead.')
 @click.option('--update', '-u', metavar='PERIOD', type=float,
               default=DEFAULT_UPDATE_PERIOD,
@@ -63,7 +63,7 @@ VIEWER_ENV_VAR = 'XCUBE_VIEWER_PATH'
               help='Tile computation mode. '
                    'This is an internal option used to switch between different tile computation implementations. '
               f'Defaults to {DEFAULT_TILE_COMP_MODE!r}.')
-@click.option('--show', '-s', is_flag=True,
+@click.option('--show','-s',  is_flag=True,
               help=f"Run viewer app. Requires setting the environment variable {VIEWER_ENV_VAR} "
               f"to a valid xcube-viewer deployment or build directory. "
               f"Refer to https://github.com/dcs4cop/xcube-viewer for more information.")
@@ -71,7 +71,7 @@ VIEWER_ENV_VAR = 'XCUBE_VIEWER_PATH'
               help="Delegate logging to the console (stderr).")
 @click.option('--traceperf', is_flag=True,
               help="Print performance diagnostics (stdout).")
-def serve(cubes: List[str],
+def serve(cube: List[str],
           address: str,
           port: int,
           prefix: str,
@@ -95,7 +95,7 @@ def serve(cubes: List[str],
 
     prefix = prefix or name
 
-    if config and cubes:
+    if config and cube:
         raise click.ClickException("CONFIG and CUBES cannot be used at the same time.")
     if styles:
         styles = parse_cli_kwargs(styles, "STYLES")
@@ -113,7 +113,7 @@ def serve(cubes: List[str],
                       prefix=prefix,
                       port=port,
                       address=address,
-                      cube_paths=cubes,
+                      cube_paths=cube,
                       styles=styles,
                       config_file=config,
                       tile_cache_size=tilecache,
@@ -135,13 +135,13 @@ def _run_viewer():
     viewer_dir = os.environ.get(VIEWER_ENV_VAR)
 
     if viewer_dir is None:
-        raise click.UsageError('Option "--show" / "-s": '
+        raise click.UsageError('Option "--show": '
                                f"In order to run the viewer, "
                                f"set environment variable {VIEWER_ENV_VAR} "
                                f"to a valid xcube-viewer deployment or build directory.")
 
     if not os.path.isdir(viewer_dir):
-        raise click.UsageError('Option "--show" / "-s": '
+        raise click.UsageError('Option "--show": '
                                f"Viewer path set by environment variable {VIEWER_ENV_VAR} "
                                f"must be a directory: " + viewer_dir)
 
diff --git a/xcube/cli/timeit.py b/xcube/cli/timeit.py
index 27de12a0..e4787a54 100644
--- a/xcube/cli/timeit.py
+++ b/xcube/cli/timeit.py
@@ -25,14 +25,14 @@ __author__ = "Norman Fomferra (Brockmann Consult GmbH)"
 
 
 @click.command(name='timeit', hidden=True)
-@click.argument('config', metavar='<config>')
-@click.option('--repeats', metavar='<repeats>', type=int, default=1,
+@click.argument('config')
+@click.option('--repeats', '-R', metavar='REPEATS', type=int, default=1,
               help="Number of repetitions")
 def timeit(config: str, repeats: int):
     """
     Time an executable.
-    Record the processing time of the executable with varying parameters defined <config>.
-    Repeat the executions <repeats> times.
+    Record the processing time of the executable with varying parameters defined <CONFIG>.
+    Repeat the executions <REPEATS> times.
     """
 
     config_path = config
diff --git a/xcube/cli/verify.py b/xcube/cli/verify.py
index ad051fbd..48b6d964 100644
--- a/xcube/cli/verify.py
+++ b/xcube/cli/verify.py
@@ -26,13 +26,13 @@ import click
 
 # noinspection PyShadowingBuiltins
 @click.command(name='verify')
-@click.argument('input')
-def verify(input):
+@click.argument('cube')
+def verify(cube):
     """
     Perform cube verification.
 
     \b
-    The tool verifies that INPUT
+    The tool verifies that CUBE
     * defines the dimensions "time", "lat", "lon";
     * has corresponding "time", "lat", "lon" coordinate variables and that they
       are valid, e.g. 1-D, non-empty, using correct units;
@@ -41,10 +41,10 @@ def verify(input):
     * has any data variables and that they are valid, e.g. min. 3-D, all have
       same dimensions, have at least dimensions "time", "lat", "lon".
 
-    If INPUT is a valid data cube, the tool returns exit code 0.
+    If INPUT is a valid xcube dataset, the tool returns exit code 0.
     Otherwise a violation report is written to stdout and the tool returns exit code 3.
     """
-    return _verify(input_path=input, monitor=print)
+    return _verify(input_path=cube, monitor=print)
 
 
 def _verify(input_path: str = None, monitor=None):
diff --git a/xcube/util/optimize.py b/xcube/util/optimize.py
index c2f6b618..359f8d6c 100644
--- a/xcube/util/optimize.py
+++ b/xcube/util/optimize.py
@@ -36,7 +36,7 @@ def optimize_dataset(input_path: str,
     """
     Optimize a dataset for faster access.
 
-    Reduces the number of metadata and coordinate data files in data cube given by given by *dataset_path*.
+    Reduces the number of metadata and coordinate data files in xcube dataset given by given by *dataset_path*.
     Consolidated cubes open much faster from remote locations, e.g. in object storage,
     because obviously much less HTTP requests are required to fetch initial cube meta
     information. That is, it merges all metadata files into a single top-level JSON file ".zmetadata".


Test patch:
diff --git a/test/api/test_verify.py b/test/api/test_verify.py
index f169c208..1986d1d8 100644
--- a/test/api/test_verify.py
+++ b/test/api/test_verify.py
@@ -25,7 +25,7 @@ class AssertAndVerifyCubeTest(unittest.TestCase):
                                                    dims=("y", "x")))
         with self.assertRaises(ValueError) as cm:
             assert_cube(cube)
-        self.assertEqual("Dataset is not a valid data cube, because:\n"
+        self.assertEqual("Dataset is not a valid xcube dataset, because:\n"
                          "- coordinate variable 'lat' must have a single dimension 'lat';\n"
                          "- coordinate variable 'lon' must have a single dimension 'lon'.",
                          f"{cm.exception}")
@@ -40,7 +40,7 @@ class AssertAndVerifyCubeTest(unittest.TestCase):
                                   lon_bnds=xr.DataArray(lon_bnds, dims=("time", "lon", "bnds")))
         with self.assertRaises(ValueError) as cm:
             assert_cube(cube)
-        self.assertEqual("Dataset is not a valid data cube, because:\n"
+        self.assertEqual("Dataset is not a valid xcube dataset, because:\n"
                          "- bounds coordinate variable 'lat_bnds' must have dimensions ('lat', <bounds_dim>);\n"
                          "- shape of bounds coordinate variable 'lat_bnds' must be (180, 2) but was (5, 180, 2);\n"
                          "- bounds coordinate variable 'lon_bnds' must have dimensions ('lon', <bounds_dim>);\n"
@@ -57,7 +57,7 @@ class AssertAndVerifyCubeTest(unittest.TestCase):
                                    coords=dict(lat=cube.lat, lon=cube.lon))
         with self.assertRaises(ValueError) as cm:
             assert_cube(cube)
-        self.assertEqual("Dataset is not a valid data cube, because:\n"
+        self.assertEqual("Dataset is not a valid xcube dataset, because:\n"
                          "- dimensions of data variable 'chl' must be"
                          " ('time', ..., 'lat', 'lon'), but were ('lat', 'lon') for 'chl';\n"
                          "- dimensions of all data variables must be same,"
diff --git a/test/cli/test_apply.py b/test/cli/test_apply.py
index 774836cd..d5138ea0 100644
--- a/test/cli/test_apply.py
+++ b/test/cli/test_apply.py
@@ -29,7 +29,7 @@ class ApplyCliTest(CliDataTest):
                                   '--dask', 'parallelized',
                                   '--params', 'a=0.1,b=0.4',
                                   '--vars', 'precipitation,soil_moisture',
-                                  OUTPUT_PATH,
+                                  '--output', OUTPUT_PATH,
                                   script_path,
                                   INPUT_PATH])
         self.assertEqual(0, result.exit_code)
diff --git a/test/cli/test_cli.py b/test/cli/test_cli.py
index 6f8f4791..8ac4d11e 100644
--- a/test/cli/test_cli.py
+++ b/test/cli/test_cli.py
@@ -76,8 +76,8 @@ class ChunkTest(CliDataTest):
         output_path = ChunkTest.TEST_OUTPUT
         result = self.invoke_cli(["chunk",
                                   TEST_ZARR_DIR,
-                                  output_path,
-                                  "-c", "time=1,lat=20,lon=40"])
+                                  "-o" , output_path,
+                                  "--chunks", "time=1,lat=20,lon=40"])
         self.assertEqual("", result.output)
         self.assertEqual(0, result.exit_code)
         self.assertTrue(os.path.isdir(output_path))
@@ -97,8 +97,8 @@ class ChunkTest(CliDataTest):
     #     output_path = "test-chunked.nc"
     #     result = self.invoke_cli(["chunk",
     #                               TEST_NC_FILE,
-    #                               output_path,
-    #                               "-c", "time=1,lat=20,lon=40"])
+    #                               "-o", output_path,
+    #                               "--chunks", "time=1,lat=20,lon=40"])
     #     self.assertEqual("", result.output)
     #     self.assertEqual(0, result.exit_code)
     #     self.assertTrue(os.path.isdir(output_path))
@@ -115,9 +115,9 @@ class ChunkTest(CliDataTest):
     def test_chunk_size_syntax(self):
         result = self.invoke_cli(["chunk",
                                   TEST_NC_FILE,
-                                  "test-chunked.zarr",
-                                  "-c", "time=1,lat!gnnn,lon=40"])
-        self.assertEqual("Error: Invalid value for <chunks>:"
+                                  "-o", "test-chunked.zarr",
+                                  "--chunks", "time=1,lat!gnnn,lon=40"])
+        self.assertEqual("Error: Invalid value for CHUNKS:"
                          " 'time=1,lat!gnnn,lon=40'\n",
                          result.output)
         self.assertEqual(1, result.exit_code)
@@ -125,9 +125,9 @@ class ChunkTest(CliDataTest):
     def test_chunk_size_not_an_int(self):
         result = self.invoke_cli(["chunk",
                                   TEST_NC_FILE,
-                                  "test-chunked.zarr",
-                                  "-c", "time=1,lat=20.3,lon=40"])
-        self.assertEqual("Error: Invalid value for <chunks>,"
+                                  "-o", "test-chunked.zarr",
+                                  "--chunks", "time=1,lat=20.3,lon=40"])
+        self.assertEqual("Error: Invalid value for CHUNKS,"
                          " chunk sizes must be positive integers:"
                          " time=1,lat=20.3,lon=40\n",
                          result.output)
@@ -136,9 +136,9 @@ class ChunkTest(CliDataTest):
     def test_chunk_size_not_a_dim(self):
         result = self.invoke_cli(["chunk",
                                   TEST_NC_FILE,
-                                  "test-chunked.zarr",
-                                  "-c", "time=1,lati=20,lon=40"])
-        self.assertEqual("Error: Invalid value for <chunks>,"
+                                  "-o", "test-chunked.zarr",
+                                  "--chunks", "time=1,lati=20,lon=40"])
+        self.assertEqual("Error: Invalid value for CHUNKS,"
                          " 'lati' is not the name of any dimension:"
                          " time=1,lati=20,lon=40\n",
                          result.output)
@@ -173,7 +173,7 @@ class LevelTest(CliDataTest):
 
     def test_level_with_zarr_link(self):
         result = self.invoke_cli(["level",
-                                  "-l",
+                                  "--link",
                                   "-t", "45",
                                   "-o", LevelTest.TEST_OUTPUT,
                                   TEST_ZARR_DIR,
@@ -208,7 +208,7 @@ class LevelTest(CliDataTest):
                                   "-o", LevelTest.TEST_OUTPUT,
                                   TEST_NC_FILE,
                                   ])
-        self.assertEqual("Error: <tile-size> must comprise positive integers\n",
+        self.assertEqual("Error: TILE-SIZE must comprise positive integers\n",
                          result.output)
         self.assertEqual(1, result.exit_code)
 
@@ -224,6 +224,6 @@ class LevelTest(CliDataTest):
                                   "-n", "0",
                                   "-o", LevelTest.TEST_OUTPUT,
                                   TEST_NC_FILE])
-        self.assertEqual("Error: <num-levels-max> must be a positive integer\n",
+        self.assertEqual("Error: NUM-LEVELS-MAX must be a positive integer\n",
                          result.output)
         self.assertEqual(1, result.exit_code)
diff --git a/test/cli/test_gen.py b/test/cli/test_gen.py
index c40d6495..7a516ea5 100644
--- a/test/cli/test_gen.py
+++ b/test/cli/test_gen.py
@@ -16,7 +16,7 @@ class GenCliTest(CliTest):
         self.assertEqual(0, result.exit_code)
 
     def test_default_proc_is_valid(self):
-        result = self.invoke_cli(['gen', '-p', 'default', 'input.nc'])
+        result = self.invoke_cli(['gen', '-P', 'default', 'input.nc'])
         self.assertEqual(0, result.exit_code)
 
     def test_main_with_illegal_proc(self):
@@ -26,23 +26,23 @@ class GenCliTest(CliTest):
 
     def test_main_with_illegal_size_option(self):
         with self.assertRaises(ValueError) as cm:
-            self.invoke_cli(['gen', '-s', '120,abc', 'input.nc'])
+            self.invoke_cli(['gen', '-S', '120,abc', 'input.nc'])
         self.assertEqual("output_size must have the form <width>,<height>,"
                          " where both values must be positive integer numbers", f'{cm.exception}')
 
     def test_main_with_illegal_region_option(self):
         with self.assertRaises(ValueError) as cm:
-            self.invoke_cli(['gen', '-r', '50,_2,55,21', 'input.nc'])
+            self.invoke_cli(['gen', '-R', '50,_2,55,21', 'input.nc'])
         self.assertEqual("output_region must have the form <lon_min>,<lat_min>,<lon_max>,<lat_max>,"
                          " where all four numbers must be floating point numbers in degrees", f'{cm.exception}')
         with self.assertRaises(ValueError) as cm:
-            self.invoke_cli(['gen', '-r', '50,20,55', 'input.nc'])
+            self.invoke_cli(['gen', '-R', '50,20,55', 'input.nc'])
         self.assertEqual("output_region must have the form <lon_min>,<lat_min>,<lon_max>,<lat_max>,"
                          " where all four numbers must be floating point numbers in degrees", f'{cm.exception}')
 
     def test_main_with_illegal_variable_option(self):
         with self.assertRaises(ValueError) as cm:
-            self.invoke_cli(['gen', '-v', ' ', 'input.nc'])
+            self.invoke_cli(['gen', '--vars', ' ', 'input.nc'])
         self.assertEqual("output_variables must be a list of existing variable names", f'{cm.exception}')
 
     def test_main_with_illegal_config_option(self):
diff --git a/test/cli/test_grid.py b/test/cli/test_grid.py
index 5ef75ae2..319ef738 100644
--- a/test/cli/test_grid.py
+++ b/test/cli/test_grid.py
@@ -73,7 +73,7 @@ class GridCliTest(unittest.TestCase):
         return runner.invoke(cli, args)
 
     def test_levels(self):
-        result = self.invoke_cli(["levels", "-r", "1/384"])
+        result = self.invoke_cli(["levels", "-R", "1/384"])
         self.assertEqual(("""
 L	H	R	R (deg)	R (m)
 0	135	4/3	1.3333333333333333	148425.99
@@ -91,7 +91,7 @@ L	H	R	R (deg)	R (m)
         self.assertEqual(0, result.exit_code)
 
     def test_res(self):
-        result = self.invoke_cli(["res", "300m", "-d", "1%", "-s", "+H0", "-n", "6"])
+        result = self.invoke_cli(["res", "300m", "-D", "1%", "--sort_by", "+H0", "-N", "6"])
         print(result.output)
         self.assertEqual(("""
 R_D (%)	R_NOM	R_DEN	R (deg)	R (m)	H	H0	L
@@ -106,7 +106,7 @@ R_D (%)	R_NOM	R_DEN	R (deg)	R (m)	H	H0	L
         self.assertEqual(0, result.exit_code)
 
     def test_abox(self):
-        result = self.invoke_cli(['abox', "0,50,5,52.5", "-r", "1/384"])
+        result = self.invoke_cli(['abox', "0,50,5,52.5", "-R", "1/384"])
         self.assertEqual(("""
 Orig. box coord. = 0.0,50.0,5.0,52.5
 Adj. box coord.  = 0.0,49.33333333333333,5.333333333333333,53.33333333333333
diff --git a/test/cli/test_serve.py b/test/cli/test_serve.py
index 0fa1e8c6..9c2b8944 100644
--- a/test/cli/test_serve.py
+++ b/test/cli/test_serve.py
@@ -24,18 +24,18 @@ class ServerCliTest(CliDataTest):
 
         result = self.invoke_cli(["serve", "--show"])
         self.assertEqual(2, result.exit_code)
-        self.assertEqual(f'Error: Option "--show" / "-s": In order to run the viewer, '
+        self.assertEqual(f'Error: Option "--show": In order to run the viewer, '
                          f'set environment variable {VIEWER_ENV_VAR} to a valid '
                          f'xcube-viewer deployment or build directory.\n',
-                         result.output[-157:])
+                         result.output[-150:])
 
         os.environ[VIEWER_ENV_VAR] = "pip/po"
         result = self.invoke_cli(["serve", "--show"])
         self.assertEqual(2, result.exit_code)
-        self.assertEqual(f'Error: Option "--show" / "-s": Viewer path set by environment '
+        self.assertEqual(f'Error: Option "--show": Viewer path set by environment '
                          f'variable {VIEWER_ENV_VAR} '
                          f'must be a directory: pip/po\n',
-                         result.output[-117:])
+                         result.output[-110:])
 
         if viewer_path is not None:
             os.environ[VIEWER_ENV_VAR] = viewer_path
diff --git a/test/webapi/test_s3buckethandlers.py b/test/webapi/test_s3buckethandlers.py
index 304decc3..5d261456 100644
--- a/test/webapi/test_s3buckethandlers.py
+++ b/test/webapi/test_s3buckethandlers.py
@@ -5,7 +5,7 @@ import numpy as np
 
 from xcube.api import read_cube
 
-SKIP_HELP = 'Skipped, because server is not running: $ xcube serve -v -c examples/serve/demo/config.yml'
+SKIP_HELP = 'Skipped, because server is not running: $ xcube serve --verbose -c examples/serve/demo/config.yml'
 SERVER_URL = 'http://localhost:8080'
 ENDPOINT_URL = SERVER_URL + '/s3bucket'