• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fogfish / iq / 19150632324

06 Nov 2025 09:35PM UTC coverage: 40.252%. First build
19150632324

Pull #26

github

fogfish
improve ci/cd auto versioning
Pull Request #26: Compose AI workflow within the shell

1095 of 2628 new or added lines in 34 files covered. (41.67%)

1119 of 2780 relevant lines covered (40.25%)

0.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.66
/internal/iosystem/processor/jsonify.go
1
//
2
// Copyright (C) 2025 Dmitry Kolesnikov
3
//
4
// This file may be modified and distributed under the terms
5
// of the MIT license.  See the LICENSE file for details.
6
// https://github.com/fogfish/iq
7
//
8

9
package processor
10

11
import (
12
        "bytes"
13
        "context"
14
        "encoding/json"
15
        "fmt"
16
        "io"
17

18
        "github.com/TylerBrock/colorjson"
19
        "github.com/fogfish/iq/internal/iosystem"
20
)
21

22
// Jsonify is a processor that formats JSON documents with color and indentation.
23
// It only processes documents with content-type "application/json" in metadata.
24
// Other documents are passed through unchanged.
25
//
26
// The processor:
27
//   - Checks document metadata for "content-type"
28
//   - Formats JSON with color syntax highlighting
29
//   - Pretty-prints with configurable indentation
30
//   - Passes through non-JSON documents unchanged
31
//
32
// Example:
33
//
34
//        proc := NewJSONFormatter(JSONFormatConfig{
35
//            Indent: 2,
36
//            Color:  true,
37
//        })
38
//        docs, err := proc.Process(ctx, inputDoc)
39
type Jsonify struct {
40
        config JsonifyConfig
41
}
42

43
// JsonifyConfig configures the JSON formatter processor.
44
type JsonifyConfig struct {
45
        Indent int  // Number of spaces for indentation (default: 2)
46
        Color  bool // Enable color syntax highlighting (default: true)
47
}
48

49
// NewJsonify creates a processor that formats JSON documents.
50
func NewJsonify(config JsonifyConfig) *Jsonify {
1✔
51
        // Set defaults
1✔
52
        if config.Indent == 0 {
1✔
NEW
53
                config.Indent = 2
×
NEW
54
        }
×
55

56
        return &Jsonify{
1✔
57
                config: config,
1✔
58
        }
1✔
59
}
60

61
// Process formats a JSON document with color and indentation.
62
// Only processes documents with content-type "application/json".
63
// Other documents are passed through unchanged.
64
func (p *Jsonify) Process(ctx context.Context, doc *iosystem.Document) ([]*iosystem.Document, error) {
1✔
65
        if doc == nil {
1✔
NEW
66
                return nil, fmt.Errorf("document is nil")
×
NEW
67
        }
×
68

69
        // Check if document is JSON
70
        contentType := doc.Type
1✔
71
        if contentType != iosystem.ContentJSON {
2✔
72
                return []*iosystem.Document{doc}, nil
1✔
73
        }
1✔
74

75
        // Read document content
76
        content, err := io.ReadAll(doc.Reader)
1✔
77
        if err != nil {
1✔
NEW
78
                // On read error, pass through unchanged
×
NEW
79
                doc.Reader = bytes.NewReader(content)
×
NEW
80
                return []*iosystem.Document{doc}, nil
×
NEW
81
        }
×
82

83
        // Parse JSON to validate and prepare for formatting
84
        var obj any
1✔
85
        if err := json.Unmarshal(content, &obj); err != nil {
2✔
86
                // Invalid JSON, pass through unchanged
1✔
87
                doc.Reader = bytes.NewReader(content)
1✔
88
                return []*iosystem.Document{doc}, nil
1✔
89
        }
1✔
90

91
        // Format JSON with color
92
        var formatted []byte
1✔
93
        if p.config.Color {
2✔
94
                f := colorjson.NewFormatter()
1✔
95
                f.Indent = p.config.Indent
1✔
96
                formatted, err = f.Marshal(obj)
1✔
97
                if err != nil {
1✔
NEW
98
                        return nil, fmt.Errorf("failed to format JSON for '%s': %w", doc.Path, err)
×
NEW
99
                }
×
100
        } else {
1✔
101
                // Format without color (standard pretty-print)
1✔
102
                formatted, err = json.MarshalIndent(obj, "", bytesIndent(p.config.Indent))
1✔
103
                if err != nil {
1✔
NEW
104
                        return nil, fmt.Errorf("failed to format JSON for '%s': %w", doc.Path, err)
×
NEW
105
                }
×
106
        }
107

108
        // Create output document
109
        out := &iosystem.Document{
1✔
110
                Type:     doc.Type,
1✔
111
                Path:     doc.Path,
1✔
112
                Reader:   bytes.NewReader(formatted),
1✔
113
                Metadata: copyMetadata(doc.Metadata),
1✔
114
        }
1✔
115

1✔
116
        return []*iosystem.Document{out}, nil
1✔
117
}
118

119
// Close releases resources. For JSONFormatter, this is a no-op.
120
func (p *Jsonify) Close() error {
1✔
121
        return nil
1✔
122
}
1✔
123

124
// bytesIndent creates an indentation string with n spaces.
125
func bytesIndent(n int) string {
1✔
126
        indent := make([]byte, n)
1✔
127
        for i := range indent {
2✔
128
                indent[i] = ' '
1✔
129
        }
1✔
130
        return string(indent)
1✔
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc