Hi everyone,
I'd like to propose a new, compressed, output format for Swift-DocC.
Motivation
Swift-DocC likes to generate filenames that contain characters like :s that, while fine on UNIX-like platforms, are fundamentally incompatible with CP/M-family operating systems like Windows.
Additionally, while macOS has features that allow directory trees to look
like and be treated like files, this is not the case on other platforms and
dealing with a tree of files is harder than dealing with a single file.
Proposed Solution
The idea here is to make Swift-DocC write out a .doccarchive file that is, under the covers, a zip file. There is plenty of precedent for this kind of behavior — Java jar and war files, Microsoft Office documents like docx, xlsx and pptx, Pages, Numbers and Keynote documents are all zip archives.
This fixes the filename problem, since the only restriction on filenames in zip files is that the / character is reserved as a directory separator (this is essentially the same restriction as UNIX has).
It also results in less disk usage and more convenient manipulation of .doccarchives on Windows and Linux as they are now a single file, rather than a directory hierarchy.
Additionally, for use-cases where it is desirable to have a directory tree, standard tools can be used to expand the zipped archive.
Changes to DocC command line
A new flag, --[no-]compress will be added for the convert and merge actions. This flag will be on by default for Windows.
Impact on DocC's dependencies
This change does mean that DocC will need to be able to generate compressed archives. We would prefer to keep the set of dependencies require to build DocC as small as possible, and ideally to avoid anything that isn't already a dependency of some other Swift component.
To that end, we will only add a dependency on Zlib.
Preview support
The preview server within DocC will be updated such that it is able to directly serve files from a zipped archive, in addition to its existing support for directory trees.
Alternatives Considered
Changing DocC to not output special characters in filenames
The downside of this is that it will change the URLs, at least for the static file serving case. We could have made this change just for Windows, but if we did that then the URLs would differ depending on whether the documentation archive was built on Windows or on some other platform, which is itself undesirable.
It is possible to work around the URL issue in the web server, but the details depend strongly on the web server that is in use, and explaining to users how to configure that would be tricky, as well as leaving them with a more fragile web server configuration.
Making compressed output the default everywhere
This might break existing build processes. Users building documentation on Windows need to use compressed output because not doing so simply doesn't work, so making it the default there seems the right choice.
If we want to make it the default everywhere, we can do that in a future release, giving people plenty of notice that it's going to change and that they'll need to add --no-compress to maintain the present behavior.
Using some other container format besides zip
We could have used tar.gz/tar.bz2/tar.xz, or one of Microsoft's various multi-stream formats, or done our own thing.
Zip has the advantage that it is standardised (as ISO/IEC 21320-1:2015), well documented and widely supported across multiple platforms. Unlike some of the other choices, it also compresses files individually and has a central index, which makes serving content directly from it relatively efficient.
More technically adept users are also used to the notion that some modern file formats are really zip files internally.
Using a new file extension rather than doccarchive
DocC itself doesn't really care what name you use for your output anyway, but it seems entirely reasonable to treat a doccarchive file as a zip, and a doccarchive directory as a directory tree.
There doesn't seem to be a good reason to e.g. add an x on the end or to use doccarchive.zip or anything of that nature.