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

Unable to get the plugin to work for repositories within a pluginManagement block #227

Open
lestephane opened this issue Sep 21, 2021 · 5 comments

Comments

@lestephane
Copy link

lestephane commented Sep 21, 2021

As I don't see any pluginManagement in your README.md, I assume it's not supported.

Are you aware of any such limitation?

This is what I'm trying to do:

pluginManagement {
    repositories {
        maven {
            url = uri(
                "https://SCRUBBED.codeartifact.REGION.amazonaws.com/maven/SCRUBBED/"
            )
        }
    }
}

As I intend to publish gradle plugins to CodeArtifact, other projects need a way to consume said plugins...

@lestephane
Copy link
Author

This allowed me to add pluginManagement repositories support for CodeArtifact

@TypeChecked
class CodeArtifactPluginRepositoriesPlugin implements Plugin<Settings> {
    void apply(Settings settings) {
        def gradle = settings.getGradle()
        def pluginRepositories = settings.pluginManagement.repositories
        SharedFunctions.setupCodeartifactRepositoriesByUrl(gradle, pluginRepositories)
    }
}

It would be better if this could be baked into the library so that others can profit from it.

I don't have a PR because:

  • the setupCodeartifactRepositories() variant seems to be doing some magic that does not allow me to use @TypeChecked (so I had to comment it out entirely), and that capability (adding repository through a codeartifact{} block??) is not mentioned in the README.md.
  • a logger is not available when dealing with Settings (at least, none that I can find). So I had to use println instead to cover the Project and the Settings execution path in the shared configRepositories(RepositoryHandler repositories, Provider<CodeArtifactToken> serviceProvider) function.
@TypeChecked
class CodeArtifactRepositoriesPlugin implements Plugin<Project> {
    void apply(Project project) {
        def gradle = project.getGradle()

        //setupCodeartifactRepositories(project, serviceProvider) <-- magic
        SharedFunctions.setupCodeartifactRepositoriesByUrl(gradle, project.repositories)
    }
}

Other than that the SharedFunctions contains the functions required by both plugins

package ai.clarity.codeartifact

import groovy.transform.TypeChecked
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.invocation.Gradle
import org.gradle.api.provider.Provider

@TypeChecked
class SharedFunctions {

    static Provider<CodeArtifactToken> codeArtifactTokenProviderFor(Gradle gradle) {
        return gradle
                .getSharedServices()
                .registerIfAbsent('codeartifact-token', CodeArtifactToken.class, {})
    }

    static void setupCodeartifactRepositoriesByUrl(Gradle gradle, RepositoryHandler repositories) {
        configRepositories(repositories, codeArtifactTokenProviderFor(gradle))
    }

    private static void configRepositories(RepositoryHandler repositories, Provider<CodeArtifactToken> serviceProvider) {
        ListIterator it = repositories.listIterator()
        while (it.hasNext()) {
            def artifactRepository = it.next()
            if (artifactRepository instanceof MavenArtifactRepository) {
                MavenArtifactRepository mavenRepo = (MavenArtifactRepository) artifactRepository;
                URI repoUri = mavenRepo.getUrl()
                if (isCodeArtifactUri(repoUri) && areCredentialsEmpty(mavenRepo)) {
                    String profile = getProfileFromUri(repoUri, getDefaultProfile())
                    //logger.info('Getting token for {} in profile {}', repoUri.toString(), profile)   <-- no logger for Settings
                    println("Getting token for $repoUri in profile $profile")
                    String token = serviceProvider.get().getToken(repoUri, profile)
                    mavenRepo.credentials({
                        it.username = 'aws'
                        it.password = token
                    })
                    mavenRepo.setUrl(removeProfile(repoUri))
                }
            }
        }
    }

    private static String getDefaultProfile() {
...
    }

    private static URI removeProfile(URI uri) {
...
    }

    private static boolean areCredentialsEmpty(MavenArtifactRepository mavenRepo) {
...
    }

    private static boolean isCodeArtifactUri(URI uri) {
...
    }

    private static String getProfileFromUri(URI uri, String defaultValue) {
...
    }
}

And the gradlePlugin block declares each of them separately

gradlePlugin {
    plugins {
        codeArtifactRepositories {
            id = 'ai.clarity.codeartifact.repositories'
            implementationClass = 'ai.clarity.codeartifact.CodeArtifactRepositoriesPlugin'
        }
        codeArtifactPluginRepositories {
            id = 'ai.clarity.codeartifact.pluginRepositories'
            implementationClass = 'ai.clarity.codeartifact.CodeArtifactPluginRepositoriesPlugin'
        }
    }
}

@lestephane
Copy link
Author

I'm going to submit a PR, with the smallest change possible, as I was unable to refactor effectively in the absence of type checking (some errors only show up at runtime, after publishing the plugin, making the refactoring experience hell).

@lestephane
Copy link
Author

Created a PR (#230). Keep what you like and throw the rest away.

@lestephane
Copy link
Author

Updated #230

@lestephane
Copy link
Author

Updated PR #230 hopefully for the last time.

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

No branches or pull requests

1 participant