Andrew Grosner
Andrew Grosner

Reputation: 2387

Artifactory + Custom Gradle Plugin Programmatically

I am writing a custom plugin to eliminate the need for:

artifactory {
    contextUrl = "${artifactory_contextUrl}"   //The base Artifactory URL if not overridden by the publisher/resolver
    publish {
        repository {
            contextUrl = "${artifactory_contextUrl}"
            repoKey = 'android-dev'
            username = "${artifactory_user}"
            password = "${artifactory_password}"
            maven = true

        }
    }
    resolve {
        repository {
            contextUrl = "${artifactory_contextUrl}"
            repoKey = 'android-dev-distributions'
            username = "${artifactory_user}"
            password = "${artifactory_password}"
            maven = true

        }
    }
}

Here is how I am doing this programmatically:

 DefaultExtraPropertiesExtension ext = (((DefaultExtraPropertiesExtension) project.property("ext")));
        ext.setProperty("artifactory", new ArtifactoryDsl(contextUrl, publish, resolve));

This should work, correct? The ArtifactoryDsl object has all of the correct fields (contextUrl, publish, resolve with their respective inner fields).

This is the error:

14:46:49.752 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: java.lang.IllegalStateException:    Context URL cannot be empty
14:46:49.753 [ERROR] [org.gradle.BuildExceptionReporter]    at org.jfrog.build.client.ArtifactoryClientConfiguration.getContextUrl(ArtifactoryClientConfiguration.java:111)
14:46:49.754 [ERROR] [org.gradle.BuildExceptionReporter]    at org.jfrog.build.client.ArtifactoryClientConfiguration$PublisherHandler.getContextUrl(ArtifactoryClientConfiguration.java:225)
14:46:49.754 [ERROR] [org.gradle.BuildExceptionReporter]    at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask.prepareAndDeploy(BuildInfoTask.java:526)
14:46:49.755 [ERROR] [org.gradle.BuildExceptionReporter]    at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask.collectProjectBuildInfo(BuildInfoTask.java:440)
14:46:49.755 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
14:46:49.755 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219)
14:46:49.756 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212)
14:46:49.756 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201)
14:46:49.757 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533)
14:46:49.757 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516)
14:46:49.758 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
14:46:49.777 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
14:46:49.778 [ERROR] [org.gradle.BuildExceptionReporter]    ... 66 more

Upvotes: 1

Views: 2988

Answers (3)

Anis CAMPOS
Anis CAMPOS

Reputation: 93

Thanks a lot @agrosner, i was looking for a very long time as well and your answer saved my day !

For anyone that wants to implement their plugin with groovy, here is my implementation based on the previous post:

PS: I'm using org.jfrog.buildinfo:build-info-extractor-gradle:4.9.8 and mave-publish

PS 2: For some reason it was necessary to apply maven to the root project as well as. otherwise you had the error Extension of type 'PublishingExtension' does not exist. Currently registered extension types: [ExtraPropertiesExtension]

class Plugin implements Plugin<Project> {
    @Override
    void apply(Project project) {

        //Maven publication plugin needs to be applied to root also
        project.rootProject.pluginManager.apply "maven-publish"
        project.pluginManager.apply "maven-publish"

        project.plugins.apply "com.jfrog.artifactory"


        def artifactory_contextUrl = project.artifactory_contextUrl
        def artifactory_writer_user = project.artifactory_writer_user
        def artifactory_writer_password = project.artifactory_writer_password

        // We will define the plugin convention here so all of our libraries do not need to
        // declare the artifactory closure manually
        ArtifactoryPluginConvention pluginConvention = ArtifactoryPluginUtil.getArtifactoryConvention(project)
        //uses closures to set the configuration
        pluginConvention.artifactory {
            contextUrl = "${artifactory_contextUrl}"
            publish{
                repository {
                    repoKey = 'repo name here'
                    username = "${artifactory_writer_user}"
                    password = "${artifactory_writer_password}"
                    maven = true
                }
                defaults {
                    publications('plugin')
                }
            }
        }
//commits changes
GradleArtifactoryClientConfigUpdater.update(pluginConvention.clientConfig, project.rootProject)


    }
}

Upvotes: 1

Andrew Grosner
Andrew Grosner

Reputation: 2387

For anyone who is curious how to achieve this, I had done it this way:

In your build.gradle ensure you can access Artifactory classes:

compile "org.jfrog.buildinfo:build-info-extractor-gradle:2.2.4"

Next in your custom plugin's apply() method:

        // Set up plugins so we never need to add them to a build.gradle
        project.getPlugins().apply(MAVEN);
        project.getPlugins().apply(ARTIFACTORY);
        project.setGroup(GROUP);

        // Add Artifactory repo to the repositories
        project.getRepositories().maven(new ArtifactoryAction(contextUrl + ARTIFACTORY_REPO_ENDPOINT, user, pass));

        // We will define the plugin convention here so all of our libraries do not need to
        // declare the artifactory closure manually
        ArtifactoryPluginConvention pluginConvention =
                ArtifactoryPluginUtil.getArtifactoryConvention(project);
        pluginConvention.setContextUrl(contextUrl);

        PublisherConfig publisherConfig = new PublisherConfig(pluginConvention);
        publisherConfig.setContextUrl(contextUrl);
        pluginConvention.setPublisherConfig(publisherConfig);

        // Use reflection to access private field
        PublisherConfig.Repository repository = null;

        Field[] fields = PublisherConfig.class.getDeclaredFields();
        for(Field field : fields) {
            if(field.getName().equalsIgnoreCase("repository")) {
                try {
                    field.setAccessible(true);
                    repository = (PublisherConfig.Repository) field.get(publisherConfig);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        if(repository != null) {
            repository.setPassword(pass);
            repository.setUsername(user);
            repository.setRepoKey(PUBLISHER_REPO_KEY);
            repository.setMavenCompatible(true);
        }

        GradleArtifactoryClientConfigUpdater.update(pluginConvention.getClientConfig(), project.getRootProject());

Upvotes: 2

Peter Niederwieser
Peter Niederwieser

Reputation: 123910

No, this isn't going to work. Your plugin will have to apply the Artifactory plugin, then get the artifactory object using project.artifactory (Groovy) or project.getExtensions().getByName("artifactory") (Java), then configure that object.

Upvotes: 4

Related Questions