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

lduchosal / ipnetwork / 23998941155

05 Apr 2026 09:43AM UTC coverage: 89.233% (-2.7%) from 91.952%
23998941155

push

travis-pro

lduchosal
feat: parse errors in formatter pipeline, action examples, llms.txt, bump 4.2.0

- Parse errors no longer write raw text to stdout; they are accumulated
  in ProgramContext.ParseErrors and rendered by the active formatter
- Errors display only the error message, not the full usage
- Each action in ArgsList now carries an example
- TextFormatter/JsonFormatter render examples in usage output
- Add llms.txt at repo root for LLM-friendly project documentation
- Bump version to 4.2.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

790 of 894 branches covered (88.37%)

Branch coverage included in aggregate %.

31 of 56 new or added lines in 7 files covered. (55.36%)

19 existing lines in 1 file now uncovered.

2177 of 2431 relevant lines covered (89.55%)

493340.3 hits per line

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

59.42
/src/ConsoleApplication/JsonFormatter.cs
1
// <copyright file="JsonFormatter.cs" company="IPNetwork">
2
// Copyright (c) IPNetwork. All rights reserved.
3
// </copyright>
4

5
namespace System.Net;
6

7
using System.Collections.Generic;
8
using System.IO;
9
using System.Text.Json;
10

