Skip to content

Commit dabb8a5

Browse files
authored
Merge pull request #3 from grove-platform/analyze-composables
Add analyze composables command
2 parents 3e4f6cd + 74d037d commit dabb8a5

File tree

31 files changed

+3482
-40
lines changed

31 files changed

+3482
-40
lines changed

AGENTS.md

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This document provides essential context for LLMs performing development tasks i
1010
- Extract code examples and procedures from RST files
1111
- Search documentation for patterns
1212
- Analyze file dependencies and relationships
13+
- Analyze composable definitions and usage across projects
1314
- Compare files across documentation versions
1415
- Count documentation pages and tested code examples
1516

@@ -31,13 +32,17 @@ audit-cli/
3132
│ ├── analyze/ # Analyze RST structures
3233
│ │ ├── includes/ # Analyze include relationships
3334
│ │ ├── usage/ # Find file usages
34-
│ │ └── procedures/ # Analyze procedure variations
35+
│ │ ├── procedures/ # Analyze procedure variations
36+
│ │ └── composables/ # Analyze composable definitions and usage
3537
│ ├── compare/ # Compare files across versions
3638
│ │ └── file-contents/ # Compare file contents
3739
│ └── count/ # Count documentation content
3840
│ ├── tested-examples/ # Count tested code examples
3941
│ └── pages/ # Count documentation pages
4042
├── internal/ # Internal packages (not importable externally)
43+
│ ├── config/ # Configuration management
44+
│ │ ├── config.go # Config loading from file/env/args
45+
│ │ └── config_test.go # Config tests
4146
│ ├── projectinfo/ # MongoDB docs project structure utilities
4247
│ │ ├── pathresolver.go # Path resolution
4348
│ │ ├── source_finder.go # Source directory detection
@@ -47,7 +52,8 @@ audit-cli/
4752
│ ├── directive_parser.go # Directive parsing
4853
│ ├── directive_regex.go # Regex patterns for directives
4954
│ ├── parse_procedures.go # Procedure parsing (core logic)
50-
│ └── get_procedure_variations.go # Variation extraction
55+
│ ├── get_procedure_variations.go # Variation extraction
56+
│ └── rstspec.go # Fetch and parse canonical rstspec.toml
5157
├── testdata/ # Test fixtures (auto-ignored by Go build)
5258
│ ├── input-files/source/ # Test RST files
5359
│ ├── expected-output/ # Expected extraction results
@@ -66,6 +72,7 @@ audit-cli/
6672
- **CLI Framework**: [spf13/cobra](https://github.com/spf13/cobra)
6773
- **Diff Library**: [aymanbagabas/go-udiff](https://github.com/aymanbagabas/go-udiff)
6874
- **YAML Parsing**: gopkg.in/yaml.vX
75+
- **TOML Parsing**: [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) v1.5.0
6976
- **Testing**: Go standard library (`testing` package)
7077

7178
Refer to the `go.mod` for version info.
@@ -93,6 +100,14 @@ Refer to the `go.mod` for version info.
93100
- `.. include::` - Include RST content from other files
94101
- `.. toctree::` - Table of contents (navigation, not content inclusion)
95102

103+
**Composables**:
104+
- Defined in `snooty.toml` files at project/version root
105+
- Canonical definitions also exist in `rstspec.toml` in the snooty-parser repository
106+
- Used in `.. composable-tutorial::` directives with `:options:` parameter
107+
- Enable context-specific documentation (e.g., different languages, deployment types)
108+
- Each composable has an ID, title, default, and list of options
109+
- The `internal/rst` module provides `FetchRstspec()` to retrieve canonical definitions
110+
96111
### MongoDB Documentation Structure
97112

98113
**Versioned Projects**: `content/{project}/{version}/source/`
@@ -103,6 +118,83 @@ Refer to the `go.mod` for version info.
103118
**Tested Code Examples**: `content/code-examples/tested/{language}/{product}/`
104119
- Products: `pymongo`, `mongosh`, `go/driver`, `go/atlas-sdk`, `javascript/driver`, `java/driver-sync`, `csharp/driver`
105120

121+
## Configuration
122+
123+
### Monorepo Path Configuration
124+
125+
Some commands require a monorepo path (`analyze composables`, `count tested-examples`, `count pages`). The path can be configured in three ways, with the following priority (highest to lowest):
126+
127+
1. **Command-line argument** - Passed directly to the command
128+
2. **Environment variable** - `AUDIT_CLI_MONOREPO_PATH`
129+
3. **Config file** - `.audit-cli.yaml` in current directory or home directory
130+
131+
**Config File Format** (`.audit-cli.yaml`):
132+
```yaml
133+
monorepo_path: /path/to/docs-monorepo
134+
```
135+
136+
**Config File Locations** (searched in order):
137+
1. Current directory: `./.audit-cli.yaml`
138+
2. Home directory: `~/.audit-cli.yaml`
139+
140+
**Implementation**:
141+
- Config loading is handled by `internal/config` package
142+
- Commands use `config.GetMonorepoPath(cmdLineArg)` to resolve the path
143+
- Commands accept 0 or 1 arguments using `cobra.MaximumNArgs(1)`
144+
- If no path is configured, a helpful error message is displayed
145+
146+
**Example Usage**:
147+
```go
148+
// In command RunE function
149+
var cmdLineArg string
150+
if len(args) > 0 {
151+
cmdLineArg = args[0]
152+
}
153+
monorepoPath, err := config.GetMonorepoPath(cmdLineArg)
154+
if err != nil {
155+
return err
156+
}
157+
```
158+
159+
### File Path Resolution
160+
161+
File-based commands support flexible path resolution through `config.ResolveFilePath()`. This allows users to specify paths in three ways:
162+
163+
1. **Absolute path** - Used as-is
164+
2. **Relative to monorepo root** - If monorepo is configured and path exists there
165+
3. **Relative to current directory** - Fallback if not found in monorepo
166+
167+
**Priority Order**:
168+
1. If path is absolute → return as-is (after verifying it exists)
169+
2. If monorepo is configured and path exists relative to monorepo → use monorepo-relative path
170+
3. Otherwise → resolve relative to current directory
171+
172+
**Implementation**:
173+
- File path resolution is handled by `config.ResolveFilePath(pathArg)` in `internal/config` package
174+
- Commands that take file paths should use this function in their `RunE` function
175+
- The function returns an absolute path or an error if the path doesn't exist
176+
177+
**Example Usage**:
178+
```go
179+
// In command RunE function for file-based commands
180+
RunE: func(cmd *cobra.Command, args []string) error {
181+
// Resolve file path (supports absolute, monorepo-relative, or cwd-relative)
182+
filePath, err := config.ResolveFilePath(args[0])
183+
if err != nil {
184+
return err
185+
}
186+
return runCommand(filePath, ...)
187+
}
188+
```
189+
190+
**Commands Using File Path Resolution**:
191+
- `extract code-examples`
192+
- `extract procedures`
193+
- `analyze includes`
194+
- `analyze usage`
195+
- `search find-string`
196+
- `compare file-contents`
197+
106198
## Building and Running
107199

108200
### Build from Source

CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,55 @@ All notable changes to audit-cli will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.2.0] - 2025-12-12
9+
10+
### Added
11+
12+
#### Analyze Commands
13+
- `analyze composables` - Analyze composable definitions in snooty.toml files
14+
- Inventory all composables across projects and versions
15+
- Identify identical composables (same ID, title, and options) across different projects/versions
16+
- Find similar composables with different IDs but overlapping option sets using Jaccard similarity (60% threshold)
17+
- Track composable usage in RST files via `composable-tutorial` directives
18+
- Identify unused composables that may be candidates for removal
19+
- Flags:
20+
- `--for-project` - Filter to a specific project
21+
- `--current-only` - Only analyze current versions
22+
- `--verbose` - Show full option details with titles
23+
- `--find-similar` - Show identical and similar composables for consolidation
24+
- `--find-usages` - Show where each composable is used in RST files with file paths
25+
- `--with-rstspec` - Show canonical composable definitions from rstspec.toml
26+
27+
#### Configuration System
28+
- Monorepo path configuration via three methods (priority order):
29+
1. Command-line argument (highest priority)
30+
2. Environment variable `AUDIT_CLI_MONOREPO_PATH`
31+
3. Config file `.audit-cli.yaml` in current or home directory (lowest priority)
32+
- Config file format:
33+
```yaml
34+
monorepo_path: /path/to/docs-monorepo
35+
```
36+
- Applies to commands: `analyze composables`, `count tested-examples`, `count pages`
37+
38+
#### File Path Resolution
39+
- Flexible path resolution for all file-based commands
40+
- Supports three path types (priority order):
41+
1. Absolute paths - Used as-is
42+
2. Relative to monorepo root - If monorepo configured and file exists there
43+
3. Relative to current directory - Fallback
44+
- Applies to commands: `extract code-examples`, `extract procedures`, `analyze includes`, `analyze usage`, `search find-string`, `compare file-contents`
45+
- Eliminates need to type full paths when working with monorepo files
46+
47+
#### Internal Packages
48+
- `internal/config` - Configuration management
49+
- Config file loading from `.audit-cli.yaml`
50+
- Environment variable support
51+
- Monorepo path resolution with priority order
52+
- File path resolution with flexible resolution
53+
- `internal/rst` - Enhanced RST parsing
54+
- `FetchRstspec()` - Fetches canonical composable definitions from snooty-parser rstspec.toml
55+
- Provides standard composable IDs, titles, defaults, and options
56+
857
## [0.1.0] - 2025-12-10
958

1059
### Added

0 commit comments

Comments
 (0)