Open Source Avonturen

He has wifi t-shirt Erik
Erik
Erik, Technical Director
Bij Kaliber maken we veel gebruik van open source software: de servers draaien erop, de code is ermee gebouwd en voor sommigen van ons bestuurt het onze laptop. In dit artikel neem ik je mee op één van mijn avonturen in open source land. Als het te technisch wordt, moet je maar gewoon doen alsof je het snapt ;-D.

Publicatie: 5 december 2019

Open source

Veel mensen denken dat we open source software gebruiken omdat het gratis is, maar dat is niet de reden. Wat is dan de reden?

De broncode is beschikbaar

En het feit dat we naar de broncode kunnen kijken, heeft een aantal voordelen:

  • Veiligheid — we kunnen de code inspecteren om te zien of er geen gekke dingen gedaan worden.
  • Kwaliteit — we kunnen aan de code zien wat de kwaliteit is van de software.
  • Problemen — als er een probleem in de software zit, kijken we of we er tijdelijk omheen kunnen werken en mogelijk een oplossing aandragen.
  • Continuïteit — als iemand besluit te stoppen met het onderhouden van de code kunnen we het onder eigen beheer blijven gebruiken.
Octocat, mascot voor de source-code hosting service GitHub

Kwaliteit en vertrouwen

Doordat iedereen de broncode kan bekijken (en potentieel aanpassen), gaat de kwaliteit omhoog. Al deze ogen op de broncode heeft als bijkomend effect dat problemen, per ongeluk of expres, sneller boven water komen.

Wanneer de broncode niet beschikbaar is zit er niets anders op dan maar vertrouwen dat de eigenaar geen kwade intenties heeft. De eigenaar zou namelijk code kunnen schrijven die niets toevoegt voor het gebruik. Er zou bijvoorbeeld code in kunnen zitten die opneemt wat jij intypt en het verstuurt naar hun servers. Op die manier kunnen ze wachtwoorden achterhalen.

Tot zover open source, op naar het avontuur.

Leading slash import

Klinkt moeilijk, dus ik zal proberen om het uit te leggen: “Dit is een specifieke techniek om code te kunnen hergebruiken op een manier die later niet in de weg zit.”

Leading slash import?

Als je precies wil weten wat het is, kun je dit hoofdstukje lezen. Het is geen probleem als je als je verder scrollt naar de volgende dikgedrukte kop en direct meegaat op avontuur

Het gebruiken van code uit een ander bestand gaat zo:

import abc from ‘./abc’

Die ./ (spreek je uit als punt, slash) betekent: ‘zoek in de directory waar dit bestand in staat’. Het kom wel eens voor dat een bestand in een directory ‘hoger’ zit dan het huidige bestand. Neem bijvoorbeeld de volgende structuur:

/directory a/bestand z
/directory a/directory b/bestand x
/directory a/directory b/bestand y
/directory c/

Stel dat ik vanuit bestand x de code uit bestand y wil gebruiken, dan doe ik dit:

import y from ‘./bestand y’

En als ik bestand z zou willen gebruiken kan ik dit doen:

import z from ‘../bestand z’

Die twee puntjes betekent: ‘1 directory omhoog’. Het probleem ontstaat wanneer we bestand x naar directory c verplaatsen, dan klopt ../bestand z’ niet meer (het zou natuurlijk ./bestand z’, 1 punt, moeten zijn). Wanneer we hier een ‘leading slash’ hadden gebruikt, had de import er zo uit gezien:

import z from ‘/directory a/bestand z’

De slash ‘/’ die aan het begin staat noemen we ‘leading slash’. Het gebruik van de ‘leading slash’ geeft ons dus de vrijheid om het bestand te verplaatsen zonder dat we dingen stuk maken.

Het probleem / begin van het avontuur

Voor de meeste van de tools die we bij het programmeren gebruiken, was het relatief makkelijk om configuratie aan te passen of een stukje code te schrijven die het gebruik van leading slash imports mogelijk maakt. Er was echter één belangrijke tool waar het gebruik van de leading slash niet werkte: onze editor Visual Studio Code. Hierin zit een machientje dat ons hele handige dingen vertelt over onze code: Typescript.

Voor de nerds onder ons: ik ben fan van Typescript, maar ik probeer het zo min mogelijk te schrijven — wellicht dat ik nog een keer een artikel schrijf waarin ik uitleg waarom wij Javascript bestanden hebben en geen Typescript bestanden.
TypeScript logo

Onderzoek doen

De eerste stap is om te kijken bij de source code van Typescript of iemand anders al heeft aangegeven dat deze feature - leading slash import - handig is om te hebben. Dit gebeurt over het algemeen door een issue (of ticket) aan te maken. Dat bleek voor dit specifieke probleem het geval te zijn: TypeScript paths config doesn’t work with leading slashes.

