@@ -28,56 +28,56 @@ extension String : LocalizedError {
2828 public var errorDescription : String ? { self }
2929}
3030
31- fileprivate func findFiles( path: String , ext: String , skipsHiddenFiles: Bool , ignoreFilenameRegex: String ) throws -> [ URL ] {
32- var isDirectory : ObjCBool = false
33- guard FileManager . default. fileExists ( atPath: path, isDirectory: & isDirectory) else {
34- throw " Path not found. "
35- }
31+ public struct Coverage {
32+ let sources : [ Source ]
33+ let minAccessLevel : AccessLevel
34+ let output : Output
3635
37- if isDirectory. boolValue {
38- var urls = [ URL] ( )
39-
40- let regex : NSRegularExpression ? = ignoreFilenameRegex. isEmpty ? nil : try NSRegularExpression ( pattern: ignoreFilenameRegex)
36+ private static func files( path: String , ext: String , skipsHiddenFiles: Bool , ignoreFilenameRegex: String ) throws -> [ URL ] {
37+ var isDirectory : ObjCBool = false
38+ guard FileManager . default. fileExists ( atPath: path, isDirectory: & isDirectory) else {
39+ throw " Path not found. "
40+ }
4141
42- let url = URL ( fileURLWithPath: path)
43- let resourceKeys = Set < URLResourceKey > ( [ . nameKey, . isDirectoryKey] )
44- let options : FileManager . DirectoryEnumerationOptions = skipsHiddenFiles ? [ . skipsHiddenFiles] : [ ]
45- if let enumerator = FileManager . default. enumerator ( at: url, includingPropertiesForKeys: [ . isDirectoryKey, . isHiddenKey] , options: options) {
46- for case let fileURL as URL in enumerator {
47- guard let resourceValues = try ? fileURL. resourceValues ( forKeys: resourceKeys) ,
48- let isDirectory = resourceValues. isDirectory, !isDirectory,
49- let name = resourceValues. name,
50- name. hasSuffix ( ext)
51- else {
52- continue
53- }
54-
55- // Skip by regex
56- if let regex = regex {
57- let fileName = fileURL. lastPathComponent
58- let range = NSRange ( location: 0 , length: fileName. utf16. count)
59- if regex. firstMatch ( in: fileName, range: range) != nil {
42+ if isDirectory. boolValue {
43+ var urls = [ URL] ( )
44+
45+ let regex : NSRegularExpression ? = ignoreFilenameRegex. isEmpty ? nil : try NSRegularExpression ( pattern: ignoreFilenameRegex)
46+
47+ let url = URL ( fileURLWithPath: path)
48+ let resourceKeys = Set < URLResourceKey > ( [ . nameKey, . isDirectoryKey] )
49+ let options : FileManager . DirectoryEnumerationOptions = skipsHiddenFiles ? [ . skipsHiddenFiles] : [ ]
50+ if let enumerator = FileManager . default. enumerator ( at: url, includingPropertiesForKeys: [ . isDirectoryKey, . isHiddenKey] , options: options) {
51+ for case let fileURL as URL in enumerator {
52+ guard let resourceValues = try ? fileURL. resourceValues ( forKeys: resourceKeys) ,
53+ let isDirectory = resourceValues. isDirectory, !isDirectory,
54+ let name = resourceValues. name,
55+ name. hasSuffix ( ext)
56+ else {
6057 continue
6158 }
59+
60+ // Skip by regex
61+ if let regex = regex {
62+ let fileName = fileURL. lastPathComponent
63+ let range = NSRange ( location: 0 , length: fileName. utf16. count)
64+ if regex. firstMatch ( in: fileName, range: range) != nil {
65+ continue
66+ }
67+ }
68+
69+ urls. append ( fileURL)
6270 }
63-
64- urls. append ( fileURL)
6571 }
72+ return urls
6673 }
67- return urls
68- }
69-
70- guard path. hasSuffix ( ext) else {
71- throw " Not swift file. "
74+
75+ guard path. hasSuffix ( ext) else {
76+ throw " Not swift file. "
77+ }
78+ let url = URL ( fileURLWithPath: path)
79+ return [ url]
7280 }
73- let url = URL ( fileURLWithPath: path)
74- return [ url]
75- }
76-
77- public struct Coverage {
78- let urls : [ URL ]
79- let minAccessLevel : AccessLevel
80- let output : Output
8181
8282 private let dateComponentsFormatter : DateComponentsFormatter = {
8383 let formatter = DateComponentsFormatter ( )
@@ -87,12 +87,15 @@ public struct Coverage {
8787 } ( )
8888
8989 public init ( paths: [ String ] , skipsHiddenFiles: Bool = true , ignoreFilenameRegex: String = " " , minAccessLevel: AccessLevel = . public, output: Output = TerminalOutput ( ) ) throws {
90- self . urls = try paths. flatMap {
91- try findFiles ( path: $0, ext: " .swift " , skipsHiddenFiles: skipsHiddenFiles, ignoreFilenameRegex: ignoreFilenameRegex)
90+ self . sources = try paths. flatMap {
91+ try Self . files ( path: $0, ext: " .swift " , skipsHiddenFiles: skipsHiddenFiles, ignoreFilenameRegex: ignoreFilenameRegex)
9292 }
93- guard urls. count > 0 else {
93+ . map { try Source ( url: $0) }
94+
95+ guard sources. count > 0 else {
9496 throw " Swift files not found. "
9597 }
98+
9699 self . minAccessLevel = minAccessLevel
97100 self . output = output
98101 }
@@ -116,33 +119,37 @@ public struct Coverage {
116119 }
117120
118121 @discardableResult
119- func report( _ body: ( ( SourceReport , TimeInterval ) -> Void ) ? = nil ) throws -> CoverageReport {
120- precondition ( urls . count > 0 )
122+ public func report( _ body: ( ( SourceReport , TimeInterval ) -> Void ) ? = nil ) throws -> CoverageReport {
123+ precondition ( sources . count > 0 )
121124
122- var sources = [ SourceReport] ( )
125+ var sourceReports = [ SourceReport] ( )
123126
124- try urls . forEach { url in
127+ sources . forEach { source in
125128 let time = Date ( )
126129
127- let source = try Source ( fileURL: url, minAccessLevel: minAccessLevel)
128130 guard source. declarations. count > 0 else {
129131 return
130132 }
131133
132- let undocumented = source. undocumented. map { DeclarationReport ( line: $0. line, column: $0. column, name: $0. name) }
133- let sourceReport = SourceReport ( path: url. path,
134- totalCount: source. declarations. count,
135- undocumented: undocumented)
136- sources. append ( sourceReport)
134+ let declarations = source. declarations. filter { $0. accessLevel. rawValue <= self . minAccessLevel. rawValue }
135+
136+ let undocumented : [ DeclarationReport ] = declarations
137+ . filter {
138+ $0. comments. contains { $0. hasDoc == false }
139+ }
140+ . map { DeclarationReport ( line: $0. line, column: $0. column, name: $0. name) }
141+
142+ let sourceReport = SourceReport ( path: source. url!. absoluteString, totalCount: source. declarations. count, undocumented: undocumented)
143+ sourceReports. append ( sourceReport)
137144
138145 body ? ( sourceReport, - time. timeIntervalSinceNow)
139146 }
140147
141- guard sources . count > 0 else {
148+ guard sourceReports . count > 0 else {
142149 throw " Declarations not found. "
143150 }
144151
145- return CoverageReport ( sources: sources )
152+ return CoverageReport ( sources: sourceReports )
146153 }
147154
148155 public func reportStatistics( ) throws {
0 commit comments