I am the author and maintainer of ModelsBuilder, an essential tool for the Umbraco CMS. If you use it regularly, or any of my other Open Source tools, you may want to consider my GitHub Sponsorship Program and help ensure that the tools you depend on are maintained in a sustainable way. Thanks!

Migrations in v8 (2)

Posted on December 29, 2018 in umbraco

(continuing from Migrations in v8)

In the previous post, I proposed that Alice adds a migration:

.To<Migration3>("state-3")
.To<AliceChanges>("state-alice-4");

And Bob adds:

.To<Migration3>("state-3");
.To<BobChanges>("state-bob-4");

And, assuming migrations are compatible (impact different things), I proposed to merge the two branches as:

.To<Migration3>("state-3")
.To<AliceChanges>("state-alice-4"); // execute Bob's changes after Alice's
.To<BobChanges>("state-5");

From("state-bob-4") // provide a way for Bob to reach the final state
.To<AliceChanges>("state-5"); // execute Alice's changes after Bob's

Both Bob and Alice would then nicely migrate to state-5 on the next run.

What's Simple?

Daniël Knippers, from our friends at Perplex, bravely emailed me back:

This seems very cumbersome to do for every merge, and fairly error prone as the new target appears in 2 places now and has to be copied by hand. I wonder if it easier when there is an API for this (apparently common) use case.

To be fair, the amount of comments I had to put in the above code fragment does probably indicate that the merge is, indeed, cumbersome. And, granted, the UmbracoPlan class already contains weird and hard-to-understand merges. Daniël suggested a few solutions, which we discussed over emails, until we came up with the following syntactic sugar:

.To<Migration3>("state-3")
.Merge().To<AliceChanges>("state-alice-4")
.With().To<BobChanges>("state-bob-5")
.As("state-5");

This syntax, which has been merged into temp8 already, also supports longer chains:

From("state-1")
.Merge()
    .To<ChangeA1>("state-a1")
    .To<ChangeA2>("state-a2")
.With()
    .To<ChangeB1>("state-b1")
    .To<ChangeB2>("state-b2")
.As("state-2");

It essentially takes care of everything, and creates the proper branches, to make sure that both Bob, Alice, everybody, would eventually reach state-2. The UmbracoPlan class has been simplified by using this construct, and looks way more understandable now.

What's Next?

First, I want to shout a big #h5yr at Daniël. It takes some time and energy to think through a problem and then write emails about it. But then, the beauty of a friendly, open platform shines: instead of having to endure writing convoluted code, you can actually change it!

And then... what would you further simplify?

comments powered by Disqus