1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "config.h" |
6 | #include "environment.h" |
7 | #include "processutil.h" |
8 | |
9 | #include <QRegularExpression> |
10 | #include <QDir> |
11 | #include <QDebug> |
12 | #include <QDirIterator> |
13 | |
14 | #include <iostream> |
15 | namespace environment { |
16 | |
17 | const QString RK_Major{"Major" }; |
18 | const QString RK_Minor{"Minor" }; |
19 | const QString RK_Revision{"Revision" }; |
20 | const QString RK_Build{"Build" }; |
21 | |
22 | namespace language { |
23 | |
24 | Version completion(Category category, Kit kit, const Version &version) |
25 | { |
26 | qInfo() << __FUNCTION__ << version.major.value(); |
27 | Version ret = version; |
28 | if (category == User) { |
29 | if (kit == Python) { |
30 | QString program = "python" ; |
31 | if (version.major) { |
32 | program += QString::number(version.major.value()); |
33 | } |
34 | ProcessUtil::execute(program, {"-V" }, [&](const QByteArray &data){ |
35 | QRegularExpression regExp {"Python\\s(?<" + RK_Major +">[0-9])" |
36 | + "\\.(?<" + RK_Minor +">[0-9])" |
37 | + "\\.(?<" + RK_Revision +">[0-9])" |
38 | + "(\\.(?<" + RK_Build + ">[0-9]))?" }; |
39 | auto matchs = regExp.match(data); |
40 | if (matchs.hasMatch()) { |
41 | auto major = matchs.captured(RK_Major); |
42 | auto minor = matchs.captured(RK_Minor); |
43 | auto revsion = matchs.captured(RK_Revision); |
44 | auto build = matchs.captured(RK_Build); |
45 | if (!major.isNull()) { |
46 | ret.major = major.toInt(); |
47 | } |
48 | if (!minor.isNull()) { |
49 | ret.minor = minor.toInt(); |
50 | } |
51 | if (!revsion.isNull()) { |
52 | ret.revision = revsion.toInt(); |
53 | } |
54 | if (!build.isNull()) { |
55 | ret.revision = build.toInt(); |
56 | } |
57 | } |
58 | }); |
59 | } |
60 | } |
61 | return ret; |
62 | } |
63 | |
64 | Program search(Category category, Kit kit, const Version &version) |
65 | { |
66 | qInfo() << __FUNCTION__; |
67 | Program ret; |
68 | if (category == User) { |
69 | if (kit == Python) { |
70 | Version executeVersion = completion(category, kit, version); |
71 | if (executeVersion.major.value() == 3) { |
72 | QString program = "python" ; |
73 | if (executeVersion.major) { |
74 | program + QString::number(executeVersion.major.value()); |
75 | } |
76 | ret.pkgsPath = QDir::homePath() + QDir::separator() |
77 | + ".local" + QDir::separator() |
78 | + "lib" + QDir::separator() |
79 | + QString("python" ) + QString::number(executeVersion.major.value()) |
80 | + "." |
81 | + QString::number(executeVersion.minor.value()) |
82 | + QDir::separator() |
83 | + "site-packages" ; |
84 | } |
85 | } |
86 | } |
87 | return ret; |
88 | } |
89 | |
90 | QProcessEnvironment get(Category category, Kit kit, const Version &version) |
91 | { |
92 | QProcess process; |
93 | auto procEnv = process.processEnvironment(); |
94 | if (category == Category::User) { |
95 | if (kit == Kit::Python) { |
96 | Program program = search(category, kit, version); |
97 | if (program.binsPath) { |
98 | QString runtimeBinPath = program.binsPath.value(); |
99 | QString PATH_EnvValue = procEnv.value("PATH" ); |
100 | procEnv.remove("PATH" ); |
101 | procEnv.insert("PATH" , runtimeBinPath + ":" + PATH_EnvValue); |
102 | } |
103 | if (program.pkgsPath) { |
104 | QString userPythonPkgPath = program.pkgsPath.value(); |
105 | procEnv.remove("PYTHONPATH" ); |
106 | procEnv.insert("PYTHONPATH" , userPythonPkgPath); |
107 | } |
108 | } |
109 | } |
110 | return procEnv; |
111 | } |
112 | |
113 | Version::Version() |
114 | { |
115 | |
116 | } |
117 | |
118 | Version::Version(int major) |
119 | : major(major) |
120 | { |
121 | |
122 | } |
123 | |
124 | Version::Version(const Version &version) |
125 | : major(version.major) |
126 | , minor(version.minor) |
127 | , revision(version.revision) |
128 | , build(version.build) |
129 | { |
130 | |
131 | } |
132 | |
133 | Version &Version::operator =(const Version &version) |
134 | { |
135 | this->major = version.major; |
136 | this->minor = version.minor; |
137 | this->revision = version.revision; |
138 | this->build = version.build; |
139 | return *this; |
140 | } |
141 | |
142 | } // language |
143 | |
144 | /*! |
145 | * @brief package::native::path |
146 | * get local install offline packge path |
147 | * @param category use package name to search |
148 | * @return if Category is empty return install top path, else return package name path |
149 | */ |
150 | QString package::native::path(const Category::type_value &category) |
151 | { |
152 | QString envPath = QString(LIBRARY_INSTALL_PREFIX) |
153 | + QDir::separator() + "tools" |
154 | + QDir::separator() + "env" ; |
155 | if (category.isEmpty()) { |
156 | return envPath; |
157 | } else { |
158 | QDirIterator sameItera(envPath, QDir::Files|QDir::NoDotAndDotDot); |
159 | while (sameItera.hasNext()) { |
160 | sameItera.next(); |
161 | QFileInfo info = sameItera.fileInfo(); |
162 | if (category == info.fileName()) { |
163 | return info.filePath(); |
164 | } |
165 | } |
166 | QDirIterator containsItera(envPath, QDir::Files|QDir::NoDotAndDotDot); |
167 | while (containsItera.hasNext()) { |
168 | containsItera.next(); |
169 | QFileInfo info = containsItera.fileInfo(); |
170 | if (info.fileName().contains(category)) { |
171 | return info.filePath(); |
172 | } |
173 | } |
174 | } |
175 | return envPath; |
176 | } |
177 | |
178 | /*! |
179 | * \brief environment::package::native::installed |
180 | * Determine whether the current offline package is installed |
181 | * \return if install return true, else return false |
182 | */ |
183 | bool environment::package::native::installed() |
184 | { |
185 | QDir dir(path()); |
186 | if (dir.exists()) |
187 | return true; |
188 | return false; |
189 | } |
190 | |
191 | } // environment |
192 | |