Utils: Store Device::osType in settings

Change-Id: I41348be752598b7a8d1f1979764e7111cccc95a9
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-03-15 09:30:14 +01:00
parent af809b3a52
commit 29873068eb
13 changed files with 95 additions and 62 deletions

View File

@@ -269,12 +269,6 @@ bool DeviceFileAccess::renameFile(const FilePath &filePath, const FilePath &targ
return false; return false;
} }
OsType DeviceFileAccess::osType(const FilePath &filePath) const
{
Q_UNUSED(filePath)
return OsTypeOther;
}
FilePath DeviceFileAccess::symLinkTarget(const FilePath &filePath) const FilePath DeviceFileAccess::symLinkTarget(const FilePath &filePath) const
{ {
Q_UNUSED(filePath) Q_UNUSED(filePath)
@@ -799,12 +793,6 @@ QByteArray DesktopDeviceFileAccess::fileId(const FilePath &filePath) const
return result; return result;
} }
OsType DesktopDeviceFileAccess::osType(const FilePath &filePath) const
{
Q_UNUSED(filePath)
return HostOsInfo::hostOs();
}
// UnixDeviceAccess // UnixDeviceAccess
UnixDeviceFileAccess::~UnixDeviceFileAccess() = default; UnixDeviceFileAccess::~UnixDeviceFileAccess() = default;
@@ -1035,30 +1023,6 @@ expected_str<FilePath> UnixDeviceFileAccess::createTempFile(const FilePath &file
return newPath; return newPath;
} }
OsType UnixDeviceFileAccess::osType() const
{
if (m_osType)
return *m_osType;
const RunResult result = runInShell({"uname", {"-s"}, OsType::OsTypeLinux});
QTC_ASSERT(result.exitCode == 0, return OsTypeLinux);
const QString osName = QString::fromUtf8(result.stdOut).trimmed();
if (osName == "Darwin")
m_osType = OsTypeMac;
else if (osName == "Linux")
m_osType = OsTypeLinux;
else
m_osType = OsTypeOtherUnix;
return *m_osType;
}
OsType UnixDeviceFileAccess::osType(const FilePath &filePath) const
{
Q_UNUSED(filePath);
return osType();
}
QDateTime UnixDeviceFileAccess::lastModified(const FilePath &filePath) const QDateTime UnixDeviceFileAccess::lastModified(const FilePath &filePath) const
{ {
const RunResult result = runInShell( const RunResult result = runInShell(
@@ -1072,7 +1036,7 @@ QStringList UnixDeviceFileAccess::statArgs(const FilePath &filePath,
const QString &linuxFormat, const QString &linuxFormat,
const QString &macFormat) const const QString &macFormat) const
{ {
return (osType() == OsTypeMac ? QStringList{"-f", macFormat} : QStringList{"-c", linuxFormat}) return (filePath.osType() == OsTypeMac ? QStringList{"-f", macFormat} : QStringList{"-c", linuxFormat})
<< "-L" << filePath.path(); << "-L" << filePath.path();
} }
@@ -1150,7 +1114,7 @@ FilePathInfo UnixDeviceFileAccess::filePathInfo(const FilePath &filePath) const
const RunResult stat = runInShell({"stat", args, OsType::OsTypeLinux}); const RunResult stat = runInShell({"stat", args, OsType::OsTypeLinux});
return FileUtils::filePathInfoFromTriple(QString::fromLatin1(stat.stdOut), return FileUtils::filePathInfoFromTriple(QString::fromLatin1(stat.stdOut),
osType() == OsTypeMac ? 8 : 16); filePath.osType() == OsTypeMac ? 8 : 16);
} }
// returns whether 'find' could be used. // returns whether 'find' could be used.
@@ -1165,7 +1129,7 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath,
// TODO: Using stat -L will always return the link target, not the link itself. // TODO: Using stat -L will always return the link target, not the link itself.
// We may wan't to add the information that it is a link at some point. // We may wan't to add the information that it is a link at some point.
const QString statFormat = osType() == OsTypeMac const QString statFormat = filePath.osType() == OsTypeMac
? QLatin1String("-f \"%p %m %z\"") : QLatin1String("-c \"%f %Y %s\""); ? QLatin1String("-f \"%p %m %z\"") : QLatin1String("-c \"%f %Y %s\"");
if (callBack.index() == 1) if (callBack.index() == 1)
@@ -1192,7 +1156,7 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath,
if (entries.isEmpty()) if (entries.isEmpty())
return true; return true;
const int modeBase = osType() == OsTypeMac ? 8 : 16; const int modeBase = filePath.osType() == OsTypeMac ? 8 : 16;
const auto toFilePath = const auto toFilePath =
[&filePath, &callBack, modeBase](const QString &entry) { [&filePath, &callBack, modeBase](const QString &entry) {

View File

@@ -45,7 +45,6 @@ protected:
const FilePath &target) const; const FilePath &target) const;
virtual bool renameFile(const FilePath &filePath, const FilePath &target) const; virtual bool renameFile(const FilePath &filePath, const FilePath &target) const;
virtual OsType osType(const FilePath &filePath) const;
virtual FilePath symLinkTarget(const FilePath &filePath) const; virtual FilePath symLinkTarget(const FilePath &filePath) const;
virtual FilePathInfo filePathInfo(const FilePath &filePath) const; virtual FilePathInfo filePathInfo(const FilePath &filePath) const;
virtual QDateTime lastModified(const FilePath &filePath) const; virtual QDateTime lastModified(const FilePath &filePath) const;
@@ -100,7 +99,6 @@ protected:
expected_str<void> copyFile(const FilePath &filePath, const FilePath &target) const override; expected_str<void> copyFile(const FilePath &filePath, const FilePath &target) const override;
bool renameFile(const FilePath &filePath, const FilePath &target) const override; bool renameFile(const FilePath &filePath, const FilePath &target) const override;
OsType osType(const FilePath &filePath) const override;
FilePath symLinkTarget(const FilePath &filePath) const override; FilePath symLinkTarget(const FilePath &filePath) const override;
FilePathInfo filePathInfo(const FilePath &filePath) const override; FilePathInfo filePathInfo(const FilePath &filePath) const override;
QDateTime lastModified(const FilePath &filePath) const override; QDateTime lastModified(const FilePath &filePath) const override;
@@ -159,7 +157,6 @@ protected:
bool renameFile(const FilePath &filePath, const FilePath &target) const override; bool renameFile(const FilePath &filePath, const FilePath &target) const override;
FilePathInfo filePathInfo(const FilePath &filePath) const override; FilePathInfo filePathInfo(const FilePath &filePath) const override;
OsType osType(const FilePath &filePath) const override;
FilePath symLinkTarget(const FilePath &filePath) const override; FilePath symLinkTarget(const FilePath &filePath) const override;
QDateTime lastModified(const FilePath &filePath) const override; QDateTime lastModified(const FilePath &filePath) const override;
QFile::Permissions permissions(const FilePath &filePath) const override; QFile::Permissions permissions(const FilePath &filePath) const override;
@@ -194,14 +191,12 @@ private:
const FileFilter &filter, const FileFilter &filter,
QStringList *found) const; QStringList *found) const;
Utils::OsType osType() const;
QStringList statArgs(const FilePath &filePath, QStringList statArgs(const FilePath &filePath,
const QString &linuxFormat, const QString &linuxFormat,
const QString &macFormat) const; const QString &macFormat) const;
mutable bool m_tryUseFind = true; mutable bool m_tryUseFind = true;
mutable std::optional<bool> m_hasMkTemp; mutable std::optional<bool> m_hasMkTemp;
mutable std::optional<Utils::OsType> m_osType;
}; };
} // Utils } // Utils

