Use a flat project structure for a Swift package

The project structure for a Swift package that includes DocC documentation is shown below for a package named CalcMaker. Are the Sources and Tests directories required for Swift packages? Does the DocC documentation have to go within the Sources/CalcMaker directory?

calc-maker/
├── Sources/
│   └── CalcMaker/
│       ├── Adder.swift
│       ├── Divider.swift
│       └── CalcMaker.docc/
│           ├── CalcMaker.md
│           ├── GetStarted.md
│           └── Examples.md
├── Tests/
│   └── CalcMakerTests/
│       ├── AdderTests.swift
│       └── DividerTests.swift
├── README.md
└── Package.swift

Instead of having a bunch of sub-directories, is it possible to flatten the project structure like the tree shown below? This removes the Sources and Tests directories and puts the package, tests, and documentation directories at the top level of the project.

calc-maker/
├── CalcMaker/
│   ├── Adder.swift
│   └── Divider.swift
├── CalcMakerTests/
│   ├── AdderTests.swift
│   └── DividerTests.swift
├── CalcMaker.docc/
│   ├── CalcMaker.md
│   ├── GetStarted.md
│   └── Examples.md
├── README.md
└── Package.swift
1 Like

you can move the tests to whatever directory you like with the target path argument, but i don’t know of any way to outline the documentation directory from the source directory of its associated module.

The documentation catalog ('.docc' directory) needs to be in the same directory as the sources for that target. This is how it gets associated with the target.

In the second structure the documentation won't be associated with either target which means that it won't be used when building documentation for either target.

1 Like

So you are saying I can remove the CalcMakerTests directory and just have a Tests directory like the following:

calc-maker
  Sources
    ...
  Tests
    AdderTests.swift
    DividerTests.swift
  README.md
  Package.swift

Then I would change the test target in Package.swift to the following:

targets: [
    .target(name: "CalcMaker"),
    .testTarget(name: "Tests", dependencies: ["CalcMaker"]),
]

you need to specify path: "Tests", otherwise it will look for a nested directory Tests/Tests.

SwiftPM already has awareness of .docc directories. (although arguably, it shouldn’t?)

if we have already accepted that SwiftPM is responsible for documentation discovery, then it’s not a huge stretch to wonder if we should be able to specify a custom location for the documentation.

The following is working fine and I didn't have to specify a path: "Tests" any where.

Here is the Package.swift contents:

import PackageDescription

let package = Package(
    name: "CalcMaker",
    products: [
        .library(name: "CalcMaker", targets: ["CalcMaker"]),
    ],
    targets: [
        .target(name: "CalcMaker"),
        .testTarget(name: "Tests", dependencies: ["CalcMaker"]),
    ]
)

And here's the project structure as seen in Xcode:

screenshot

1 Like

today i learned SwiftPM supports single-level Tests directories!