aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java173
1 files changed, 114 insertions, 59 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
index ad2eeb0205..dbfd415943 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
@@ -1,56 +1,25 @@
/*
- * Copyright (C) 2015 Obeo.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2015 Obeo. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.hooks;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.PrintStream;
+import java.io.OutputStream;
import java.util.concurrent.Callable;
import org.eclipse.jgit.api.errors.AbortedByHookException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.ProcessResult;
+import org.eclipse.jgit.util.SystemReader;
+import org.eclipse.jgit.util.io.TeeOutputStream;
/**
* Git can fire off custom scripts when certain important actions occur. These
@@ -64,45 +33,75 @@ import org.eclipse.jgit.util.ProcessResult;
* the return type which is expected from {@link #call()}
* @see <a href="http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">Git
* Hooks on the git-scm official site</a>
- * @since 4.0
+ * @since 5.11
*/
-abstract class GitHook<T> implements Callable<T> {
+public abstract class GitHook<T> implements Callable<T> {
private final Repository repo;
/**
* The output stream to be used by the hook.
*/
- protected final PrintStream outputStream;
+ private final OutputStream outputStream;
+
+ /**
+ * The error stream to be used by the hook.
+ */
+ private final OutputStream errorStream;
+
+ /**
+ * Constructor for GitHook.
+ * <p>
+ * This constructor will use stderr for the error stream.
+ * </p>
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ */
+ protected GitHook(Repository repo, OutputStream outputStream) {
+ this(repo, outputStream, null);
+ }
/**
+ * Constructor for GitHook
+ *
* @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
* @param outputStream
* The output stream the hook must use. {@code null} is allowed,
* in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
*/
- protected GitHook(Repository repo, PrintStream outputStream) {
+ protected GitHook(Repository repo, OutputStream outputStream,
+ OutputStream errorStream) {
this.repo = repo;
this.outputStream = outputStream;
+ this.errorStream = errorStream;
}
/**
+ * {@inheritDoc}
+ * <p>
* Run the hook.
- *
- * @throws IOException
- * if IO goes wrong.
- * @throws AbortedByHookException
- * If the hook has been run and a returned an exit code
- * different from zero.
*/
+ @Override
public abstract T call() throws IOException, AbortedByHookException;
/**
+ * Get name of the hook
+ *
* @return The name of the hook, which must not be {@code null}.
*/
public abstract String getHookName();
/**
+ * Get the repository
+ *
* @return The repository.
*/
protected Repository getRepository() {
@@ -131,29 +130,85 @@ abstract class GitHook<T> implements Callable<T> {
}
/**
+ * Get output stream
+ *
* @return The output stream the hook must use. Never {@code null},
* {@code System.out} is returned by default.
*/
- protected PrintStream getOutputStream() {
+ protected OutputStream getOutputStream() {
return outputStream == null ? System.out : outputStream;
}
/**
+ * Get error stream
+ *
+ * @return The error stream the hook must use. Never {@code null},
+ * {@code System.err} is returned by default.
+ */
+ protected OutputStream getErrorStream() {
+ return errorStream == null ? System.err : errorStream;
+ }
+
+ /**
* Runs the hook, without performing any validity checks.
*
- * @throws AbortedByHookException
+ * @throws org.eclipse.jgit.api.errors.AbortedByHookException
* If the underlying hook script exited with non-zero.
+ * @throws IOException
+ * if an IO error occurred
*/
- protected void doRun() throws AbortedByHookException {
+ protected void doRun() throws AbortedByHookException, IOException {
final ByteArrayOutputStream errorByteArray = new ByteArrayOutputStream();
- final PrintStream hookErrRedirect = new PrintStream(errorByteArray);
- ProcessResult result = FS.DETECTED.runHookIfPresent(getRepository(),
- getHookName(), getParameters(), getOutputStream(),
- hookErrRedirect, getStdinArgs());
+ final TeeOutputStream stderrStream = new TeeOutputStream(errorByteArray,
+ getErrorStream());
+ Repository repository = getRepository();
+ FS fs = repository.getFS();
+ if (fs == null) {
+ fs = FS.DETECTED;
+ }
+ ProcessResult result = fs.runHookIfPresent(repository, getHookName(),
+ getParameters(), getOutputStream(), stderrStream,
+ getStdinArgs());
if (result.isExecutedWithError()) {
- throw new AbortedByHookException(errorByteArray.toString(),
- getHookName(), result.getExitCode());
+ handleError(new String(errorByteArray.toByteArray(),
+ SystemReader.getInstance().getDefaultCharset().name()),
+ result);
+ }
+ }
+
+ /**
+ * Process that the hook exited with an error. This default implementation
+ * throws an {@link AbortedByHookException }. Hooks which need a different
+ * behavior can overwrite this method.
+ *
+ * @param message
+ * error message
+ * @param result
+ * The process result of the hook
+ * @throws AbortedByHookException
+ * When the hook should be aborted
+ * @since 5.11
+ */
+ protected void handleError(String message,
+ final ProcessResult result)
+ throws AbortedByHookException {
+ throw new AbortedByHookException(message, getHookName(),
+ result.getExitCode());
+ }
+
+ /**
+ * Check whether a 'native' (i.e. script) hook is installed in the
+ * repository.
+ *
+ * @return whether a native hook script is installed in the repository.
+ * @since 4.11
+ */
+ public boolean isNativeHookPresent() {
+ FS fs = getRepository().getFS();
+ if (fs == null) {
+ fs = FS.DETECTED;
}
+ return fs.findHook(getRepository(), getHookName()) != null;
}
-} \ No newline at end of file
+}