All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ajoberstar.gradle.git.ghpages.GithubPagesPlugin.groovy Maven / Gradle / Ivy

There is a newer version: 1.7.2
Show newest version
/*
 * Copyright 2012-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.ajoberstar.gradle.git.ghpages

import org.ajoberstar.grgit.Grgit
import org.ajoberstar.grgit.operation.ResetOp
import org.ajoberstar.grgit.exception.GrgitException
import org.eclipse.jgit.errors.RepositoryNotFoundException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.Copy

/**
 * Plugin to enable publishing to gh-pages branch of Github.
 * @since 0.1.0
 */
class GithubPagesPlugin implements Plugin {
    static final String PREPARE_TASK_NAME = 'prepareGhPages'
    static final String PUBLISH_TASK_NAME = 'publishGhPages'

    /**
     * Applies the plugin to the given project.
     * @param project the project
     */
    void apply(Project project) {
        GithubPagesPluginExtension extension = project.extensions.create('githubPages', GithubPagesPluginExtension, project)
        configureTasks(project, extension)
    }

    /**
     * Configures the tasks to publish to gh-pages.
     * @param project the project to configure
     * @param extension the plugin extension
     */
    private void configureTasks(final Project project, final GithubPagesPluginExtension extension) {
        Task prepare = createPrepareTask(project, extension)
        Task publish = createPublishTask(project, extension)
        publish.dependsOn(prepare)
    }

    private Task createPrepareTask(Project project, GithubPagesPluginExtension extension) {
        Task task = project.tasks.create(PREPARE_TASK_NAME, Copy)
        task.with {
            description = 'Prepare the gh-pages changes locally'
            with extension.pages.realSpec
            into { extension.workingDir }
            doFirst {
                def repo = repo(project, extension)
                if (extension.deleteExistingFiles) {
                    def relDestDir = extension.pages.relativeDestinationDir
                    def targetDir = new File(extension.workingDir, relDestDir)
                    def filesList = targetDir.list { dir, name -> !name.equals('.git') }
                    if(filesList) {
                        def removePatterns = filesList
                        if(relDestDir && relDestDir != '.') {
                            removePatterns = filesList.collect {name -> "$relDestDir/$name"}
                        }
                        repo.remove(patterns: removePatterns)
                    }
                }
            }
            doLast {
                def repo = repo(project, extension)
                repo.with {
                    add(patterns: ['.'])
                    if (status().clean) {
                        project.logger.warn 'Nothing to commit, skipping publish.'
                    } else {
                        commit(message: extension.commitMessage)
                    }
                }
            }
        }
        return task
    }

    private Task createPublishTask(Project project, GithubPagesPluginExtension extension) {
        return project.tasks.create(PUBLISH_TASK_NAME) {
            description = 'Publishes all gh-pages changes to Github'
            group = 'publishing'
            // only push if there are commits to push
            onlyIf {
                def repo = repo(project, extension)
                def status = repo.branch.status(name: repo.branch.current)
                status.aheadCount > 0
            }
            doLast {
                repo(project, extension).push()
            }
        }
    }

    private Grgit repo(Project project, GithubPagesPluginExtension extension) {
        if (extension.ext.has('repo')) {
            return extension.ext.repo
        }
        def repo = null
        try {
            // attempt to reuse existing repository
            repo = Grgit.open(dir: extension.workingDir)
            if (extension.repoUri == repo.remote.list().find { it.name == 'origin' }?.url &&
                    repo.branch.current.name == extension.targetBranch) {
                repo.clean(directories: true, ignore: false)
                repo.fetch()
                repo.reset(commit: 'origin/' + extension.targetBranch, mode: ResetOp.Mode.HARD)
            }
            else {
                logger.warn('Found a git repository at workingDir, but it does not match configuration. A fresh clone will be used.')
                repo.close()
                repo = null
            }
        } catch (RepositoryNotFoundException ignored) {
            // not a git repo
        } catch (GrgitException ignored) {
            // invalid/corrup git repo
        }

        if (!repo) {
            extension.workingDir.deleteDir()
            repo = Grgit.clone(
                uri: extension.repoUri,
                refToCheckout: extension.targetBranch,
                dir: extension.workingDir,
                credentials: extension.credentials?.toGrgit()
            )

            // check if on the correct branch, which implies it doesn't exist
            if (repo.branch.current.name != extension.targetBranch) {
                repo.checkout(branch: extension.targetBranch, orphan: true)
                // need to wipe out the current files
                extension.deleteExistingFiles = true
            }
        }
        extension.ext.repo = repo
        return repo
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy