|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +metanorma-cli is the command-line interface for the Metanorma document processing toolchain. It provides the `metanorma` executable for compiling Metanorma documents across multiple standard flavors (ISO, IEC, IETF, BIPM, ITU, OGC, IEEE, JIS, etc.). It wraps the `metanorma` gem and adds CLI-level features: document compilation, collection rendering, site generation, template management, and STS XML conversion via `mnconvert`. |
| 8 | + |
| 9 | +## Build & Development Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Install dependencies |
| 13 | +bundle install |
| 14 | + |
| 15 | +# Run full test suite |
| 16 | +bundle exec rake |
| 17 | + |
| 18 | +# Run a single spec file |
| 19 | +bundle exec rspec spec/metanorma/cli/compiler_spec.rb |
| 20 | + |
| 21 | +# Run a single example by line number |
| 22 | +bundle exec rspec spec/metanorma/cli/compiler_spec.rb:42 |
| 23 | + |
| 24 | +# Lint |
| 25 | +bundle exec rubocop |
| 26 | + |
| 27 | +# Run the CLI locally |
| 28 | +bundle exec exe/metanorma compile document.adoc -t iso |
| 29 | + |
| 30 | +# IRB console with project loaded |
| 31 | +bin/console |
| 32 | +``` |
| 33 | + |
| 34 | +The project uses direnv + nix flake (see `flake.nix`) for environment setup. If using nix, run `direnv allow` to enter the dev shell. |
| 35 | + |
| 36 | +Tests use RSpec with VCR cassettes (for HTTP stubbing), webmock, and rspec-command. SimpleCov is configured for coverage. Test state persistence is in `.rspec_status`. |
| 37 | + |
| 38 | +## Architecture |
| 39 | + |
| 40 | +### Entry Points |
| 41 | + |
| 42 | +- **`exe/metanorma`** — Main CLI executable. Sets up encoding, handles SOCKS proxy support via `socksify`, then delegates to `Metanorma::Cli.start(ARGV)`. |
| 43 | +- **`exe/metanorma-manifest`** — Standalone tool that converts YAML manifests into Metanorma XML/HTML collection indexes. |
| 44 | +- **`lib/metanorma-cli.rb`** — Just requires `metanorma/cli`. |
| 45 | +- **`lib/metanorma/cli.rb`** — Core module. `Cli.start` intercepts arguments: if no known command is found, it prepends `"compile"` (so bare `metanorma foo.adoc` works). Defines config paths (`~/.metanorma/config.yml` global, `.metanorma/config.yml` local). |
| 46 | + |
| 47 | +### Command System (Thor) |
| 48 | + |
| 49 | +- **`Command`** (`lib/metanorma/cli/command.rb`) — Main Thor command class. Defines all top-level commands: `compile`, `collection`, `convert`, `version`, `new`, `log_messages`, `list-extensions`, `list-doctypes`, `export-config`. Also has three subcommands: `template-repo`, `site`, `config`. |
| 50 | +- **`ThorWithConfig`** (`lib/metanorma/cli/thor_with_config.rb`) — Base class for commands. Overrides `options` to merge CLI arguments with values from global and local config files (`~/.metanorma/config.yml` and `.metanorma/config.yml`). The merging is done by `Commands::Config.load_configs`. |
| 51 | +- **`flavor.rb`** (module, not the one in `lib/metanorma/`) — Mixed into `Command`. Provides flavor discovery, extension listing, doctype tables, backend version lookups, and the `export-config` command. |
| 52 | + |
| 53 | +### Key Classes |
| 54 | + |
| 55 | +- **`Compiler`** (`compiler.rb`) — Wraps `Metanorma::Compile`. Validates input file existence, normalizes options (splits extract/extensions on commas), and calls the metanorma core compile pipeline. |
| 56 | +- **`Collection`** (`collection.rb`) — Renders Metanorma collections from YAML or XML files. Delegates to `Metanorma::Collection.parse` for the actual processing. |
| 57 | +- **`SiteGenerator`** (`site_generator.rb`) — Generates an HTML site from a collection of Metanorma documents. Reads a `metanorma.yml` manifest (via `SiteManifest` models), compiles individual `.adoc` files and collection files, builds a Relaton collection index, then converts to HTML using Liquid templates. |
| 58 | +- **`Generator`** (`generator.rb`) — Creates new Metanorma documents from templates. Merges base templates (`templates/base/`) with type-specific templates downloaded from Git repos. |
| 59 | +- **`GitTemplate`** (`git_template.rb`) — Manages Git-hosted document templates. Clones template repos to `~/.metanorma/templates/git/`. |
| 60 | +- **`TemplateRepo`** (`template_repo.rb`) — Manages template repo registrations in the global config file. |
| 61 | + |
| 62 | +### Subcommands |
| 63 | + |
| 64 | +- **`Commands::Config`** (`commands/config.rb`) — `metanorma config get/set/unset`. Manages hierarchical YAML config (global + local). The `load_configs` class method merges global then local config into CLI options. |
| 65 | +- **`Commands::Site`** (`commands/site.rb`) — `metanorma site generate`. Resolves manifest paths, stylesheet/template paths, and delegates to `SiteGenerator`. |
| 66 | +- **`Commands::TemplateRepo`** (`commands/template_repo.rb`) — `metanorma template-repo add`. Registers template repos. |
| 67 | + |
| 68 | +### Flavor System |
| 69 | + |
| 70 | +- **`Metanorma::Flavor`** (`lib/metanorma/flavor.rb`) — Activates and loads all supported metanorma flavor gems (`metanorma-iso`, `metanorma-iec`, etc.). Activation happens at require time (line 77). Private gems (nist, ribose) fail silently. |
| 71 | +- **`Metanorma::SiteManifest`** (`lib/metanorma/site_manifest.rb`) — Lutaml::Model serializable classes for parsing `metanorma.yml` site manifest files. |
| 72 | + |
| 73 | +### Supporting Code |
| 74 | + |
| 75 | +- **`UI`** (`ui.rb`) — Thin Thor-based wrapper for console output (say, info, error, table). |
| 76 | +- **`Errors`** (`errors.rb`) — Custom error classes: `FileNotFoundError`, `FatalCompilationError`, `InvalidManifestFileError`, `DuplicateTemplateError`. |
| 77 | +- **`stringify_all_keys.rb`** — Core extensions for deep key stringification/symbolization on Hash and Array. Note: `metanorma-utils` provides similar functionality via `Metanorma::Utils::Hash`. |
| 78 | + |
| 79 | +## Configuration |
| 80 | + |
| 81 | +Config files are YAML with a `cli` key at the top level. Values from config are merged into Thor options (global first, then local). Example: |
| 82 | + |
| 83 | +```yaml |
| 84 | +cli: |
| 85 | + agree_to_terms: true |
| 86 | + install_fonts: false |
| 87 | +``` |
| 88 | +
|
| 89 | +- Global: `~/.metanorma/config.yml` |
| 90 | +- Local: `.metanorma/config.yml` |
| 91 | + |
| 92 | +## Testing Notes |
| 93 | + |
| 94 | +- Spec helper mocks `Mn2pdf.convert` and `MnConvert.convert` to copy files instead of running real conversions. |
| 95 | +- `strip_guid` helper normalizes UUIDs in XML output for deterministic comparisons. |
| 96 | +- Acceptance specs (`spec/acceptance/`) test the CLI end-to-end via `rspec-command`. |
| 97 | +- VCR cassettes are in `spec/vcr_cassettes/` for HTTP request stubs. |
0 commit comments