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

dendrodocs / dotnet-tool / 16829906524

08 Aug 2025 12:02PM UTC coverage: 64.525% (-1.6%) from 66.139%
16829906524

Pull #51

github

web-flow
Merge 63e9da058 into 47db85f2b
Pull Request #51: Add support for folder and glob pattern project selection

186 of 335 branches covered (55.52%)

Branch coverage included in aggregate %.

33 of 66 new or added lines in 3 files covered. (50.0%)

487 of 708 relevant lines covered (68.79%)

0.69 hits per line

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

0.85
/src/DendroDocs.Tool/Program.cs
1
using System.Diagnostics;
2
using System.Text.Json;
3

4
namespace DendroDocs.Tool;
5

6
public static partial class Program
7
{
8
    private static ParserResult<Options>? ParsedResults;
9

10
    public static Options RuntimeOptions { get; private set; } = new Options();
1✔
11

12
    public static async Task<int> Main(string[] args)
13
    {
×
14
        ParsedResults = Parser.Default.ParseArguments<Options>(args);
×
15

16
        var resultCode = await ParsedResults.MapResult(
×
17
            options => RunApplicationAsync(options),
×
18
            errors => Task.FromResult(1)
×
19
        );
×
20

21
        return resultCode;
×
22
    }
×
23

24
    private static async Task<int> RunApplicationAsync(Options options)
25
    {
×
26
        RuntimeOptions = options;
×
27

28
        var types = new List<TypeDescription>();
×
29

30
        var stopwatch = Stopwatch.StartNew();
×
31

32
        using (var analyzer = options.SolutionPath is not null
×
33
            ? AnalyzerSetup.BuildSolutionAnalyzer(options.SolutionPath, options.ExcludedProjectPaths)
×
NEW
34
            : options.ProjectPath is not null
×
NEW
35
            ? AnalyzerSetup.BuildProjectAnalyzer(options.ProjectPath!)
×
NEW
36
            : AnalyzerSetup.BuildFolderAnalyzer(options.FolderPath!, options.ExcludedProjectPaths))
×
37
        {
×
38
            await AnalyzeWorkspace(types, analyzer).ConfigureAwait(false);
×
39
        }
×
40

41
        stopwatch.Stop();
×
42

43
        // Write analysis 
44
        var serializerSettings = JsonDefaults.SerializerOptions();
×
45
        serializerSettings.WriteIndented = options.PrettyPrint;
×
46

47
        var result = JsonSerializer.Serialize(types.OrderBy(t => t.FullName), serializerSettings);
×
48
        File.WriteAllText(options.OutputPath!, result);
×
49

50
        if (!options.Quiet)
×
51
        {
×
52
            Console.WriteLine($"DendroDocs Analysis output generated in {stopwatch.ElapsedMilliseconds}ms at {options.OutputPath}");
×
53
            Console.WriteLine($"- {types.Count} types found");
×
54
        }
×
55

56
        // Validate the JSON output
57
        if (JsonValidator.ValidateJson(ref result, out var validationErrors))
×
58
        {
×
59
            if (!options.Quiet)
×
60
            {
×
61
                Console.WriteLine("- JSON is valid according to the schema.");
×
62
            }
×
63
        }
×
64
        else
65
        {
×
66
            if (!options.Quiet)
×
67
            {
×
68
                Console.WriteLine();
×
69
            }
×
70
            
71
            Console.Error.WriteLine("Generated JSON file is invalid. See errors below:");
×
72
            foreach (var error in validationErrors)
×
73
            {
×
74
                Console.Error.WriteLine($"- {error}");
×
75
            }
×
76

77
            return 1;
×
78
        }
79

80
        return 0;
×
81
    }
×
82

83
    private static async Task AnalyzeWorkspace(List<TypeDescription> types, AnalyzerSetup analysis)
84
    {
×
85
        foreach (var project in analysis.Projects)
×
86
        {
×
87
            await AnalyzeProjectAsyc(types, project).ConfigureAwait(false);
×
88
        }
×
89
    }
×
90

91
    private static async Task AnalyzeProjectAsyc(List<TypeDescription> types, Project project)
92
    {
×
93
        var compilation = await project.GetCompilationAsync().ConfigureAwait(false);
×
94
        if (compilation is null)
×
95
        {
×
96
            return;
×
97
        }
98

99
        if (RuntimeOptions.VerboseOutput)
×
100
        {
×
101
            var diagnostics = compilation.GetDiagnostics();
×
102
            if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
×
103
            {
×
104
                Console.WriteLine($"The following errors occured during compilation of project '{project.FilePath}'");
×
105
                foreach (var diagnostic in diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
×
106
                {
×
107
                    Console.WriteLine($"- {diagnostic}");
×
108
                }
×
109
            }
×
110
        }
×
111

112
        // Every file in the project
113
        foreach (var syntaxTree in compilation.SyntaxTrees)
×
114
        {
×
115
            var semanticModel = compilation.GetSemanticModel(syntaxTree, true);
×
116

117
            var visitor = new SourceAnalyzer(semanticModel, types);
×
118
            visitor.Visit(syntaxTree.GetRoot());
×
119
        }
×
120
    }
×
121
}
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

© 2025 Coveralls, Inc