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