Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2026 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "knownaudiopluginsmigrationregister.h"
24 :
25 : #include "../audiopluginstypes.h"
26 :
27 : #include "log.h"
28 :
29 : using namespace muse;
30 : using namespace muse::audioplugins;
31 :
32 10 : KnownAudioPluginsMigrationRegister::KnownAudioPluginsMigrationRegister()
33 : {
34 : // v0 -> v1: {version, plugins} envelope introduced; wrapping happens in load(), no-op here
35 10 : registerMigration(0, [](const JsonArray& plugins) {
36 1 : return plugins;
37 : });
38 :
39 : // v1 -> v2: enabled boolean replaced by the state string
40 10 : registerMigration(1, [](const JsonArray& plugins) {
41 1 : JsonArray out;
42 3 : for (size_t i = 0; i < plugins.size(); ++i) {
43 2 : JsonObject obj = plugins.at(i).toObject();
44 6 : const bool enabled = obj.value("enabled").toBool();
45 4 : obj.set("state", audioPluginStateName(enabled ? AudioPluginState::Validated
46 : : AudioPluginState::Error));
47 :
48 2 : JsonObject rebuilt;
49 9 : for (const std::string& k : obj.keys()) {
50 7 : if (k == "enabled") {
51 2 : continue;
52 : }
53 5 : rebuilt.set(k, obj.value(k));
54 2 : }
55 2 : out << rebuilt;
56 2 : }
57 1 : return out;
58 0 : });
59 :
60 : // v2 -> v3: no-op default, apps override this slot with their own work
61 10 : registerMigration(2, [](const JsonArray& plugins) {
62 1 : return plugins;
63 : });
64 :
65 : // v3 -> v4: bundled plugins are persisted under a portable ${INSTALL_ROOT} path
66 10 : registerMigration(3, [](const JsonArray& plugins) {
67 0 : return plugins;
68 : });
69 10 : }
70 :
71 46 : void KnownAudioPluginsMigrationRegister::registerMigration(int fromVersion, PluginsMigration cb)
72 : {
73 46 : m_migrations[fromVersion] = std::move(cb);
74 46 : }
75 :
76 11 : Ret KnownAudioPluginsMigrationRegister::migrate(int fromVersion, int toVersion, JsonArray& plugins) const
77 : {
78 11 : if (fromVersion == toVersion) {
79 1 : return make_ok();
80 : }
81 :
82 10 : if (fromVersion > toVersion) {
83 0 : return Ret(static_cast<int>(Ret::Code::UnknownError),
84 4 : "cache file version " + std::to_string(fromVersion)
85 4 : + " is newer than this build's expected version "
86 8 : + std::to_string(toVersion)
87 4 : + " (no downgrade). Delete the file or upgrade the build.");
88 : }
89 :
90 17 : for (int v = fromVersion; v < toVersion; ++v) {
91 10 : auto it = m_migrations.find(v);
92 10 : if (it == m_migrations.end()) {
93 0 : return Ret(static_cast<int>(Ret::Code::UnknownError),
94 : "missing migrator for cache version step "
95 2 : + std::to_string(v) + " -> " + std::to_string(v + 1)
96 2 : + ". If you just bumped CURRENT_KNOWN_AUDIO_PLUGINS_VERSION, "
97 2 : + "register a migrator in your app's AudioPluginsAppConfigModule.");
98 : }
99 :
100 9 : plugins = it->second(plugins);
101 : }
102 :
103 7 : return make_ok();
104 : }
|