Skip to content

Commit 0e5e7b9

Browse files
authored
Merge pull request #634 from allevato/inline-config
Allow JSON configuration text to be passed directly on the command line.
2 parents 2050b92 + 85b6ba6 commit 0e5e7b9

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

Sources/SwiftFormat/API/Configuration.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,14 @@ public struct Configuration: Codable, Equatable {
186186
/// ```
187187
public var multiElementCollectionTrailingCommas: Bool
188188

189-
/// Constructs a Configuration by loading it from a configuration file.
189+
/// Creates a new `Configuration` by loading it from a configuration file.
190190
public init(contentsOf url: URL) throws {
191191
let data = try Data(contentsOf: url)
192+
try self.init(data: data)
193+
}
194+
195+
/// Creates a new `Configuration` by decoding it from the UTF-8 representation in the given data.
196+
public init(data: Data) throws {
192197
self = try JSONDecoder().decode(Configuration.self, from: data)
193198
}
194199

Sources/swift-format/Frontend/Frontend.swift

+27-14
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class Frontend {
109109
/// Processes source content from standard input.
110110
private func processStandardInput() {
111111
guard let configuration = configuration(
112-
at: lintFormatOptions.configurationPath.map(URL.init(fileURLWithPath:)),
112+
fromPathOrString: lintFormatOptions.configuration,
113113
orInferredFromSwiftFileAt: nil)
114114
else {
115115
// Already diagnosed in the called method.
@@ -150,7 +150,7 @@ class Frontend {
150150

151151
guard
152152
let configuration = configuration(
153-
at: lintFormatOptions.configurationPath.map(URL.init(fileURLWithPath:)),
153+
fromPathOrString: lintFormatOptions.configuration,
154154
orInferredFromSwiftFileAt: url)
155155
else {
156156
// Already diagnosed in the called method.
@@ -161,31 +161,44 @@ class Frontend {
161161
}
162162

163163
/// Returns the configuration that applies to the given `.swift` source file, when an explicit
164-
/// configuration path is also perhaps provided. Checks for unrecognized rules within the configuration.
164+
/// configuration path is also perhaps provided.
165+
///
166+
/// This method also checks for unrecognized rules within the configuration.
165167
///
166168
/// - Parameters:
167-
/// - configurationFilePath: The path to a configuration file that will be loaded, or `nil` to
168-
/// try to infer it from `swiftFilePath`.
169+
/// - pathOrString: A string containing either the path to a configuration file that will be
170+
/// loaded, JSON configuration data directly, or `nil` to try to infer it from
171+
/// `swiftFilePath`.
169172
/// - swiftFilePath: The path to a `.swift` file, which will be used to infer the path to the
170173
/// configuration file if `configurationFilePath` is nil.
171174
///
172-
/// - Returns: If successful, the returned configuration is the one loaded from
173-
/// `configurationFilePath` if it was provided, or by searching in paths inferred by
174-
/// `swiftFilePath` if one exists, or the default configuration otherwise. If an error occurred
175-
/// when reading the configuration, a diagnostic is emitted and `nil` is returned.
176-
/// if neither `configurationFilePath` nor `swiftFilePath` were provided, a default `Configuration()` will be returned.
175+
/// - Returns: If successful, the returned configuration is the one loaded from `pathOrString` if
176+
/// it was provided, or by searching in paths inferred by `swiftFilePath` if one exists, or the
177+
/// default configuration otherwise. If an error occurred when reading the configuration, a
178+
/// diagnostic is emitted and `nil` is returned. If neither `pathOrString` nor `swiftFilePath`
179+
/// were provided, a default `Configuration()` will be returned.
177180
private func configuration(
178-
at configurationFileURL: URL?,
181+
fromPathOrString pathOrString: String?,
179182
orInferredFromSwiftFileAt swiftFileURL: URL?
180183
) -> Configuration? {
181-
// If an explicit configuration file path was given, try to load it and fail if it cannot be
182-
// loaded. (Do not try to fall back to a path inferred from the source file path.)
183-
if let configurationFileURL = configurationFileURL {
184+
if let pathOrString = pathOrString {
185+
// If an explicit configuration file path was given, try to load it and fail if it cannot be
186+
// loaded. (Do not try to fall back to a path inferred from the source file path.)
187+
let configurationFileURL = URL(fileURLWithPath: pathOrString)
184188
do {
185189
let configuration = try configurationLoader.configuration(at: configurationFileURL)
186190
self.checkForUnrecognizedRules(in: configuration)
187191
return configuration
188192
} catch {
193+
// If we failed to load this from the path, try interpreting the string as configuration
194+
// data itself because the user might have written something like `--configuration '{...}'`,
195+
let data = pathOrString.data(using: .utf8)!
196+
if let configuration = try? Configuration(data: data) {
197+
return configuration
198+
}
199+
200+
// Fail if the configuration flag was neither a valid file path nor valid configuration
201+
// data.
189202
diagnosticsEngine.emitError("Unable to read configuration: \(error.localizedDescription)")
190203
return nil
191204
}

Sources/swift-format/Subcommands/LintFormatOptions.swift

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ struct LintFormatOptions: ParsableArguments {
2020
/// If not specified, the default configuration will be used.
2121
@Option(
2222
name: .customLong("configuration"),
23-
help: "The path to a JSON file containing the configuration of the linter/formatter.")
24-
var configurationPath: String?
23+
help: """
24+
The path to a JSON file containing the configuration of the linter/formatter or a JSON \
25+
string containing the configuration directly.
26+
""")
27+
var configuration: String?
2528

2629
/// The filename for the source code when reading from standard input, to include in diagnostic
2730
/// messages.

0 commit comments

Comments
 (0)