| 1115 | } |
| 1116 | |
| 1117 | void migration_v2(nlohmann::json& fileTree) { |
| 1118 | static const int this_version = 2; |
| 1119 | // Determine the current migration version (default to 1 if not present). |
| 1120 | int file_version = 1; |
| 1121 | if (fileTree.contains("version")) { |
| 1122 | try { |
| 1123 | file_version = fileTree["version"].get<int>(); |
| 1124 | } catch (const std::exception& e) { |
| 1125 | BOOST_LOG(info) << "Cannot parse apps.json version, treating as v1: " << e.what(); |
| 1126 | } |
| 1127 | } |
| 1128 | |
| 1129 | // If the version is less than this_version, perform legacy conversion. |
| 1130 | if (file_version < this_version) { |
| 1131 | BOOST_LOG(info) << "Migrating app list from v1 to v2..."; |
| 1132 | migrate_apps(&fileTree, nullptr); |
| 1133 | |
| 1134 | // List of keys to convert to booleans. |
| 1135 | std::vector<std::string> boolean_keys = { |
| 1136 | "allow-client-commands", |
| 1137 | "exclude-global-prep-cmd", |
| 1138 | "elevated", |
| 1139 | "auto-detach", |
| 1140 | "wait-all", |
| 1141 | "use-app-identity", |
| 1142 | "per-client-app-identity", |
| 1143 | "virtual-display" |
| 1144 | }; |
| 1145 | |
| 1146 | // List of keys to convert to integers. |
| 1147 | std::vector<std::string> integer_keys = { |
| 1148 | "exit-timeout", |
| 1149 | "scale-factor" |
| 1150 | }; |
| 1151 | |
| 1152 | // Walk through each app and convert legacy string values. |
| 1153 | for (auto &app : fileTree["apps"]) { |
| 1154 | for (const auto &key : boolean_keys) { |
| 1155 | if (app.contains(key)) { |
| 1156 | auto& _key = app[key]; |
| 1157 | if (_key.is_string()) { |
| 1158 | std::string s = _key.get<std::string>(); |
| 1159 | std::transform(s.begin(), s.end(), s.begin(), ::tolower); // Normalize to lowercase for comparison |
| 1160 | _key = (s == "true" || s == "on" || s == "yes"); |
| 1161 | } else if (_key.is_array()) { |
| 1162 | // Check if the array contains at least one item and interpret the first element |
| 1163 | if (!_key.empty() && _key[0].is_string()) { |
| 1164 | std::string first = _key[0].get<std::string>(); |
| 1165 | std::transform(first.begin(), first.end(), first.begin(), ::tolower); // Normalize |
| 1166 | if (first == "on" || first == "true" || first == "yes") { |
| 1167 | _key = true; |
| 1168 | } else if (first == "off" || first == "false" || first == "no") { |
| 1169 | _key = false; |
| 1170 | } else { |
| 1171 | _key = false; // Default for unknown values |
| 1172 | } |
| 1173 | } else { |
| 1174 | _key = false; // Treat empty arrays or non-string first elements as false |
no test coverage detected