Skip to content

Commit 7f29035

Browse files
committed
First iteration of automatic bash finding on Windows
1 parent 8c884c3 commit 7f29035

File tree

9 files changed

+164
-117
lines changed

9 files changed

+164
-117
lines changed

src/main/java/com/github/introfog/gitwave/GitWaveLauncher.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package com.github.introfog.gitwave;
1818

1919
import com.github.introfog.gitwave.model.AppConfig;
20-
import com.github.introfog.gitwave.model.OsRecogniser;
20+
import com.github.introfog.gitwave.model.OsHelper;
2121
import com.github.introfog.gitwave.model.StageFactory;
2222

2323
import javafx.application.Application;
@@ -28,11 +28,8 @@ public class GitWaveLauncher extends Application {
2828
public void start(Stage stage) {
2929
StageFactory.createPrimaryExecuteWindow(stage).getStage().show();
3030
AppConfig.getInstance().setHostServices(getHostServices());
31-
if (!OsRecogniser.isCurrentOsUnixLike()) {
32-
final String pathToGitBashExe = AppConfig.getInstance().getPathToGitBashExe();
33-
if (pathToGitBashExe == null || pathToGitBashExe.isEmpty()) {
34-
StageFactory.createModalSetupWindow().getStage().showAndWait();
35-
}
31+
if (OsHelper.getPathToBash() == null) {
32+
StageFactory.createModalSetupWindow().getStage().showAndWait();
3633
}
3734
}
3835

src/main/java/com/github/introfog/gitwave/controller/SettingsController.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616

1717
package com.github.introfog.gitwave.controller;
1818

19-
import com.github.introfog.gitwave.model.AppConfig;
2019
import com.github.introfog.gitwave.model.DialogFactory;
21-
import com.github.introfog.gitwave.model.OsRecogniser;
20+
import com.github.introfog.gitwave.model.OsHelper;
2221
import com.github.introfog.gitwave.model.StageFactory.FxmlStageHolder;
2322

2423
import java.io.File;
@@ -59,12 +58,12 @@ public class SettingsController extends BaseController {
5958
public void initialize(FxmlStageHolder fxmlStageHolder) {
6059
super.initialize(fxmlStageHolder);
6160
super.setClosingOnEscapePressing(fxmlStageHolder);
62-
if (OsRecogniser.isCurrentOsUnixLike()) {
61+
if (OsHelper.isCurrentOsUnixLike()) {
6362
pathToBashExe.disableProperty().set(true);
6463
browse.setDisable(true);
6564
pathToBashText.setDisable(true);
6665
} else {
67-
final String pathToGitBashExeStr = AppConfig.getInstance().getPathToGitBashExe();
66+
final String pathToGitBashExeStr = OsHelper.getPathToBash();
6867
if (pathToGitBashExeStr != null && !pathToGitBashExeStr.isEmpty()) {
6968
pathToBashExe.setText(pathToGitBashExeStr);
7069
}
@@ -80,7 +79,7 @@ protected void save() {
8079
File bashExeFile = new File(pathToBashExe.getText());
8180
if (bashExeFile.exists() && bashExeFile.getAbsolutePath().endsWith(".exe")) {
8281
final String absolutePath = bashExeFile.getAbsolutePath();
83-
AppConfig.getInstance().setPathToGitBashExe(absolutePath);
82+
OsHelper.setPathToBash(absolutePath);
8483
// TODO #7 add check that path is specified to GitBash.exe not for any other .exe
8584
LOGGER.info("Path to GitBash.exe registered to '{}'", absolutePath);
8685
closeStage();
@@ -122,7 +121,7 @@ protected void browseGitBashExe() {
122121
FileChooser.ExtensionFilter exeFilter = new FileChooser.ExtensionFilter("Bash executable (*.exe)", "*.exe");
123122
fileChooser.getExtensionFilters().add(exeFilter);
124123

125-
final String pathToGitBashExeStr = AppConfig.getInstance().getPathToGitBashExe();
124+
final String pathToGitBashExeStr = OsHelper.getPathToBash();
126125
if (pathToGitBashExeStr != null && !pathToGitBashExeStr.isEmpty()) {
127126
File gitBashDir = new File(pathToGitBashExeStr.substring(0, pathToGitBashExeStr.lastIndexOf("\\")));
128127
if (gitBashDir.exists() && gitBashDir.isDirectory()) {

src/main/java/com/github/introfog/gitwave/controller/main/MenuController.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package com.github.introfog.gitwave.controller.main;
22

33
import com.github.introfog.gitwave.controller.SupportController;
4-
import com.github.introfog.gitwave.model.AppConfig;
54
import com.github.introfog.gitwave.model.DialogFactory;
6-
import com.github.introfog.gitwave.model.OsRecogniser;
5+
import com.github.introfog.gitwave.model.OsHelper;
76
import com.github.introfog.gitwave.model.StageFactory;
87
import com.github.introfog.gitwave.model.StageFactory.FxmlStageHolder;
98
import com.github.introfog.gitwave.model.UpdateChecker;
@@ -32,10 +31,10 @@ public MenuController(FxmlStageHolder fxmlStageHolder, Menu menu, MenuItem updat
3231

3332
@Override
3433
public boolean isValid() {
35-
if (OsRecogniser.isCurrentOsUnixLike()) {
34+
if (OsHelper.isCurrentOsUnixLike()) {
3635
return true;
3736
}
38-
final String pathToGitBashExe = AppConfig.getInstance().getPathToGitBashExe();
37+
final String pathToGitBashExe = OsHelper.getPathToBash();
3938
if (pathToGitBashExe == null || pathToGitBashExe.isEmpty()) {
4039
DialogFactory.createErrorAlert("GitBash path hasn't been specified", "Specify path to GitBash in Menu->Settings.");
4140
return false;

src/main/java/com/github/introfog/gitwave/model/AppConfig.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,6 @@ public void setHostServices(HostServices hostServices) {
6161
this.hostServices = hostServices;
6262
}
6363

64-
public void setPathToGitBashExe(String pathToGitBashExe) {
65-
config.setPathToGitBash(pathToGitBashExe);
66-
saveConfig();
67-
}
68-
69-
public String getPathToGitBashExe() {
70-
return config.getPathToGitBash();
71-
}
72-
7364
public void setLastRunFolder(String lastRunFolder) {
7465
config.setLastRunFolder(lastRunFolder);
7566
saveConfig();
@@ -79,6 +70,10 @@ public String getLastRunFolder() {
7970
return config.getLastRunFolder();
8071
}
8172

73+
public String getPathToGitBash() {
74+
return config.getPathToGitBash();
75+
}
76+
8277
public List<CommandDto> getCommands() {
8378
return config.getCommands();
8479
}

src/main/java/com/github/introfog/gitwave/model/CommandExecutor.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,7 @@ private static List<RunnableCommand> createRunnableCommands(List<File> repositor
8686

8787
private static String[] constructCmdCommand(String gitRepoPath, String command) {
8888
List<String> cmdCommand = new ArrayList<>();
89-
if (OsRecogniser.isCurrentOsUnixLike()) {
90-
cmdCommand.add("bash");
91-
} else {
92-
cmdCommand.add(AppConfig.getInstance().getPathToGitBashExe().replace("\\", "/"));
93-
}
89+
cmdCommand.add(OsHelper.getPathToBash());
9490
cmdCommand.add("-c");
9591
cmdCommand.add("cd '" + gitRepoPath + "' && " + command);
9692
return cmdCommand.toArray(new String[]{});
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2023-2024 Dmitry Chubrick
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 com.github.introfog.gitwave.model;
18+
19+
import java.io.BufferedReader;
20+
import java.io.InputStreamReader;
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
23+
24+
public final class OsHelper {
25+
private static final Logger LOGGER = LoggerFactory.getLogger(OsHelper.class);
26+
27+
private static CurrentOs currentOs;
28+
private static String pathToBash;
29+
30+
private OsHelper() {
31+
// Do nothing
32+
}
33+
34+
public static boolean isCurrentOsUnixLike() {
35+
return getCurrentOs() == CurrentOs.MACOS || getCurrentOs() == CurrentOs.LINUX;
36+
}
37+
38+
public static String getPathToBash() {
39+
if (pathToBash != null) {
40+
if (isCurrentOsUnixLike()) {
41+
pathToBash = "bash";
42+
} else {
43+
LOGGER.info("Find path to git bash for Windows OS.");
44+
final String pathFromConfig = AppConfig.getInstance().getPathToGitBash();
45+
if (pathFromConfig != null && !pathFromConfig.isEmpty()) {
46+
LOGGER.info("Using path to bash from config: {}", pathFromConfig);
47+
pathToBash = pathFromConfig;
48+
}
49+
final String temp = extractPathToGitForWindows();
50+
LOGGER.info("Extracted path from Windows Registry: {}", temp);
51+
if (temp != null) {
52+
pathToBash = temp.replace("\\", "/");
53+
}
54+
}
55+
}
56+
return pathToBash;
57+
}
58+
59+
public static void setPathToBash(String pathToBash) {
60+
OsHelper.pathToBash = pathToBash.replace("\\", "/");
61+
}
62+
63+
private static CurrentOs getCurrentOs() {
64+
if (currentOs == null) {
65+
String os = System.getProperty("os.name").toLowerCase();
66+
if (os.contains("win")) {
67+
currentOs = CurrentOs.WINDOWS;
68+
} else if (os.contains("mac")) {
69+
currentOs = CurrentOs.MACOS;
70+
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
71+
currentOs = CurrentOs.LINUX;
72+
} else {
73+
currentOs = CurrentOs.UNRECOGNISED;
74+
}
75+
LOGGER.info("System.getProperty(\"os.name\")={}. Recognised OS: {}", os, currentOs);
76+
}
77+
return currentOs;
78+
}
79+
80+
private static String extractPathToGitForWindows() {
81+
String installPath = null;
82+
83+
try {
84+
String value = readRegistry("HKLM\\SOFTWARE\\GitForWindows", "InstallPath");
85+
if (value != null && !value.isEmpty()) {
86+
installPath = value;
87+
}
88+
89+
if (installPath == null) {
90+
value = readRegistry("HKCU\\Software\\GitForWindows", "InstallPath");
91+
if (value != null && !value.isEmpty()) {
92+
installPath = value;
93+
}
94+
}
95+
} catch (Exception e) {
96+
LOGGER.warn("Extracting path from Windows Registry throw an exception.", e);
97+
}
98+
99+
return installPath != null ? installPath + "\\bin\\bash.exe" : null;
100+
}
101+
102+
private static String readRegistry(String location, String key){
103+
try {
104+
// Run reg query, then read output with StreamReader (internal class)
105+
Process process = Runtime.getRuntime().exec("REG QUERY " + location + " /v " + key);
106+
107+
String line;
108+
StringBuilder result = new StringBuilder();
109+
BufferedReader stdout = new BufferedReader(new InputStreamReader(process.getInputStream()));
110+
111+
while ((line = stdout.readLine()) != null) {
112+
result.append(line);
113+
}
114+
stdout.close();
115+
116+
// Example of result: HKEY_LOCAL_MACHINE\SOFTWARE\GitForWindows InstallPath REG_SZ E:\Programs\Git
117+
if( !result.toString().contains(key)){
118+
return null;
119+
}
120+
121+
// Parse out the value
122+
String[] parsed = result.toString().split("\\s+");
123+
return parsed[parsed.length-1];
124+
}
125+
catch (Exception e) {
126+
return null;
127+
}
128+
}
129+
130+
private enum CurrentOs {
131+
WINDOWS,
132+
MACOS,
133+
LINUX,
134+
UNRECOGNISED
135+
}
136+
}

src/main/java/com/github/introfog/gitwave/model/OsRecogniser.java

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/main/resources/com/github/introfog/gitwave/view/settings.fxml

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

3-
<?import javafx.geometry.Insets?>
4-
<?import javafx.scene.control.Button?>
5-
<?import javafx.scene.control.Label?>
6-
<?import javafx.scene.control.Separator?>
7-
<?import javafx.scene.control.TextField?>
8-
<?import javafx.scene.layout.AnchorPane?>
9-
<?import javafx.scene.layout.ColumnConstraints?>
10-
<?import javafx.scene.layout.GridPane?>
11-
<?import javafx.scene.layout.RowConstraints?>
12-
<?import javafx.scene.text.Font?>
13-
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="550.0" style="-fx-font-family: verdana; -fx-font-size: 12;" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.github.introfog.gitwave.controller.SettingsController">
3+
<?import javafx.geometry.*?>
4+
<?import javafx.scene.control.*?>
5+
<?import javafx.scene.layout.*?>
6+
<?import javafx.scene.text.*?>
7+
8+
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="550.0" style="-fx-font-family: verdana; -fx-font-size: 12;" xmlns="http://javafx.com/javafx/17.0.12" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.github.introfog.gitwave.controller.SettingsController">
149
<children>
1510
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
1611
<columnConstraints>
@@ -25,7 +20,7 @@
2520
<children>
2621
<AnchorPane prefHeight="200.0" prefWidth="200.0">
2722
<children>
28-
<Label fx:id="pathToBashText" prefHeight="17.0" prefWidth="430.0" text="Path to bash.exe on your PC (usually &quot;PATH_TO_GIT/bin/bash.exe&quot;)." AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
23+
<Label fx:id="pathToBashText" prefHeight="17.0" prefWidth="430.0" text="Path to bash (on Windows usually &quot;PATH_TO_GIT/bin/bash.exe&quot;)." AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
2924
<Button fx:id="browse" mnemonicParsing="false" onAction="#browseGitBashExe" text="Browse" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0">
3025
<font>
3126
<Font name="Verdana" size="12.0" />

0 commit comments

Comments
 (0)