Package org.kathrynhuxtable.maven.wagon.gitsite.git

Source Code of org.kathrynhuxtable.maven.wagon.gitsite.git.GitSiteCheckInCommand

/*
* Copyright (c) 2010 Kathryn Huxtable
*
* 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.kathrynhuxtable.maven.wagon.gitsite.git;

import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFile;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.ScmFileStatus;
import org.apache.maven.scm.ScmVersion;
import org.apache.maven.scm.command.checkin.AbstractCheckInCommand;
import org.apache.maven.scm.command.checkin.CheckInScmResult;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.git.command.GitCommand;
import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils;
import org.apache.maven.scm.provider.git.gitexe.command.add.GitAddCommand;
import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
import org.apache.maven.scm.provider.git.util.GitUtil;

import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;

/**
* Handle git check-in and push to remote site.
*
* <p>Based on GitCheckInCommand by Mark Struberg.</p>
*
* @author Kathryn Huxtable
* @see    org.apache.maven.scm.provider.git.gitexe.command.checkin.GitCheckInCommand
*/
public class GitSiteCheckInCommand extends AbstractCheckInCommand implements GitCommand {

    /**
     * @see org.apache.maven.scm.command.checkin.AbstractCheckInCommand#executeCheckInCommand(org.apache.maven.scm.provider.ScmProviderRepository,
     *      org.apache.maven.scm.ScmFileSet, java.lang.String,
     *      org.apache.maven.scm.ScmVersion)
     */
    protected CheckInScmResult executeCheckInCommand(ScmProviderRepository repo, ScmFileSet fileSet, String message, ScmVersion version)
        throws ScmException {
        GitScmProviderRepository repository = (GitScmProviderRepository) repo;

        CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
        CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();

        int exitCode;

        File messageFile = FileUtils.createTempFile("maven-scm-", ".commit", null);

        try {
            FileUtils.fileWrite(messageFile.getAbsolutePath(), message);
        } catch (IOException ex) {
            return new CheckInScmResult(null, "Error while making a temporary file for the commit message: " + ex.getMessage(), null,
                                        false);
        }

        try {
            Commandline cl = null;

            if (!fileSet.getFileList().isEmpty()) {
                // If specific fileSet is given, we have to git-add them first,
                // otherwise we will use 'git-commit -a' later.
                cl       = GitAddCommand.createCommandLine(fileSet.getBasedir(), fileSet.getFileList());
                exitCode = GitCommandLineUtils.execute(cl, stdout, stderr, getLogger());
                if (exitCode != 0) {
                    return new CheckInScmResult(cl.toString(), "The git-add command failed.", stderr.getOutput(), false);
                }
            }

            // The git-commit command doesn't show single files, but only summary :/
            // so we must run git-status and consume the output.
            // Borrow a few things from the git-status command.
            GitStatusConsumer statusConsumer = new GitStatusConsumer(getLogger(), fileSet.getBasedir());

            cl       = GitStatusCommand.createCommandLine(repository, fileSet);
            exitCode = GitCommandLineUtils.execute(cl, statusConsumer, stderr, getLogger());
            if (exitCode != 0) {
                // git-status returns non-zero if nothing to do.
                if (getLogger().isInfoEnabled()) {
                    getLogger().info("nothing added to commit but untracked files present (use \"git add\" to "
                                     + "track)");
                }
            }

            cl       = createCommitCommandLine(fileSet, messageFile);
            exitCode = GitCommandLineUtils.execute(cl, stdout, stderr, getLogger());
            if (exitCode != 0) {
                return new CheckInScmResult(cl.toString(), "The git-commit command failed.", stderr.getOutput(), false);
            }

            cl       = createPushCommandLine(fileSet, repository, version);
            exitCode = GitCommandLineUtils.execute(cl, stdout, stderr, getLogger());
            if (exitCode != 0) {
                return new CheckInScmResult(cl.toString(), "The git-push command failed.", stderr.getOutput(), false);
            }

            List<ScmFile> checkedInFiles = new ArrayList<ScmFile>(statusConsumer.getChangedFiles().size());

            // rewrite all detected files to now have status 'checked_in'
            for (Object foo : statusConsumer.getChangedFiles()) {
                ScmFile scmfile = new ScmFile(((ScmFile) foo).getPath(), ScmFileStatus.CHECKED_IN);

                if (fileSet.getFileList().isEmpty()) {
                    checkedInFiles.add(scmfile);
                } else {
                    // If a specific fileSet is given, we have to check if the file is really tracked.
                    for (Iterator<?> itfl = fileSet.getFileList().iterator(); itfl.hasNext();) {
                        File f = (File) itfl.next();

                        if (f.toString().equals(scmfile.getPath())) {
                            checkedInFiles.add(scmfile);
                        }
                    }
                }
            }

            return new CheckInScmResult(cl.toString(), checkedInFiles);
        } finally {
            try {
                FileUtils.forceDelete(messageFile);
            } catch (IOException ex) {
                // ignore
            }
        }
    }

    /**
     * Create the "git commit" command line.
     *
     * @param  fileSet     the file set to commit.
     * @param  messageFile the file containing the commit message.
     *
     * @return the command line to commit the changes.
     *
     * @throws ScmException if an error occurs.
     */
    private Commandline createCommitCommandLine(ScmFileSet fileSet, File messageFile) throws ScmException {
        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine(fileSet.getBasedir(), "commit");

        cl.createArg().setValue("--verbose");

        cl.createArg().setValue("--allow-empty");

        cl.createArg().setValue("-F");

        cl.createArg().setValue(messageFile.getAbsolutePath());

        if (fileSet.getFileList().isEmpty()) {
            // commit all tracked files
            cl.createArg().setValue("-a");
        } else {
            // specify exactly which files to commit
            GitCommandLineUtils.addTarget(cl, fileSet.getFileList());
        }

        if (GitUtil.getSettings().isCommitNoVerify()) {
            cl.createArg().setValue("--no-verify");
        }

        return cl;
    }

    /**
     * Create the "git push origin" command.
     *
     * @param  fileSet    the file set.
     * @param  repository the SCM repository.
     * @param  version    the site branch.
     *
     * @return the command line to push the changes to the site branch.
     */
    private Commandline createPushCommandLine(ScmFileSet fileSet, GitScmProviderRepository repository, ScmVersion version) {
        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine(fileSet.getBasedir(), "push");

        cl.createArg().setValue("origin");

        cl.createArg().setValue("master:" + version.getName());

        return cl;
    }
}
TOP

Related Classes of org.kathrynhuxtable.maven.wagon.gitsite.git.GitSiteCheckInCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.