[git] IDEA-59215 Better default Git executable configuration on Windows
[idea/community.git] / plugins / git4idea / src / git4idea / config / GitVcsApplicationSettings.java
1 /*
2  * Copyright 2000-2012 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.components.*;
19 import com.intellij.openapi.util.SystemInfo;
20 import org.jetbrains.annotations.NonNls;
21 import org.jetbrains.annotations.NotNull;
22 import org.jetbrains.annotations.Nullable;
23
24 import java.io.File;
25
26 /**
27  * The application wide settings for the git
28  */
29 @State(
30   name = "Git.Application.Settings",
31   storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/vcs.xml")})
32 public class GitVcsApplicationSettings implements PersistentStateComponent<GitVcsApplicationSettings.State> {
33
34   @NonNls private static final String[] DEFAULT_WINDOWS_PATHS = { "C:\\Program Files\\Git\\bin",
35                                                                   "C:\\Program Files (x86)\\Git\\bin",
36                                                                   "C:\\cygwin\\bin" };
37   @NonNls private static final String[] DEFAULT_UNIX_PATHS = { "/usr/local/bin",
38                                                                "/usr/bin",
39                                                                "/opt/local/bin",
40                                                                "/opt/bin",
41                                                                "/usr/local/git/bin" };
42   @NonNls private static final String[] DEFAULT_WINDOWS_GITS = { "git.cmd", "git.exe" };
43   @NonNls private static final String DEFAULT_UNIX_GIT = "git";
44   
45   private State myState = new State();
46
47   /**
48    * Kinds of SSH executable to be used with the git
49    */
50   public enum SshExecutable {
51     IDEA_SSH,
52     NATIVE_SSH,
53   }
54
55   public static class State {
56     public String myPathToGit = null;
57     public SshExecutable SSH_EXECUTABLE = null;
58   }
59
60   public static GitVcsApplicationSettings getInstance() {
61     return ServiceManager.getService(GitVcsApplicationSettings.class);
62   }
63
64   @Override
65   public State getState() {
66     return myState;
67   }
68
69   public void loadState(State state) {
70     myState = state;
71   }
72
73   /**
74    * @return the default executable name depending on the platform
75    */
76   @NotNull
77   public String defaultGit() {
78     if (myState.myPathToGit == null) {
79       String[] paths;
80       String[] programVariants;
81       if (SystemInfo.isWindows) {
82         programVariants = DEFAULT_WINDOWS_GITS;
83         paths = DEFAULT_WINDOWS_PATHS;
84       }
85       else {
86         programVariants = new String[] { DEFAULT_UNIX_GIT };
87         paths = DEFAULT_UNIX_PATHS;
88       }
89
90       for (String p : paths) {
91         for (String program : programVariants) {
92           File f = new File(p, program);
93           if (f.exists()) {
94             myState.myPathToGit = f.getAbsolutePath();
95             break;
96           }
97         }
98       }
99       if (myState.myPathToGit == null) { // otherwise, take the first variant and hope it's in $PATH
100         myState.myPathToGit = programVariants[0];
101       }
102     }
103     return myState.myPathToGit;
104   }
105
106   @NotNull
107   public String getPathToGit() {
108     return myState.myPathToGit == null ? defaultGit() : myState.myPathToGit;
109   }
110
111   public void setPathToGit(String pathToGit) {
112     myState.myPathToGit = pathToGit;
113   }
114
115   public void setIdeaSsh(@NotNull SshExecutable executable) {
116     myState.SSH_EXECUTABLE = executable;
117   }
118
119   @Nullable
120   SshExecutable getIdeaSsh() {
121     return myState.SSH_EXECUTABLE;
122   }
123
124 }