De volgende stap is om een beetje een gevoel te krijgen van de situatie. In dit geval was het issue gerapporteerd op 27 januari 2017 en ik vond het issue in april 2018. Daarnaast waren er genoeg comments en duimpjes omhoog wat mij het gevoel geeft dat dit iets is waar meer mensen profijt van zouden hebben. Het feit dat dit issue lang open stond (meer dan een jaar) geeft voor mij ook aan dat het voor de eigenaars geen hoge prioriteit heeft en er niemand anders is dit het probleem wil of kan oplossen.

Vervolgens is het belangrijk om het idee duidelijk te maken, in dit geval heb ik dat gedaan door een comment te plaatsen. De reacties hierop waren goed en dan is het zaak om met de ‘maintainers’ (de mensen die de code onderhouden) af te stemmen hoe de nieuwe feature precies geïmplementeerd moet worden.

In deze fase is het ook belangrijk om te kijken welke randvoorwaarden er zitten aan het bijdragen van code. Aangezien dit een groot en enorm populair project is was er een uitgebreide contribution guide aanwezig. Naast het ondertekenen van een ‘contribution licence agreement’ waren er nog een aantal andere randvoorwaarden. Er is redelijk wat tijd overheen gegaan en het was in dit geval ook nodig om wat tactieken uit de kunst van psychologische oorlogsvoering toe te passen. Resultaat: matig succesvol.

Screenshot van de voorgestelde veranderingen

De code in

Om er toch wat meer beweging in te krijgen ben ik de code ingedoken om een gevoel te krijgen wat er nodig was om dit te implementeren. Dat was een redelijk grote uitdaging: de codebase is gigantisch (heel veel code) en geschreven in een programmeertaal waar ik nog nooit mee gewerkt had (Typescript).

Inception — jij had natuurlijk al door dat het gek is: “Typescript geschreven in Typescript?” Jup, mensen nemen je programmeertaal pas serieus wanneer die geschreven is met zichzelf, dat noemen ze ‘Self-hosting’.

Uiteindelijk had ik de plekken gevonden waar ik code moest aanpassen en de tests die hiervoor geschreven moesten worden. Nadat ik de aanpassingen gedaan had en een versie had waar de ‘maintainers’ iets mee zouden kunnen heb ik een ‘pull request’ aangemaakt. Een ‘pull request’ is een verzoek aan de eigenaren om de aanpassingen die je hebt gemaakt mee te nemen in de ‘echte’ code.

De reactie

Alles bij elkaar heeft dit er voor gezorgd dat het Typescript team bij Microsoft dit heeft besproken in een design meeting. Een greep uit de notities:

  • “This person used path mapping to set up their imports, which was their first mistake…”
  • Not crazy when you’re hosting on a web server
  • We see this as the drive root, which is obviously madness
  • It looks like an absolute path but it’s not
  • Is there any reason to not do this? We don’t even need a flag
  • Not really a breaking change since you’d have to have an “incorrect” extant path mapping
  • Three kinds of paths: relative, non-relative, absolute (relative and non-relative are not exact opposites)

Het is leuk om te zien dat ze het onderwerp serieus hebben genomen en dat ze er een flinke discussie over gehad hebben. Het belangrijkste is dat ze het uiteindelijk goedgekeurd hebben!

Het schaven

Wanneer je code schrijft die iemand anders moet onderhouden, is het belangrijk dat je de stijl en conventies van de ander aanhoud. Dat is super moeilijk, vaak typen mijn vingers dingen op een bepaalde manier zonder dat ik het doorheb. Als ik code schrijf dan is dat standaard in mijn eigen handschrift.

Om dit goed te krijgen doen we ‘code reviews’ waarbij iemand anders de code bekijkt. Hierbij worden een aantal verschillende dingen besproken:

  • Problemen — zitten er problemen in de code?
  • Code stijl — is de code in de stijl van de bestaande code?
  • Tests — zijn de tests afdoende?
  • Blinde vlekken — heb je nog dingen gemist?

Op alle vlakken heb ik aanpassingen moeten doen. Ik heb geen problemen met feedback vanuit ‘pull request’, ik probeer altijd in mijn hoofd te houden wat mijn broertje me verteld heeft:

Als iemand kritiek heeft of feedback geeft op je werk, dan geven ze je impliciet ook het vertrouwen dat je daar iets mee kunt.
Mijn code die nu in TypeScript staat

Het resultaat

En uiteindelijk, 3 weken later, is het zover: de wijzigingen worden geaccepteerd en meegenomen in de volgende versie. De eerste versie is de ‘nightly’ build, deze wordt elke nacht gemaakt en bevat dus alle wijzigingen van de vorige dag (als het goed is).

Vervolgens wordt het later in een echte release meegenomen. En weer wat later wordt het meegenomen in de tool waar het mee begon: onze code editor Visual Studio Code.

En nu draait er dus een stukje software van Kaliber op de computers van duizenden ontwikkelaars over de hele wereld, dat is toch tof?

Als jullie het leuk vinden zal ik nog een keer iets schrijven over 1 van mijn andere open source avonturen.

Zelf aan slag met leading slash imports? Onze @kaliber/build library heeft dit standaard ingebakken. En als je het leuk vindt kun je lezen over het ontstaan van @kaliber/build.