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

Skip plugin should report error when the target has no transitive skip dependencies #154

Open
mark-urbanthings opened this issue Jun 23, 2024 · 7 comments
Labels
enhancement New feature or request

Comments

@mark-urbanthings
Copy link

I have been trying out skip on a small a modular project that's started giving a gradle error. It started when I added a dependency on Model to the API and DataStore modules. The Package.swift parses and the iOS build phase completes successfully I don't think there's anything wrong with the Package.swift (below). I've tried clean and rebuild, reset packages etc.

Any ideas or pointers? Thanks!

The error transcript is:

Error: /Users/markw/Library/Developer/Xcode/DerivedData/LAQN-ccxxvnzqbwxafpefjhxnlucgbyof/Build/Intermediates.noindex/LAQN.build/Debug-iphonesimulator/LAQN.build/skip-gradle.log.txt:41:0: error: The gradle command failed. Review the log for details and consult https://skip.tools/docs/faq for common solutions. Command: gradle -p ../Android launchDebug
GRADLE> Configuration on demand is an incubating feature.
GRADLE> > Task :skip-plugins:checkKotlinGradlePluginConfigurationErrors
GRADLE> > Task :skip-plugins:compileKotlin UP-TO-DATE
GRADLE> > Task :skip-plugins:compileJava NO-SOURCE
GRADLE> > Task :skip-plugins:pluginDescriptors UP-TO-DATE
GRADLE> > Task :skip-plugins:processResources UP-TO-DATE
GRADLE> > Task :skip-plugins:classes UP-TO-DATE
GRADLE> > Task :skip-plugins:jar UP-TO-DATE
GRADLE> Configuring project ':SkipFFI' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipFFI' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':DataStore' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/DataStore' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipSQL' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipSQL' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':LAQN' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/LAQN' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipModel' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipModel' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipFoundation' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipFoundation' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipUI' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipUI' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipUnit' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipUnit' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':Model' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/Model' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> Configuring project ':SkipLib' without an existing directory is deprecated. The configured projectDirectory '/Users/markw/imperial/laqn/Android/SkipLib' does not exist, can't be written to or is not a directory. This behavior has been deprecated. This will fail with an error in Gradle 9.0. Make sure the project directory exists and can be written. Consult the upgrading guide for further information: https://docs.gradle.org/8.7/userguide/upgrading_version_8.html#deprecated_missing_project_directory
GRADLE> 
GRADLE> FAILURE: Build failed with an exception.
GRADLE> 
GRADLE> * What went wrong:
GRADLE> Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
error: Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
GRADLE> > Could not resolve all task dependencies for configuration ':app:debugCompileClasspath'.
GRADLE>    > Could not resolve project :skipstone:Model.
GRADLE>      Required by:
GRADLE>          project :app > project :skipstone:LAQN
GRADLE>          project :app > project :skipstone:LAQN > project :skipstone:DataStore
GRADLE>       > No matching variant of project :skipstone:Model was found. The consumer was configured to find a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.2.2', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
GRADLE>           - None of the variants have attributes.
GRADLE> 
GRADLE> * Try:
GRADLE> > Review the variant matching algorithm at https://docs.gradle.org/8.7/userguide/variant_attributes.html#sec:abm_algorithm.
GRADLE> > No matching variant errors are explained in more detail at https://docs.gradle.org/8.7/userguide/variant_model.html#sub:variant-no-match.
GRADLE> > Run with --stacktrace option to get the stack trace.
GRADLE> > Run with --info or --debug option to get more log output.
GRADLE> > Run with --scan to get full insights.
GRADLE> > Get more help at https://help.gradle.org.
GRADLE> 
GRADLE> BUILD FAILED in 784ms
GRADLE> 5 actionable tasks: 1 executed, 4 up-to-date
note: Gradle FAILED: 
/Users/markw/Library/Developer/Xcode/DerivedData/LAQN-ccxxvnzqbwxafpefjhxnlucgbyof/Build/Intermediates.noindex/LAQN.build/Debug-iphonesimulator/LAQN.build/skip-gradle.log.txt:41:0: error: The gradle command failed. Review the log for details and consult https://skip.tools/docs/faq for common solutions. Command: gradle -p ../Android launchDebug

Package.swift

// swift-tools-version: 5.9
// This is a Skip (https://skip.tools) package,
// containing a Swift Package Manager project
// that will use the Skip build plugin to transpile the
// Swift Package, Sources, and Tests into an
// Android Gradle Project with Kotlin sources and JUnit tests.
import PackageDescription
import Foundation

// Set SKIP_ZERO=1 to build without Skip libraries
let zero = ProcessInfo.processInfo.environment["SKIP_ZERO"] != nil
let skipstone = !zero ? [Target.PluginUsage.plugin(name: "skipstone", package: "skip")] : []

