Invoking swift format
causes the Swift driver to look for the swift-format
binary in the toolchain and spawn that with the same args, so if we decided we wanted swift format
to do swift package format
, we'd need swift-format
to be able to distinguish whether it was invoked as swift format
or swift-format
and then do that invocation. I don't immediately know if the child process's argv
reflects that, but it would certainly be worth exploring.
git clang-format
(which formats all lines which have changed since a given base commit) refuses to do anything if it would modify a file that already has uncommitted changes.
By comparison, based on the documentation of rustfmt
, there is not a 1:1 coupling between cargo fmt
and rustfmt
when invoked without arguments. Invoking rustfmt
directly does what swift-format currently does (read from stdin, write to stdout).
Another data point to consider here: Prettier (a code formatted for JS/CSS/HTML and related languages):
prettier
by itself prints a usage description and exits with code 1.cat foo.js | prettier
formats the standard input and prints the formatted code to stdout (with an optional--stdin-filepath
argument to configure which parser is inferred for the file)prettier .
outputs the formatted content of all files to stdout (although I understand this to be mainly for backwards compatibility)prettier --check .
outputs a success/failure message and a list of files that would be modified.prettier --debug-check .
reformats the files, then parses them again and compares the ASTs for equality, but doesnât write anything out. This tells you if youâd hit a formatted bug that would change the meaning of your code.prettier --write .
prints out a list of files that were modified.
Also, when connected to a TTY, the last line shows a live-updating path of the current file being processed.
Would swift help format
need to display the same global options (e.g. --package-path
) as the build
, package
, run
, and test
subcommands? The toolchain uses symbolic links:
swift-build -> swift-package
swift-run -> swift-package
swift-test -> swift-package
The help description only reserves swift package plugin <verb>
, so there should be different namespaces:
swift package format
to invoke the built-in formatter.swift package plugin format
to invoke a command plugin with theformat
verb.
Existing verbs:
format-source-code
(predefined by SwiftPM)lint-source-code
swiftformat
swiftlint
UPDATE: Another reason to use swift package plugin <verb>
is that it might have avoided issue swift-format#668.
100% agree that the default behavior here needs to change so that running swift format does what the majority of users would expect.
If that means that swift format and running swift-format the tool have different behavior to preserve existing tools then thatâs fine. But as it is today, requiring two flags and a directory makes the language and tooling confusing. It should work like it does in almost every other language with a built in formatter
I also donât think this should be part of the package sub command as not everyone writing Swift code uses SPM.
Since swift-format predates even the existence of SwiftPM command plugins, it's worth asking if the better intention here is to have it be a top-level "swift command" (aka in the set of "swift run, repl, build, test, package), or should it be treated as a binary that's exposed in the toolchain, but invoked as a package plugin?
My preference would be seeing it exposed as a package manager style command, refining the swift package _format
to a full operation, and as an initial flow doing any linting/reporting on mismatches rather than changing any content as a default. I prefer having the scope of what's going to be effected limited within the context of an existing package. This comes from more-than-one mistake invoking something that's purely CLI/directory recursive from the wrong location and stomping on formatting over a MUCH broader area than I intended.
If it works better being a package command plugin, and leveraging that context, then I'd suggest that the binary might be best renamed as well, moving away from swift-format
which is set up with the existing tooling to expose top level commands.
This also begs the question of having system-provided built-in SwiftPM command plugins, which I think is desperately needed as well. Like docc-plugin
, I think format
should be one of those included with the toolchain.
To be clear, I wasn't suggesting that a command plugin be used here, when responding to Konrad's post.
(I assumed that the plugin
subcommand might avoid having to rename --configuration
to --swift-format-configuration
. However, that doesn't seem to be the case, with the latest version of SwiftPM in Xcode 16 beta 6.)
Using git
terminology:
swift format
could remain as the low-level "plumbing" command.swift package format
andswift package lint
could be the high-level "porcelain" commands.
Seems unseemly to expose the plumbing more than the porcelain, no? I'd want to fire the plumber if I tripped on the pipes before I got to the toilet.
That was sort also the the way I was thinking about it - I get (and like) that it's a plumbing command with lots of controls, but it's presented fore-most by being swift-format.
I apologize for assuming incorrectly, but agree strongly that the more prominent the command, the more polish and ease of use it should have, especially to newcomers. As an existing example, docc
is clearly a plumbing command as well, and it's not named swift-docc
, which I think was a good choice.
does this problem really just boil down to swift format
squatting on the string âformatâ, that is motivating the desire to namespace it under swift package format
?
i wonder if we might be better off with something like?
swift lint
swift lint --fix
Yes same issue here as in my team i's the only swift dev the others need to run swift format on generated code. They often complain about the complexity and long runs. Have formatting build in makes it a lot better for them to accept the need for them to run it too.
I do feel I can improve with including formatting inside my codegen tool as that is also swift. I did however not do that as that would require adding formatting as a dependency and needing to build it in the tool. Do you think swift format as an import could be made available too? And while you are add it add swift-syntax maybe?
Started to use swift format recently and can +1 here, also feel confused so far and think this could be improved.
- Why there are
swift-format
andswift format
? - Why
swift format .
just won't work? swift package _format
will give me aError: 'blah/blah/blah' is a path to a directory, not a Swift source file.
error.swift format lint
will just wait for stdin.- on top of it
swift format . --recursive --in-place
will just do nothing andswift-format . --recursive --in-place
will work
I do get now how things are working, but initial perception is quite strange.
If you run swift format
you are using it as a plugin to the build tooling. swift-format
is a separate command-line tool that can be used for easier scripting and whatnot.
Apple seems to understand it's confusing and there is an open issue on it.
To be clear, this thread is a key part of the discussion that will or won't resolve the issue, so it's entirely appropriate to continue to conversation here. The existence of an open issue doesn't mean that something will just happen.
Oh 100% understood. This thread and that issue are what we have to work with.
(And the radar I guess, but most of us canât see that.)