aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/mesonprojectmanager/machinefiles/machinefilemanager.cpp
blob: 67169f0812017fbdaff71b398364c3af6b54a05e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (C) 2020 Alexis Jeandet.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#include "machinefilemanager.h"

#include "kithelper/kitdata.h"
#include "kithelper/kithelper.h"
#include "nativefilegenerator.h"

#include <coreplugin/icore.h>

#include <utils/optional.h>
#include <utils/qtcassert.h>

#include <QDir>
#include <QFile>
#include <QRegularExpression>

namespace MesonProjectManager {
namespace Internal {

const char MACHINE_FILE_PREFIX[] = "Meson-MachineFile-";
const char MACHINE_FILE_EXT[] = ".ini";

template<typename F>
bool withFile(const Utils::FilePath &path, const F &f)
{
    QFile file(path.toString());
    if (file.open(QIODevice::WriteOnly)) {
        f(&file);
        return file.flush();
    }
    return false;
}

Utils::FilePath MachineFilesDir()
{
    return Core::ICore::userResourcePath("Meson-machine-files");
}

MachineFileManager::MachineFileManager()
{
    using namespace ProjectExplorer;
    connect(KitManager::instance(),
            &KitManager::kitAdded,
            this,
            &MachineFileManager::addMachineFile);
    connect(KitManager::instance(),
            &KitManager::kitUpdated,
            this,
            &MachineFileManager::updateMachineFile);
    connect(KitManager::instance(),
            &KitManager::kitRemoved,
            this,
            &MachineFileManager::removeMachineFile);
    connect(KitManager::instance(),
            &KitManager::kitsLoaded,
            this,
            &MachineFileManager::cleanupMachineFiles);
}

Utils::FilePath MachineFileManager::machineFile(const ProjectExplorer::Kit *kit)
{
    QTC_ASSERT(kit, return {});
    auto baseName
        = QString("%1%2%3").arg(MACHINE_FILE_PREFIX).arg(kit->id().toString()).arg(MACHINE_FILE_EXT);
    baseName = baseName.remove('{').remove('}');
    return MachineFilesDir().pathAppended(baseName);
}

void MachineFileManager::addMachineFile(const ProjectExplorer::Kit *kit)
{
    auto filePath = machineFile(kit);
    QTC_ASSERT(!filePath.isEmpty(), return );
    auto data = KitHelper::kitData(kit);
    QTC_ASSERT(withFile(filePath,
                        [&data](QFile *file) { NativeFileGenerator::makeNativeFile(file, data); }),
               return );
}

void MachineFileManager::removeMachineFile(const ProjectExplorer::Kit *kit)
{
    auto filePath = machineFile(kit);
    if (filePath.exists())
        QFile::remove(filePath.toString());
}

void MachineFileManager::updateMachineFile(const ProjectExplorer::Kit *kit)
{
    addMachineFile(kit);
}

void MachineFileManager::cleanupMachineFiles()
{
    const auto kits = ProjectExplorer::KitManager::kits();
    auto machineFilesDir = QDir(MachineFilesDir().toString());
    if (!machineFilesDir.exists()) {
        machineFilesDir.mkdir(machineFilesDir.path());
    }
    auto machineFiles = QDir(MachineFilesDir().toString())
                            .entryList(
                                {QString("%1*%2").arg(MACHINE_FILE_PREFIX).arg(MACHINE_FILE_EXT)});
    QStringList expected;
    for (auto const *kit : kits) {
        QString fname = machineFile(kit).toString();
        expected.push_back(fname);
        if (!machineFiles.contains(fname))
            addMachineFile(kit);
    }

    for (const auto &file : machineFiles) {
        if (!expected.contains(file))
            QFile::remove(file);
    }
}

} // namespace Internal
} // namespace MesonProjectManager