Merge remote-tracking branch 'origin/master'
[idea/community.git] / plugins / git4idea / src / git4idea / config / GitConfigUtil.java
1 /*
2  * Copyright 2000-2009 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 package git4idea.config;
17
18 import com.intellij.openapi.project.Project;
19 import com.intellij.openapi.util.Pair;
20 import com.intellij.openapi.vcs.VcsException;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import git4idea.GitUtil;
23 import git4idea.commands.GitCommand;
24 import git4idea.commands.GitSimpleHandler;
25 import org.jetbrains.annotations.NonNls;
26 import org.jetbrains.annotations.Nullable;
27
28 import java.nio.charset.Charset;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Map;
32
33 /**
34  * Git utilities for working with configuration
35  */
36 public class GitConfigUtil {
37   public static final String USER_NAME = "user.name";
38   public static final String USER_EMAIL = "user.email";
39
40   /**
41    * A private constructor for utility class
42    */
43   private GitConfigUtil() {
44   }
45
46   /**
47    * Get configuration values for the repository. Note that the method executes a git command.
48    *
49    * @param project the context project
50    * @param root    the git root
51    * @param keyMask the keys to be queried
52    * @param result  the map to put results to
53    * @throws VcsException if there is a problem with running git
54    */
55   public static void getValues(Project project, VirtualFile root, String keyMask, Map<String, String> result) throws VcsException {
56     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CONFIG);
57     h.setNoSSH(true);
58     h.setSilent(true);
59     h.addParameters("--null");
60     if (keyMask != null) {
61       h.addParameters("--get-regexp", keyMask);
62     } else {
63       h.addParameters("-l");
64     }
65     String output = h.run();
66     int start = 0;
67     int pos;
68     while ((pos = output.indexOf('\n', start)) != -1) {
69       String key = output.substring(start, pos);
70       start = pos + 1;
71       if ((pos = output.indexOf('\u0000', start)) == -1) {
72         break;
73       }
74       String value = output.substring(start, pos);
75       start = pos + 1;
76       result.put(key, value);
77     }
78   }
79
80   /**
81    * Get configuration values for the repository. Note that the method executes a git command.
82    *
83    * @param project the context project
84    * @param root    the git root
85    * @param key     the keys to be queried
86    * @return list of pairs ({@link Pair#first} is the key, {@link Pair#second} is the value)
87    * @throws VcsException an exception
88    */
89   public static List<Pair<String, String>> getAllValues(Project project, VirtualFile root, @NonNls String key) throws VcsException {
90     List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
91     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CONFIG);
92     h.setNoSSH(true);
93     h.setSilent(true);
94     h.addParameters("--null", "--get-all", key);
95     String output = h.run();
96     int start = 0;
97     int pos;
98     while ((pos = output.indexOf('\u0000', start)) != -1) {
99       String value = output.substring(start, pos);
100       start = pos + 1;
101       result.add(new Pair<String, String>(key, value));
102     }
103     return result;
104   }
105
106
107   /**
108    * Get configuration value for the repository. Note that the method executes a git command.
109    *
110    * @param project the context project
111    * @param root    the git root
112    * @param key     the keys to be queried
113    * @return the value associated with the key or null if the value is not found
114    * @throws VcsException an exception
115    */
116   @Nullable
117   public static String getValue(Project project, VirtualFile root, @NonNls String key) throws VcsException {
118     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CONFIG);
119     h.setNoSSH(true);
120     h.setSilent(true);
121     h.ignoreErrorCode(1);
122     h.addParameters("--null", "--get", key);
123     String output = h.run();
124     int pos = output.indexOf('\u0000');
125     if (h.getExitCode() != 0 || pos == -1) {
126       return null;
127     }
128     return output.substring(0, pos);
129   }
130
131   /**
132    * Get boolean configuration value for the repository. Note that the method executes a git command.
133    *
134    * @param project the context project
135    * @param root    the git root
136    * @param key     the keys to be queried
137    * @return the value associated with the key or null if the value is not found, value is not valid integer or boolean
138    * @throws VcsException an exception
139    */
140   @SuppressWarnings({"HardCodedStringLiteral"})
141   @Nullable
142   public static Boolean getBoolValue(final Project project, final VirtualFile root, @NonNls final String key) throws VcsException {
143     String value = getValue(project, root, key);
144     if (value == null) {
145       return null;
146     }
147     value = value.trim();
148     if (value.length() == 0) {
149       return null;
150     }
151     if ("yes".equals(value) || "true".equals(value)) {
152       return Boolean.TRUE;
153     }
154     if ("no".equals(value) || "false".equals(value)) {
155       return Boolean.FALSE;
156     }
157     try {
158       int i = Integer.parseInt(value);
159       return i != 0;
160     }
161     catch (NumberFormatException ex) {
162       return null;
163     }
164   }
165
166   /**
167    * Get commit encoding for the specified root
168    *
169    * @param project the context project
170    * @param root    the project root
171    * @return the commit encoding or UTF-8 if the encoding is note explicitly specified
172    */
173   public static String getCommitEncoding(final Project project, VirtualFile root) {
174     @NonNls String encoding = null;
175     try {
176       encoding = getValue(project, root, "i18n.commitencoding");
177     }
178     catch (VcsException e) {
179       // ignore exception
180     }
181     if (encoding == null || encoding.length() == 0) {
182       encoding = GitUtil.UTF8_ENCODING;
183     }
184     return encoding;
185   }
186
187   /**
188    * Get log output encoding for the specified root
189    *
190    * @param project the context project
191    * @param root    the project root
192    * @return the log output encoding, the commit encoding, or UTF-8 if the encoding is note explicitly specified
193    */
194   public static String getLogEncoding(final Project project, VirtualFile root) {
195     @NonNls String encoding = null;
196     try {
197       encoding = getValue(project, root, "i18n.logoutputencoding");
198     }
199     catch (VcsException e) {
200       // ignore exception
201     }
202     if (encoding == null || encoding.length() == 0) {
203       encoding = getCommitEncoding(project, root);
204     }
205     return encoding;
206   }
207
208   /**
209    * Get encoding that GIT uses for file names.
210    *
211    * @return the encoding for file names
212    */
213   public static String getFileNameEncoding() {
214     // TODO the best guess is that the default encoding is used.
215     return Charset.defaultCharset().name();
216   }
217
218   /**
219    * Unset the current value
220    *
221    * @param project the project
222    * @param root    the git root
223    * @param key     the key to unset
224    * @throws VcsException if there is a problem with running git
225    */
226   public static void unsetValue(Project project, VirtualFile root, String key) throws VcsException {
227     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CONFIG);
228     h.setNoSSH(true);
229     h.setSilent(true);
230     h.ignoreErrorCode(1);
231     h.addParameters("--unset", key);
232     h.run();
233   }
234
235   /**
236    * Set the value
237    *
238    * @param project the project
239    * @param root    the git root
240    * @param key     the key to set
241    * @param value   the value to set
242    * @throws VcsException if there is a problem with running git
243    */
244   public static void setValue(Project project, VirtualFile root, String key, String value, String... additionalParameters) throws VcsException {
245     GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CONFIG);
246     h.setNoSSH(true);
247     h.setSilent(true);
248     h.ignoreErrorCode(1);
249     h.addParameters(additionalParameters);
250     h.addParameters(key, value);
251     h.run();
252   }
253 }