11
/// <summary>
12
/// Renders action results as JSON.
13
/// </summary>
14
public class JsonFormatter : IFormatter
15
{
16
    private readonly TextWriter _textWriter;
17
    private Utf8JsonWriter _json = null!;
15✔
18

19
    /// <summary>
20
    /// Initializes a new instance of the <see cref="JsonFormatter"/> class.
21
    /// </summary>
22
    public JsonFormatter(TextWriter textWriter)
15✔
23
    {
15✔
24
        _textWriter = textWriter;
15✔
25
    }
15✔
26

27
    /// <inheritdoc/>
28
    public void Write(ActionOutput output, ProgramContext ac)
29
    {
15✔
30
        using var stream = new MemoryStream();
15✔
31
        using var json = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
15✔
32
        _json = json;
15✔
33

34
        json.WriteStartArray();
15✔
35
        output.WriteTo(this, ac);
15✔
36
        json.WriteEndArray();
15✔
37
        json.Flush();
15✔
38

39
        _textWriter.Write(System.Text.Encoding.UTF8.GetString(stream.ToArray()));
15✔
40
        _textWriter.WriteLine();
15✔
41
    }
30✔
42

43
    /// <inheritdoc/>
44
    public void Write(ActionOutput.Networks n, ProgramContext ac)
45
    {
8✔
46
        WriteNetworks(n.Items, ac);
8✔
47
    }
8✔
48

49
    /// <inheritdoc/>
50
    public void Write(ActionOutput.NetworkGroups g, ProgramContext ac)
51
    {
1✔
52
        for (int i = 0; i < g.Groups.Count; i++)
4✔
53
        {
1✔
54
            var group = g.Groups[i];
1✔
55
            if (group.Count == 0)
1!
56
            {
×
57
                _json.WriteStartObject();
×
58
                _json.WriteString("error",
×
59
                    $"Unable to subnet ipnetwork {g.InputNetworks[i]} into cidr {g.SubnetCidr}");
×
60
                _json.WriteEndObject();
×
61
            }
×
62
            else
63
            {
1✔
64
                _json.WriteStartArray();
1✔
65
                WriteNetworks(group, ac);
1✔
66
                _json.WriteEndArray();
1✔
67
            }
1✔
68
        }
1✔
69
    }
1✔
70

71
    /// <inheritdoc/>
72
    public void Write(ActionOutput.SubtractResults sub, ProgramContext ac)
73
    {
1✔
74
        WriteNetworks(sub.Items, ac);
1✔
75
    }
1✔
76

77
    /// <inheritdoc/>
78
    public void Write(ActionOutput.ContainResults c, ProgramContext ac)
79
    {
2✔
80
        foreach (var r in c.Items)
12✔
81
        {
3✔
82
            _json.WriteStartObject();
3✔
83
            _json.WriteString("network", r.Network);
3✔
84
            _json.WriteString("test", r.Test);
3✔
85
            _json.WriteBoolean("contains", r.Contains);
3✔
86
            _json.WriteEndObject();
3✔
87
        }
3✔
88
    }
2✔
89

90
    /// <inheritdoc/>
91
    public void Write(ActionOutput.OverlapResults o, ProgramContext ac)
92
    {
2✔
93
        foreach (var r in o.Items)
12✔
94
        {
3✔
95
            _json.WriteStartObject();
3✔
96
            _json.WriteString("network", r.Network);
3✔
97
            _json.WriteString("test", r.Test);
3✔
98
            _json.WriteBoolean("overlaps", r.Overlaps);
3✔
99
            _json.WriteEndObject();
3✔
100
        }
3✔
101
    }
2✔
102

103
    /// <inheritdoc/>
104
    public void Write(ActionOutput.IpAddresses ip, ProgramContext ac)
105
    {
1✔
106
        foreach (string addr in ip.Items)
11✔
107
        {
4✔
108
            _json.WriteStringValue(addr);
4✔
109
        }
4✔
110
    }
1✔
111

112
    /// <inheritdoc/>
113
    public void Write(ActionOutput.Error e, ProgramContext ac)
114
    {
×
115
        _json.WriteStartObject();
×
116
        _json.WriteString("error", e.Message);
×
117
        _json.WriteEndObject();
×
118
    }
×
119

120
    /// <inheritdoc/>
121
    public void Write(ActionOutput.UsageInfo usage, ProgramContext ac)
122
    {
×
NEW
123
        if (usage.Errors.Count > 0)
×
NEW
124
        {
×
NEW
125
            foreach (string error in usage.Errors)
×
NEW
126
            {
×
NEW
127
                _json.WriteStartObject();
×
NEW
128
                _json.WriteString("error", error);
×
NEW
129
                _json.WriteEndObject();
×
NEW
130
            }
×
131

NEW
132
            return;
×
133
        }
134

135
        _json.WriteStartObject();
×
136
        _json.WriteString("version", usage.Version);
×
137
        _json.WriteString("synopsis", usage.Synopsis);
×
138

139
        _json.WritePropertyName("optionGroups");
×
140
        _json.WriteStartArray();
×
141
        foreach (var group in usage.OptionGroups)
×
142
        {
×
143
            _json.WriteStartObject();
×
144
            _json.WriteString("name", group.Name);
×
145
            _json.WritePropertyName("options");
×
146
            _json.WriteStartArray();
×
147
            foreach (var opt in group.Options)
×
148
            {
×
149
                _json.WriteStartObject();
×
150
                _json.WriteString("flag", opt.Flag);
×
151
                if (opt.ArgName is not null)
×
152
                {
×
153
                    _json.WriteString("argName", opt.ArgName);
×
154
                }
×
155

156
                _json.WriteString("description", opt.Description);
×
NEW
157
                if (opt.Example is not null)
×
NEW
158
                {
×
NEW
159
                    _json.WriteString("example", opt.Example);
×
NEW
160
                }
×
161

162
                _json.WriteEndObject();
×
163
            }
×
164

165
            _json.WriteEndArray();
×
166
            _json.WriteEndObject();
×
167
        }
×
168

169
        _json.WriteEndArray();
×
170

171
        _json.WritePropertyName("positionalArgs");
×
172
        _json.WriteStartObject();
×
173
        _json.WriteString("name", "networks");
×
174
        _json.WriteString("description", usage.NetworksDescription);
×
175
        _json.WritePropertyName("examples");
×
176
        _json.WriteStartArray();
×
177
        foreach (string example in usage.NetworksExamples)
×
178
        {
×
179
            _json.WriteStringValue(example);
×
180
        }
×
181

182
        _json.WriteEndArray();
×
183
        _json.WriteEndObject();
×
184

185
        _json.WriteEndObject();
×
186
    }
×
187

188
    private void WriteNetworks(List<IPNetwork2> networks, ProgramContext ac)
189
    {
10✔
190
        foreach (var ipn in networks)
54✔
191
        {
12✔
192
            WriteNetwork(ipn, ac);
12✔
193
        }
12✔
194
    }
10✔
195

196
    private void WriteNetwork(IPNetwork2 ipn, ProgramContext ac)
197
    {
12✔
198
        _json.WriteStartObject();
12✔
199
        if (ac.IPNetwork) { _json.WriteString("ipnetwork", ipn.ToString()); }
42✔
200
        if (ac.Network) { _json.WriteString("network", ipn.Network?.ToString()); }
45!
201
        if (ac.Netmask) { _json.WriteString("netmask", ipn.Netmask?.ToString()); }
42!
202
        if (ac.Cidr) { _json.WriteNumber("cidr", ipn.Cidr); }
45✔
203

204
        if (ac.Broadcast)
12✔
205
        {
10✔
206
            if (ipn.Broadcast is not null)
10✔
207
            {
9✔
208
                _json.WriteString("broadcast", ipn.Broadcast.ToString());
9✔
209
            }
9✔
210
            else
211
            {
1✔
212
                _json.WriteNull("broadcast");
1✔
213
            }
1✔
214
        }
10✔
215

216
        if (ac.FirstUsable) { _json.WriteString("firstUsable", ipn.FirstUsable?.ToString()); }
42!
217
        if (ac.LastUsable) { _json.WriteString("lastUsable", ipn.LastUsable?.ToString()); }
42!
218
        if (ac.Usable) { _json.WriteString("usable", ipn.Usable.ToString()); }
42✔
219
        if (ac.Total) { _json.WriteString("total", ipn.Total.ToString()); }
45✔
220
        _json.WriteEndObject();
12✔
221
    }
12✔
222
}
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