Ability to fetch all heads only if build's commit is not found on the agent
[teamcity/git-plugin.git] / git-agent / src / jetbrains / buildServer / buildTriggers / vcs / git / agent / PluginConfigImpl.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package jetbrains.buildServer.buildTriggers.vcs.git.agent;
18
19 import jetbrains.buildServer.agent.AgentRunningBuild;
20 import jetbrains.buildServer.agent.AgentRuntimeProperties;
21 import jetbrains.buildServer.agent.BuildAgentConfiguration;
22 import jetbrains.buildServer.buildTriggers.vcs.git.GitVcsRoot;
23 import jetbrains.buildServer.buildTriggers.vcs.git.agent.command.impl.CommandUtil;
24 import jetbrains.buildServer.util.StringUtil;
25 import org.apache.log4j.Logger;
26 import org.jetbrains.annotations.NotNull;
27
28 import java.io.File;
29 import java.util.Map;
30
31 /**
32  * @author dmitry.neverov
33  */
34 public class PluginConfigImpl implements AgentPluginConfig {
35
36   private final static Logger LOG = Logger.getLogger(PluginConfigImpl.class);
37
38   public static final String IDLE_TIMEOUT = "teamcity.git.idle.timeout.seconds";
39   public static final String USE_NATIVE_SSH = "teamcity.git.use.native.ssh";
40   public static final String USE_MIRRORS = "teamcity.git.use.local.mirrors";
41   public static final String USE_ALTERNATES = "teamcity.git.useAlternates";
42   public static final String USE_SHALLOW_CLONE = "teamcity.git.use.shallow.clone";
43   public static final String TEAMCITY_DONT_DELETE_TEMP_FILES = "teamcity.dont.delete.temp.files";
44   public static final String USE_MAIN_REPO_USER_FOR_SUBMODULES = "teamcity.git.useMainRepoUserForSubmodules";
45   public static final String VCS_ROOT_MIRRORS_STRATEGY = "teamcity.git.mirrorStrategy";
46   public static final String VCS_ROOT_MIRRORS_STRATEGY_ALTERNATES = "alternates";
47   public static final String VCS_ROOT_MIRRORS_STRATEGY_MIRRORS_ONLY = "mirrors";
48   public static final String USE_SPARSE_CHECKOUT = "teamcity.git.useSparseCheckout";
49   public static final String USE_BUILD_ENV = "teamcity.git.useBuildEnv";
50   public static final String FETCH_ALL_HEADS = "teamcity.git.fetchAllHeads";
51   public static final String FETCH_TAGS = "teamcity.git.fetchTags";
52   public static final String EXCLUDE_USERNAME_FROM_HTTP_URL = "teamcity.git.excludeUsernameFromHttpUrl";
53   public static final String CLEAN_CRED_HELPER_SCRIPT = "teamcity.git.cleanCredHelperScript";
54   public static final String PROVIDE_CRED_HELPER = "teamcity.git.provideCredentialHelper";
55
56   private final BuildAgentConfiguration myAgentConfig;
57   private final AgentRunningBuild myBuild;
58   private final GitExec myGitExec;
59
60   public PluginConfigImpl(@NotNull BuildAgentConfiguration agentConfig,
61                           @NotNull AgentRunningBuild build,
62                           @NotNull GitExec gitExec) {
63     myAgentConfig = agentConfig;
64     myBuild = build;
65     myGitExec = gitExec;
66   }
67
68
69   @NotNull
70   public File getCachesDir() {
71     return myAgentConfig.getCacheDirectory("git");
72   }
73
74
75   public int getIdleTimeoutSeconds() {
76     String valueFromBuild = myBuild.getSharedConfigParameters().get(IDLE_TIMEOUT);
77     if (valueFromBuild != null)
78       return parseTimeout(valueFromBuild);
79     else
80       return DEFAULT_IDLE_TIMEOUT;
81   }
82
83
84   @NotNull
85   public String getPathToGit() {
86     return myGitExec.getPath();
87   }
88
89
90   public boolean isUseNativeSSH() {
91     String value = myBuild.getSharedConfigParameters().get(USE_NATIVE_SSH);
92     return "true".equals(value);
93   }
94
95
96   public boolean isUseLocalMirrors(@NotNull GitVcsRoot root) {
97     String buildSetting = myBuild.getSharedConfigParameters().get(USE_MIRRORS);
98     if (!StringUtil.isEmpty(buildSetting)) {
99       LOG.info("Use the '" + USE_MIRRORS + "' option specified in the build");
100       return Boolean.parseBoolean(buildSetting);
101     }
102
103     Boolean rootSetting = root.isUseAgentMirrors();
104     String mirrorStrategy = getMirrorStrategy();
105     if (rootSetting != null && rootSetting && VCS_ROOT_MIRRORS_STRATEGY_MIRRORS_ONLY.equals(mirrorStrategy)) {
106       LOG.info("Use the mirrors option specified in the VCS root");
107       return true;
108     }
109
110     return false;
111   }
112
113
114   public boolean isUseAlternates(@NotNull GitVcsRoot root) {
115     String buildSetting = myBuild.getSharedConfigParameters().get(USE_ALTERNATES);
116     if (!StringUtil.isEmpty(buildSetting)) {
117       LOG.info("Use the '" + USE_ALTERNATES + "' option specified in the build");
118       return Boolean.parseBoolean(buildSetting);
119     }
120
121     Boolean rootSetting = root.isUseAgentMirrors();
122     String mirrorStrategy = getMirrorStrategy();
123     if (rootSetting != null && rootSetting && VCS_ROOT_MIRRORS_STRATEGY_ALTERNATES.equals(mirrorStrategy)) {
124       LOG.info("Use the mirrors option specified in the VCS root");
125       return true;
126     }
127
128     return false;
129   }
130
131
132   public boolean isUseSparseCheckout() {
133     String buildSetting = myBuild.getSharedConfigParameters().get(USE_SPARSE_CHECKOUT);
134     if (StringUtil.isEmpty(buildSetting))
135       return true;
136     return Boolean.parseBoolean(buildSetting);
137   }
138
139
140   public boolean isRunGitWithBuildEnv() {
141     String buildSetting = myBuild.getSharedConfigParameters().get(USE_BUILD_ENV);
142     if (StringUtil.isEmpty(buildSetting))
143       return false;
144     return Boolean.parseBoolean(buildSetting);
145   }
146
147   @NotNull
148   private String getMirrorStrategy() {
149     String strategy = myBuild.getSharedConfigParameters().get(VCS_ROOT_MIRRORS_STRATEGY);
150     if (!StringUtil.isEmpty(strategy))
151       return strategy;
152     return VCS_ROOT_MIRRORS_STRATEGY_ALTERNATES;
153   }
154
155   public boolean isUseShallowClone() {
156     String valueFromBuildConfiguration = myBuild.getSharedConfigParameters().get(USE_SHALLOW_CLONE);
157     if (valueFromBuildConfiguration != null) {
158       return "true".equals(valueFromBuildConfiguration);
159     } else {
160       String valueFromAgentConfig = myAgentConfig.getConfigurationParameters().get(USE_SHALLOW_CLONE);
161       return "true".equals(valueFromAgentConfig);
162     }
163   }
164
165
166   public boolean isDeleteTempFiles() {
167     boolean doNotDelete = Boolean.parseBoolean(myBuild.getSharedConfigParameters().get(TEAMCITY_DONT_DELETE_TEMP_FILES));
168     return !doNotDelete;
169   }
170
171
172   @NotNull
173   @Override
174   public FetchHeadsMode getFetchHeadsMode() {
175     Map<String, String> params = myBuild.getSharedConfigParameters();
176     String fetchAllHeads = params.get(FETCH_ALL_HEADS);
177     if (StringUtil.isEmpty(fetchAllHeads) || "false".equals(fetchAllHeads) || "afterBuildBranch".equals(fetchAllHeads))
178       return FetchHeadsMode.AFTER_BUILD_BRANCH;
179
180     if ("true".equals(fetchAllHeads) || "always".equals(fetchAllHeads))
181       return FetchHeadsMode.ALWAYS;
182
183     if ("beforeBuildBranch".equals(fetchAllHeads))
184       return FetchHeadsMode.BEFORE_BUILD_BRANCH;
185
186     LOG.warn("Unsupported value of the " + FETCH_ALL_HEADS + " parameter: '" + fetchAllHeads + "', treat it as false");
187     return FetchHeadsMode.AFTER_BUILD_BRANCH;
188   }
189
190   public boolean isUseMainRepoUserForSubmodules() {
191     String fromBuildConfiguration = myBuild.getSharedConfigParameters().get(USE_MAIN_REPO_USER_FOR_SUBMODULES);
192     if (fromBuildConfiguration != null)
193       return Boolean.parseBoolean(fromBuildConfiguration);
194
195     String fromAgentConfig = myAgentConfig.getConfigurationParameters().get(USE_MAIN_REPO_USER_FOR_SUBMODULES);
196     if (fromAgentConfig != null)
197       return Boolean.parseBoolean(fromAgentConfig);
198
199     return true;
200   }
201
202   @NotNull
203   public GitVersion getGitVersion() {
204     return myGitExec.getVersion();
205   }
206
207   @NotNull
208   public GitExec getGitExec() {
209     return myGitExec;
210   }
211
212   public int getCheckoutIdleTimeoutSeconds() {
213     String valueFromBuild = myBuild.getSharedConfigParameters().get(IDLE_TIMEOUT);
214     if (valueFromBuild != null) {
215       return parseTimeout(valueFromBuild, CommandUtil.DEFAULT_COMMAND_TIMEOUT_SEC);
216     } else {
217       return CommandUtil.DEFAULT_COMMAND_TIMEOUT_SEC;
218     }
219   }
220
221   public boolean isUpdateSubmoduleOriginUrl() {
222     String value = myBuild.getSharedConfigParameters().get("teamcity.git.updateSubmoduleOriginUrl");
223     return !"false".equals(value);
224   }
225
226   @Override
227   public boolean isFailOnCleanCheckout() {
228     return "true".equals(myBuild.getSharedConfigParameters().get(AgentRuntimeProperties.FAIL_ON_CLEAN_CHECKOUT));
229   }
230
231
232   @Override
233   public boolean isFetchTags() {
234     String value = myBuild.getSharedConfigParameters().get(FETCH_TAGS);
235     //by default tags are fetched
236     return !"false".equals(value);
237   }
238
239   public boolean isCredHelperMatchesAllUrls() {
240     //it looks to be safe to enable all urls matching by default because we did
241     //a similar thing with ask-pass script: it provides password for any server
242     String value = myBuild.getSharedConfigParameters().get("teamcity.git.credentialHelperMatchesAllUrls");
243     return !"false".equals(value);
244   }
245
246   @NotNull
247   @Override
248   public GitProgressMode getGitProgressMode() {
249     String value = myBuild.getSharedConfigParameters().get("teamcity.git.progressMode");
250     if (value == null)
251       return GitProgressMode.DEBUG;
252     try {
253       return GitProgressMode.valueOf(value.toUpperCase());
254     } catch (IllegalArgumentException e) {
255       return GitProgressMode.DEBUG;
256     }
257   }
258
259   @Override
260   public boolean isExcludeUsernameFromHttpUrl() {
261     String value = myBuild.getSharedConfigParameters().get(EXCLUDE_USERNAME_FROM_HTTP_URL);
262     return !"false".equals(value);
263   }
264
265   @Override
266   public boolean isCleanCredHelperScript() {
267     String value = myBuild.getSharedConfigParameters().get(CLEAN_CRED_HELPER_SCRIPT);
268     return !"false".equals(value);
269   }
270
271   @Override
272   public boolean isProvideCredHelper() {
273     String value = myBuild.getSharedConfigParameters().get(PROVIDE_CRED_HELPER);
274     return !"false".equals(value);
275   }
276
277   private int parseTimeout(String valueFromBuild) {
278     return parseTimeout(valueFromBuild, DEFAULT_IDLE_TIMEOUT);
279   }
280
281   private int parseTimeout(String valueFromBuild, int defaultValue) {
282     try {
283       int timeout = Integer.parseInt(valueFromBuild);
284       if (timeout > 0)
285         return timeout;
286       else
287         return defaultValue;
288     } catch (NumberFormatException e) {
289       return defaultValue;
290     }
291   }
292 }