Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates README, hides --no-auto-decompress for cmds without i/o #120

Merged
merged 2 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 78 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
## `ion-cli`
# `ion-cli`

This repository is home to the `ion` command line tool, which provides subcommands
for working with [the Ion data format](https://amzn.github.io/ion-docs/docs/spec.html).

## Table of contents

* [Examples](#examples)
* [Converting between formats with `dump`](#converting-between-formats-with-dump)
* [Converting between Ion and other formats with `to` and `from`](#converting-between-ion-and-other-formats-with-to-and-from)
* [Analyzing binary Ion file encodings with `inspect`](#analyzing-binary-ion-file-encodings-with-inspect)
* [Viewing the contents of an Ion file](#viewing-the-contents-of-an-ion-file)
* [Converting between Ion formats](#converting-between-ion-formats)
* [Converting between Ion and other formats with `to` and `from`](#converting-between-ion-and-other-formats-with-to-and-from)
* [Analyzing binary Ion file encodings with `inspect`](#analyzing-binary-ion-file-encodings-with-inspect)
* [Installation](#installation)
Comment on lines +9 to +12
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ I added a "Viewing the contents of an Ion file" section to demonstrate ion cat and removed a reference to dump.

* [via `brew`](#via-brew)
* [via `cargo`](#via-cargo)
* [via `brew`](#via-brew)
* [via `cargo`](#via-cargo)
* [Build Instructions](#build-instructions)
Comment on lines +14 to +15
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ My IDE modified the spacing for the bullet lists. Hard to be mad about it though; GitHub markdown's default list indentation is three spaces. 🤨

* [From source](#from-source)
* [Using Docker](#using-docker)
* [From source](#from-source)
* [Using Docker](#using-docker)

## Examples

Expand All @@ -22,21 +25,40 @@ evaluate the file extension.

Unless otherwise noted, these commands can accept any Ion format as input.

### Converting between formats with `dump`
### Viewing the contents of an Ion file

The `ion cat` command reads the contents of the specified files (or `STDIN`) sequentially
and writes their content to `STDOUT` in the requested Ion format.

Comment on lines +30 to +31
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ This sentence was mostly borrowed from man cat.

```shell
ion cat my_file.ion
```

You can use the `--format`/`-f` flag to specify the desired format. The supported formats are:

* `pretty` - Generously spaced, human-friendly text Ion. This is the default.
* `text` - Minimally spaced text Ion.
* `lines` - Text Ion that places each value on its own line.
* `binary`- Binary Ion

### Converting between Ion formats

Convert Ion text (or JSON) to Ion binary:

```shell
ion dump --format binary my_file.ion
ion cat --format binary my_text_file.ion -o my_binary_file.ion
```

Convert Ion binary to generously-spaced, human-friendly text:

```shell
ion dump --format pretty my_file.10n
ion cat --format pretty my_binary_file.ion -o my_text_file.ion
```

Convert Ion binary to minimally-spaced, compact text:

```shell
ion dump --format text my_file.10n
ion cat --format text my_binary_file.ion -o my_text_file.ion
```

### Converting between Ion and other formats with `to` and `from`
Expand All @@ -45,118 +67,81 @@ The `beta to` and `beta from` commands can convert Ion to and from other formats
Currently, JSON is supported.

Convert Ion to JSON:

```shell
ion beta to json my_file.10n
```

Convert JSON to Ion:

```shell
ion beta from json my_file.json
```

### Analyzing binary Ion file encodings with `inspect`

The `beta inspect` command can display the hex bytes of a binary Ion file alongside
The `inspect` command can display the hex bytes of a binary Ion file alongside
the equivalent text Ion for easier analysis.

```shell
# Write some text Ion to a file
echo '{foo: null, bar: true, baz: [1, 2, 3]}' > my_file.ion

# Convert the text Ion to binary Ion
ion dump --format binary my_file.ion > my_file.10n
ion cat --format binary my_file.ion > my_file.10n

# Show the binary encoding alongside its equivalent text
ion beta inspect my_file.10n

---------------------------------------------------------------------------
Offset | Length | Binary Ion | Text Ion
---------------------------------------------------------------------------
| 4 | e0 01 00 ea | // Ion 1.0 Version Marker
4 | 4 | ee 95 81 83 | '$ion_symbol_table':: // $3::
8 | 19 | de 91 | {
10 | 1 | 86 | 'imports': // $6:
11 | 2 | 71 03 | $ion_symbol_table, // $3
13 | 1 | 87 | 'symbols': // $7:
14 | 13 | bc | [
15 | 4 | 83 66 6f 6f | "foo",
19 | 4 | 83 62 61 72 | "bar",
23 | 4 | 83 62 61 7a | "baz",
| | | ],
| | | }
27 | 13 | dc | {
28 | 1 | 8a | 'foo': // $10:
29 | 1 | 0f | null,
30 | 1 | 8b | 'bar': // $11:
31 | 1 | 11 | true,
32 | 1 | 8c | 'baz': // $12:
33 | 7 | b6 | [
34 | 2 | 21 01 | 1,
36 | 2 | 21 02 | 2,
38 | 2 | 21 03 | 3,
| | | ],
| | | }
ion inspect my_file.10n
Comment on lines -70 to -98
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Now that inspect uses a variety of colors/styles, copy/pasted terminal output doesn't do it justice. I replaced each output example with a screenshot.

```

To skip to a particular offset in the stream, you can use the `--skip-bytes` flag:
![example_inspect_output.png](images/example_inspect_output.png)

```
ion beta inspect --skip-bytes 30 my_file.10n
---------------------------------------------------------------------------
Offset | Length | Binary Ion | Text Ion
---------------------------------------------------------------------------
| 4 | e0 01 00 ea | // Ion 1.0 Version Marker
| | ... | // Skipped 23 bytes of user-level data
27 | 13 | dc | {
| | ... | // Skipped 2 bytes of user-level data
30 | 1 | 8b | 'bar': // $11:
31 | 1 | 11 | true,
32 | 1 | 8c | 'baz': // $12:
33 | 7 | b6 | [
34 | 2 | 21 01 | 1,
36 | 2 | 21 02 | 2,
38 | 2 | 21 03 | 3,
| | | ],
| | | }
----
**The `--skip-bytes` flag**

To skip to a particular offset in the stream, you can use the `--skip-bytes` flag.

```shell
ion inspect --skip-bytes 30 my_file.10n
```

![img.png](images/example_inspect_skip_bytes.png)

Notice that the text column adds comments indicating where data has been skipped.
Also, if the requested index is nested inside one or more containers, the beginnings
of those containers (along with their lengths and offsets) will still be included
in the output.

-----
**The `--limit-bytes` flag**

You can limit the amount of data that `inspect` displays by using the `--limit-bytes`
flag:

```shell
ion beta inspect --skip-bytes 30 --limit-bytes 2 my_file.10n
---------------------------------------------------------------------------
Offset | Length | Binary Ion | Text Ion
---------------------------------------------------------------------------
| 4 | e0 01 00 ea | // Ion 1.0 Version Marker
| | ... | // Skipped 23 bytes of user-level data
27 | 13 | dc | {
| | ... | // Skipped 2 bytes of user-level data
30 | 1 | 8b | 'bar': // $11:
31 | 1 | 11 | true,
| | ... | // --limit-bytes reached, stepping out.
| | | }
ion inspect --skip-bytes 30 --limit-bytes 2 my_file.10n
```

![img.png](images/example_inspect_limit_bytes.png)

### Schema subcommands

All the subcommand to load or validate schema are under the `beta schema` subcommand.

To load a schema:

```bash
ion beta schema load --directory <DIRECTORY> --schema <SCHEMA_FILE>
```

To validate an ion value against a schema type:

```bash
ion beta schema validate --directory <DIRECTORY> --schema <SCHEMA_FILE> --input <INPUT_FILE> --type <TYPE>
```

For more information on how to use the schema subcommands using CLI, run the following command:

```bash
ion beta schema help
```
Expand Down Expand Up @@ -196,21 +181,23 @@ ion help
You should see output that resembles the following:

```
ion 0.4.0
The Ion Team <[email protected]>

USAGE:
ion <SUBCOMMAND>

FLAGS:
-h, --help Prints help information
-V, --version Prints version information

SUBCOMMANDS:
beta The 'beta' command is a namespace for commands whose interfaces are
not yet stable.
dump Prints Ion in the requested format
help Prints this message or the help of the given subcommand(s)
A collection of tools for working with Ion data.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section has been updated to the current --help output.


Usage: ion [OPTIONS] <COMMAND>

Commands:
beta The 'beta' command is a namespace for commands whose interfaces are not yet stable.
cat Prints all Ion input files to the specified output in the requested format.
head Prints the specified number of top-level values in the input stream.
inspect Displays hex-encoded binary Ion alongside its equivalent text Ion.
Its output prioritizes human readability and is likely to change
between versions. Stable output for programmatic use cases is a
non-goal.
help Print this message or the help of the given subcommand(s)

Options:
-h, --help Print help
-V, --version Print version
```

## Build instructions
Expand Down Expand Up @@ -270,8 +257,8 @@ SUBCOMMANDS:
# print the help message
docker run -it --rm ion-cli:0.1.1 ion -V

# mount current directory to /data volume and dump an ion file
docker run -it --rm -v $PWD:/data ion-cli:0.1.1 ion dump /data/test.ion
# mount current directory to /data volume and cat an ion file
docker run -it --rm -v $PWD:/data ion-cli:0.1.1 ion cat /data/test.ion

```

Expand Down
Binary file added images/example_inspect_limit_bytes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/example_inspect_output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/example_inspect_skip_bytes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 7 additions & 4 deletions src/bin/ion/commands/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@ impl<'a, 'b> IonInspector<'a, 'b> {
loop {
let item = reader.next_item()?;
let is_last_item = matches!(item, SystemStreamItem::EndOfStream(_));
item.raw_stream_item()
.map(|i| self.confirm_encoding_is_supported(i.encoding()))
.unwrap_or(Ok(()))?;
Comment on lines +215 to +217
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ I revised this section to fix a layout bug that would cause the table header to be output multiple times if you were using --skip-bytes.


if is_first_item {
// The first item in a stream cannot be ephemeral, so we can safely unwrap this.
let encoding = item.raw_stream_item().unwrap().encoding();
self.confirm_encoding_is_supported(encoding)?;
self.write_table_header()?;
}

Expand All @@ -227,7 +227,10 @@ impl<'a, 'b> IonInspector<'a, 'b> {
"stream items",
"ending",
)? {
InspectorAction::Skip => continue,
InspectorAction::Skip => {
is_first_item = false;
continue;
}
InspectorAction::Inspect => {}
InspectorAction::LimitReached => break,
}
Expand Down
14 changes: 10 additions & 4 deletions src/bin/ion/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub trait IonCliCommand {
.version(crate_version!())
.author(crate_authors!())
.hide(self.hide_from_help_message())
.with_compression_control();
.with_decompression_control();

// If there are subcommands, add them to the configuration and set 'subcommand_required'.
if !clap_subcommands.is_empty() {
Expand Down Expand Up @@ -121,7 +121,7 @@ pub trait WithIonCliArgument {
fn with_input(self) -> Self;
fn with_output(self) -> Self;
fn with_format(self) -> Self;
fn with_compression_control(self) -> Self;
fn with_decompression_control(self) -> Self;
}

impl WithIonCliArgument for ClapCommand {
Expand Down Expand Up @@ -155,12 +155,18 @@ impl WithIonCliArgument for ClapCommand {
)
}

fn with_compression_control(self) -> Self {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Prior to this change, ion help would include the --no-auto-decompress flag in its output. This was potentially confusing, as ion help (and ion itself) take no input.

fn with_decompression_control(self) -> Self {
let accepts_input = self
.get_arguments()
.any(|flag| dbg!(dbg!(flag.get_id()) == "input"));
self.arg(
Arg::new("no-auto-decompress")
.long("no-auto-decompress")
.default_value("false")
.action(ArgAction::SetTrue)
.help("Turn off automatic decompression detection."),
.help("Turn off automatic decompression detection.")
// Do not show this flag in `help` for commands that don't take an `--input` flag.
.hide(!accepts_input),
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/bin/ion/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ fn main() -> Result<()> {

if let Err(e) = root_command.run(&mut command_path, &args) {
match e.downcast_ref::<IonError>() {
// If `ion-cli` is being invoked as part of a pipeline we want to allow the pipeline to
// to shut off without printing an error to stderr
// If `ion-cli` is being invoked as part of a pipeline we want to allow the pipeline
// to shut off without printing an error to STDERR.
Some(IonError::Io(error)) if error.source().kind() == ErrorKind::BrokenPipe => {
return Ok(());
}
Expand Down
Loading