let package = Package(
    name: "laqn",
    defaultLocalization: "en",
    platforms: [.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)],
    products: [
        .library(name: "LAQNApp", type: .dynamic, targets: ["LAQN"]),
        .library(name: "DataStore", targets: ["DataStore"]),
        .library(name: "Model", targets: ["Model"]),
        .library(name: "API", targets: ["API"]),
    ],
    dependencies: [
        .package(url: "https://source.skip.tools/skip.git", from: "0.8.36"),
        .package(url: "https://source.skip.tools/skip-ui.git", from: "0.0.0"),
        .package(url: "https://source.skip.tools/skip-model.git", from: "0.0.0"),
        .package(url: "https://source.skip.tools/skip-foundation.git", from: "0.0.0"),
        .package(url: "https://github.com/skiptools/skip-sql.git", from: "0.0.0")
    ],
    targets: [
        .target(name: "LAQN", dependencies: ["DataStore", "Model"] + (zero ? [] : [.product(name: "SkipUI", package: "skip-ui")]), resources: [.process("Resources")], plugins: skipstone),
        .testTarget(name: "LAQNTests", dependencies: ["LAQN"] + (zero ? [] : [.product(name: "SkipTest", package: "skip")]), resources: [.process("Resources")], plugins: skipstone),
        .target(name: "DataStore", dependencies: ["Model"] + (zero ? [] : [.product(name: "SkipFoundation", package: "skip-foundation"), .product(name: "SkipModel", package: "skip-model"), .product(name: "SkipSQL", package: "skip-sql")]), resources: [.process("Resources")], plugins: skipstone),
        .testTarget(name: "DataStoreTests", dependencies: ["DataStore"] + (zero ? [] : [.product(name: "SkipTest", package: "skip")]), resources: [.process("Resources")], plugins: skipstone),
        .target(name: "Model", dependencies: [], resources: [.process("Resources")], plugins: skipstone),
        .testTarget(name: "ModelTests", dependencies: ["Model"] + (zero ? [] : [.product(name: "SkipTest", package: "skip")]), resources: [.process("Resources")], plugins: skipstone),
        .target(name: "API", dependencies: ["Model"] + (zero ? [] : [.product(name: "SkipFoundation", package: "skip-foundation")]), resources: [.process("Resources")], plugins: skipstone),
        .testTarget(name: "APITests", dependencies: ["API"] + (zero ? [] : [.product(name: "SkipTest", package: "skip")]), resources: [.process("Resources")], plugins: skipstone),
    ]
)

@marcprux
Copy link
Contributor

I'm not 100% sure, but I suspect that you need to have at least one Skip dependency for Model. Typically, you will depend at least on SkipLib, but usually it will be SkipFoundation so you can use the various Foundation types.

So try changing:

        .target(name: "Model", dependencies: [], resources: [.process("Resources")], plugins: skipstone),

to:

        .target(name: "Model", dependencies: [.product(name: "SkipFoundation", package: "skip-foundation")], resources: [.process("Resources")], plugins: skipstone),

And then re-build the project.

If that doesn't help, let us know and we will keep digging.

@mark-urbanthings
Copy link
Author

Thanks for reply, yes adding the dependency on SkipFoundation fixes the issue.

The Package.swift came about from skip init with the list of 3 modules DataStore, Model, API. In the generated Package.swift Model had a dependency API but not on any skip libraries. Then edited Package.swift to swap dependencies between Model and API thus ending up with Model having no dependencies. Is this a bug with skip tool?

@marcprux
Copy link
Contributor

Running:

skip init --no-module-tests sample-module DataStore Model API

gives me:

import PackageDescription

let package = Package(
    name: "sample-module",
    defaultLocalization: "en",
    platforms: [.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)],
    products: [
        .library(name: "DataStore", targets: ["DataStore"]),
        .library(name: "Model", targets: ["Model"]),
        .library(name: "API", targets: ["API"]),
    ],
    dependencies: [
        .package(url: "https://source.skip.tools/skip.git", from: "0.8.55"),
        .package(url: "https://source.skip.tools/skip-foundation.git", from: "0.0.0")
    ],
    targets: [
        .target(name: "DataStore", dependencies: ["Model"], plugins: [.plugin(name: "skipstone", package: "skip")]),
        .target(name: "Model", dependencies: ["API"], plugins: [.plugin(name: "skipstone", package: "skip")]),
        .target(name: "API", dependencies: [.product(name: "SkipFoundation", package: "skip-foundation")], plugins: [.plugin(name: "skipstone", package: "skip")]),
    ]
)

DataSource depends on Model, which depends on API, which, in turn, has the Skip dependency of SkipFoundation.

Did you perchance remove the dependency of Model on API? That would be fine, but it would need to be replaced by some other Skip module, since there needs to be at least one Skip dependency for the transpiled Gradle package to be buildable.

@mark-urbanthings
Copy link
Author

So only the last module of the three has a dependency on SkipFoundation but not the first two. If you subsequently change dependency order of the modules you need to adjust which has the dependency. Wondering why all modules don't have dependency on SkipFoundation ?

@marcprux
Copy link
Contributor

marcprux commented Jun 24, 2024

In the example above, the first two modules have a transitive dependency on SkipFoundation via API. That's sufficient to create a buildable project. Every module needs to either depend on a Skip module, or depend on a module that depends on a Skip module.

If your skip init project wan't created in a way that wasn't buildable, then that is a bug. Could you post the command that you used to create the project?

@mark-urbanthings
Copy link
Author

The original generated code was buildable, it broke when I changed the dependencies such that not all had a transitive dependency on SkipFoundation. So not a bug 👍.

@marcprux
Copy link
Contributor

Thanks for the info. This is something that we should be able to detect and report a nicer error message like: "Skipstone plugin requires at least one transitive dependency on a Skip module". I'll update the issue report title to that effect.

@marcprux marcprux changed the title Gradle dependency error Skip plugin should report error when the target has no transitive skip dependencies Jun 24, 2024
@marcprux marcprux added the enhancement New feature or request label Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants