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

samsmithnz / DotNetCensus / 4773330594

pending completion
4773330594

Pull #90

github

GitHub
Merge 6991c8b68 into 0b3e1d200
Pull Request #90: Code gardening

444 of 486 branches covered (91.36%)

Branch coverage included in aggregate %.

75 of 75 new or added lines in 9 files covered. (100.0%)

912 of 959 relevant lines covered (95.1%)

934.72 hits per line

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

93.16
/src/DotNetCensus.Core/Projects/RepoScanning.cs
1
using DotNetCensus.Core.APIs;
2
using DotNetCensus.Core.Models;
3
using DotNetCensus.Core.Models.GitHub;
4
using System.Text;
5

6
namespace DotNetCensus.Core.Projects
7
{
8
    public static class RepoScanning
9
    {
10
        public async static Task<List<Project>> SearchRepo(string? clientId, string? clientSecret,
11
            string owner, string repository, string branch = "main")
12
        {
7✔
13
            //Get all files for the current repo, looking for projects
14
            List<Project> repoProjects = await GitHubAPI.GetRepoFiles(clientId, clientSecret,
7✔
15
                   owner, repository, branch);
7✔
16

17
            //Recreate the folder structure with the primary directory, sub-directories, and any files. 
18
            RepoDirectory baseDir = CreateRepoDirectoryStructure(repoProjects);
7✔
19

20
            //Recursively search directories until a project file is found
21
            List<Project> projects = new();
7✔
22
            if (baseDir != null && baseDir.Path != null)
7!
23
            {
7✔
24
                projects = await SearchRepoDirectory(baseDir, baseDir.Path,
7✔
25
                    clientId, clientSecret,
7✔
26
                    owner, repository, branch);
7✔
27
            }
7✔
28

29
            return projects;
7✔
30
        }
7✔
31

32
        private async static Task<List<Project>> SearchRepoDirectory(RepoDirectory baseDir, string fullPath,
33
            string? clientId, string? clientSecret,
34
            string owner, string repository, string branch,
35
            string? directoryBuildPropFileContent = null,
36
            int currentRecursionLevel = 1)
37
        {
332✔
38
            List<Project> projects = new();
332✔
39
            bool foundProjectFile = false;
332✔
40
            System.Diagnostics.Debug.WriteLine("Processing " + baseDir.Name + " at " + fullPath);
332✔
41

42
            StringBuilder newDirectoryBuildPropFileContent = new();
332✔
43
            if (directoryBuildPropFileContent != null)
332✔
44
            {
325✔
45
                newDirectoryBuildPropFileContent.Append(directoryBuildPropFileContent);
325✔
46
            }
325✔
47

48
            //Now that the files are arranged in a directory/tree-like structure, start the simulated search
49
            if (baseDir.Files.Count > 0)
332✔
50
            {
282✔
51
                foreach (string file in baseDir.Files)
1,458✔
52
                {
306✔
53
                    if (ProjectClassification.IsProjectFile(file))
306✔
54
                    {
240✔
55
                        FileInfo fileInfo = new(file);
240✔
56
                        string filePath = (fullPath + "/" + file).Replace("//", "/");
240✔
57
                        FileDetails? fileDetails = await GitHubAPI.GetRepoFileContents(clientId, clientSecret,
240✔
58
                               owner, repository, filePath, branch);
240✔
59
                        List<Project> directoryProjects = ProjectFileProcessing.SearchProjectFile(fileInfo, filePath, fileDetails?.content, newDirectoryBuildPropFileContent.ToString());
240!
60
                        if (directoryProjects.Count > 0)
240✔
61
                        {
240✔
62
                            projects.AddRange(directoryProjects);
240✔
63
                            foundProjectFile = true;
240✔
64
                        }
240✔
65
                    }
240✔
66
                }
306✔
67

68
                //If we didn't find projects in the initial pass, do a secondary pass looking for more obscurce and older projects
69
                if (!foundProjectFile)
282✔
70
                {
42✔
71
                    foreach (string file in baseDir.Files)
192✔
72
                    {
42✔
73
                        FileInfo fileInfo = new(file);
42✔
74
                        if (ProjectClassification.IsProjectFile(file, false))
42✔
75
                        {
18✔
76
                            foundProjectFile = true;
18✔
77
                            string filePath = (fullPath + "/" + file).Replace("//", "/");
18✔
78
                            FileDetails? fileDetails = await GitHubAPI.GetRepoFileContents(clientId, clientSecret,
18✔
79
                                   owner, repository, filePath, branch);
18✔
80
                            if (fileDetails != null)
18!
81
                            {
18✔
82
                                List<Project> directoryProjects = ProjectFileProcessing.SearchSecondaryProjects(fileInfo, filePath, fileDetails?.content);
18!
83
                                if (directoryProjects.Count > 0)
18!
84
                                {
18✔
85
                                    projects.AddRange(directoryProjects);
18✔
86
                                    foundProjectFile = true;
18✔
87
                                    break;
18✔
88
                                }
89
                            }
×
90
                        }
×
91
                    }
24✔
92
                }
42✔
93
            }
282✔
94

95
            //If we still didn't find a project, then look deeper in the sub-directories.
96
            if (!foundProjectFile)
332✔
97
            {
74✔
98
                //Check for a Directory.Build.props file first
99
                foreach (string file in baseDir.Files)
246✔
100
                {
24✔
101
                    if (file == "Directory.Build.props")
24!
102
                    {
24✔
103
                        string filePath = (fullPath + "/" + file).Replace("//", "/");
24✔
104
                        FileDetails? fileDetails = await GitHubAPI.GetRepoFileContents(clientId, clientSecret,
24✔
105
                               owner, repository, filePath, branch);
24✔
106
                        if (fileDetails != null)
24✔
107
                        {
24✔
108
                            newDirectoryBuildPropFileContent.Append(fileDetails.content);
24✔
109
                        }
24✔
110
                        break;
24✔
111
                    }
112
                }
×
113
                HashSet<string> foldersDone = new();
74✔
114
                foreach (RepoDirectory subDirectory in baseDir.Directories)
872✔
115
                {
325✔
116
                    string filePath = (fullPath + "/" + subDirectory.Name).Replace("//", "/");
325✔
117
                    List<Project> projects2 = await SearchRepoDirectory(subDirectory, filePath,
325✔
118
                        clientId, clientSecret,
325✔
119
                        owner, repository, branch,
325✔
120
                        newDirectoryBuildPropFileContent.ToString(),
325✔
121
                        currentRecursionLevel + 1);
325✔
122
                    if (subDirectory != null && subDirectory.Name != null &&
325!
123
                        projects2.Count > 0 &&
325✔
124
                        !foldersDone.Contains(subDirectory.Name))
325✔
125
                    {
325✔
126
                        projects.AddRange(projects2);
325✔
127
                        foldersDone.Add(subDirectory.Name);
325✔
128
                        //break;
129
                    }
325✔
130
                }
325✔
131
            }
74✔
132

133
            return projects;
332✔
134
        }
332✔
135

136
        public static RepoDirectory CreateRepoDirectoryStructure(List<Project> projects)
137
        {
11✔
138
            //Create a base repo directory
139
            RepoDirectory baseDir = new()
11✔
140
            {
11✔
141
                Name = "",
11✔
142
                Path = "/"
11✔
143
            };
11✔
144

145
            //Loop through every project.
146
            foreach (Project project in projects)
741✔
147
            {
354✔
148
                //Look at each level of the path
149
                string[] dirs = (project.Path + project.FileName).Split('/');
354✔
150
                //Drop any empty items from the array
151
                dirs = CleanArrayOfEmptyValues(dirs);
354✔
152
                Queue<string> dirQueue = new(dirs);
354✔
153

154
                if (dirQueue.Count > 1)
354✔
155
                {
353✔
156
                    ParseDirectorys(baseDir, dirQueue);
353✔
157
                }
353✔
158
                else if (dirQueue.Count == 1)
1✔
159
                {
1✔
160
                    baseDir.Files.Add(dirQueue.Dequeue());
1✔
161
                }
1✔
162
            }
354✔
163
            return baseDir;
11✔
164
        }
11✔
165

166
        private static void ParseDirectorys(RepoDirectory? baseDir, Queue<string> dirQueue)
167
        {
1,084✔
168
            string name = dirQueue.Dequeue();
1,084✔
169

170
            if (baseDir != null)
1,084✔
171
            {
1,084✔
172
                //Add any directories missing
173
                if (!baseDir.Directories.Any(r => r.Name == name))
5,745✔
174
                {
369✔
175
                    baseDir.Directories.Add(new()
369✔
176
                    {
369✔
177
                        Name = name,
369✔
178
                        Path = baseDir.Path + name + "/"
369✔
179
                    });
369✔
180
                }
369✔
181

182
                //If there are still items to process, recursively add sub directories
183
                if (dirQueue.Count > 1 && baseDir != null && baseDir.Directories != null)
1,084✔
184
                {
731✔
185
                    ParseDirectorys(baseDir.Directories.Find(r => r.Name == name), dirQueue);
1,882✔
186
                }
731✔
187
                else if (dirQueue.Count == 1 &&
353!
188
                    baseDir != null &&
353✔
189
                    baseDir.Directories != null)
353✔
190
                {
353✔
191
                    //Add files in the correct directory position
192
                    baseDir?.Directories?.Find(r => r.Name == name)?.Files.Add(dirQueue.Dequeue());
4,232!
193
                }
353✔
194
            }
1,084✔
195
        }
1,084✔
196

197
        //Clean a string array of any empty/"" or null values
198
        private static string[] CleanArrayOfEmptyValues(string[] array)
199
        {
354✔
200
            List<string> items = new(array);
354✔
201
            for (int i = items.Count - 1; i >= 0; i--)
3,586✔
202
            {
1,439✔
203
                if (string.IsNullOrEmpty(items[i]))
1,439✔
204
                {
1✔
205
                    items.RemoveAt(i);
1✔
206
                }
1✔
207
            }
1,439✔
208
            return items.ToArray();
354✔
209
        }
354✔
210

211
    }
212
}
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