001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm.provider.git.gitexe;
020
021import javax.inject.Named;
022import javax.inject.Singleton;
023
024import java.io.File;
025import java.util.HashMap;
026import java.util.Map;
027
028import org.apache.maven.scm.ScmException;
029import org.apache.maven.scm.ScmFileSet;
030import org.apache.maven.scm.command.info.InfoScmResult;
031import org.apache.maven.scm.provider.git.AbstractGitScmProvider;
032import org.apache.maven.scm.provider.git.command.GitCommand;
033import org.apache.maven.scm.provider.git.gitexe.command.add.GitAddCommand;
034import org.apache.maven.scm.provider.git.gitexe.command.blame.GitBlameCommand;
035import org.apache.maven.scm.provider.git.gitexe.command.branch.GitBranchCommand;
036import org.apache.maven.scm.provider.git.gitexe.command.changelog.GitChangeLogCommand;
037import org.apache.maven.scm.provider.git.gitexe.command.checkin.GitCheckInCommand;
038import org.apache.maven.scm.provider.git.gitexe.command.checkout.GitCheckOutCommand;
039import org.apache.maven.scm.provider.git.gitexe.command.diff.GitDiffCommand;
040import org.apache.maven.scm.provider.git.gitexe.command.info.GitInfoCommand;
041import org.apache.maven.scm.provider.git.gitexe.command.remoteinfo.GitRemoteInfoCommand;
042import org.apache.maven.scm.provider.git.gitexe.command.remove.GitRemoveCommand;
043import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
044import org.apache.maven.scm.provider.git.gitexe.command.tag.GitTagCommand;
045import org.apache.maven.scm.provider.git.gitexe.command.untag.GitUntagCommand;
046import org.apache.maven.scm.provider.git.gitexe.command.update.GitUpdateCommand;
047import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
048import org.apache.maven.scm.repository.ScmRepositoryException;
049
050/**
051 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
052 */
053@Singleton
054@Named("git")
055public class GitExeScmProvider extends AbstractGitScmProvider {
056    private final Map<String, String> environmentVariables;
057
058    /**
059     * The environment variable that controls whether Git prompts for credentials in the terminal.
060     *
061     * @see <a href="https://git-scm.com/docs/git-credential#Documentation/git-credential.txt-envGIT_TERMINAL_PROMPT">GIT_TERMINAL_PROMPT</a>
062     */
063    private static final String GIT_TERMINAL_PROMPT = "GIT_TERMINAL_PROMPT";
064
065    public GitExeScmProvider() {
066        environmentVariables = new HashMap<>();
067    }
068
069    @Override
070    public void setInteractive(boolean interactive) {
071        if (interactive) {
072            // This is the default behavior therefore make sure to remove the variable if it was set before.
073            environmentVariables.remove(GIT_TERMINAL_PROMPT);
074        } else {
075            environmentVariables.put(GIT_TERMINAL_PROMPT, "0");
076        }
077    }
078
079    /**
080     * {@inheritDoc}
081     */
082    protected GitCommand getAddCommand() {
083        return new GitAddCommand();
084    }
085
086    /**
087     * {@inheritDoc}
088     */
089    protected GitCommand getBranchCommand() {
090        return new GitBranchCommand(environmentVariables);
091    }
092
093    /**
094     * {@inheritDoc}
095     */
096    protected GitCommand getChangeLogCommand() {
097        return new GitChangeLogCommand();
098    }
099
100    /**
101     * {@inheritDoc}
102     */
103    protected GitCommand getCheckInCommand() {
104        return new GitCheckInCommand(environmentVariables);
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    protected GitCommand getCheckOutCommand() {
111        return new GitCheckOutCommand(environmentVariables);
112    }
113
114    /**
115     * {@inheritDoc}
116     */
117    protected GitCommand getDiffCommand() {
118        return new GitDiffCommand();
119    }
120
121    /**
122     * {@inheritDoc}
123     */
124    protected GitCommand getExportCommand() {
125        return null; // X TODO
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    protected GitCommand getRemoveCommand() {
132        return new GitRemoveCommand();
133    }
134
135    /**
136     * {@inheritDoc}
137     */
138    protected GitCommand getStatusCommand() {
139        return new GitStatusCommand();
140    }
141
142    /**
143     * {@inheritDoc}
144     */
145    protected GitCommand getTagCommand() {
146        return new GitTagCommand(environmentVariables);
147    }
148
149    /**
150     * {@inheritDoc}
151     */
152    protected GitCommand getUntagCommand() {
153        return new GitUntagCommand(environmentVariables);
154    }
155
156    /**
157     * {@inheritDoc}
158     */
159    protected GitCommand getUpdateCommand() {
160        return new GitUpdateCommand();
161    }
162
163    /**
164     * {@inheritDoc}
165     */
166    public GitCommand getInfoCommand() {
167        return new GitInfoCommand();
168    }
169
170    /**
171     * {@inheritDoc}
172     */
173    protected GitCommand getBlameCommand() {
174        return new GitBlameCommand();
175    }
176
177    /**
178     * {@inheritDoc}
179     */
180    protected GitCommand getRemoteInfoCommand() {
181        return new GitRemoteInfoCommand(environmentVariables);
182    }
183
184    /**
185     * {@inheritDoc}
186     */
187    protected String getRepositoryURL(File path) throws ScmException {
188        // Note: I need to supply just 1 absolute path, but ScmFileSet won't let me without
189        // a basedir (which isn't used here anyway), so use a dummy file.
190        // and a dummy ScmProviderRepository
191        InfoScmResult result =
192                info(new GitScmProviderRepository(path.toPath().toUri().toASCIIString()), new ScmFileSet(path), null);
193
194        if (result.getInfoItems().size() != 1) {
195            throw new ScmRepositoryException("Cannot find URL: "
196                    + (result.getInfoItems().size() == 0 ? "no" : "multiple") + " items returned by the info command");
197        }
198
199        return result.getInfoItems().get(0).getURL();
200    }
201
202    public void setEnvironmentVariable(String key, String value) {
203        environmentVariables.put(key, value);
204    }
205}