Documentation
¶
Overview ¶
Package output is the filesystem writer for gojira. It owns the per-issue directory layout, idempotency rules (skip-if-exists vs. refetch), and atomic write semantics. It knows nothing about Jira, ADF, Markdown content, or any other project-internal concern.
API design choice ¶
Write accepts plain parameters rather than a *config.Config so that callers (primarily internal/crawl) can pass only the two fields they need (OutputDir and Refetch) without importing the full config type into every test. The config package is still the canonical source of those values; the caller extracts them.
Atomic write strategy ¶
Each file is written to a temporary file in the same directory as the destination (e.g. index.md.tmp.<pid>), then renamed into place with os.Rename. Because source and destination are on the same filesystem, the rename is atomic on POSIX systems, so a crash mid-write cannot leave a half-written file at the canonical path.
references/ directory ¶
The references/ subdirectory is always created (0755) even when outboundMD is empty. This makes the directory structure predictable for downstream tools. The outbound.md file itself is only written when outboundMD is non-empty.
Key validation ¶
Jira issue keys match [A-Z][A-Z0-9]+-[0-9]+, which is filesystem-safe. This package rejects empty keys and keys that contain a path separator (/ or \) to prevent path-traversal attacks. It does not enforce the full Jira key regex — that is the caller's responsibility.
Package output is the filesystem writer for gojira. This file defines the Store interface, which decouples the crawl orchestrator from the concrete filesystem implementation.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyExists = errors.New("output: issue already exists on disk")
ErrAlreadyExists is returned by Write when the destination index.md already exists on disk and refetch is false. Callers can test for this with errors.Is.
Functions ¶
func IssueDir ¶
IssueDir returns the canonical per-issue directory path: filepath.Join(outputDir, key). Render and crawl packages use this to compute relative paths between issues without re-implementing the layout rule.
func Write ¶
Write creates the per-issue directory tree under outputDir and writes the rendered Markdown files for a single Jira issue.
Parameters:
- outputDir: root output directory (e.g. "/tmp/out").
- key: Jira issue key (e.g. "PROJ-1147"). Must be non-empty and must not contain a path separator.
- indexMD: content for <outputDir>/<key>/index.md.
- outboundMD: content for <outputDir>/<key>/references/outbound.md. If empty, the file is not created (but the references/ directory is still created).
- refetch: when false and index.md already exists, Write returns ErrAlreadyExists without touching any file. When true, existing files are overwritten.
Directory permissions: 0755. File permissions: 0644. Writes are atomic: a temp file is written then renamed into place.
Types ¶
type FSStore ¶ added in v0.2.0
FSStore is a Store implementation that writes Jira issue Markdown to the local filesystem. It delegates to Write, preserving atomic write semantics and skip-if-exists behaviour.
func NewFSStore ¶ added in v0.2.0
NewFSStore returns an FSStore rooted at outputDir. When refetch is false, Write returns ErrAlreadyExists if the issue's index.md already exists.
type Store ¶ added in v0.2.0
Store is the injectable output destination for a crawl run. Implementations are called exactly once per Jira issue and must not retain the content after Write returns.
Write persists the rendered Markdown for a single issue:
- key: Jira issue key (e.g. "PROJ-1147").
- indexMD: content for <key>/index.md.
- outboundMD: content for <key>/references/outbound.md. An empty string means no outbound file is written, but implementations should still create the references/ directory.
Write returns ErrAlreadyExists when the destination already exists and the implementation is configured to skip existing issues. Callers can test for this with errors.Is.