2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
5
- // Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
5
+ // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
9
9
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
+ import ArgumentParser
13
14
import Foundation
14
15
import SwiftFormat
15
16
import SwiftFormatConfiguration
16
- import SwiftFormatCore
17
17
import SwiftSyntax
18
18
import TSCBasic
19
19
20
- /// Runs the linting pipeline over the provided source file.
21
- ///
22
- /// If there were any lint diagnostics emitted, this function returns a non-zero exit code.
23
- /// - Parameters:
24
- /// - configuration: The `Configuration` that contains user-specific settings.
25
- /// - sourceFile: A file handle from which to read the source code to be linted.
26
- /// - assumingFilename: The filename of the source file, used in diagnostic output.
27
- /// - ignoreUnparsableFiles: Whether or not to ignore files that contain syntax errors.
28
- /// - debugOptions: The set containing any debug options that were supplied on the command line.
29
- /// - diagnosticEngine: A diagnostic collector that handles diagnostic messages.
30
- /// - Returns: Zero if there were no lint errors, otherwise a non-zero number.
31
- func lintMain(
32
- configuration: Configuration , sourceFile: FileHandle , assumingFilename: String ? ,
33
- ignoreUnparsableFiles: Bool , debugOptions: DebugOptions , diagnosticEngine: DiagnosticEngine
34
- ) {
35
- let linter = SwiftLinter ( configuration: configuration, diagnosticEngine: diagnosticEngine)
36
- linter. debugOptions = debugOptions
37
- let assumingFileURL = URL ( fileURLWithPath: assumingFilename ?? " <stdin> " )
20
+ extension SwiftFormatCommand {
21
+ /// Formats one or more files containing Swift code.
22
+ struct Format : ParsableCommand {
23
+ static var configuration = CommandConfiguration (
24
+ abstract: " Format Swift source code " ,
25
+ discussion: " When no files are specified, it expects the source from standard input. " )
38
26
39
- guard let source = readSource ( from: sourceFile) else {
40
- diagnosticEngine. diagnose (
41
- Diagnostic . Message ( . error, " Unable to read source for linting from \( assumingFileURL. path) . " ) )
42
- return
43
- }
27
+ /// Whether or not to format the Swift file in-place.
28
+ ///
29
+ /// If specified, the current file is overwritten when formatting.
30
+ @Flag (
31
+ name: . shortAndLong,
32
+ help: " Overwrite the current file when formatting. " )
33
+ var inPlace : Bool
44
34
45
- do {
46
- try linter. lint ( source: source, assumingFileURL: assumingFileURL)
47
- } catch SwiftFormatError . fileNotReadable {
48
- let path = assumingFileURL. path
49
- diagnosticEngine. diagnose (
50
- Diagnostic . Message ( . error, " Unable to lint \( path) : file is not readable or does not exist. " ) )
51
- return
52
- } catch SwiftFormatError . fileContainsInvalidSyntax( let position) {
53
- guard !ignoreUnparsableFiles else {
54
- return
35
+ @OptionGroup ( )
36
+ var formatOptions : LintFormatOptions
37
+
38
+ func validate( ) throws {
39
+ if inPlace && formatOptions. paths. isEmpty {
40
+ throw ValidationError ( " '--in-place' is only valid when formatting files " )
41
+ }
42
+ }
43
+
44
+ func run( ) throws {
45
+ let diagnosticEngine = makeDiagnosticEngine ( )
46
+
47
+ if formatOptions. paths. isEmpty {
48
+ let configuration = try loadConfiguration (
49
+ forSwiftFile: nil , configFilePath: formatOptions. configurationPath)
50
+ formatMain (
51
+ configuration: configuration, sourceFile: FileHandle . standardInput,
52
+ assumingFilename: formatOptions. assumeFilename, inPlace: false ,
53
+ ignoreUnparsableFiles: formatOptions. ignoreUnparsableFiles,
54
+ debugOptions: formatOptions. debugOptions, diagnosticEngine: diagnosticEngine)
55
+ } else {
56
+ try processSources (
57
+ from: formatOptions. paths, configurationPath: formatOptions. configurationPath,
58
+ diagnosticEngine: diagnosticEngine
59
+ ) { sourceFile, path, configuration in
60
+ formatMain (
61
+ configuration: configuration, sourceFile: sourceFile, assumingFilename: path,
62
+ inPlace: inPlace, ignoreUnparsableFiles: formatOptions. ignoreUnparsableFiles,
63
+ debugOptions: formatOptions. debugOptions, diagnosticEngine: diagnosticEngine)
64
+ }
65
+ }
66
+
67
+ try failIfDiagnosticsEmitted ( diagnosticEngine)
55
68
}
56
- let path = assumingFileURL. path
57
- let location = SourceLocationConverter ( file: path, source: source) . location ( for: position)
58
- diagnosticEngine. diagnose (
59
- Diagnostic . Message ( . error, " file contains invalid or unrecognized Swift syntax. " ) ,
60
- location: location)
61
- return
62
- } catch {
63
- let path = assumingFileURL. path
64
- diagnosticEngine. diagnose ( Diagnostic . Message ( . error, " Unable to lint \( path) : \( error) " ) )
65
- return
66
69
}
67
70
}
68
71
@@ -77,7 +80,7 @@ func lintMain(
77
80
/// - debugOptions: The set containing any debug options that were supplied on the command line.
78
81
/// - diagnosticEngine: A diagnostic collector that handles diagnostic messages.
79
82
/// - Returns: Zero if there were no format errors, otherwise a non-zero number.
80
- func formatMain(
83
+ private func formatMain(
81
84
configuration: Configuration , sourceFile: FileHandle , assumingFilename: String ? , inPlace: Bool ,
82
85
ignoreUnparsableFiles: Bool , debugOptions: DebugOptions , diagnosticEngine: DiagnosticEngine
83
86
) {
@@ -137,10 +140,3 @@ func formatMain(
137
140
return
138
141
}
139
142
}
140
-
141
- /// Reads from the given file handle until EOF is reached, then returns the contents as a UTF8
142
- /// encoded string.
143
- fileprivate func readSource( from fileHandle: FileHandle ) -> String ? {
144
- let sourceData = fileHandle. readDataToEndOfFile ( )
145
- return String ( data: sourceData, encoding: . utf8)
146
- }
0 commit comments