Now that we're shipping swift format with toolchains in 6.0+ the following command became available "out of the box": swift format
.
This is fantastic development and I'm very happy that we finally have a "just run swift format" for newcomers to Swift.
Within both my day to day on-the-job and my role in the server workgroup, I often work with people coming to Swift from other ecosystems and this will be a tremendous help in helping transitioning teams.
--
[1] Here's the catch though. Excited about the addition I recently attempted to use it, and the experience is as follows:
// cd MyCoolProject
swift format
// "hangs" (waits for stdin)
This part can be pretty jarring. What actually happens is that swift-format waits on stdin input... and will then format that. I'd like to argue that this is a very confusing behavior for a swift format
invocation, especially while in a directory with a swiftpm package.
Expected behavior, especially coming from other language ecosystems (go fmt
, sbt format
, cargo fmt
, etc.), would be to format sources in the project.
[1.Q] While I understand changing default behavior can be difficult, but I do think we need to improve the default behavior here to actually format sources.
This will help fight the perception that Swift is this "weird thing that has weird stuff" that we often need to fight when bringing teams new to Swift over to the language.
And yes, I had developers (experienced ones even), at this point be shocked and "give up", moving ask "swift format seems broken, just hangs for me", which is a really bad first impression (even when we then explain what happened).
--
[2] The second part to this is, that given noticing this issue, some developers then try swift format .
which one would expect to work on the directory.
[2.1] This also doesn't quite work, and we'll get:
-> % swift format .
Error: '.' is a path to a directory, not a Swift source file.
Use the '--recursive' option to handle directories.
Usage: swift-format format [--in-place] [--configuration <configuration>] [--offsets <offsets> ...] [--assume-filename <assume-filename>] [--recursive] [--ignore-unparsable-files] [--parallel] [--color-diagnostics] [--no-color-diagnostics] [--follow-symlinks] [<paths> ...]
See 'swift-format format --help' for more information.
Which is all true, but still adds to the "why is Swift making things so hard for me?" experience for newcomers.
[2.2] Then we add the --recursive
option:
swift format . --recursive
Which prints all files to stdout, which again isn't what I'd expect when already "work on directories" mode in my interactive command line session with my SwiftPM project (directory).
[2.3] So then one has to consult --help
and realize we need another flag:
swift format . --recursive --in-place
which finally does what I wanted to do: format source files in my project, although with much more typing than in competing ecosystems. It makes Swift feel clunky as formatting source code is a common thing developers do, as often as git add .
or similar.
[2.Q] I would like to argue these options should also be default when invoked as swift format
. We could debate if perhaps a good default would be to look at Sources/
, Tests/
and Package.swift
files by default perhaps, rather than .
which could do more than one would anticipate, but I do think all those flags do get in the way of making Swift a nice and simple language and ecosystem.
--
So, how can we figure out changing the default behavior of swift format
to actually format sources? This will make the Swift adoption for people new to Swift a much nicer, and less of a jarring experience.
I understand the behavior of stdin->stdout may be useful for when swift-format
is invoked by other tools, and we may have to keep it for compatibility reasons, but I really believe we have to improve the developer experience when invoked as swift format
.
One workaround may be to force people to install a format plugin, and then use swift package format
but I don't think this is a great solution. It adds to the "extra steps" and making things difficult for people who just opened up Swift and want to give it a shot, have a nice experience, and then keep learning about plugins, configuring formatters etc.