From a6fabc48a39fd9d0db55d3153164b8ee48813738 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 3 Jun 2024 09:42:33 +0200 Subject: [PATCH] Utils: Add effective binary getter to FilePathAspect It is quite common to provide a single command as default value for commands to be executed. In several cases we fail to handle this correctly when trying to validate or using the executable although it is validated correctly inside the underlying path chooser. This patch provides a method to explicitly get the effective binary, means either the configured path or if it just had been a single command it retrieves the full path information by looking up the command in PATH. This functionality is limited to non-device file paths which are expected to be an (optionally existing) command. Change-Id: I17db69f546f5fb9fec8809db91232f212d21e9a6 Reviewed-by: Marcus Tillmanns --- src/libs/utils/aspects.cpp | 35 ++++++++++++++++++++++++++++++++--- src/libs/utils/aspects.h | 1 + 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index bc233ed188a..13db6a1ecef 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -1410,6 +1410,7 @@ public: FilePath m_baseFileName; StringAspect::ValueAcceptor m_valueAcceptor; std::optional m_validator; + std::optional m_effectiveBinary; std::function m_openTerminal; CheckableAspectImplementation m_checkerImpl; @@ -1430,6 +1431,8 @@ FilePathAspect::FilePathAspect(AspectContainer *container) addDataExtractor(this, &FilePathAspect::value, &Data::value); addDataExtractor(this, &FilePathAspect::operator(), &Data::filePath); + + connect(this, &BaseAspect::changed, this, [this] { d->m_effectiveBinary.reset(); }); } FilePathAspect::~FilePathAspect() = default; @@ -1455,6 +1458,29 @@ FilePath FilePathAspect::expandedValue() const return FilePath::fromUserInput(value); } +/*! + Returns the full path of the set command. Only makes a difference if + expected kind is \c Command or \c ExistingCommand and the current + file path is an executable provided without its path. + Performs a lookup in PATH if necessary. + */ +FilePath FilePathAspect::effectiveBinary() const +{ + if (d->m_effectiveBinary) + return *d->m_effectiveBinary; + + const FilePath current = expandedValue(); + const PathChooser::Kind kind = d->m_expectedKind; + if (kind != PathChooser::ExistingCommand && kind != PathChooser::Command) + return current; + + if (current.needsDevice()) + return current; + + d->m_effectiveBinary.emplace(current.searchInPath()); + return *d->m_effectiveBinary; +} + QString FilePathAspect::value() const { return TypedAspect::value(); @@ -1693,9 +1719,12 @@ void FilePathAspect::setAutoApplyOnEditingFinished(bool applyOnEditingFinished) */ void FilePathAspect::setExpectedKind(const PathChooser::Kind expectedKind) { - d->m_expectedKind = expectedKind; - if (d->m_pathChooserDisplay) - d->m_pathChooserDisplay->setExpectedKind(expectedKind); + if (d->m_expectedKind != expectedKind) { + d->m_expectedKind = expectedKind; + d->m_effectiveBinary.reset(); + if (d->m_pathChooserDisplay) + d->m_pathChooserDisplay->setExpectedKind(expectedKind); + } } void FilePathAspect::setEnvironment(const Environment &env) diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index 47aeb35458b..8faeaf7a9e3 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -663,6 +663,7 @@ public: }; FilePath operator()() const; + FilePath effectiveBinary() const; FilePath expandedValue() const; QString value() const; void setValue(const FilePath &filePath, Announcement howToAnnounce = DoEmit);