SwiftDocOrg / DocTest

An experimental tool for testing Swift example code in documentation.
358 stars 9 forks source link

Needs option to run against all files #26

Open schwa opened 4 years ago

schwa commented 4 years ago

I'd love to be able to just swift doctest . and have it run recursively on all swift files under my CWD.

mattt commented 4 years ago

I absolutely agree that we should support running doctest over multiple arguments in a single invocation. What I've been struggling with for this and swiftdoc has been how "Unix-y" (in the "do one thing well" sense) to make this.

I can think of a few options:

The problem is, like most CLI matters, is that you can find examples of all of these, but often none of them are convincingly better than any alternatives. I want doctest to be convenient to run on a bunch of files at once, yet flexible enough to do so selectively (that's more a concern when running on non-swift doc annotated code blocks, #27).

iainsmith commented 4 years ago

@mattt just my opinion, but I'd make the case that solutions that require using (or piping from) other tools create a barrier to entry for beginners. Instead of being able to quickly use a new tool, the user need to learn two commands.

In practice the find --exec example is long enough that many people would create an alias for it rather than type it out frequently. I feel that common commands should aim to be more ergonomic.

Personally I really like the pytest interface which provides an intuitive interface:

Going further, I'd argue that the unix-y philosophy of do one thing well and compose with other tools, is much more important for very generalised tools like cut, sed, wc that work across a myriad of file types & scenarios.

Specialised tools should probably prioritise user ergonomics over strict composability.

mattt commented 4 years ago

@iainsmith Thanks for sharing your thoughts. I think that's a really helpful way to think about things! On the command line, there's a spectrum from generalized utilities to applications, and where an executable finds itself on that largely determines the right balance of composability and ergonomics.

The thing I struggle with is that ergonomics seem to be subjective, and often turn into a slippery slope of affordances.

For example, I agree with the behavior of pytest adapting its behavior based on whether it's passed a file or directory. However, the recursive behavior has unintended consequences. If you were to do that in the directory of a Swift package, you'd (counter-intuitively) pick up all of the source files of its dependencies in .build/repositories.

Do you change the behavior to say "ignore hidden directories"? If so, do you add a flag to explicitly include certain directories? Pretty soon, you've reinvented globbing. Rather than close the skill gap by eliminating find --exec, you've created a wider gap by introducing your own, new way of doing things.

iainsmith commented 4 years ago

On the command line, there's a spectrum from generalized utilities to applications, and where an executable finds itself on that largely determines the right balance of composability and ergonomics.

Very nicely put.

However, the recursive behavior has unintended consequences. If you were to do that in the directory of a Swift package, you'd (counter-intuitively) pick up all of the source files of its dependencies in .build/repositories.

I think this is a good example where we can follow the "rule of least astonishment". I would expect running swift doctest . (or variant) from the root of a package to run on swift & text files in the current package (excluding dependencies & the .git folder).

Do you change the behavior to say "ignore hidden directories"? If so, do you add a flag to explicitly include certain directories? Pretty soon, you've reinvented globbing. Rather than close the skill gap by eliminating find --exec, you've created a wider gap by introducing your own, new way of doing things.

I feel like there is a false dichotomy between "ergonomics" and "closing the skill gap" in the last sentence, as it seems like we can have both. Having a "Composition" section in the README or detailed in the --help command is a great way to teach people how to compose swift doctest with other commands, but need not be a prerequisite.

Giving people short intuitive commands like swift format . / swift doctest . /etc with a few options/flags/etc that cover the typical developer use cases, provides a great experience for everyone regardless of their knowledge of other tools. Power users can still compose other tools as they'd like and ideally we should respect the standard unix-y ways of enabling that. (I tried to resist making the "It just works" comment, but I have failed.)

The thing I struggle with is that ergonomics seem to be subjective, and often turn into a slippery slope of affordances.

I totally agree this is all subjective. Personally I tend to lean towards tools providing memorable, "easy to type" commands for common use cases, but as long as there is documentation on how to get things done, people can build aliases and wrappers to get the UX they want 👍.