#+TITLE: Package sdml-cli
#+AUTHOR: Simon Johnston
#+EMAIL: johnstonskj@gmail.com
#+LANGUAGE: en
#+STARTUP: overview hidestars inlineimages entitiespretty
#+OPTIONS: author:nil created:nil creator:nil date:nil email:nil num:3 toc:nil

Rust CLI for the Simple Domain Modeling Language (SDML).

[[https://crates.io/crates/sdml_cli][https://img.shields.io/crates/v/sdml_cli.svg]]

This package is part of the Rust SDML project and specifically implements the =sdml= command-line interface (CLI).
The project's intent is to provide an idiomatic implementation of the in-memory model, parser, generators, and the CLI tool.

The following figure demonstrates this package in the broader project context.

#+CAPTION: Package Organization
#+BEGIN_EXAMPLE
                         ╭───────╮
                         │  CLI  │
                    ╔══  │ crate │  ══╗
                    ║    ╰───────╯    ║
┌╌╌╌╌╌╌╌╌┐          V                 V
┆        ┆       ╭───────╮       ╭──────────╮       Formatted Source
┆ source ┆  ══>  │ parse │  ══>  │ generate │  ══>  RDF Representation 
┆  file  ┆   ╭───│ crate │───────│   crate  │───╮   Documentation
┆        ┆   │   ╰───────╯       ╰──────────╯   │   Diagrams
└╌╌╌╌╌╌╌╌┘   │        core/errors crate         │
             ╰──────────────────────────────────╯
 ┌───────┐                  ⋀
 │ other │                  ║
 │ tools │  ════════════════╝
 └───────┘
#+END_EXAMPLE

* Installation

To install the command-line tool on MacOS or Linux use the Homebrew package manager and the SDML Tap. Installing in this
way also installs dependencies such as GraphViz and PlantUML used for diagram generation.

#+BEGIN_SRC sh :exports code :eval never
❯ brew install sdm-lang/sdml/sdml
#+END_SRC

You can check that you have the tool installed and on the path with the following check.

#+BEGIN_EXAMPLE bash
 ❯ sdml versions               
SDML CLI:        0.2.7
SDML grammar:    0.2.16
Tree-Sitter ABI: 14
#+END_EXAMPLE

** Install via cargo

Cargo is usually installed with the Rust toolchain using [[https://rustup.rs/[rustup]].

The following command should download and build the tool, and will also work to install any updates.

#+BEGIN_EXAMPLE bash
❯ cargo install sdml-cli
#+END_EXAMPLE

Cargo will sometimes report that you have the latest version installed, to be sure you can force it to install
regardless with the =--force= option.

#+BEGIN_EXAMPLE bash
❯ cargo install sdml-cli --force
#+END_EXAMPLE

** Install from source

To install the CLI from source you need to clone the entire repository.

#+BEGIN_EXAMPLE bash
❯ git clone https://github.com/sdm-lang/rust-sdml.git
#+END_EXAMPLE

In the =rust-sdml= directory you can build/test/install using the following commands.

#+BEGIN_EXAMPLE bash
❯ cargo build
❯ cargo test
❯ cargo install --path sdml-cli
#+END_EXAMPLE

* Global Options

Certain command-line options act on all commands, these must appear before the command. The SDML tool has a log-filter
and a no-color global option.

The set of packages making up =rust-sdml= all have extensive logging which can be enabled when running the tool. The
global argument =--log-filter= takes a log level and displays any log event with a severity greater than, or equal to,
the filter.

#+BEGIN_EXAMPLE bash
❯ sdml --log-filter tracing versions
2024-02-20T19:06:53.141741Z  INFO sdml: Log level set to `LevelFilter::Tracing`
2024-02-20T19:06:53.141877Z TRACE sdml: Commands::execute self: Versions
SDML CLI:        0.2.7
SDML grammar:    0.2.16
Tree-Sitter ABI: 14
#+END_EXAMPLE

Some of the commands will, by default, use colored output which can be a problem if you save a file for future
processing as the control characters play havoc with diff tools for example. 

#+BEGIN_EXAMPLE bash
❯ sdml --no-color versions
❯ NO_COLOR=1  sdml versions
❯ CLI_COLOR=0 sdml versions
#+END_EXAMPLE

* Commands

Input Files

** Getting Help

#+BEGIN_EXAMPLE bash
❯ sdml --help
Rust CLI for Simple Domain Modeling Language (SDML)

Usage: sdml [OPTIONS] <COMMAND>

Commands:
  convert    Convert module into alternate representations
  draw       Draw diagrams from a module
  deps       Show module dependencies
  doc        Document a module
  highlight  Syntax highlight a module source
  tags       Extract tags from a module
  validate   Validate a module
  versions   Show tool and library versions
  view       View formatted module source code
  help       Print this message or the help of the given subcommand(s)

Options:
      --log-filter <LOG_FILTER>
          Level of logging to enable
          
          [default: none]

          Possible values:
          - none:        Turn off all logging
          - errors:      Enable error logging only
          - warnings:    Enable warnings and above
          - information: Enable information and above
          - debugging:   Enable debugging and above
          - tracing:     Enable tracing (ALL) and above

      --no-color
          Turn off color for code emitters
          
          [env: NO_COLOR=]

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version
#+END_EXAMPLE

** Representation Conversion

This command (convert) allows the conversion of a module from the SDML surface syntax into one of a number of alternate
representations.

*** RDF

This uses the surface to RDF mapping defined in the SDML Language Reference. The mapping is normative and stable.

*** JSON

This is a direct representation of the in-memory model in the Rust package =sdml_core= in JSON. This mapping is
non-normative and may change according to any model structure change.

*** S-Expression

This is a debugging representation, and supported as the underlying tree-sitter library uses s-expressions as a
parse-tree visualization.

** Dependency Visualization

This command (dep) generates a representation of the transitive closure of dependencies for a given module into one of a
number of alternate representations.

*** Tree

Show dependencies as a text tree with the original as the root.

#+BEGIN_EXAMPLE bash
❯ sdml deps sdml
sdml
├── owl
│   ├── rdf
│   │   └── rdfs
│   │       └── rdf
│   ├── rdfs
│   └── xsd
│       ├── rdf
│       └── rdfs
├── rdf
├── rdfs
├── skos
│   ├── rdf
│   └── rdfs
└── xsd
#+END_EXAMPLE

In some cases the entire set of dependencies is not necessary and the =--depth= argument can be added to only show a
number of levels of import from the root. The depth argument instructs to command to stop after that many dependencies
away from the original module. Setting depth to 1 will only show the direct dependencies of the original.

#+BEGIN_EXAMPLE bash
❯ sdml deps --depth 1 sdml
sdml
├── owl
├── rdf
├── rdfs
├── skos
└── xsd
#+END_EXAMPLE

*** Graph

Create an SVG representation of the dependency graph using GraphViz.

#+BEGIN_EXAMPLE bash
❯ sdml deps --output-format graph sdml > sdml-deps.svg
❯ open -a Safari sdml-deps.svg
#+END_EXAMPLE

[[https://raw.githubusercontent.com/sdm-lang/rust-sdml/main/sdml-generate/doc/example_deps_graph.svg]]

*** RDF

Create a set of RDF statements,as N-Triples, that represent the individual OWL import relationships.

#+BEGIN_EXAMPLE bash
❯ sdml deps --depth 1 --output-format rdf sdml
<http://sdml.io/sdml-owl.ttl#> <http://www.w3.org/2002/07/owl#imports> <http://www.w3.org/2002/07/owl#> .
<http://sdml.io/sdml-owl.ttl#> <http://www.w3.org/2002/07/owl#imports> <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://sdml.io/sdml-owl.ttl#> <http://www.w3.org/2002/07/owl#imports> <http://www.w3.org/2000/01/rdf-schema#> .
<http://sdml.io/sdml-owl.ttl#> <http://www.w3.org/2002/07/owl#imports> <http://www.w3.org/2004/02/skos/core#> .
<http://sdml.io/sdml-owl.ttl#> <http://www.w3.org/2002/07/owl#imports> <http://www.w3.org/2001/XMLSchema#> .
#+END_EXAMPLE

** Diagram Generation

This command (draw) generates diagrams of a module with different perspectives.

*** Concepts

#+BEGIN_EXAMPLE bash
❯ sdml draw --diagram concepts --o example-concepts.svg -i example/example.sdm
❯ open -a Safari example-concepts.svg
#+END_EXAMPLE

[[https://raw.githubusercontent.com/sdm-lang/rust-sdml/main/sdml-generate/doc/example-concepts.svg]]

*** Entity Relationship

#+BEGIN_EXAMPLE bash
❯ sdml draw --diagram entity-relationship --o example-erd.svg -i example/example.sdm
❯ open -a Safari example-erd.svg
#+END_EXAMPLE

[[https://raw.githubusercontent.com/sdm-lang/rust-sdml/main/sdml-generate/doc/example-erd.svg]]

*** UML Class

#+BEGIN_EXAMPLE bash
❯ sdml draw --diagram uml-class --o example-uml.svg -i example/example.sdm
❯ open -a Safari example-uml.svg
#+END_EXAMPLE

[[https://raw.githubusercontent.com/sdm-lang/rust-sdml/main/sdml-generate/doc/example-uml.svg]]

** Document (Project) Generation

This command (doc-book) creates structured documentation for a collection of modules, and includes annotations,
constraints and all definition types. The generated documentation also include diagrams and dependency graphs.

*** Org-mode

Create an Emacs org-mode formatted file. This format allows all content to be written into a single file with export
options to HTML, LaTeX, Word, PDF and more.

** Document (Module) Generation

This command (doc) creates structured documentation for a module, and includes annotations, constraints and all definition
types. The generated documentation also include diagrams and dependency graphs.

*** Org-mode

Create an Emacs org-mode formatted file. This format allows all content to be written into a single file with export
options to HTML, LaTeX, Word, PDF and more.

*** Markdown

Create a markdown formatted file, this file uses GitHub-flavored markdown to allow for some better content formatting
than CommonMark.

** Module Highlighting

TBD

** XRef Tag Generation

TBD

** Validation

This command (validate) provides deep validation of a module's content, including errors, warnings, and linter-like advice. Checks
are run not only on the initial module, but it's transitively loaded dependencies.

#+BEGIN_EXAMPLE bash
❯ sdml validate --level all -i examples/errors/i0506.sdm
note[I0506]: identifier not using preferred casing
  ┌─ examples/errors/i0506.sdm:1:8
  │
1 │ module Example <https://example.com/api> is
  │        ^^^^^^^ this identifier
  │
  = expected snake case (snake_case)
  = help: for more details, see <https://sdml.io/errors/#I0506>

note[I0506]: identifier not using preferred casing
  ┌─ examples/errors/i0506.sdm:3:13
  │
3 │   structure access_record is
  │             ^^^^^^^^^^^^^ this identifier
  │
  = expected upper camel case (UpperCamelCase)
  = help: for more details, see <https://sdml.io/errors/#I0506>
#+END_EXAMPLE

Additionally, a `short-form` option will generate diagnostics using a CSV format that is easier for tools to parse. The
fields in this format are: severity, file name, start line, start column, end line, end column, error code, and message.

#+BEGIN_EXAMPLE bash
❯ sdml validate --level all --short-form -i examples/errors/i0506.sdm
note,examples/errors/i0506.sdm,1,8,1,15,I0506,identifier not using preferred casing
note,examples/errors/i0506.sdm,3,13,3,26,I0506,identifier not using preferred casing
#+END_EXAMPLE

** Version Information

This command (versions) shows more information than the simple =--version= global argument and is useful for debugging.

#+BEGIN_EXAMPLE bash
❯ sdml versions               
SDML CLI:        0.2.7
SDML grammar:    0.2.16
Tree-Sitter ABI: 14
#+END_EXAMPLE

** Module Viewer

This command (view) will generate source code from a module file, which at first seems redundant. However, this view provides
levels of detail that allow for an overview of module definitions. The =--level= argument can be used to elide content and
get an overview of a module.

*** Definitions Only

Show only the definitions in the module, any definition body will be elided, for an overview of the module contents.
Elided definitions are followed by =";; ..."=.

#+BEGIN_EXAMPLE bash
❯ sdml view --level definitions -i examples/example.sdm
module example <https://example.com/api> is

  import [ dc xsd ]

  datatype Uuid <- sdml:string ;; ...

  entity Example ;; ...

end
#+END_EXAMPLE

*** Members

Show definitions in the module and show the members of product types and variants of sum types but
not their bodies if present.

#+BEGIN_EXAMPLE bash
❯ sdml view --level members -i examples/example.sdm
module example <https://example.com/api> is

  import [ dc xsd ]

  datatype Uuid <- sdml:string ;; ...

  entity Example is
    version -> Uuid
    name -> sdml:string ;; ...
  end

end
#+END_EXAMPLE

*** Full

Show all contents of the module.

#+BEGIN_EXAMPLE bash
❯ sdml view --level full -i examples/example.sdm
module example <https://example.com/api> is

  import [ dc xsd ]

  datatype Uuid <- sdml:string is
    @xsd:pattern = "[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}"
  end

  entity Example is
    version -> Uuid
    name -> sdml:string is
      @dc:description = "the name of this thing"@en
    end
  end

end
#+END_EXAMPLE

* Changes

*Version 0.3.0*

- Feature: updates to support the latest grammar, see ~sdml-core~.
- Refactor: use the latest ~Generator~ trait.

*Version 0.2.10*

- Feature: added new command =doc-book= to create a more complex documentation output for a collection of modules.
- Build: bump version of =sdml-errors=, =sdml-core=, and =sdml-generate=.

*Version 0.2.9*

- Build: update dependency from =sdml_error= to =sdml-errors=.
- Build: bump versions of =sdml-core=, =sdml-parse=, =sdml-generate=.

*Version 0.2.8*

- Build: upgrade to =sdml_core= version =0.2.14= and the new =ModelStore= trait.

*Version 0.2.7*

- Feature: better error handling in conjunction with the validation and diagnostics in =sdml-errors=.

*Version 0.2.6*

- Build: update dependencies.

*Version 0.2.5*

- Feature: Add new =--no-color= flag to the CLI which also uses the =NO_COLOR= environment variable.
- Feature: Removed indirect dependencies from =Cargo.toml=.
- Update: New generator features for colored RDF.
  
*Version 0.2.4*

- Feature: Add new =source= command to call the new source generator.
- Fix: Change the description of =depth= parameter for =deps= command, =0= is the default which means all depths are included
  in the output.
- Update: Use new generator traits that require a module cache parameter.

*Version 0.2.3*

- Feature: add new =stdlib= modules with standard layout.
- Feature: minor refactor of cache and loader.

*Version 0.2.2*

- Feature: Update to latest grammar for version URIs and RDF definitions.
  - Add support for base URI on modules.
  - Add support for version info and URI on modules.
  - Add support for version URI on module import.
  - Parse RDF definitions for classes and properties.

*Version 0.2.1*

- Feature: Remove member groups.

*Version 0.2.0*

- Feature: Update to latest grammar.
  - Remove =ValueVariant= numeric values.
  - Update formal constraints.
  - Add type classes.

*Version 0.1.6*

- Updated dependencies.

*Version 0.1.5*

Initial stand-alone crate.

*Version 0.1.4*

Previously part of a single crate [[https://crates.io/crates/sdml][sdml]].
