Prendiamo come esempio il bug generato dalla breaking change di RavenDB, bug che abbiamo usato come incipit di questa discussione.

È possibile prevenirlo?

Si, e pure con estrema facilità. Uno degli step del nostro processo di build consiste nel far girare un tool che confronta l’API pubblica di due assembly e in base alla versione degli assembly decide se far fallire o meno la build nel caso in cui SemVer non sia rispettato.

Il tool, a fini di test, è esposto anche come web server, potete quindi provarlo voi stessi:

http://apicomparer-preview.particular.net/compare/ravendb.client/3.0.30165...3.5.2#.NETFramework,Version=v4.5

La chiamata di cui sopra altro non fa che:

  • recuperare i pacchetti nuget referenziati nell’URL
  • spacchettarli
  • confrontare le API pubbliche a fronte di un set di regole

E…boom. Tra la 3.0 e la 3.5 ci sono una quantità spaventosa di breaking change.

Se non fosse che è molto costoso dovremmo sottoporre al nostro simpatico ApiComparer anche tutte le dipendenze.

Nota

ApiComparer è open source: https://github.com/ParticularLabs/APIComparer

Test, test, test e ancora test

I tool, essendo robi automatici e molto poco senzienti, fanno tanto ma hanno tanti limiti. La seconda cosa da fare è quindi scrivere tanti test che garantiscano che il comportamento atteso sia rispettato. Questa seconda parte è forse la più difficile.

Perché la più difficile? perché è molto complesso (al limite dell’impossibile secondo me) prevedere tutti gli usi possibili che il vostro utente farà dell’API che gli fornite.

Una strategia

Alla lunga mi sto rendendo conto che una strategia, figlia sia del lavoro in Particular, ma anche dell’aver manutenuto Radical per circa 10 anni, è quella di ridurre all’osso la superficie dell’API pubblica. Tutto è internal per definizione e quando avete voglia di metterlo public fatevi delle domande.

Proprio al fine di garantire il più possibile il rispetto di SemVer ogni volta che in Particular qualcuno ha bisogno di un API pubblica ci si ferma e si fa un lungo ragionamento finalizzato a capire come ottenere lo stesso risultato senza un’API pubblica.

La breaking change sono il nostro incubo, e nonostante tutto quello che facciamo ad ogni major release siamo di fronte alla dolorosa necessità di introdurne. Miglioriamo sempre di più, ma la perfezione è utopica oppure ha un costo insostenibile ;-)