GitClient: Don't call blocking waitForStarted()

Connect to done() signal in order to detect the start
failure and try to start a gitk from different path.
All trials of starting gitk are done sequentially
and non-blocking.

Give process a parent in order to avoid process leak
on shutdown.

Change-Id: I1d74bfeaca23d38643f3d2f262428732314aefe4
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-06-22 11:21:50 +02:00
parent 14965f5792
commit a1ad64a50b
2 changed files with 69 additions and 43 deletions

View File

@@ -2574,31 +2574,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
void GitClient::launchGitK(const FilePath &workingDirectory, const QString &fileName) const
{
FilePath foundBinDir = vcsBinary().parentDir();
Environment env = processEnvironment();
if (tryLauchingGitK(env, workingDirectory, fileName, foundBinDir))
return;
VcsOutputWindow::appendSilently(msgCannotLaunch(foundBinDir / "gitk"));
if (foundBinDir.fileName() == "bin") {
foundBinDir = foundBinDir.parentDir();
const QString binDirName = foundBinDir.fileName();
if (binDirName == "usr" || binDirName.startsWith("mingw"))
foundBinDir = foundBinDir.parentDir();
if (tryLauchingGitK(env, workingDirectory, fileName, foundBinDir / "cmd"))
return;
VcsOutputWindow::appendSilently(msgCannotLaunch(foundBinDir / "cmd/gitk"));
}
Environment sysEnv = Environment::systemEnvironment();
const FilePath exec = sysEnv.searchInPath("gitk");
if (!exec.isEmpty() && tryLauchingGitK(env, workingDirectory, fileName, exec.parentDir()))
return;
VcsOutputWindow::appendError(msgCannotLaunch("gitk"));
tryLaunchingGitK(processEnvironment(), workingDirectory, fileName);
}
void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const
@@ -2608,16 +2584,35 @@ void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const
QtcProcess::startDetached({repBrowserBinary, {workingDirectory.toString()}}, workingDirectory);
}
bool GitClient::tryLauchingGitK(const Environment &env,
const FilePath &workingDirectory,
const QString &fileName,
const FilePath &gitBinDirectory) const
static FilePath gitBinDir(const GitClient::GitKLaunchTrial trial, const FilePath &parentDir)
{
if (trial == GitClient::Bin)
return parentDir;
if (trial == GitClient::ParentOfBin) {
QTC_CHECK(parentDir.fileName() == "bin");
FilePath foundBinDir = parentDir.parentDir();
const QString binDirName = foundBinDir.fileName();
if (binDirName == "usr" || binDirName.startsWith("mingw"))
foundBinDir = foundBinDir.parentDir();
return foundBinDir / "cmd";
}
if (trial == GitClient::SystemPath)
return Environment::systemEnvironment().searchInPath("gitk").parentDir();
QTC_CHECK(false);
return FilePath();
}
void GitClient::tryLaunchingGitK(const Environment &env,
const FilePath &workingDirectory,
const QString &fileName,
GitClient::GitKLaunchTrial trial) const
{
const FilePath gitBinDirectory = gitBinDir(trial, vcsBinary().parentDir());
FilePath binary = gitBinDirectory.pathAppended("gitk").withExecutableSuffix();
QStringList arguments;
if (HostOsInfo::isWindowsHost()) {
// If git/bin is in path, use 'wish' shell to run. Otherwise (git/cmd), directly run gitk
FilePath wish = gitBinDirectory.pathAppended("wish").withExecutableSuffix();
const FilePath wish = gitBinDirectory.pathAppended("wish").withExecutableSuffix();
if (wish.withExecutableSuffix().exists()) {
arguments << binary.toString();
binary = wish;
@@ -2629,25 +2624,50 @@ bool GitClient::tryLauchingGitK(const Environment &env,
if (!fileName.isEmpty())
arguments << "--" << fileName;
VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments});
// This should always use QtcProcess::startDetached (as not to kill
// the child), but that does not have an environment parameter.
bool success = false;
if (!settings().path.value().isEmpty()) {
auto process = new QtcProcess;
auto process = new QtcProcess(const_cast<GitClient*>(this));
process->setWorkingDirectory(workingDirectory);
process->setEnvironment(env);
process->setCommand({binary, arguments});
connect(process, &QtcProcess::done, this, [=] {
if (process->result() == ProcessResult::StartFailed)
handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory);
process->deleteLater();
});
process->start();
success = process->waitForStarted();
if (success)
connect(process, &QtcProcess::finished, process, &QObject::deleteLater);
else
delete process;
} else {
success = QtcProcess::startDetached({binary, arguments}, workingDirectory);
if (!QtcProcess::startDetached({binary, arguments}, workingDirectory))
handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory);
}
}
void GitClient::handleGitKFailedToStart(const Environment &env,
const FilePath &workingDirectory,
const QString &fileName,
const GitClient::GitKLaunchTrial oldTrial,
const FilePath &oldGitBinDir) const
{
QTC_ASSERT(oldTrial != None, return);
VcsOutputWindow::appendSilently(msgCannotLaunch(oldGitBinDir / "gitk"));
GitKLaunchTrial nextTrial = None;
if (oldTrial == Bin && vcsBinary().parentDir().fileName() == "bin") {
nextTrial = ParentOfBin;
} else if (oldTrial != SystemPath
&& !Environment::systemEnvironment().searchInPath("gitk").isEmpty()) {
nextTrial = SystemPath;
}
return success;
if (nextTrial == None) {
VcsOutputWindow::appendError(msgCannotLaunch("gitk"));
return;
}
tryLaunchingGitK(env, workingDirectory, fileName, nextTrial);
}
bool GitClient::launchGitGui(const FilePath &workingDirectory) {