View File

@@ -1566,7 +1566,11 @@ bool FilePath::setPermissions(QFile::Permissions permissions) const
OsType FilePath::osType() const OsType FilePath::osType() const
{ {
return fileAccess()->osType(*this); if (!needsDevice())
return HostOsInfo::hostOs();
QTC_ASSERT(s_deviceHooks.osType, return HostOsInfo::hostOs());
return s_deviceHooks.osType(*this);
} }
bool FilePath::removeFile() const bool FilePath::removeFile() const

View File

@@ -291,6 +291,7 @@ public:
std::function<bool(const FilePath &left, const FilePath &right)> isSameDevice; std::function<bool(const FilePath &left, const FilePath &right)> isSameDevice;
std::function<expected_str<FilePath>(const FilePath &)> localSource; std::function<expected_str<FilePath>(const FilePath &)> localSource;
std::function<void(const FilePath &, const Environment &)> openTerminal; std::function<void(const FilePath &, const Environment &)> openTerminal;
std::function<OsType(const FilePath &)> osType;
}; };
// For testing // For testing

View File

@@ -14,6 +14,36 @@ namespace Utils {
// Add more as needed. // Add more as needed.
enum OsType { OsTypeWindows, OsTypeLinux, OsTypeMac, OsTypeOtherUnix, OsTypeOther }; enum OsType { OsTypeWindows, OsTypeLinux, OsTypeMac, OsTypeOtherUnix, OsTypeOther };
inline QString osTypeToString(OsType osType)
{
switch (osType) {
case OsTypeWindows:
return "Windows";
case OsTypeLinux:
return "Linux";
case OsTypeMac:
return "Mac";
case OsTypeOtherUnix:
return "Other Unix";
case OsTypeOther:
default:
return "Other";
}
}
inline OsType osTypeFromString(const QString &string)
{
if (string == "Windows")
return OsTypeWindows;
if (string == "Linux")
return OsTypeLinux;
if (string == "Mac")
return OsTypeMac;
if (string == "Other Unix")
return OsTypeOtherUnix;
return OsTypeOther;
}
namespace OsSpecificAspects { namespace OsSpecificAspects {
inline QString withExecutableSuffix(OsType osType, const QString &executable) inline QString withExecutableSuffix(OsType osType, const QString &executable)

View File

@@ -126,7 +126,6 @@ public:
RunResult runInShell(const CommandLine &cmdLine, RunResult runInShell(const CommandLine &cmdLine,
const QByteArray &stdInData) const override; const QByteArray &stdInData) const override;
QString mapToDevicePath(const QString &hostPath) const override; QString mapToDevicePath(const QString &hostPath) const override;
OsType osType(const FilePath &filePath) const override;
DockerDevicePrivate *m_dev = nullptr; DockerDevicePrivate *m_dev = nullptr;
}; };
@@ -377,12 +376,6 @@ QString DockerDeviceFileAccess::mapToDevicePath(const QString &hostPath) const
return newPath; return newPath;
} }
OsType DockerDeviceFileAccess::osType(const FilePath &filePath) const
{
QTC_ASSERT(m_dev, return UnixDeviceFileAccess::osType(filePath));
return m_dev->q->osType();
}
DockerDevice::DockerDevice(DockerSettings *settings, const DockerDeviceData &data) DockerDevice::DockerDevice(DockerSettings *settings, const DockerDeviceData &data)
: d(new DockerDevicePrivate(this, settings, data)) : d(new DockerDevicePrivate(this, settings, data))
{ {

View File

@@ -443,6 +443,13 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
device->openTerminal(env, filePath); device->openTerminal(env, filePath);
}; };
deviceHooks.osType = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath);
if (!device)
return OsTypeLinux;
return device->osType();
};
DeviceProcessHooks processHooks; DeviceProcessHooks processHooks;
processHooks.processImplHook = [](const FilePath &filePath) -> ProcessInterface * { processHooks.processImplHook = [](const FilePath &filePath) -> ProcessInterface * {

View File

@@ -17,6 +17,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/asynctask.h>
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -182,6 +183,8 @@ void DeviceSettingsWidget::addDevice()
if (device.isNull()) if (device.isNull())
return; return;
Utils::asyncRun([device] { device->checkOsType(); });
m_deviceManager->addDevice(device); m_deviceManager->addDevice(device);
m_removeConfigButton->setEnabled(true); m_removeConfigButton->setEnabled(true);
m_configurationComboBox->setCurrentIndex(m_deviceManagerModel->indexOf(device)); m_configurationComboBox->setCurrentIndex(m_deviceManagerModel->indexOf(device));

View File

@@ -93,6 +93,7 @@ static Id newId()
const char DisplayNameKey[] = "Name"; const char DisplayNameKey[] = "Name";
const char TypeKey[] = "OsType"; const char TypeKey[] = "OsType";
const char ClientOsTypeKey[] = "ClientOsType";
const char IdKey[] = "InternalId"; const char IdKey[] = "InternalId";
const char OriginKey[] = "Origin"; const char OriginKey[] = "Origin";
const char MachineTypeKey[] = "Type"; const char MachineTypeKey[] = "Type";
@@ -426,6 +427,8 @@ void IDevice::fromMap(const QVariantMap &map)
d->type = typeFromMap(map); d->type = typeFromMap(map);
d->displayName.fromMap(map, DisplayNameKey); d->displayName.fromMap(map, DisplayNameKey);
d->id = Id::fromSetting(map.value(QLatin1String(IdKey))); d->id = Id::fromSetting(map.value(QLatin1String(IdKey)));
d->osType = osTypeFromString(
map.value(QLatin1String(ClientOsTypeKey), osTypeToString(OsTypeLinux)).toString());
if (!d->id.isValid()) if (!d->id.isValid())
d->id = newId(); d->id = newId();
d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt()); d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt());
@@ -472,6 +475,7 @@ QVariantMap IDevice::toMap() const
QVariantMap map; QVariantMap map;
d->displayName.toMap(map, DisplayNameKey); d->displayName.toMap(map, DisplayNameKey);
map.insert(QLatin1String(TypeKey), d->type.toString()); map.insert(QLatin1String(TypeKey), d->type.toString());
map.insert(QLatin1String(ClientOsTypeKey), osTypeToString(d->osType));
map.insert(QLatin1String(IdKey), d->id.toSetting()); map.insert(QLatin1String(IdKey), d->id.toSetting());
map.insert(QLatin1String(OriginKey), d->origin); map.insert(QLatin1String(OriginKey), d->origin);
@@ -504,9 +508,6 @@ IDevice::Ptr IDevice::clone() const
device->d->deviceState = d->deviceState; device->d->deviceState = d->deviceState;
device->d->deviceActions = d->deviceActions; device->d->deviceActions = d->deviceActions;
device->d->deviceIcons = d->deviceIcons; device->d->deviceIcons = d->deviceIcons;
// Os type is only set in the constructor, always to the same value.
// But make sure we notice if that changes in the future (which it shouldn't).
QTC_CHECK(device->d->osType == d->osType);
device->d->osType = d->osType; device->d->osType = d->osType;
device->fromMap(toMap()); device->fromMap(toMap());
return device; return device;

