Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability To Turn Off Formatting For Subdirectory #873

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Documentation/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ top-level keys and values:
* `version` _(number)_: The version of the configuration file. For now, this
should always be `1`.

* `skipAll` _(boolean)_: If this is true, all other configuration
options are ignored, and formatting/linting is disabled.

* `lineLength` _(number)_: The maximum allowed length of a line, in
characters.

Expand Down
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,21 @@ configuration, by redirecting it to a file and editing it.
### Configuring the Command Line Tool

For any source file being checked or formatted, `swift-format` looks for a
JSON-formatted file named `.swift-format` in the same directory. If one is
found, then that file is loaded to determine the tool's configuration. If the
file is not found, then it looks in the parent directory, and so on.

If no configuration file is found, a default configuration is used. The
settings in the default configuration can be viewed by running
`swift-format dump-configuration`, which will dump it to standard
output.
JSON-formatted file named `.no-swift-format` in the same directory.
The presence of this file will disable all formatting and linting.
The contents of `.no-swift-format` are ignored - it can be an empty file.

If the file is not found, then it looks in the same directory for a file
called `.swift-format`. If one is found, then that file is loaded to
determine the tool's configuration.

If neither configuration file is found, the search for files continues
in the parent directory, and so on.

If no configuration file is found at any level, a default configuration
is used. The settings in the default configuration can be viewed by
running `swift-format dump-configuration`, which will dump it to
standard output.

If the `--configuration <file>` option is passed to `swift-format`, then that
configuration will be used unconditionally and the file system will not be
Expand Down
31 changes: 30 additions & 1 deletion Sources/SwiftFormat/API/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,19 @@ internal let highestSupportedConfigurationVersion = 1
/// Holds the complete set of configured values and defaults.
public struct Configuration: Codable, Equatable {

/// Name of the configuration file to look for.
/// The presence of this file in a directory will cause the formatter
/// to use the configuration specified in that file.
private static let configurationFileName = ".swift-format"

/// Name of the suppression file to look for.
/// The presence of this file in a directory will cause the formatter
/// to skip formatting files in that directory and its subdirectories.
private static let suppressionFileName = ".no-swift-format"

private enum CodingKeys: CodingKey {
case version
case skipAll
case maximumBlankLines
case lineLength
case spacesBeforeEndOfLineComments
Expand Down Expand Up @@ -59,6 +70,9 @@ public struct Configuration: Codable, Equatable {

/// MARK: Common configuration

/// Is all formatting disbled?
public var skipAll = false

/// The dictionary containing the rule names that we wish to run on. A rule is not used if it is
/// marked as `false`, or if it is missing from the dictionary.
public var rules: [String: Bool]
Expand Down Expand Up @@ -262,6 +276,13 @@ public struct Configuration: Codable, Equatable {

/// Creates a new `Configuration` by loading it from a configuration file.
public init(contentsOf url: URL) throws {
if url.lastPathComponent == Self.suppressionFileName {
var config = Configuration()
config.skipAll = true
self = config
return
}

let data = try Data(contentsOf: url)
try self.init(data: data)
}
Expand Down Expand Up @@ -295,6 +316,9 @@ public struct Configuration: Codable, Equatable {
// default-initialized instance.
let defaults = Configuration()

self.skipAll =
try container.decodeIfPresent(Bool.self, forKey: .skipAll)
?? false
self.maximumBlankLines =
try container.decodeIfPresent(Int.self, forKey: .maximumBlankLines)
?? defaults.maximumBlankLines
Expand Down Expand Up @@ -382,6 +406,7 @@ public struct Configuration: Codable, Equatable {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(version, forKey: .version)
try container.encode(skipAll, forKey: .skipAll)
try container.encode(maximumBlankLines, forKey: .maximumBlankLines)
try container.encode(lineLength, forKey: .lineLength)
try container.encode(spacesBeforeEndOfLineComments, forKey: .spacesBeforeEndOfLineComments)
Expand Down Expand Up @@ -426,7 +451,11 @@ public struct Configuration: Codable, Equatable {
}
repeat {
candidateDirectory.deleteLastPathComponent()
let candidateFile = candidateDirectory.appendingPathComponent(".swift-format")
let suppressingFile = candidateDirectory.appendingPathComponent(Self.suppressionFileName)
if FileManager.default.isReadableFile(atPath: suppressingFile.path) {
return suppressingFile
}
let candidateFile = candidateDirectory.appendingPathComponent(Self.configurationFileName)
if FileManager.default.isReadableFile(atPath: candidateFile.path) {
return candidateFile
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/SwiftFormat/API/SwiftFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ public final class SwiftFormatter {
// also does not touch an empty file even if the setting to add trailing newlines is enabled.)
guard !source.isEmpty else { return }

// If skipAll is set, just emit the source as-is.
guard !configuration.skipAll else {
outputStream.write(source)
return
}

let sourceFile = try parseAndEmitDiagnostics(
source: source,
operatorTable: .standardOperators,
Expand Down
5 changes: 5 additions & 0 deletions Sources/SwiftFormat/API/SwiftLinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public final class SwiftLinter {
// also does not touch an empty file even if the setting to add trailing newlines is enabled.)
guard !source.isEmpty else { return }

// If skipAll is set, do nothing.
guard !configuration.skipAll else {
return
}

let sourceFile = try parseAndEmitDiagnostics(
source: source,
operatorTable: .standardOperators,
Expand Down