CommandLineToolkit

Форк
0
91 строка · 2.8 Кб
1
import FileSystem
2
import Foundation
3
import PathLib
4
import ProcessController
5

6
public final class ClocTool: Cloc {
7
    private let filePropertiesProvider: FilePropertiesProvider
8
    private let processControllerProvider: ProcessControllerProvider
9
    
10
    private struct ClocOutput: Codable, CustomStringConvertible {
11
        struct SUM: Codable {
12
            let code: Int
13
        }
14
        
15
        let SUM: SUM
16
        
17
        var description: String {
18
            "sum.code=\(self.SUM.code)"
19
        }
20
    }
21
    
22
    public init(
23
        filePropertiesProvider: FilePropertiesProvider,
24
        processControllerProvider: ProcessControllerProvider
25
    ) {
26
        self.filePropertiesProvider = filePropertiesProvider
27
        self.processControllerProvider = processControllerProvider
28
    }
29
    
30
    private let clocBinaryPaths = [
31
        AbsolutePath("/usr/local/bin/cloc"),
32
        AbsolutePath("/opt/homebrew/bin/cloc"),
33
    ]
34
    
35
    public func countLinesOfCode(
36
        sourceFiles: [AbsolutePath],
37
        includeLangOptions: Set<IncludeLangOption>
38
    ) throws -> Int {
39
        for clocBinaryPath in clocBinaryPaths {
40
            if !filePropertiesProvider.exists(path: clocBinaryPath) {
41
                continue
42
            }
43
            
44
            if try filePropertiesProvider.properties(path: clocBinaryPath).isExecutable {
45
                return try run(
46
                    clocBinaryPath: clocBinaryPath,
47
                    sourceFiles: sourceFiles,
48
                    includeLangOptions: includeLangOptions
49
                )
50
            }
51
        }
52
        
53
        throw "Could not locate cloc binary"
54
    }
55
    
56
    private func run(
57
        clocBinaryPath: AbsolutePath,
58
        sourceFiles: [AbsolutePath],
59
        includeLangOptions: Set<IncludeLangOption>
60
    ) throws -> Int {
61
        do {
62
            let processController = try processControllerProvider.createProcessController(
63
                subprocess: Subprocess(
64
                    arguments: [
65
                        clocBinaryPath,
66
                        "--json",
67
                        "--include-lang=\(includeLangOptions.map(\.rawValue).joined(separator: ","))"
68
                    ] + sourceFiles
69
                )
70
            )
71
            var clocOutput = Data()
72
            processController.onStdout { _, data, _ in clocOutput.append(contentsOf: data) }
73

74
            try processController.startAndWaitForSuccessfulTermination()
75

76
            if let parsedOutput = try? JSONDecoder().decode(ClocOutput.self, from: clocOutput) {
77
                return parsedOutput.SUM.code
78
            } else {
79
                return 0
80
            }
81
        } catch {
82
            throw """
83
            Failed to get cloc
84
            from \(sourceFiles)
85
            using \(clocBinaryPath)
86
            for \(includeLangOptions)
87
            becasue of \(error)
88
            """
89
        }
90
    }
91
}
92

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.