View File

@@ -221,6 +221,8 @@ public:
virtual bool prepareForBuild(const Target *target); virtual bool prepareForBuild(const Target *target);
virtual std::optional<Utils::FilePath> clangdExecutable() const; virtual std::optional<Utils::FilePath> clangdExecutable() const;
virtual void checkOsType(){};
protected: protected:
IDevice(); IDevice();

View File

@@ -305,6 +305,9 @@ public:
Environment getEnvironment(); Environment getEnvironment();
void invalidateEnvironmentCache(); void invalidateEnvironmentCache();
void checkOsType();
void queryOsType(std::function<RunResult(const CommandLine &)> run);
LinuxDevice *q = nullptr; LinuxDevice *q = nullptr;
QThread m_shellThread; QThread m_shellThread;
ShellThreadHandler *m_handler = nullptr; ShellThreadHandler *m_handler = nullptr;
@@ -939,6 +942,12 @@ LinuxDevice::LinuxDevice()
}}); }});
} }
void LinuxDevice::_setOsType(Utils::OsType osType)
{
qCDebug(linuxDeviceLog) << "Setting OS type to" << osType << "for" << displayName();
IDevice::setOsType(osType);
}
LinuxDevice::~LinuxDevice() LinuxDevice::~LinuxDevice()
{ {
delete d; delete d;
@@ -1045,6 +1054,23 @@ LinuxDevicePrivate::~LinuxDevicePrivate()
QMetaObject::invokeMethod(&m_shellThread, closeShell, Qt::BlockingQueuedConnection); QMetaObject::invokeMethod(&m_shellThread, closeShell, Qt::BlockingQueuedConnection);
} }
void LinuxDevicePrivate::queryOsType(std::function<RunResult(const CommandLine &)> runInShell)
{
const RunResult result = runInShell({"uname", {"-s"}, OsType::OsTypeLinux});
if (result.exitCode != 0)
q->_setOsType(OsTypeOtherUnix);
const QString osName = QString::fromUtf8(result.stdOut).trimmed();
if (osName == "Darwin")
q->_setOsType(OsTypeMac);
if (osName == "Linux")
q->_setOsType(OsTypeLinux);
}
void LinuxDevicePrivate::checkOsType()
{
queryOsType([this](const CommandLine &cmd) { return runInShell(cmd); });
}
// Call me with shell mutex locked // Call me with shell mutex locked
bool LinuxDevicePrivate::setupShell() bool LinuxDevicePrivate::setupShell()
{ {
@@ -1058,6 +1084,10 @@ bool LinuxDevicePrivate::setupShell()
QMetaObject::invokeMethod(m_handler, [this, sshParameters] { QMetaObject::invokeMethod(m_handler, [this, sshParameters] {
return m_handler->start(sshParameters); return m_handler->start(sshParameters);
}, Qt::BlockingQueuedConnection, &ok); }, Qt::BlockingQueuedConnection, &ok);
if (ok) {
queryOsType([this](const CommandLine &cmd) { return m_handler->runInShell(cmd); });
}
return ok; return ok;
} }
@@ -1452,6 +1482,11 @@ LinuxDevicePrivate *LinuxDevice::connectionAccess() const
return d; return d;
} }
void LinuxDevice::checkOsType()
{
d->checkOsType();
}
namespace Internal { namespace Internal {
// Factory // Factory

View File

@@ -42,11 +42,15 @@ public:
const ProjectExplorer::FileTransferSetupData &setup) const override; const ProjectExplorer::FileTransferSetupData &setup) const override;
class LinuxDevicePrivate *connectionAccess() const; class LinuxDevicePrivate *connectionAccess() const;
void checkOsType() override;
protected: protected:
LinuxDevice(); LinuxDevice();
void _setOsType(Utils::OsType osType);
class LinuxDevicePrivate *d; class LinuxDevicePrivate *d;
friend class LinuxDevicePrivate;
}; };
namespace Internal { namespace Internal {

View File

@@ -59,12 +59,6 @@ private slots:
m_fileSizeTestFile.writeFileContents(QByteArray(1024, 'a')); m_fileSizeTestFile.writeFileContents(QByteArray(1024, 'a'));
} }
void osType()
{
const auto osType = m_dfaPtr->osType({});
QCOMPARE(osType, HostOsInfo::hostOs());
}
void fileSize() void fileSize()
{ {
const auto size = m_dfaPtr->fileSize(m_fileSizeTestFile); const auto size = m_dfaPtr->fileSize(m_fileSizeTestFile);