render

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package render converts a parsed Jira issue into Markdown content.

Design boundary

render is a pure package: no network calls, no filesystem access. It accepts a parse.Issue value and produces Markdown strings. The caller (internal/crawl or the gojira facade) is responsible for writing those strings to disk via internal/output.

render imports only internal/parse and internal/adf. It deliberately does NOT import classify. Link classification is the caller's responsibility: the caller must pre-classify outbound references and pass them in as []OutboundRef. The mapping from classify.Kind constants to the string labels used by OutboundRef.Kind ("jira", "github-pr", "external") is the caller's responsibility and must be documented at the call site.

Neighbour resolution

RenderIssue accepts a neighbours map (issue key → true) representing the set of issue keys that have already been downloaded. When a relationship link target key is present in neighbours, the rendered link is a relative Markdown path (../KEY/index.md). When the key is absent from neighbours (unresolved, permission-denied, or cap-limited), the rendered link falls back to an absolute Jira browse URL derived from the issue's own SourceURL base. If SourceURL is empty, the key is rendered as plain text with no hyperlink.

Unknown ADF node visibility

When adf.RenderMarkdown encounters an unknown node type it emits an inline Markdown comment (<!-- adf: unknown node type "..." -->) and preserves any inner text. RenderIssue additionally appends an "## Unknown content" section listing each unknown node type. This maximises visibility of preserved-but-unrendered content in v0.1 and can be removed once the ADF renderer covers all node types in use.

Section elision

Sections with no content are omitted entirely from the output. The Relationships heading is omitted when all subsections (Parent, Sub-tasks, Children, Linked issues, Remote links) are empty. The Custom fields section is omitted when issue.CustomFields is empty. The Unknown content section is omitted when adf.RenderMarkdown returns no unknown nodes.

Sub-tasks vs. Children

Two relationship subsections render Jira's two distinct child concepts:

  • "### Sub-tasks" lists issue.Subtasks, the legacy Jira "Sub-task" type children returned inline on the parent's GET response.
  • "### Children" lists issue.Children, the modern hierarchy children discovered by internal/crawl via JQL search (parent = "KEY" and, where the Epic Link field exists, "Epic Link" = "KEY") after the issue has been parsed.

Earlier versions of gojira rendered issue.Subtasks under "### Children". The rename clarifies the distinction and matches Jira's own vocabulary; it is documented in the package change log of the design mini-doc (v4).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RenderIssue

func RenderIssue(issue parse.Issue, neighbours map[string]bool, renderNullCustomFields bool) (string, error)

RenderIssue produces the Markdown content for <KEY>/index.md.

neighbours is the set of already-downloaded issue keys. A key present in neighbours gets a relative link (../KEY/index.md); an absent key gets an absolute Jira browse URL (derived from issue.SourceURL) or plain text if SourceURL is empty.

renderNullCustomFields toggles the behaviour of the "## Custom fields" section when a custom field's JSON value is `null`:

  • false (default): null-valued custom fields are skipped entirely. On a typical Jira tenant the vast majority of customfield_* entries are null per issue, so suppressing them removes the noise without losing information.
  • true: each null-valued custom field renders as `- <label>: null`, preserving every field's presence for audits.

The flag is a positional bool rather than an options struct because it is the only renderer toggle today; the project's signature- honesty rule (docs/engineering-principles.md) prefers an explicit parameter to a hidden constant. Add an options struct if a third toggle ever lands.

Sections with no content are omitted. The Relationships heading is omitted when all subsections are empty. The Custom fields section is omitted when every entry would be elided (default config + all-null fields) or when issue.CustomFields is empty. The Unknown content section is omitted when the ADF renderer encounters no unknown nodes.

func RenderIssueJSON added in v0.2.0

func RenderIssueJSON(issue parse.Issue, refs []extract.Reference) (string, error)

RenderIssueJSON serialises issue and refs to indented JSON.

It is a pure function: no I/O, no side effects. The caller is responsible for writing the returned string to disk.

The output is produced by json.MarshalIndent with prefix "" and indent " " (two spaces), consistent with the project's JSON formatting convention.

func RenderOutbound

func RenderOutbound(refs []OutboundRef) (string, error)

RenderOutbound produces the Markdown content for <KEY>/references/outbound.md.

refs is a slice of pre-classified outbound references. The caller is responsible for populating refs with the correct Kind labels.

Sections with no content are omitted. If refs is empty, an empty string is returned with no error — the caller (internal/output) treats an empty string as "do not create outbound.md".

func RenderStub

func RenderStub(key string, reason string, sourceURL string) (string, error)

RenderStub produces the Markdown content for <KEY>/index.md when the issue could not be fetched (e.g. 403 Permission denied or 404 Not found).

The stub format is:

# KEY

> Could not fetch: <reason>

- Source: [KEY](<jiraBrowseURL>)  (omitted when sourceURL is empty)

reason is a human-readable string supplied by the caller, e.g. "Permission denied (403)" or "Not found (404)".

Types

type IssueWithRefs added in v0.2.0

type IssueWithRefs struct {
	Issue      parse.Issue         `json:"issue"`
	References []extract.Reference `json:"references"`
}

IssueWithRefs combines a parsed Jira issue and its discovered outbound references into a single value suitable for JSON serialisation.

type OutboundRef

type OutboundRef struct {
	// Kind is one of "jira", "github-pr", or "external".
	Kind string

	// IssueKey is the Jira issue key for Kind=="jira" references.
	IssueKey string

	// URL is the raw URL for "github-pr" and "external" references.
	URL string

	// Text is the display label for "external" references. If empty, URL is
	// used as the label.
	Text string

	// Owner, Repo, PRNumber are set for Kind=="github-pr" references.
	Owner    string
	Repo     string
	PRNumber int
}

OutboundRef is a pre-classified outbound reference passed to RenderOutbound by the caller. render does not import classify; the caller is responsible for mapping classify.Kind constants to the Kind string labels below.

Kind values:

  • "jira" — a Jira issue reference (IssueKey is set)
  • "github-pr" — a GitHub pull request (Owner, Repo, PRNumber are set)
  • "external" — any other URL (URL and Text are set)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL