aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils/environment.h
blob: 1b6b7d2c0e00808f2023ad1e92aea6daf700a89b (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#pragma once

#include "utils_global.h"

#include "environmentfwd.h"
#include "filepath.h"
#include "namevaluedictionary.h"
#include "utiltypes.h"

#include <functional>
#include <optional>

QT_BEGIN_NAMESPACE
class QProcessEnvironment;
QT_END_NAMESPACE

namespace Utils {

class QTCREATOR_UTILS_EXPORT Environment final
{
public:
    enum class PathSeparator { Auto, Colon, Semicolon };

    Environment();
    explicit Environment(OsType osType);
    explicit Environment(const QStringList &env, OsType osType = HostOsInfo::hostOs());
    explicit Environment(const NameValuePairs &nameValues);
    explicit Environment(const NameValueDictionary &dict);

    QString value(const QString &key) const;
    QString value_or(const QString &key, const QString &defaultValue) const;
    bool hasKey(const QString &key) const;

    void set(const QString &key, const QString &value, bool enabled = true);
    void setFallback(const QString &key, const QString &value);
    void unset(const QString &key);
    void modify(const EnvironmentItems &items);

    bool hasChanges() const;

    OsType osType() const;
    QStringList toStringList() const;
    QProcessEnvironment toProcessEnvironment() const;

    void appendOrSet(const QString &key,
                     const QString &value,
                     PathSeparator sep = PathSeparator::Auto);
    void prependOrSet(const QString &key,
                      const QString &value,
                      PathSeparator sep = PathSeparator::Auto);

    void appendOrSetPath(const FilePath &value);
    void prependOrSetPath(const FilePath &value);
    void prependOrSetPath(const QString &directories); // Could be several ':'/';' separated entries.

    void prependOrSetLibrarySearchPath(const FilePath &value);
    void prependOrSetLibrarySearchPaths(const FilePaths &values);

    void prependToPath(const FilePaths &values);
    void appendToPath(const FilePaths &values);

    void setupEnglishOutput();
    void setupSudoAskPass(const FilePath &askPass);

    FilePath searchInPath(const QString &executable,
                          const FilePaths &additionalDirs = FilePaths(),
                          const FilePathPredicate &func = {},
                          FilePath::MatchScope = FilePath::WithAnySuffix) const;

    FilePaths path() const;
    FilePaths pathListValue(const QString &varName) const;

    QString expandedValueForKey(const QString &key) const;
    QString expandVariables(const QString &input) const;
    FilePath expandVariables(const FilePath &input) const;
    QStringList expandVariables(const QStringList &input) const;

    NameValueDictionary toDictionary() const; // FIXME: avoid
    EnvironmentItems diff(const Environment &other, bool checkAppendPrepend = false) const; // FIXME: avoid

    struct Entry { QString key; QString value; bool enabled; };
    using FindResult = std::optional<Entry>;
    FindResult find(const QString &name) const; // Note res->key may differ in case from name.

    void forEachEntry(const std::function<void (const QString &, const QString &, bool)> &callBack) const;

    bool operator!=(const Environment &other) const;
    bool operator==(const Environment &other) const;

    static Environment systemEnvironment();

    static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!!
    static void setSystemEnvironment(const Environment &environment);  // don't use at all!!!

    QChar pathListSeparator(PathSeparator sep) const;

    enum Type {
        SetSystemEnvironment,
        SetFixedDictionary,
        SetValue,
        SetFallbackValue,
        UnsetValue,
        PrependOrSet,
        AppendOrSet,
        Modify,
        SetupEnglishOutput
    };

    using Item = std::variant<
        std::monostate,                              // SetSystemEnvironment dummy
        NameValueDictionary,                         // SetFixedDictionary
        std::tuple<QString, QString, bool>,          // SetValue (key, value, enabled)
        std::tuple<QString, QString>,                // SetFallbackValue (key, value)
        QString,                                     // UnsetValue (key)
        std::tuple<QString, QString, PathSeparator>, // PrependOrSet (key, value, separator)
        std::tuple<QString, QString, PathSeparator>, // AppendOrSet (key, value, separator)
        EnvironmentItems,                              // Modify
        std::monostate,                              // SetupEnglishOutput
        FilePath                                     // SetupSudoAskPass (file path of qtc-askpass or ssh-askpass)
        >;

    void addItem(const Item &item);

    Environment appliedToEnvironment(const Environment &base) const;

    const NameValueDictionary &resolved() const;

private:
    mutable QList<Item> m_changeItems;
    mutable NameValueDictionary m_dict; // Latest resolved.
    mutable bool m_fullDict = false;
};

using EnviromentChange = Environment;

class QTCREATOR_UTILS_EXPORT EnvironmentProvider
{
public:
    QByteArray id;
    QString displayName;
    std::function<Environment()> environment;

    static void addProvider(EnvironmentProvider &&provider);
    static const QList<EnvironmentProvider> providers();
    static std::optional<EnvironmentProvider> provider(const QByteArray &id);
};

QTCREATOR_UTILS_EXPORT QString qtcEnvironmentVariable(const QString &key);
QTCREATOR_UTILS_EXPORT QString qtcEnvironmentVariable(const QString &key,
                                                      const QString &defaultValue);
QTCREATOR_UTILS_EXPORT bool qtcEnvironmentVariableIsSet(const QString &key);
QTCREATOR_UTILS_EXPORT bool qtcEnvironmentVariableIsEmpty(const QString &key);
QTCREATOR_UTILS_EXPORT int qtcEnvironmentVariableIntValue(const QString &key, bool *ok = nullptr);

} // namespace Utils

Q_DECLARE_METATYPE(Utils::Environment)