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

[BUG][Gradle plugin] templateDir can't refer to a classpath anymore #14455

Closed
SardarNL opened this issue Jan 13, 2023 · 6 comments
Closed

[BUG][Gradle plugin] templateDir can't refer to a classpath anymore #14455

SardarNL opened this issue Jan 13, 2023 · 6 comments

Comments

@SardarNL
Copy link

SardarNL commented Jan 13, 2023

Description

templateDir could be assigned a/path/to/directory which will be looked up in different places, including classpath set via buildsript:

# build.gradle
tasks.register("my-task", org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
    generatorName = "java"
    library = "webclient"
    inputSpec = "${projectDir}/src/main/resources/spec.yaml"
    outputDir = "${projectDir}/generated/openapi/client"
    templateDir = "a/path/to/directory"
}

# settings.gradle
buildscript {
    dependencies {
        classpath "my.group:my-library-with-templates"
    }
}

This feature made it possible to provide templates in a .jar dependency instead of keeping it with the project source code. After all, there many many services and just one custom x-my-feature implementation used in OpenAPI spec yaml.

The latest change added @PathSensitive(PathSensitivity.RELATIVE) to templateDir property which forces lookup in the current directory relative to build.gradle file.

With that change, it became impossible to refer to templates in the classpath. Is there a way to specify templates from the classpath explicitly (classpath: prefix doesn't work)? Or maybe is there a way to revert that change as it was vastly superior before.

latest org.openapi.generator Gradle plugin version which works 6.2.0
first org.openapi.generator version which doesn't work 6.2.1 (latest)
gradle version 7.4.x to 7.6 - in all of them this issue happens

Generation Details
A problem was found with the configuration of task ':my-generate-task' (type 'GenerateTask').
  - In plugin 'org.openapi.generator' type 'org.openapitools.generator.gradle.plugin.tasks.GenerateTask' property 'templateDir' specifies directory '/absolute/path/to/project/path/to/templates' which doesn't exist.

Note that path/to/templates does exist on the classpath, but gradle plugin looks for a relative path to build.gradle only. So it looks in the project code (user of x-my-feature) and doesn't look for templates in buildscript classpath where necessary templates were provided as a dependency. This setup did work perfectly before.

Steps to reproduce

Create a .jar with your custom templates. Add them to buildscript/dependencies/classpath. Configure the generator with templateDir = path/to/templates/in/jar. The generator will fail with a complaint that directory doesn't exist.

Related issues/PRs

I believe this pull request introduced the regression.

Suggest a fix

Don't annotate templateDir with PathSensitivity?

@wing328
Copy link
Member

wing328 commented Jan 13, 2023

@SardarNL thanks for reporting the issue.

cc @erichaagdev

@erichaagdev
Copy link
Contributor

erichaagdev commented Jan 13, 2023

Thanks for reporting this! This is not a bug.

I do not believe the suggested fix of removing the PathSensitivity annotation from templateDir is the correct answer. Removing the annotation would negatively impact build cacheability, the reason why the annotation was added in the first place.

Using files from the file system, dependencies, or archives in Gradle tasks is very common. The typical way to accomplish this is to actually split the work being done into two tasks.

In the context of the OpenAPI Generator Gradle plugin, the first task is a Copy task and copies the required template files from /absolute/path/to/project/path/to/templates, or from a project dependency, into a well-known directory within the project's build directory (e.g. build/templates/openapi). The second task is a GenerateTask and consumes from this well-known directory. For example:

def templateDir = layout.buildDirectory.dir('templates/openapi')

def copyOpenApiTask = tasks.register("copyOpenApi", Copy) {
    from '/absolute/path/to/project/path/to/templates'
    into templateDir
}

tasks.register("generateOpenApi", org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
    // ...
    dependsOn copyOpenApiTask
    templateDir = templateDir.get().asFile.path
}

@SardarNL
Copy link
Author

SardarNL commented Jan 13, 2023

Looks like copying from .jar build dependency is a bit more involved than simple Copy, but this is indeed a working solution.

Copying on every build touches all template files. I wonder if this fact messes up with generateOpenApi caching.

@erichaagdev
Copy link
Contributor

Looks like copying from .jar build dependency is a bit more involved than simple Copy, but this is indeed a working solution.

Yes, unfortunately a few more steps will be required. In general you will have to:

  1. Create a new configuration for your template dependency (e.g. openApiTemplates)
  2. Wire the Copy task to copy "from" the new configuration, filtering files if necessary.

From here, the rest of the configuration is the same as my previous comment.

I wonder if this fact messes up with generateOpenApi caching.

This is part of the reason why it is recommended to split the copying and generation to two tasks. Copy tasks are cheap and non-cacheable by default. It is okay that they are executed on each build. The Copy task executing on each build will not impact the cacheability of the generate task.

@SardarNL
Copy link
Author

Thanks!

@erichaagdev
Copy link
Contributor

My pleasure! If you still have questions or want help on the implementation, please consider joining the openapi-generator Slack. Or, as this issue is more related to Gradle, the Gradle Community Slack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants