mirror of
https://github.com/kjanat/articulate-parser.git
synced 2026-01-16 07:02:09 +01:00
5.0 KiB
5.0 KiB
Agent Guidelines for articulate-parser
A Go CLI tool that parses Articulate Rise courses from URLs or local JSON files and exports them to Markdown, HTML, or DOCX formats.
Build/Test Commands
Primary Commands (using Taskfile)
task build # Build binary to bin/articulate-parser
task test # Run all tests with race detection
task lint # Run all linters (vet, fmt, staticcheck, golangci-lint)
task fmt # Format all Go files
task ci # Full CI pipeline: deps, lint, test with coverage, build
task qa # Quick QA: fmt + lint + test
Direct Go Commands
# Build
go build -o bin/articulate-parser main.go
# Run all tests
go test -race -timeout 5m ./...
# Run single test by name
go test -v -race -run ^TestMarkdownExporter_Export$ ./internal/exporters
# Run tests in specific package
go test -v -race ./internal/services
# Run tests matching pattern
go test -v -race -run "TestParser" ./...
# Test with coverage
go test -race -coverprofile=coverage/coverage.out -covermode=atomic ./...
go tool cover -html=coverage/coverage.out -o coverage/coverage.html
# Benchmarks
go test -bench=. -benchmem ./...
go test -bench=BenchmarkMarkdownExporter ./internal/exporters
Security & Auditing
task security:check # Run gosec security scanner
task security:audit # Run govulncheck for vulnerabilities
Code Style Guidelines
Imports
- Use
goimportswith local prefix:github.com/kjanat/articulate-parser - Order: stdlib, blank line, external packages, blank line, internal packages
import (
"context"
"fmt"
"github.com/fumiama/go-docx"
"github.com/kjanat/articulate-parser/internal/interfaces"
)
Formatting
- Use
gofmt -s(simplify) andgofumptwith extra rules - Function length: max 100 lines, 50 statements
- Cyclomatic complexity: max 15; Cognitive complexity: max 20
Types & Naming
- Use interface-based design (see
internal/interfaces/) - Exported types/functions require godoc comments ending with period
- Use descriptive names:
ArticulateParser,MarkdownExporter - Receiver names: short (1-2 chars), consistent per type
Error Handling
- Always wrap errors with context:
fmt.Errorf("operation failed: %w", err) - Use
%wverb for error wrapping to preserve error chain - Check all error returns (enforced by
errcheck) - Document error handling rationale in defer blocks when ignoring close errors
// Good: Error wrapping with context
if err := json.Unmarshal(body, &course); err != nil {
return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
}
// Good: Documented defer with error handling
defer func() {
if err := resp.Body.Close(); err != nil {
p.Logger.Warn("failed to close response body", "error", err)
}
}()
Comments
- All exported types/functions require godoc comments
- End sentences with periods (
godotlinter enforced) - Mark known issues with TODO/FIXME/HACK/BUG/XXX
Security
- Use
#nosecwith justification for deliberate security exceptions - G304: File paths from CLI args; G306: Export file permissions
// #nosec G304 - File path provided by user via CLI argument
data, err := os.ReadFile(filePath)
Testing
- Enable race detection:
-raceflag always - Use table-driven tests where applicable
- Mark test helpers with
t.Helper() - Use
t.TempDir()for temporary files - Benchmarks in
*_bench_test.go, examples in*_example_test.go - Test naming:
Test<Type>_<Method>orTest<Function>
func TestMarkdownExporter_ProcessItemToMarkdown_AllTypes(t *testing.T) {
tests := []struct {
name, itemType, expectedText string
}{
{"text item", "text", ""},
{"divider item", "divider", "---"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// test implementation
})
}
}
Dependencies
- Minimal external dependencies (go-docx, golang.org/x/net, golang.org/x/text)
- Run
task deps:tidyafter adding/removing dependencies - CGO disabled by default (
CGO_ENABLED=0)
Project Structure
articulate-parser/
internal/
config/ # Configuration loading
exporters/ # Export implementations (markdown, html, docx)
interfaces/ # Core interfaces (Exporter, CourseParser, Logger)
models/ # Data models (Course, Lesson, Item, Media)
services/ # Core services (parser, html cleaner, app, logger)
version/ # Version information
main.go # Application entry point
Common Patterns
Creating a new exporter
- Implement
interfaces.Exporterinterface - Add factory method to
internal/exporters/factory.go - Register format in
NewFactory() - Add tests following existing patterns
Adding configuration options
- Add field to
Configstruct ininternal/config/config.go - Load from environment variable with sensible default
- Document in config struct comments