๐ Version Management - Evoluciรณn sin Ruptura¶
๐ Descripciรณn¶
El Version Management System gestiona la evoluciรณn de presets a travรฉs del tiempo, garantizando backward compatibility y permitiendo migraciรณn automรกtica entre versiones. Es el sistema que permite que presets antiguos funcionen en versiones nuevas del software.
Criticidad: โญโญโญโญโญ (Crรญtico - sin esto, los usuarios pierden sus presets al actualizar)
๐ฏ Objetivos¶
- Backward Compatibility: Garantizar que presets antiguos funcionen siempre
- Automatic Migration: Migrar presets automรกticamente a versiones nuevas
- Safe Rollback: Permitir rollback si la migraciรณn falla
- Compatibility Matrix: Tracking de quรฉ versiones son compatibles
- Deprecation System: Sistema de warnings para features deprecated
๐๏ธ Arquitectura¶
Componentes Principales¶
Version Management System
โ
โโโ Version System
โ โโโ SemanticVersion (MAJOR.MINOR.PATCH)
โ โโโ VersionParser (string โ Version)
โ โโโ VersionComparator (A < B, A == B)
โ โโโ VersionRange (>=1.0.0, <2.0.0)
โ
โโโ Migration System
โ โโโ MigrationScript (v1.0 โ v1.1)
โ โโโ MigrationChain (v1.0 โ v1.5 โ v2.0)
โ โโโ MigrationRegistry (script lookup)
โ โโโ MigrationExecutor (run + validate)
โ
โโโ Compatibility System
โ โโโ CompatibilityMatrix (version โ version map)
โ โโโ CompatibilityChecker (can migrate?)
โ โโโ BreakingChanges tracker
โ
โโโ Version Manager (orchestrator)
โโโ migrate(preset, target_version)
โโโ checkCompatibility(v1, v2)
โโโ canMigrate(preset, target_version)
โโโ rollback(preset)
Semantic Versioning¶
MAJOR.MINOR.PATCH - MAJOR: Breaking changes (incompatible API) - MINOR: New features (backward compatible) - PATCH: Bug fixes (backward compatible)
Ejemplos:
- 1.0.0 โ 1.0.1: Patch (bug fix)
- 1.0.1 โ 1.1.0: Minor (new feature)
- 1.1.0 โ 2.0.0: Major (breaking change)
๐ Migration Pipeline¶
1. Detection Phase¶
auto version = preset.getVersion();
auto current = VersionManager::getCurrentVersion();
if (version < current) {
// Migration needed
}
2. Compatibility Check¶
bool can_migrate = manager.canMigrate(preset, current);
if (!can_migrate) {
// Version too old or incompatible
throw IncompatibleVersionError();
}
3. Migration Execution¶
// Build migration chain: v1.0 โ v1.5 โ v2.0
auto chain = manager.buildMigrationChain(version, current);
// Execute migrations
for (auto& migration : chain) {
preset = migration->migrate(preset);
preset.validate(); // Ensure validity at each step
}
4. Validation¶
// Verify migrated preset is valid
if (!preset.validate()) {
// Rollback if validation fails
preset = manager.rollback(preset);
}
๐ Migration Scripts¶
Script Structure¶
class MigrationScript {
public:
Version from_version() const;
Version to_version() const;
PresetSchema migrate(const PresetSchema& preset) const;
PresetSchema rollback(const PresetSchema& preset) const;
std::string description() const;
std::vector<std::string> breaking_changes() const;
};
Example Migration: v1.0 โ v1.1¶
Changes:
- Added new parameter filter.drive
- Renamed osc.waveform โ osc.wave_type
- Deprecated env.curve (use env.shape instead)
class Migration_1_0_to_1_1 : public MigrationScript {
PresetSchema migrate(const PresetSchema& preset) const override {
PresetSchema migrated = preset;
// Add new parameter with default value
if (!migrated.hasParameter("filter.drive")) {
migrated.setParameter("filter.drive", 1.0);
}
// Rename parameter
if (migrated.hasParameter("osc.waveform")) {
auto value = migrated.getParameter("osc.waveform");
migrated.setParameter("osc.wave_type", value);
migrated.removeParameter("osc.waveform");
}
// Deprecate parameter (keep for now)
if (migrated.hasParameter("env.curve")) {
auto value = migrated.getParameter("env.curve");
migrated.setParameter("env.shape", value);
// Mark as deprecated but don't remove
migrated.addDeprecationWarning("env.curve", "Use env.shape instead");
}
// Update version
migrated.setVersion({1, 1, 0});
return migrated;
}
};
๐งช Compatibility Matrix¶
Version Compatibility Table¶
| From Version | To Version | Compatible? | Migration Path | Breaking Changes |
|---|---|---|---|---|
| 1.0.0 | 1.0.1 | โ Yes | Direct | None |
| 1.0.0 | 1.1.0 | โ Yes | Direct | None |
| 1.0.0 | 2.0.0 | โ Yes | Via 1.5.0 | Parameter renames |
| 1.0.0 | 3.0.0 | โ No | - | Too many changes |
Compatibility Rules¶
Within MAJOR version: - โ Always compatible forward (1.0 โ 1.9) - โ Usually compatible backward (1.9 โ 1.0)
Across MAJOR versions: - โ ๏ธ Needs migration (1.x โ 2.x) - โ May be incompatible (1.x โ 3.x)
๐จ Breaking Changes¶
Types of Breaking Changes¶
- Parameter Removal
- Parameter deleted completely
-
Requires fallback or migration
-
Parameter Rename
- Name changed
-
Migration script can handle
-
Parameter Type Change
- Type changed (float โ int, string โ enum)
-
May require value conversion
-
Parameter Semantics Change
- Meaning changed (range, units)
-
Requires careful migration
-
Structure Change
- Schema structure changed
- Complex migration needed
Handling Breaking Changes¶
class BreakingChange {
enum Type {
ParameterRemoved,
ParameterRenamed,
ParameterTypeChanged,
ParameterSemanticsChanged,
StructureChanged
};
Type type;
std::string description;
std::string mitigation; // How to handle it
};
๐ Usage Examples¶
Example 1: Load Old Preset¶
// Load preset from file
auto preset = PresetSchema::loadFromFile("old_preset.json");
// Check if migration needed
auto manager = VersionManager::getInstance();
if (manager.needsMigration(preset)) {
std::cout << "Migrating from v" << preset.getVersion().toString()
<< " to v" << manager.getCurrentVersion().toString() << "\n";
// Migrate automatically
preset = manager.migrate(preset);
// Save migrated version
preset.saveToFile("old_preset_migrated.json");
}
Example 2: Check Compatibility¶
Version v1{1, 0, 0};
Version v2{2, 5, 0};
auto manager = VersionManager::getInstance();
if (manager.isCompatible(v1, v2)) {
std::cout << "Can migrate from v" << v1.toString()
<< " to v" << v2.toString() << "\n";
// Show migration path
auto path = manager.getMigrationPath(v1, v2);
std::cout << "Migration path: ";
for (const auto& step : path) {
std::cout << step.toString() << " โ ";
}
std::cout << "done\n";
}
Example 3: Safe Migration with Rollback¶
auto manager = VersionManager::getInstance();
auto target = Version{2, 0, 0};
try {
// Create backup
auto backup = preset;
// Attempt migration
preset = manager.migrate(preset, target);
// Validate
if (!preset.validate()) {
throw MigrationError("Validation failed");
}
std::cout << "โ
Migration successful\n";
} catch (const MigrationError& e) {
std::cerr << "โ Migration failed: " << e.what() << "\n";
// Rollback
preset = backup;
std::cerr << "Rolled back to v" << preset.getVersion().toString() << "\n";
}
๐ฏ Performance Targets¶
| Operation | Target | Typical |
|---|---|---|
| Version parsing | <1 ฮผs | 0.5 ฮผs |
| Compatibility check | <10 ฮผs | 5 ฮผs |
| Single migration | <10 ms | 5 ms |
| Chain migration (3 steps) | <30 ms | 15 ms |
| Rollback | <5 ms | 2 ms |
๐งช Testing Strategy¶
Test Coverage¶
- Unit Tests
- Version parsing and comparison
- Migration script logic
-
Compatibility checking
-
Integration Tests
- Full migration chains
- Rollback scenarios
-
Multi-version compatibility
-
Regression Tests
- Real legacy presets
- Edge cases (very old versions)
- Performance tests
Test Scenarios¶
TEST_CASE("Version Parsing") {
REQUIRE(Version::parse("1.2.3") == Version{1, 2, 3});
REQUIRE(Version::parse("v1.0.0") == Version{1, 0, 0});
}
TEST_CASE("Migration Chain") {
auto preset = createV1Preset();
auto migrated = manager.migrate(preset, Version{2, 0, 0});
REQUIRE(migrated.getVersion() == Version{2, 0, 0});
REQUIRE(migrated.validate());
}
TEST_CASE("Rollback on Failure") {
auto preset = createCorruptedPreset();
REQUIRE_THROWS(manager.migrate(preset, Version{2, 0, 0}));
// Should still have original version
REQUIRE(preset.getVersion() == Version{1, 0, 0});
}
๐ API Reference¶
Version Class¶
class Version {
public:
int major, minor, patch;
std::string toString() const;
static Version parse(const std::string& str);
bool operator<(const Version& other) const;
bool operator==(const Version& other) const;
bool isCompatibleWith(const Version& other) const;
};
VersionManager Class¶
class VersionManager {
public:
static VersionManager& getInstance();
// Migration
PresetSchema migrate(const PresetSchema& preset, const Version& target);
bool canMigrate(const PresetSchema& preset, const Version& target);
std::vector<Version> getMigrationPath(const Version& from, const Version& to);
// Compatibility
bool isCompatible(const Version& v1, const Version& v2);
CompatibilityMatrix getCompatibilityMatrix() const;
// Version info
Version getCurrentVersion() const;
std::vector<Version> getSupportedVersions() const;
std::vector<BreakingChange> getBreakingChanges(const Version& from, const Version& to);
};
๐ Getting Started¶
1. Basic Usage¶
#include "version_manager.hpp"
// Load preset
auto preset = PresetSchema::loadFromFile("preset.json");
// Migrate to current version
auto manager = VersionManager::getInstance();
auto migrated = manager.migrate(preset, manager.getCurrentVersion());
// Save
migrated.saveToFile("preset_updated.json");
2. Add New Migration Script¶
// Create migration script
class Migration_1_5_to_1_6 : public MigrationScript {
Version from_version() const override { return {1, 5, 0}; }
Version to_version() const override { return {1, 6, 0}; }
PresetSchema migrate(const PresetSchema& preset) const override {
// Your migration logic here
}
};
// Register migration
VersionManager::getInstance().registerMigration(
std::make_unique<Migration_1_5_to_1_6>()
);
๐ Best Practices¶
For Developers¶
- Always increment version when changing schema
- Write migration scripts for breaking changes
- Test with real presets from all versions
- Document breaking changes clearly
- Provide rollback when possible
For Users¶
- Backup presets before major updates
- Test migrations on copy first
- Report migration issues immediately
- Keep old version available if needed
๐ Related Systems¶
- Preset Schemas (TAREA 1): Define structure to migrate
- Serialization Engine (TAREA 2): Load/save different versions
- Validation System (TAREA 5): Verify migrated presets
- Cloud Integration (TAREA 10): Sync version-aware presets
๐ Metrics & Monitoring¶
Key Metrics¶
- Migration success rate: >99%
- Rollback rate: <1%
- Average migration time: <20ms
- Compatibility coverage: 100% within MAJOR version
Monitoring¶
- Track migration failures
- Log breaking changes encountered
- Monitor performance of migration chains
- Alert on incompatible versions
Status: ๐ In Development Last Updated: 2025-01-15 Version: 1.0.0