Component Interactions Diagrams
This document shows how specific components interact within DocBuilder, focusing on theme configuration, forge integration, and change detection.
Last Updated: January 4, 2026 - Reflects Relearn-only configuration.
Relearn Theme Configuration
DocBuilder uses the Relearn theme exclusively with hardcoded default configuration.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Relearn Theme Configuration β
β (internal/hugo/config_writer.go) β
β β
β applyRelearnThemeDefaults(params) β
β β
β Default Parameters: β
β - themeVariant: ["auto", "zen-light", "zen-dark"]β
β - themeVariantAuto: ["zen-light", "zen-dark"] β
β - showVisitedLinks: true β
β - collapsibleMenu: true β
β - alwaysopen: false β
β - disableBreadcrumb: false β
β - disableLandingPageButton: true β
β - disableShortcutsTitle: false β
β - disableLanguageSwitchingButton: true β
β - disableTagHiddenPages: false β
β - disableGeneratorVersion: false β
β - mermaid.enable: true β
β - math.enable: true β
β - enable_transitions: (if configured) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Generation Flow:
1. Load config β title, baseURL, etc.
2. Apply Relearn defaults (via applyRelearnThemeDefaults)
3. User params deep merge (user values override defaults)
4. Add dynamic fields (build_date, doc_builder_version)
5. Add Hugo module: github.com/McShelby/hugo-theme-relearn
6. Configure i18n settings (defaultContentLanguage: "en")
7. Write hugo.yaml to staging directory
Configuration Merging Strategy
Deep Merge Algorithm :
For each key in user params:
If value is map:
Recursively merge with default map
Else:
Override default value
Example:
Default: { mermaid: { enable: true, theme: "default" } }
User: { mermaid: { theme: "dark" } }
Result: { mermaid: { enable: true, theme: "dark" } }
Non-Overridable Settings :
Hugo module path: Always github.com/McShelby/hugo-theme-relearn
Language configuration: Always English (en)
Markup configuration: Goldmark with specific extensions
Theme-Specific Features
Auto Theme Variant :
Detects OS light/dark preference
Switches between configured variants
Default: zen-light (light) / zen-dark (dark)
Mermaid Diagrams :
Enabled by default
Supports flowcharts, sequence diagrams, Gantt charts
Theme-aware styling
Math Support (MathJax) :
Enabled by default
LaTeX-style equations
Inline: $equation$
Block: $$equation$$
Search :
Lunr.js-powered offline search
Searches titles, content, and tags
Automatically indexes all pages
Implementation Files
internal/hugo/config_writer.go - Configuration generation
internal/hugo/modules.go - Hugo module management
internal/config/typed/hugo_config.go - Configuration validation
Forge Integration
Forge clients provide repository metadata and edit link generation.
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Forge Factory β
β (internal/forge/factory.go) β
β β
β NewForge(config) β Forge β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
β Based on URL detection
β
ββββββββββββΌβββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββ ββββββββββ βββββββββββ
βGitHub β βGitLab β βForgejo β
βClient β βClient β βClient β
βββββ¬βββββ βββββ¬βββββ ββββββ¬βββββ
β β β
ββββββββββββ΄ββββββββββββ
β
β All compose
βΌ
βββββββββββββββ
β BaseForge β
β β
β HTTP Client β
β Auth Header β
β Base URL β
ββββββββ¬βββββββ
β
β Uses
βΌ
βββββββββββββββ
βhttp.Client β
β β
β- Timeout β
β- TLS Config β
β- Transport β
βββββββββββββββ
Forge Detection
URL-Based Detection :
Repository URL Analysis:
β
ββ Contains "github.com" β GitHubClient
ββ Contains "gitlab.com" β GitLabClient
ββ Contains "forgejo" β ForgejoClient
ββ Default β GenericForge
Configuration Priority :
Explicit forge.type in config (if provided)
URL pattern matching
API endpoint detection (if accessible)
Operation Flow
Edit Link Generation :
1. Document processed in pipeline
β
βΌ
2. addEditLink transform called
β
ββ Extract repository metadata
β ββ Repository URL
β ββ Source commit
β ββ Source branch
β
ββ Detect forge type
β ββ GitHubClient
β
ββ Build edit URL
β ββ Base: https://github.com/user/repo
β ββ Action: /edit/
β ββ Branch: main
β ββ Path: /docs/file.md
β Result: https://github.com/user/repo/edit/main/docs/file.md
β
ββ Inject into front matter
ββ editURL: https://...
API Integration (Future):
Forge Client
β
ββ Authenticate
β ββ Token header: "Authorization: Bearer {token}"
β ββ Custom headers (API version, User-Agent)
β
ββ Fetch Repository Metadata
β ββ GET /repos/{owner}/{repo}
β ββ Parse response
β ββ Return: name, description, default_branch
β
ββ Fetch Commit Info
ββ GET /repos/{owner}/{repo}/commits/{sha}
ββ Parse response
ββ Return: author, date, message
Forge-Specific Patterns
GitHub :
Edit URL: /{owner}/{repo}/edit/{branch}/{path}
API: https://api.github.com
Headers: X-GitHub-Api-Version: 2022-11-28
GitLab :
Edit URL: /{owner}/{repo}/-/edit/{branch}/{path}
API: https://gitlab.com/api/v4
Headers: PRIVATE-TOKEN: {token}
Forgejo :
Edit URL: /{owner}/{repo}/_edit/{branch}/{path}
API: https://forge.example.com/api/v1
Headers: Authorization: token {token}
Implementation Files
internal/forge/factory.go - Forge detection and creation
internal/forge/github/ - GitHub client
internal/forge/gitlab/ - GitLab client
internal/forge/forgejo/ - Forgejo client
internal/hugo/edit_link_resolver.go - Edit link generation
Change Detection System
Multi-level change detection optimizes incremental builds.
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Change Detector β
β (internal/hugo/doc_changes.go) β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β DetectChanges(repos)
βΌ
ββββββββββββββββββββββββ
β Load Previous State β
β - HEAD refs β
β - Doc hashes β
β - Commit dates β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β For each repository β
ββββββββββββ¬ββββββββββββ
β
ββ Level 1: HEAD Comparison
β ββ Read current HEAD
β ββ Compare to previous
β ββ Changed? β Include
β ββ Cost: O(1) - single git command
β
ββ Level 2: Quick Hash
β ββ Hash directory tree
β ββ Compare to previous
β ββ Changed? β Include
β ββ Cost: O(n) - filesystem scan
β
ββ Level 3: Doc Files Hash
β ββ Discover docs
β ββ Sort paths
β ββ SHA-256 hash
β ββ Compare to previous
β ββ Changed? β Include
β ββ Cost: O(n*m) - read file contents
β
ββ Level 4: Deletion Detection
ββ Compare file lists
ββ Detect removed files
ββ Deletions? β Include
ββ Cost: O(n) - set difference
βΌ
ββββββββββββββββββββββββ
β ChangeSet β
β β
β - ChangedRepos: [] β
β - SkippedRepos: [] β
β - Reasons: map[] β
β - RequiresRebuild β
ββββββββββββββββββββββββ
Change Detection Algorithm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
func DetectChanges ( repos [] Repository , prevState BuildState ) ChangeSet {
changeSet := NewChangeSet ()
for _ , repo := range repos {
// Level 1: HEAD comparison
currentHEAD := git . GetHEAD ( repo )
previousHEAD := prevState . Commits [ repo . Name ]
if currentHEAD != previousHEAD {
changeSet . AddChanged ( repo , "HEAD changed" )
continue
}
// Level 2: Quick directory hash
dirHash := computeDirectoryHash ( repo . Path )
prevHash := prevState . DirectoryHashes [ repo . Name ]
if dirHash != prevHash {
changeSet . AddChanged ( repo , "directory structure changed" )
continue
}
// Level 3: Documentation files hash
docs := DiscoverDocs ( repo )
docHash := computeDocHash ( docs )
prevDocHash := prevState . DocHashes [ repo . Name ]
if docHash != prevDocHash {
changeSet . AddChanged ( repo , "documentation changed" )
continue
}
// Level 4: Deletion detection
prevDocs := prevState . DocsByRepo [ repo . Name ]
if detectDeletions ( docs , prevDocs ) {
changeSet . AddChanged ( repo , "files deleted" )
continue
}
// No changes detected
changeSet . AddSkipped ( repo , "no changes" )
}
return changeSet
}
Optimization Strategies
Early Exit :
Stop at first detected change
Don’t compute expensive hashes if HEAD differs
Saves computation time
Caching :
Cache HEAD references
Cache directory hashes
Cache file content hashes
Reuse across builds
Parallel Detection :
Check multiple repositories concurrently
Use worker pool pattern
Aggregate results
Implementation Files
internal/hugo/doc_changes.go - Change detection logic
internal/hugo/early_skip.go - Early skip evaluation
internal/state/git_state.go - State persistence
internal/git/git.go - HEAD reference reading
Build State Management
Build state tracks progress and enables incremental builds.
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β BuildState β
β (internal/hugo/build_state.go) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β GitState β β
β β - WorkspaceDir: /tmp/docbuilder-xyz/ β β
β β - Repositories: []Repository β β
β β - Commits: map[repo]string β β
β β - CommitDates: map[repo]time.Time β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β DocsState β β
β β - Files: []DocFile β β
β β - IsSingleRepo: bool β β
β β - FilesByRepository: map[repo][]DocFile β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β PipelineState β β
β β - ConfigHash: string β β
β β - ExecutedStages: []string β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β BuildReport β β
β β - Status: BuildStatus β β
β β - StageDurations: map[stage]Duration β β
β β - Errors: []BuildIssue β β
β β - Warnings: []BuildIssue β β
β β - Summary: string β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β Generator β β
β β - Reference to Hugo generator β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
State Lifecycle
1. Initialization
β
ββ Create BuildState
ββ Initialize GitState
ββ Initialize DocsState
ββ Initialize PipelineState
ββ Create BuildReport
β
βΌ
2. Stage Execution
β
ββ For each stage:
β ββ Record start time
β ββ Execute stage function
β ββ Update sub-states
β ββ Record duration
β ββ Handle errors
β
βΌ
3. Persistence
β
ββ Serialize GitState
ββ Serialize DocsState
ββ Serialize PipelineState
ββ Write to .docbuilder/state.json
β
βΌ
4. Next Build
β
ββ Load previous state
ββ Compare for changes
ββ Decide incremental/full
State Update Patterns
GitState Updates :
1
2
3
4
5
6
// After cloning repository
bs . Git . Commits [ repo . Name ] = headCommit
bs . Git . CommitDates [ repo . Name ] = commitTime
// After all repos cloned
bs . Report . ClonedRepositories = len ( bs . Git . Commits )
DocsState Updates :
1
2
3
4
5
6
7
// After discovery
bs . Docs . Files = discoveredFiles
bs . Docs . IsSingleRepo = ( len ( repos ) == 1 )
bs . Docs . FilesByRepository = groupByRepo ( discoveredFiles )
// After processing
bs . Report . FilesProcessed = len ( bs . Docs . Files )
PipelineState Updates :
1
2
3
4
5
// After config generation
bs . Pipeline . ConfigHash = computeHash ( config )
// After each stage
bs . Pipeline . ExecutedStages = append ( bs . Pipeline . ExecutedStages , stageName )
Implementation Files
internal/hugo/build_state.go - BuildState definition
internal/state/git_state.go - Git-specific state
internal/state/docs_state.go - Documentation-specific state
internal/state/pipeline_state.go - Pipeline metadata
References
permalink[component-interactions-diagrams](https://docs.home.luguber.info/_uid/36766002-6e10-4a98-9c90-981b15fa6f99/)