• 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

58.06
/src/ConsoleApplication/TextFormatter.cs
1
// <copyright file="TextFormatter.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.Numerics;
10

11
/// <summary>
12
/// Renders action results as human-readable text.
13
/// </summary>
14
public class TextFormatter : IFormatter
15
{
16
    private readonly TextWriter _writer;
17

18
    /// <summary>
19
    /// Initializes a new instance of the <see cref="TextFormatter"/> class.
20
    /// </summary>
21
    public TextFormatter(TextWriter writer)
11✔
22
    {
11✔
23
        _writer = writer;
11✔
24
    }
11✔
25

26
    /// <inheritdoc/>
27
    public void Write(ActionOutput output, ProgramContext ac)
28
    {
11✔
29
        output.WriteTo(this, ac);
11✔
30
    }
11✔
31

32
    /// <inheritdoc/>
33
    public void Write(ActionOutput.Networks n, ProgramContext ac)
34
    {
6✔
35
        WriteNetworkList(n.Items, ac);
6✔
36
    }
6✔
37

38
    /// <inheritdoc/>
39
    public void Write(ActionOutput.NetworkGroups g, ProgramContext ac)
40
    {
1✔
41
        for (int i = 0; i < g.Groups.Count; i++)
4✔
42
        {
1✔
43
            var group = g.Groups[i];
1✔
44
            if (group.Count == 0)
1!
45
            {
×
46
                _writer.WriteLine("Unable to subnet ipnetwork {0} into cidr {1}", g.InputNetworks[i], g.SubnetCidr);
×
47
            }
×
48
            else
49
            {
1✔
50
                WriteNetworkList(group, ac);
1✔
51
            }
1✔
52

53
            WriteSeparator(g.Groups.Count, i + 1);
1✔
54
        }
1✔
55
    }
1✔
56

57
    /// <inheritdoc/>
58
    public void Write(ActionOutput.SubtractResults sub, ProgramContext ac)
59
    {
1✔
60
        foreach (var ipn in sub.Items)
13✔
61
        {
5✔
62
            _writer.WriteLine("{0}", ipn);
5✔
63
        }
5✔
64
    }
1✔
65

66
    /// <inheritdoc/>
67
    public void Write(ActionOutput.ContainResults c, ProgramContext ac)
68
    {
1✔
69
        foreach (var r in c.Items)
5✔
70
        {
1✔
71
            _writer.WriteLine("{0} contains {1} : {2}", r.Network, r.Test, r.Contains);
1✔
72
        }
1✔
73
    }
1✔
74

75
    /// <inheritdoc/>
76
    public void Write(ActionOutput.OverlapResults o, ProgramContext ac)
77
    {
1✔
78
        foreach (var r in o.Items)
5✔
79
        {
1✔
80
            _writer.WriteLine("{0} overlaps {1} : {2}", r.Network, r.Test, r.Overlaps);
1✔
81
        }
1✔
82
    }
1✔
83

84
    /// <inheritdoc/>
85
    public void Write(ActionOutput.IpAddresses ip, ProgramContext ac)
86
    {
×
87
        foreach (var ipnetwork in ip.InputNetworks)
×
88
        {
×
89
            if (ipnetwork.Cidr < 16)
×
90
            {
×
91
                Console.Error.WriteLine(
×
92
                    "WARNING: listing all IP addresses in {0} ({1} addresses). This may take a very long time.",
×
93
                    ipnetwork,
×
94
                    ipnetwork.Total);
×
95
            }
×
96
        }
×
97

98
        foreach (string addr in ip.Items)
×
99
        {
×
100
            _writer.WriteLine("{0}", addr);
×
101
        }
×
102
    }
×
103

104
    /// <inheritdoc/>
105
    public void Write(ActionOutput.Error e, ProgramContext ac)
106
    {
×
107
        _writer.WriteLine(e.Message);
×
108
    }
×
109

110
    /// <inheritdoc/>
111
    public void Write(ActionOutput.UsageInfo usage, ProgramContext ac)
112
    {
1✔
113
        if (usage.Errors.Count > 0)
1!
114
        {
1✔
115
            foreach (string error in usage.Errors)
7✔
116
            {
2✔
117
                _writer.WriteLine(error);
2✔
118
            }
2✔
119

120
            return;
1✔
121
        }
122

123
        _writer.WriteLine("Usage: {0}", usage.Synopsis);
×
124
        _writer.WriteLine("Version: {0}", usage.Version);
×
125

126
        foreach (var group in usage.OptionGroups)
×
127
        {
×
128
            _writer.WriteLine();
×
129
            _writer.WriteLine(group.Name);
×
130

131
            int maxWidth = 0;
×
132
            foreach (var opt in group.Options)
×
133
            {
×
134
                int width = 1 + opt.Flag.Length;
×
135
                if (opt.ArgName is not null)
×
136
                {
×
137
                    width += 1 + opt.ArgName.Length;
×
138
                }
×
139

140
                if (width > maxWidth)
×
141
                {
×
142
                    maxWidth = width;
×
143
                }
×
144
            }
×
145

146
            foreach (var opt in group.Options)
×
147
            {
×
148
                string flagPart = opt.ArgName is not null
×
149
                    ? $"-{opt.Flag} {opt.ArgName}"
×
150
                    : $"-{opt.Flag}";
×
151
                _writer.WriteLine("\t{0} : {1}", flagPart.PadRight(maxWidth), opt.Description);
×
NEW
152
                if (opt.Example is not null)
×
NEW
153
                {
×
NEW
154
                    _writer.WriteLine("\t{0}   {1}", new string(' ', maxWidth), opt.Example);
×
NEW
155
                }
×
156
            }
×
157
        }
×
158

159
        _writer.WriteLine();
×
160
        _writer.WriteLine("networks  : {0} ", usage.NetworksDescription);
×
161
        _writer.WriteLine("            ({0} )", string.Join(" ", usage.NetworksExamples));
×
162
    }
1✔
163

164
    private void WriteNetworkList(List<IPNetwork2> networks, ProgramContext ac)
165
    {
7✔
166
        for (int i = 0; i < networks.Count; i++)
552✔
167
        {
269✔
168
            WriteNetwork(networks[i], ac);
269✔
169
            WriteSeparator(networks.Count, i + 1);
269✔
170
        }
269✔
171
    }
7✔
172

173
    private void WriteNetwork(IPNetwork2 ipn, ProgramContext ac)
174
    {
269✔
175
        if (ac.IPNetwork) { _writer.WriteLine("IPNetwork   : {0}", ipn); }
1,070✔
176
        if (ac.Network) { _writer.WriteLine("Network     : {0}", ipn.Network); }
1,058✔
177
        if (ac.Netmask) { _writer.WriteLine("Netmask     : {0}", ipn.Netmask); }
1,058✔
178
        if (ac.Cidr) { _writer.WriteLine("Cidr        : {0}", ipn.Cidr); }
1,058✔
179
        if (ac.Broadcast) { _writer.WriteLine("Broadcast   : {0}", ipn.Broadcast); }
1,058✔
180
        if (ac.FirstUsable) { _writer.WriteLine("FirstUsable : {0}", ipn.FirstUsable); }
1,058✔
181
        if (ac.LastUsable) { _writer.WriteLine("LastUsable  : {0}", ipn.LastUsable); }
1,058✔
182
        if (ac.Usable) { _writer.WriteLine("Usable      : {0}", ipn.Usable); }
1,058✔
183
        if (ac.Total) { _writer.WriteLine("Total       : {0}", ipn.Total); }
1,052✔
184
    }
269✔
185

186
    private void WriteSeparator(BigInteger max, BigInteger index)
187
    {
270✔
188
        if (max > 1 && index != max)
270✔
189
        {
262✔
190
            _writer.WriteLine("--");
262✔
191
        }
262✔
192
    }
270✔
193
}
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