-
Notifications
You must be signed in to change notification settings - Fork 225
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
Implement a warning or error if an unrecognized Rule is specified in .swift-format #607
Comments
This is a great idea for improvement, but I think it's a little bit more complicated than you've described here. The configuration decoding logic doesn't have any way to pass information out of it other than "here's a successfully parsed config" or "here's an error because it failed". So if we want a warning, we have to check it in the frontend after decoding it; otherwise, we can make it an error during the actual decoding process. The only real value to a warning—aside from just being a little more relaxed—would be to retain compatibility of newer config files with older versions of swift-format, but I don't think that's something we really need to do. So just throwing an error would be easier to implement. I don't know if we need all the ceremony of generating a new enum for this, though. We already generate a Feel free to send a PR! |
I've explored a bit yesterday, and yep — I think one of the questions is at what level should that check be. It could be in Then, there's We could put that into
If we decide to go with an error, than the simplest solution by far is a check in self.rules = try container.decode(...)
// If any rules in the decoded configuration are not supported by the registry,
// emit them into the diagnosticsEngine as warnings.
// That way they will be printed out, but we'll continue execution on the valid rules.
let invalidRules = self.rules.filter { !RuleRegistry.rules.keys.contains($0.key) }
if !invalidRules.isEmpty {
throw ConfigurationError.invalidConfiguration("Configuration contains an unsupported rule: \(invalidRules.keys.joined(separator: ", "))"
} But, if we stick with a warning, we could do that check after we decode, and that would make it so any projects that have a broken config today won't blow up their CI when they update.
Yep, I think Here's what I have now (rough draft, copy and pasting): // In frontend.swift
private func configuration(
at configurationFileURL: URL?,
orInferredFromSwiftFileAt swiftFileURL: URL?
) -> Configuration? {
// If an explicit configuration file path was given, try to load it and fail if it cannot be
// loaded. (Do not try to fall back to a path inferred from the source file path.)
if let configurationFileURL = configurationFileURL {
do {
let configuration = try configurationLoader.configuration(at: configurationFileURL)
// If any rules in the decoded configuration are not supported by the registry,
// emit them into the diagnosticsEngine as warnings.
// That way they will be printed out, but we'll continue execution on the valid rules.
let invalidRules = configuration.rules.filter { !RuleRegistry.rules.keys.contains($0.key) }
if !invalidRules.isEmpty {
diagnosticsEngine.emitWarning("Configuration contains an unsupported rule: \(invalidRules.keys.joined(separator: ", "))", location: nil)
return nil
}
return configuration
} catch {
diagnosticsEngine.emitError("Unable to read configuration: \(error.localizedDescription)")
return nil
}
}
// If no explicit configuration file path was given but a `.swift` source file path was given,
// then try to load the configuration by inferring it based on the source file path.
if let swiftFileURL = swiftFileURL {
do {
if let configuration = try configurationLoader.configuration(forSwiftFileAt: swiftFileURL) {
return configuration
}
// Fall through to the default return at the end of the function.
} catch {
diagnosticsEngine.emitError(
"Unable to read configuration for \(swiftFileURL.path): \(error.localizedDescription)")
return nil
}
}
// If neither path was given (for example, formatting standard input with no assumed filename)
// or if there was no configuration found by inferring it from the source file path, return the
// default configuration.
return Configuration()
} I think if I just make that check run in both branches of loading configuration, we'll be fine. Expect a PR in a few hours, depending on my 3 y/o daughter's mood. So far, she does not really understand why |
**Summary**: - Helps developers surface any errors and typos in their `.swift-format` config files by showing a warning when running `swift-format` if the configuration includes invalid rules. - The actual check is in `Frontend.swift`. - The dictionary of rules for verification is in `RuleRegistry`, which is made `public` to be able to import it in `swift-format` target. **Motivation**: - Closes swiftlang#607
**Summary**: - Helps developers surface any errors and typos in their `.swift-format` config files by showing a warning when running `swift-format` if the configuration includes invalid rules. - The actual check is in `Frontend.swift`. - The dictionary of rules for verification is in `RuleRegistry`, which is made `public` to be able to import it in `swift-format` target. **Motivation**: - Closes swiftlang#607
**Summary**: - Helps developers surface any errors and typos in their `.swift-format` config files by showing a warning when running `swift-format` if the configuration includes invalid rules. - The actual check is in `Frontend.swift`. - The dictionary of rules for verification is in `RuleRegistry`, which is made `public` to be able to import it in `swift-format` target. **Motivation**: - Closes swiftlang#607
**Summary**: - Helps developers surface any errors and typos in their `.swift-format` config files by showing a warning when running `swift-format` if the configuration includes invalid rules. - The actual check is in `Frontend.swift`. - The dictionary of rules for verification is in `RuleRegistry`, which is made `public` to be able to import it in `swift-format` target. **Motivation**: - Closes swiftlang#607
**Summary**: - Helps developers surface any errors and typos in their `.swift-format` config files by showing a warning when running `swift-format` if the configuration includes invalid rules. - The actual check is in `Frontend.swift`. - The dictionary of rules for verification is in `RuleRegistry`, which is made `public` to be able to import it in `swift-format` target. **Motivation**: - Closes swiftlang#607 Apply suggestions from code review Co-authored-by: Tony Allevato <tony.allevato@gmail.com> Cleaning up based on PR review
Right now, if one made a typo in a rule name in
.swift-format
and then ran the formatter, it will ignore the typo and, obviously, not apply the rule.I was working on swiftlang/swift-syntax#2145, and of course, that's precisely what I did. Oh, nice, our imports are already ordered, right?
Proposed solution
Since we know the list of all available rules, we could verify that each string in the Rules block matches an existing rule.
It should be relatively easy, we could just generate an
enum
with all rule names, and use that as the key when decoding the rules.Should I draft this in a PR?
The text was updated successfully, but these errors were encountered: