skip icon indicating copy to clipboard operation
skip copied to clipboard

`skip init` should create `Package.swift` in a subdirectory

Open dfabulich opened this issue 5 months ago • 3 comments

Apropos #448, the Xcode workspace structure for a generated project is (still) extremely strange.

skip init creates an Xcode project .xcodeproj in the ./Darwin folder, and creates a ./Package.swift file in the generated root folder.

To make the generated library visible in the project, the root ./ folder is added to the .xcodeproj by reference, and the library name e.g. ModuleName is added as a dependency of the app project. A few file references are tossed in to the project, too, including README.md, Skip.env, and Localizable.xcstrings.

I think the normal way to have an app project that references a Swift library is to have the library appear in a ModuleName subdirectory next to the Darwin directory. Instead of:

Project.xcworkspace
Darwin/ModuleName.xcodeproj
Package.swift
Sources/ModuleName/ModuleNameApp.swift

It would look like this:

Project.xcworkspace
Darwin/ModuleName.xcodeproj
ModuleName/Package.swift
ModuleName/Sources/ModuleNameApp.swift

This would make the project structure much less confusing, IMO.

dfabulich avatar Jul 03 '25 14:07 dfabulich

skip init and skip create can generate either a library or an app project. The latter option is just an expansion of the first, but with additional Darwin/ and Android/ folders that house the platform-specific app build files. In both cases, the project's structure is dominated by the fact that it is a pure SwiftPM project, which requires that the Package.swift file be in the top directory if other packages are to be able to use it as a dependency.

The current arrangement is admittedly non-standard compared to a traditional Xcode-oriented project setup, but it provides consistency between library and application projects.

marcprux avatar Jul 03 '25 15:07 marcprux

The point of my bug is that the current layout makes skip application projects and library projects inconsistent inside a workspace.

Today, when skip create creates a basic app, it's creating three things:

  1. A Skip-enabled SwiftPM project rooted at the top level, project-name/Package.swift which includes project-name/Sources/ModuleName/ModuleNameApp.swift
  2. A workspace, also rooted at the top level, project-name/Project.xcworkspace
  3. The app's project-name/Darwin/ModuleName.xcodeproj, which isn't (and can't be) a pure SwiftPM project.

When skip create creates a library package, it only does #1.

But if you're working on multiple top-level library packages inside one workspace (e.g. if you're hacking on skip-ui), you then have to create your own workspace and stop using the auto-generated workspace.

[Example A: Hacking on skip-ui in today's status quo]
ManuallyCreated.xcworkspace
project-name/Project.xcworkspace <-- now you must stop using this
project-name/Darwin/ModuleName.xcodeproj
project-name/Package.swift
project-name/Sources/ModuleName/ModuleNameApp.swift
skip-ui/Package.swift

It would be more consistent for the App's SwiftPM project to live in a subdirectory of the workspace folder, just like skip-ui.

[Example B: Hacking on skip-ui in my proposed layout]
Project.xcworkspace
Darwin/ModuleName.xcodeproj
project-name/Package.swift
project-name/Sources/ModuleNameApp.swift
skip-ui/Package.swift

Then, users who wanted to add a new Skip SwiftPM package to their workspace could run skip create in the workspace folder, creating a new sibling to the core app's package.

dfabulich avatar Jul 21 '25 22:07 dfabulich

But if you're working on multiple top-level library packages inside one workspace (e.g. if you're hacking on skip-ui), you then have to create your own workspace and stop using the auto-generated workspace.

What makes you think that? One of the reasons we now create a Project.xcworkspace is to facilitate exactly that scenario. E.g., here is Showcases's Project.xcworkspace with a local SkipUI checkout developed alongside it.

Image

marcprux avatar Jul 24 '25 14:07 marcprux