Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying explicit product destinations in PackageSettings #6073

Merged
merged 5 commits into from Mar 18, 2024

Conversation

fortmarek
Copy link
Member

Resolves https://github.com/tuist/tuist-cloud/issues/153

Short description 📝

Let's take the following Package.swift:

import PackageDescription

let package = Package(
    name: "MyPackage",
    products: [
        .library(
            name: "MyPackage",
            targets: ["MyPackage"]
        ),
        .library(
            name: "MyUIKitPackage",
            targets: ["MyUIKitPackage"]
        ),
    ],
    targets: [
        .target(
            name: "MyPackage"
        ),
        .target(
            name: "MyUIKitPackage"
        ),
    ]
)

In this example, we have two products – MyPackage and MyUIKitPackage. MyPackage supports all destinations, whereas MyUIKitPackage only support iOS-based platforms since it depends on UIKit (which is not available on platforms like macOS).

If you try to use e.g. tuist cache when developing a package, we will try to cache all platforms since packages implicitly support all platforms. To explicitly encode in Package.swift if some of your products support only some destinations, we're adding a new property of PackageSettings called productDestinations. For the above example, you could encode that MyUIKitPackage supports only iOS-based platforms by:

#if TUIST
    import ProjectDescription

    let packageSettings = PackageSettings(
        productDestinations: [
            "MyUIKitPackage": [
                .iPad,
                .iPhone,
            ],
        ]
    )
#endif

How to test the changes locally 🧐

Run tuist generate in the spm_package fixture. MyPackage target should have all destinations whereas MyUIKitPackage only iPhone and iPad.

Contributor checklist ✅

  • The code has been linted using run mise run lint:fix
  • The change is tested via unit testing or acceptance testing, or both
  • The title of the PR is formulated in a way that is usable as a changelog entry
  • In case the PR introduces changes that affect users, the documentation has been updated

Reviewer checklist ✅

  • The code architecture and patterns are consistent with the rest of the codebase
  • Reviewer has checked that, if needed, the PR includes the label changelog:added, changelog:fixed, or changelog:changed, and the title is usable as a changelog entry

@fortmarek fortmarek added the changelog:added PR will be listed in the Added section of CHANGELOG label Mar 13, 2024
@danieleformichelli
Copy link
Collaborator

Aren't target platform determined depending on which targets depend on the product?

@pepicrft
Copy link
Contributor

Aren't target platform determined depending on which targets depend on the product?

This is where you have a Tuist project depending on Swift targets. I believe the scenario @fortmarek addresses here is where you run Tuist against a Swift Package. In that scenario, we have no information that allows us to narrow-down the list of platforms.

@@ -29,6 +29,12 @@ public struct PackageSettings: Codable, Equatable {
/// The custom `Product` type to be used for SPM targets.
public var productTypes: [String: Product]

/// Custom product destinations. This setting should only be used when using Tuist for SPM packages.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd mention first that the key in the dictionary represents the name of the product for which the destinations are defined.

@@ -175,7 +175,7 @@ final class ProjectEditor: ProjectEditing {

/// We error if the user tries to edit a project in a directory where there are no editable files.
if projectManifests.isEmpty, editablePluginManifests.isEmpty, helpers.isEmpty, templateSources.isEmpty,
resourceSynthesizers.isEmpty, stencils.isEmpty
resourceSynthesizers.isEmpty, stencils.isEmpty, packageManifestPath == nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So users can run tuist edit on a project that has the Package.swift manifest only

@@ -40,6 +40,14 @@ final class EditAcceptanceTestAppWithSPMDependencies: TuistAcceptanceTestCase {
}
}

final class EditAcceptanceTestSPMPackage: TuistAcceptanceTestCase {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good one!

@@ -53,6 +53,8 @@ final class InstallServiceTests: TuistUnitTestCase {
// Given
let stubbedPath = try temporaryPath()

manifestFilesLocator.locatePackageManifestStub = stubbedPath.appending(components: "Tuist", "Package.swift")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered taking the opportunity to use @Mockable with ManifestsFileLocating?

@fortmarek
Copy link
Member Author

I believe the scenario @fortmarek addresses here is where you run Tuist against a Swift Package.

Yup, that's exactly the scenario this PR aims to fix 🙏

@danieleformichelli
Copy link
Collaborator

I believe the scenario @fortmarek addresses here is where you run Tuist against a Swift Package.

Yup, that's exactly the scenario this PR aims to fix 🙏

I see, are we ignoring the setting in case we are running against a tuist project instead?

@danieleformichelli
Copy link
Collaborator

danieleformichelli commented Mar 14, 2024

Also, I need we need to support tuist editing Package.swift file alone if we want to go down this path, right?
(Maybe this PR does it already and I'm missing it)

@fortmarek
Copy link
Member Author

I see, are we ignoring the setting in case we are running against a tuist project instead?

No, we're not. I feel it would be weird if that setting didn't do anything depending on if the Package.swift is a root one or not.

Also, I need we need to support tuist editing Package.swift file alone if we want to go down this path, right?
(Maybe this PR does it already and I'm missing it)

Yes, the PR already adds support for that.

@danieleformichelli
Copy link
Collaborator

No, we're not. I feel it would be weird if that setting didn't do anything depending on if the Package.swift is a root one or not.

I think we should.
The fact that we need this for Package.swift generation shouldn't impact (and I would say worsen) the "standard" generation

@fortmarek
Copy link
Member Author

The fact that we need this for Package.swift generation shouldn't impact (and I would say worsen) the "standard" generation

Sure, done!

@fortmarek fortmarek merged commit d10b1b3 into main Mar 18, 2024
8 checks passed
@fortmarek fortmarek deleted the spm/product-destinations branch March 18, 2024 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog:added PR will be listed in the Added section of CHANGELOG
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants