decode 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/documentation-coverage.md +254 -0
- data/context/getting-started.md +34 -222
- data/context/index.yaml +22 -0
- data/context/ruby-documentation.md +59 -26
- data/lib/decode/comment/constant.rb +1 -1
- data/lib/decode/comment/example.rb +62 -0
- data/lib/decode/comment/option.rb +1 -1
- data/lib/decode/comment/tag.rb +1 -0
- data/lib/decode/documentation.rb +1 -0
- data/lib/decode/language/generic.rb +2 -0
- data/lib/decode/language/ruby/generic.rb +2 -0
- data/lib/decode/language/ruby/parser.rb +2 -2
- data/lib/decode/rbs/type.rb +2 -2
- data/lib/decode/scope.rb +1 -1
- data/lib/decode/version.rb +1 -1
- data/readme.md +7 -1
- data/releases.md +4 -0
- data.tar.gz.sig +1 -3
- metadata +5 -4
- metadata.gz.sig +0 -0
- data/context/coverage.md +0 -325
- data/context/types.md +0 -127
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 453b1f28ebb358dd7f37f17d12e6e48616895970d0a9a9225ddb8d3384f2fc90
|
|
4
|
+
data.tar.gz: 3720af135885d5d002f91a3bc758a3f04e58c1d7022fc4d90b008754568b66d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf74b8ffc88195be9440a81aeceb0da5b2b77ff9c2e45df2961f683b27ed15f1d5ccab54d161f05931d2c9c5fdd5641b50b6122757b91d55d3a5668c8dcbde1a
|
|
7
|
+
data.tar.gz: 417e14f2501bdb368a25f5872915d4d3de47cd57f39164977c4a42b372ab41f4a9d4d435644972297f076c84cc3d475f732a4d90677ba0bb7b01e897586ca9b1
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Documentation Coverage
|
|
2
|
+
|
|
3
|
+
This guide explains how to test and monitor documentation coverage in your Ruby projects using the Decode gem's built-in bake tasks.
|
|
4
|
+
|
|
5
|
+
## Available Bake Tasks
|
|
6
|
+
|
|
7
|
+
The Decode gem provides several bake tasks for analyzing your codebase:
|
|
8
|
+
|
|
9
|
+
- `bake decode:index:coverage` - Check documentation coverage.
|
|
10
|
+
- `bake decode:index:symbols` - List all symbols in the codebase.
|
|
11
|
+
- `bake decode:index:documentation` - Extract all documentation.
|
|
12
|
+
|
|
13
|
+
## Checking Documentation Coverage
|
|
14
|
+
|
|
15
|
+
### Basic Coverage Check
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Check coverage for the lib directory:
|
|
19
|
+
bake decode:index:coverage lib
|
|
20
|
+
|
|
21
|
+
# Check coverage for a specific directory:
|
|
22
|
+
bake decode:index:coverage app/models
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Example Output
|
|
26
|
+
|
|
27
|
+
When you run the coverage command, you'll see output like:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Decode
|
|
31
|
+
Decode::VERSION
|
|
32
|
+
Decode::Languages.all
|
|
33
|
+
Decode::Languages#initialize
|
|
34
|
+
Decode::Languages#freeze
|
|
35
|
+
Decode::Languages#add
|
|
36
|
+
Decode::Languages#fetch
|
|
37
|
+
Decode::Languages#source_for
|
|
38
|
+
Decode::Languages::REFERENCE
|
|
39
|
+
Decode::Languages#reference_for
|
|
40
|
+
Decode::Source#initialize
|
|
41
|
+
... snip ...
|
|
42
|
+
135/215 definitions have documentation.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Using this tool can show you areas that might require more attention.
|
|
46
|
+
|
|
47
|
+
### Understanding Coverage Output
|
|
48
|
+
|
|
49
|
+
The coverage check:
|
|
50
|
+
- **Counts only public definitions** (public methods, classes, modules).
|
|
51
|
+
- **Reports the ratio** of documented vs total public definitions.
|
|
52
|
+
- **Lists missing documentation** by qualified name.
|
|
53
|
+
- **Fails with an error** if coverage is incomplete.
|
|
54
|
+
|
|
55
|
+
### What Counts as "Documented"
|
|
56
|
+
|
|
57
|
+
A definition is considered documented if it has:
|
|
58
|
+
- Any comment preceding it.
|
|
59
|
+
- Documentation pragmas (like `@parameter`, `@returns`, `@example`).
|
|
60
|
+
- A `@namespace` pragma (for organizational modules).
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
# Represents a user in the system.
|
|
64
|
+
class MyClass
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @namespace
|
|
68
|
+
module OrganizationalModule
|
|
69
|
+
# Contains helper functionality.
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Process user data and return formatted results.
|
|
73
|
+
# @parameter name [String] The user's name.
|
|
74
|
+
# @returns [bool] Success status.
|
|
75
|
+
def process(name)
|
|
76
|
+
# Validation logic here:
|
|
77
|
+
return false if name.empty?
|
|
78
|
+
|
|
79
|
+
# Processing logic:
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class UndocumentedClass
|
|
84
|
+
end
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Analyzing Symbols
|
|
88
|
+
|
|
89
|
+
### List All Symbols
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# See the structure of your codebase
|
|
93
|
+
bake decode:index:symbols lib
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This shows the hierarchical structure of your code:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
[] -> []
|
|
100
|
+
["MyGem"] -> [#<Decode::Language::Ruby::Module:...>]
|
|
101
|
+
MyGem
|
|
102
|
+
["MyGem", "User"] -> [#<Decode::Language::Ruby::Class:...>]
|
|
103
|
+
MyGem::User
|
|
104
|
+
["MyGem", "User", "initialize"] -> [#<Decode::Language::Ruby::Method:...>]
|
|
105
|
+
MyGem::User#initialize
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Extract Documentation
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Extract all documentation from your codebase
|
|
112
|
+
bake decode:index:documentation lib
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
This outputs formatted documentation for all documented definitions:
|
|
116
|
+
|
|
117
|
+
~~~markdown
|
|
118
|
+
## `MyGem::User#initialize`
|
|
119
|
+
|
|
120
|
+
Initialize a new user with the given email address.
|
|
121
|
+
|
|
122
|
+
## `MyGem::User#authenticate`
|
|
123
|
+
|
|
124
|
+
Authenticate the user with a password.
|
|
125
|
+
Returns true if authentication is successful.
|
|
126
|
+
~~~
|
|
127
|
+
|
|
128
|
+
## Achieving 100% Coverage
|
|
129
|
+
|
|
130
|
+
### Document all public APIs
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
# Represents a user management system.
|
|
134
|
+
class User
|
|
135
|
+
# @attribute [String] The user's email address.
|
|
136
|
+
attr_reader :email
|
|
137
|
+
|
|
138
|
+
# Initialize a new user.
|
|
139
|
+
# @parameter email [String] The user's email address.
|
|
140
|
+
def initialize(email)
|
|
141
|
+
# Store the email address:
|
|
142
|
+
@email = email
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Use @namespace for organizational modules
|
|
148
|
+
|
|
149
|
+
The best place to add these by default is `version.rb`.
|
|
150
|
+
|
|
151
|
+
```ruby
|
|
152
|
+
# @namespace
|
|
153
|
+
module MyGem
|
|
154
|
+
VERSION = "0.1.0"
|
|
155
|
+
end
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Document edge cases
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# @private
|
|
162
|
+
def internal_helper
|
|
163
|
+
# Add the fields:
|
|
164
|
+
return foo + bar
|
|
165
|
+
end
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Common Coverage Issues
|
|
169
|
+
|
|
170
|
+
#### Missing namespace documentation
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
# This module has no documentation and will show as missing coverage:
|
|
174
|
+
module MyGem
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Solution: Add @namespace pragma:
|
|
178
|
+
# @namespace
|
|
179
|
+
module MyGem
|
|
180
|
+
# Provides core functionality.
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Undocumented methods
|
|
185
|
+
|
|
186
|
+
Problem: Methods without any comments will show as missing coverage:
|
|
187
|
+
```ruby
|
|
188
|
+
def process_data
|
|
189
|
+
# Implementation here
|
|
190
|
+
end
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Solution: Add description and pragmas:
|
|
194
|
+
```ruby
|
|
195
|
+
# Process the input data and return results.
|
|
196
|
+
# @parameter data [Hash] Input data to process.
|
|
197
|
+
# @returns [Array] Processed results.
|
|
198
|
+
def process_data(data)
|
|
199
|
+
# Process the input:
|
|
200
|
+
results = data.map {|item| transform(item)}
|
|
201
|
+
|
|
202
|
+
# Return processed results:
|
|
203
|
+
results
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Missing attr documentation
|
|
208
|
+
|
|
209
|
+
Problem: Attributes without documentation will show as missing coverage:
|
|
210
|
+
```ruby
|
|
211
|
+
attr_reader :name
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Solution: Document with @attribute pragma:
|
|
215
|
+
```ruby
|
|
216
|
+
# @attribute [String] The user's full name.
|
|
217
|
+
attr_reader :name
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Integrating into CI/CD
|
|
221
|
+
|
|
222
|
+
### GitHub Actions Example
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
name: Documentation Coverage
|
|
226
|
+
|
|
227
|
+
on: [push, pull_request]
|
|
228
|
+
|
|
229
|
+
jobs:
|
|
230
|
+
docs:
|
|
231
|
+
runs-on: ubuntu-latest
|
|
232
|
+
steps:
|
|
233
|
+
- uses: actions/checkout@v3
|
|
234
|
+
- uses: ruby/setup-ruby@v1
|
|
235
|
+
with:
|
|
236
|
+
bundler-cache: true
|
|
237
|
+
- name: Check documentation coverage
|
|
238
|
+
run: bake decode:index:coverage lib
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Rake Task Integration
|
|
242
|
+
|
|
243
|
+
Add to your `Rakefile`:
|
|
244
|
+
|
|
245
|
+
```ruby
|
|
246
|
+
require "decode"
|
|
247
|
+
|
|
248
|
+
desc "Check documentation coverage"
|
|
249
|
+
task :doc_coverage do
|
|
250
|
+
system("bake decode:index:coverage lib") || exit(1)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
task default: [:test, :doc_coverage]
|
|
254
|
+
```
|
data/context/getting-started.md
CHANGED
|
@@ -1,242 +1,54 @@
|
|
|
1
|
-
# Getting Started
|
|
1
|
+
# Getting Started
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This guide explains how to use `decode` for source code analysis.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
Add to your
|
|
7
|
+
Add the gem to your project:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
~~~ bash
|
|
10
|
+
$ bundle add decode
|
|
11
|
+
~~~
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Indexing
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
bundle add decode
|
|
17
|
-
```
|
|
15
|
+
`decode` turns your source code into a kind of database with rich access to definitions, segments and associated comments. Use {ruby Decode::Index} to build an index of your project by loading in source files:
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
~~~ ruby
|
|
18
|
+
require 'decode/index'
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```ruby
|
|
24
|
-
require 'decode'
|
|
25
|
-
|
|
26
|
-
# Create a source object:
|
|
27
|
-
source = Decode::Source.new('lib/my_class.rb', Decode::Language::Ruby.new)
|
|
28
|
-
|
|
29
|
-
# Extract definitions (classes, methods, etc.):
|
|
30
|
-
definitions = source.definitions.to_a
|
|
31
|
-
|
|
32
|
-
definitions.each do |definition|
|
|
33
|
-
puts "#{definition.name}: #{definition.short_form}"
|
|
34
|
-
end
|
|
35
|
-
```
|
|
20
|
+
index = Decode::Index.new
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
# Load all Ruby files into the index:
|
|
23
|
+
index.update(Dir['**/*.rb'])
|
|
24
|
+
~~~
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
# Get segments (blocks of comments + code):
|
|
41
|
-
segments = source.segments.to_a
|
|
26
|
+
Once you've done this, you can print out all the definitions from your project:
|
|
42
27
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
~~~ ruby
|
|
29
|
+
index.definitions.each do |name, symbol|
|
|
30
|
+
puts symbol.long_form
|
|
46
31
|
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### Checking Documentation Coverage
|
|
32
|
+
~~~
|
|
50
33
|
|
|
51
|
-
|
|
52
|
-
# Check which definitions have documentation:
|
|
53
|
-
definitions.each do |definition|
|
|
54
|
-
status = definition.comments.any? ? 'documented' : 'missing docs'
|
|
55
|
-
puts "#{definition.name}: #{status}"
|
|
56
|
-
end
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Working with Documentation Pragmas
|
|
60
|
-
|
|
61
|
-
The Decode gem understands structured documentation pragmas:
|
|
62
|
-
|
|
63
|
-
```ruby
|
|
64
|
-
# This will be parsed and structured:
|
|
65
|
-
source_code = <<~RUBY
|
|
66
|
-
# Represents a user in the system.
|
|
67
|
-
class User
|
|
68
|
-
# @attribute [String] The user's email address.
|
|
69
|
-
attr_reader :email
|
|
70
|
-
|
|
71
|
-
# Initialize a new user.
|
|
72
|
-
# @parameter email [String] The user's email address.
|
|
73
|
-
# @parameter options [Hash] Additional options.
|
|
74
|
-
# @option :active [bool] Whether the account is active.
|
|
75
|
-
# @raises [ArgumentError] If email is invalid.
|
|
76
|
-
def initialize(email, options = {})
|
|
77
|
-
# Validate the email format:
|
|
78
|
-
raise ArgumentError, "Invalid email" if email.empty?
|
|
79
|
-
|
|
80
|
-
# Set instance variables:
|
|
81
|
-
@email = email
|
|
82
|
-
@active = options.fetch(:active, true)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
RUBY
|
|
86
|
-
|
|
87
|
-
# Parse and analyze:
|
|
88
|
-
result = Decode::Language::Ruby.new.parser.parse_source(source_code)
|
|
89
|
-
definitions = Decode::Language::Ruby.new.parser.definitions_for(source_code).to_a
|
|
90
|
-
|
|
91
|
-
definitions.each do |definition|
|
|
92
|
-
puts "#{definition.name}: #{definition.comments.join(' ')}"
|
|
93
|
-
end
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Common Use Cases
|
|
97
|
-
|
|
98
|
-
### 1. Code Analysis and Metrics
|
|
99
|
-
|
|
100
|
-
```ruby
|
|
101
|
-
# Analyze a codebase and return metrics.
|
|
102
|
-
# @parameter file_path [String] Path to the Ruby file to analyze.
|
|
103
|
-
def analyze_codebase(file_path)
|
|
104
|
-
source = Decode::Source.new(file_path, Decode::Language::Ruby.new)
|
|
105
|
-
definitions = source.definitions.to_a
|
|
106
|
-
|
|
107
|
-
# Count different definition types:
|
|
108
|
-
classes = definitions.count { |d| d.is_a?(Decode::Language::Ruby::Class) }
|
|
109
|
-
methods = definitions.count { |d| d.is_a?(Decode::Language::Ruby::Method) }
|
|
110
|
-
modules = definitions.count { |d| d.is_a?(Decode::Language::Ruby::Module) }
|
|
111
|
-
|
|
112
|
-
puts "Classes: #{classes}, Methods: #{methods}, Modules: #{modules}"
|
|
113
|
-
end
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### 2. Documentation Coverage Reports
|
|
117
|
-
|
|
118
|
-
```ruby
|
|
119
|
-
# Calculate documentation coverage for a file.
|
|
120
|
-
# @parameter file_path [String] Path to the Ruby file to analyze.
|
|
121
|
-
def documentation_coverage(file_path)
|
|
122
|
-
source = Decode::Source.new(file_path, Decode::Language::Ruby.new)
|
|
123
|
-
definitions = source.definitions.to_a
|
|
124
|
-
|
|
125
|
-
# Calculate coverage statistics:
|
|
126
|
-
total = definitions.count
|
|
127
|
-
documented = definitions.count { |d| d.comments.any? }
|
|
128
|
-
|
|
129
|
-
puts "Coverage: #{documented}/#{total} (#{(documented.to_f / total * 100).round(1)}%)"
|
|
130
|
-
end
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### 3. Extracting API Information
|
|
134
|
-
|
|
135
|
-
```ruby
|
|
136
|
-
# Extract API information from a Ruby file.
|
|
137
|
-
# @parameter file_path [String] Path to the Ruby file to analyze.
|
|
138
|
-
def extract_api_info(file_path)
|
|
139
|
-
source = Decode::Source.new(file_path, Decode::Language::Ruby.new)
|
|
140
|
-
definitions = source.definitions.to_a
|
|
141
|
-
|
|
142
|
-
# Get public methods only:
|
|
143
|
-
public_methods = definitions.select do |definition|
|
|
144
|
-
definition.is_a?(Decode::Language::Ruby::Method) &&
|
|
145
|
-
definition.visibility == :public
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
public_methods.each do |method|
|
|
149
|
-
puts "#{method.long_form}"
|
|
150
|
-
puts " Comments: #{method.comments.join(' ')}" if method.comments.any?
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### 4. Code Structure Analysis
|
|
156
|
-
|
|
157
|
-
```ruby
|
|
158
|
-
# Analyze the structure of Ruby files in a directory.
|
|
159
|
-
# @parameter directory [String] Path to the directory to analyze.
|
|
160
|
-
def analyze_structure(directory)
|
|
161
|
-
Dir.glob("#{directory}/**/*.rb").each do |file|
|
|
162
|
-
source = Decode::Source.new(file, Decode::Language::Ruby.new)
|
|
163
|
-
definitions = source.definitions.to_a
|
|
164
|
-
|
|
165
|
-
# Find nested classes and modules:
|
|
166
|
-
nested = definitions.select { |d| d.parent }
|
|
167
|
-
|
|
168
|
-
if nested.any?
|
|
169
|
-
puts "#{file}:"
|
|
170
|
-
nested.each do |definition|
|
|
171
|
-
puts " #{definition.qualified_name}"
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### 5. Finding Undocumented Code
|
|
179
|
-
|
|
180
|
-
```ruby
|
|
181
|
-
# Find undocumented code in a directory.
|
|
182
|
-
# @parameter directory [String] Path to the directory to analyze.
|
|
183
|
-
def find_undocumented(directory)
|
|
184
|
-
Dir.glob("#{directory}/**/*.rb").each do |file|
|
|
185
|
-
source = Decode::Source.new(file, Decode::Language::Ruby.new)
|
|
186
|
-
definitions = source.definitions.to_a
|
|
187
|
-
|
|
188
|
-
# Filter for undocumented public definitions:
|
|
189
|
-
undocumented = definitions.select { |d| d.comments.empty? && d.visibility == :public }
|
|
190
|
-
|
|
191
|
-
if undocumented.any?
|
|
192
|
-
puts "#{file}:"
|
|
193
|
-
undocumented.each do |definition|
|
|
194
|
-
puts " - #{definition.short_form}"
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Advanced Features
|
|
202
|
-
|
|
203
|
-
### Using the Index
|
|
204
|
-
|
|
205
|
-
```ruby
|
|
206
|
-
# Create an index for multiple files:
|
|
207
|
-
index = Decode::Index.new
|
|
208
|
-
index.update(Dir.glob("lib/**/*.rb"))
|
|
209
|
-
|
|
210
|
-
# Search through the index:
|
|
211
|
-
index.trie.traverse do |path, node, descend|
|
|
212
|
-
if node.values
|
|
213
|
-
node.values.each do |definition|
|
|
214
|
-
puts "#{path.join('::')} - #{definition.short_form}"
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
descend.call
|
|
218
|
-
end
|
|
219
|
-
```
|
|
34
|
+
## References
|
|
220
35
|
|
|
221
|
-
|
|
36
|
+
References are strings which can be resolved into definitions. The index allows you to efficiently resolve references.
|
|
222
37
|
|
|
223
|
-
|
|
224
|
-
#
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
38
|
+
~~~ ruby
|
|
39
|
+
# Lookup a specific symbol:
|
|
40
|
+
reference = index.languages.parse_reference("ruby Decode::Index#lookup")
|
|
41
|
+
definition = index.lookup(reference).first
|
|
42
|
+
puts definition.long_form
|
|
43
|
+
~~~
|
|
228
44
|
|
|
229
|
-
##
|
|
45
|
+
## Documentation
|
|
230
46
|
|
|
231
|
-
|
|
232
|
-
2. **Leverage programmatic access** - Build tools that analyze and manipulate code.
|
|
233
|
-
3. **Use @namespace** - For organizational modules to achieve complete coverage.
|
|
234
|
-
4. **Analyze code patterns** - Use decode to understand codebase structure.
|
|
235
|
-
5. **Build automation** - Use decode in CI/CD pipelines for code quality checks.
|
|
47
|
+
The {ruby Decode::Documentation} provides rich access to the comments that preceed a definition. This includes metadata including `@parameter`, `@returns` and other tags.
|
|
236
48
|
|
|
237
|
-
|
|
49
|
+
~~~ ruby
|
|
50
|
+
lines = definition.documentation.text
|
|
51
|
+
puts lines
|
|
52
|
+
~~~
|
|
238
53
|
|
|
239
|
-
|
|
240
|
-
- Check out [Documentation Coverage](coverage.md) for coverage monitoring.
|
|
241
|
-
- Use decode to build code analysis tools for your projects.
|
|
242
|
-
- Integrate decode into your development workflow and CI/CD pipelines.
|
|
54
|
+
See {ruby Decode::Comment::Node#traverse} for more details about how to consume this data.
|
data/context/index.yaml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Automatically generated context index for Utopia::Project guides.
|
|
2
|
+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
|
|
3
|
+
---
|
|
4
|
+
description: Code analysis for documentation generation.
|
|
5
|
+
metadata:
|
|
6
|
+
documentation_uri: https://socketry.github.io/decode/
|
|
7
|
+
funding_uri: https://github.com/sponsors/socketry/
|
|
8
|
+
source_code_uri: https://github.com/socketry/decode.git
|
|
9
|
+
files:
|
|
10
|
+
- path: getting-started.md
|
|
11
|
+
title: Getting Started
|
|
12
|
+
description: This guide explains how to use `decode` for source code analysis.
|
|
13
|
+
- path: documentation-coverage.md
|
|
14
|
+
title: Documentation Coverage
|
|
15
|
+
description: This guide explains how to test and monitor documentation coverage
|
|
16
|
+
in your Ruby projects using the Decode gem's built-in bake tasks.
|
|
17
|
+
- path: ruby-documentation.md
|
|
18
|
+
title: Ruby Documentation
|
|
19
|
+
description: This guide covers documentation practices and pragmas supported by
|
|
20
|
+
the Decode gem for documenting Ruby code. These pragmas provide structured documentation
|
|
21
|
+
that can be parsed and used to generate API documentation and achieve complete
|
|
22
|
+
documentation coverage.
|
|
@@ -8,27 +8,27 @@ This guide covers documentation practices and pragmas supported by the Decode ge
|
|
|
8
8
|
|
|
9
9
|
#### Definition Documentation
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- Full sentences: All documentation for definitions (classes, modules, methods) should be written as complete sentences with proper grammar and punctuation.
|
|
12
|
+
- Class documentation: Documentation for classes should generally start with "Represents a ..." to clearly indicate what the class models or encapsulates.
|
|
13
|
+
- Method documentation: Should clearly describe what the method does, not how it does it.
|
|
14
|
+
- Markdown format: All documentation comments are written in Markdown format, allowing for rich formatting including lists, emphasis, code blocks, and links.
|
|
15
15
|
|
|
16
16
|
#### Inline Code Comments
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
18
|
+
- Explanatory comments: Comments within methods that explain specific lines or sections of code should end with a colon `:` to distinguish them from definition documentation.
|
|
19
|
+
- Purpose: These comments explain the reasoning behind specific implementation details.
|
|
20
20
|
|
|
21
21
|
#### Links and Code Formatting
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
- Curly braces `{}`: Use curly braces to create links to other methods, classes, or modules. The Decode gem uses `@index.lookup(text)` to resolve these references.
|
|
24
|
+
- Absolute references: `{Decode::Index#lookup}` - Links to a specific method in a specific class
|
|
25
|
+
- Relative references: `{lookup}` - Links to a method in the current scope or class
|
|
26
|
+
- Class references: `{User}` - Links to a class or module
|
|
27
|
+
- Backticks: Use backticks for code formatting of symbols, values, method names, and technical terms that should appear in monospace font.
|
|
28
|
+
- Symbols: `:admin`, `:user`, `:guest`
|
|
29
|
+
- Values: `true`, `false`, `nil`
|
|
30
|
+
- Technical terms: `attr_*`, `catch`/`throw`
|
|
31
|
+
- Code expressions: `**options`
|
|
32
32
|
|
|
33
33
|
#### Examples
|
|
34
34
|
|
|
@@ -98,14 +98,14 @@ end
|
|
|
98
98
|
|
|
99
99
|
### Best Practices
|
|
100
100
|
|
|
101
|
-
1.
|
|
102
|
-
2.
|
|
103
|
-
3.
|
|
104
|
-
4.
|
|
105
|
-
5.
|
|
106
|
-
6.
|
|
107
|
-
7.
|
|
108
|
-
8.
|
|
101
|
+
1. Be Consistent: Use the same format for similar types of documentation.
|
|
102
|
+
2. Include Types: Always specify types for parameters, returns, and attributes.
|
|
103
|
+
3. Be Descriptive: Provide clear, actionable descriptions.
|
|
104
|
+
4. Document Exceptions: Always document what exceptions might be raised.
|
|
105
|
+
5. Use Examples: Include usage examples when the behavior isn't obvious.
|
|
106
|
+
6. Keep Updated: Update documentation when you change the code.
|
|
107
|
+
7. Use @namespace wisely: Apply to organizational modules to achieve 100% coverage.
|
|
108
|
+
8. Avoid redundancy: For simple attributes and methods, attach descriptions directly to pragmas rather than repeating obvious information.
|
|
109
109
|
|
|
110
110
|
#### Simple Attributes and Methods
|
|
111
111
|
|
|
@@ -247,14 +247,14 @@ Documents block parameters and behavior.
|
|
|
247
247
|
|
|
248
248
|
```ruby
|
|
249
249
|
# @yields {|item| ...} Each item in the collection.
|
|
250
|
-
#
|
|
250
|
+
# @parameter item [Object] The current item being processed.
|
|
251
251
|
def each_item(&block)
|
|
252
252
|
items.each(&block)
|
|
253
253
|
end
|
|
254
254
|
|
|
255
255
|
# @yields {|user, index| ...} User and their index.
|
|
256
|
-
#
|
|
257
|
-
#
|
|
256
|
+
# @parameter user [User] The current user.
|
|
257
|
+
# @parameter index [Integer] The user's position in the list.
|
|
258
258
|
def each_user_with_index(&block)
|
|
259
259
|
users.each_with_index(&block)
|
|
260
260
|
end
|
|
@@ -308,6 +308,39 @@ def fetch_data
|
|
|
308
308
|
end
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
+
### Example Code
|
|
312
|
+
|
|
313
|
+
#### `@example Title?`
|
|
314
|
+
|
|
315
|
+
Includes an example usage snippet for a method or definition. The `@example` directive can have an optional title on the same line, followed by one or more indented lines of code:
|
|
316
|
+
|
|
317
|
+
```ruby
|
|
318
|
+
# @example Create a new thing
|
|
319
|
+
# thing = Thing.new
|
|
320
|
+
# thing.process
|
|
321
|
+
def process
|
|
322
|
+
# ...
|
|
323
|
+
end
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Behaviour:
|
|
327
|
+
|
|
328
|
+
- The optional title is captured verbatim (e.g., `"Create a new thing"`).
|
|
329
|
+
- Indented lines following the directive are captured as the example code.
|
|
330
|
+
- When parsed, examples are available as `Decode::Comment::Example` nodes with:
|
|
331
|
+
- `title` – `String?`, the optional example title.
|
|
332
|
+
- `text` – `Array(String)?`, the raw code lines (including leading indentation).
|
|
333
|
+
- `code` – `String?`, the code as a single string with leading indentation removed (convenience).
|
|
334
|
+
|
|
335
|
+
Multiple `@example` pragmas can be used on the same definition to show different scenarios.
|
|
336
|
+
|
|
337
|
+
```ruby
|
|
338
|
+
definition.documentation.filter(Decode::Comment::Example) do |example|
|
|
339
|
+
puts "Title: #{example.title.inspect}"
|
|
340
|
+
puts example.code # => joined string with indentation removed
|
|
341
|
+
end
|
|
342
|
+
```
|
|
343
|
+
|
|
311
344
|
### Namespace Documentation
|
|
312
345
|
|
|
313
346
|
#### `@namespace`
|