Open source software krijgt nog al eens het verwijt dat de programmeurs ervan heel vaak schuttingtaal durven op te nemen in hun commentaar. Hieronder zie je bijvoorbeeld de evolutie van het aantal schuttingwoorden die opduiken in de Linux kernel: bij de laatste telling waren er 159 craps, 38 shits, 42 fucks, 23 bastards, … en 102 penguins.
Voor deze opgave vragen we je om een bash
shell script schuttingtaal
te schrijven, waarmee kan nagegaan worden hoe vaak een bepaald token gebruikt werd in een GitHub repository. Aan het shell script moeten twee argumenten doorgegeven worden: i) de locatie van de repository en ii) het token waarnaar moet gezocht worden.
Indien er in de huidige directory nog geen kopie van de repository aanwezig is, dan moet het shell script eerst een kopie van de repository downloaden van GitHub. Voor een repository met locatie
protocol://github.com/organisation/reponaam[.git]
moet een kopie van de repository in de huidige directory opgeslaan worden in een directory met naam reponaam
(waarbij dus ook de eventuele suffix .git
uit de naam van de repository moet verwijderd worden). Indien er wel reeds een kopie van de repository beschikbaar was in de huidge directory, dan moet er enkel voor gezorgd worden dat die overeenkomt met de meest recente versie van de repository op GitHub.
Daarna moet het shell script in alle gewone bestanden van de repository tellen hoeveel regels er zijn waarin het gegeven token voorkomt. Dit aantal moet uitgeschreven worden naar standaard uitvoer.
Bovendien moet het shell script ook de volgende twee opties ondersteunen:
optie -f
: indien deze optie gebruikt wordt, dan moet niet het aantal regels geteld worden waarin het gegeven token voorkomt, maar het aantal bestanden waarin het gegeven token voorkomt
optie -c
: met deze optie moet verplicht een argument doorgegeven worden dat een bepaalde commit uit de repository aanduidt (dit kan bijvoorbeeld een hashwaarde, de naam van een branch of de naam van een tag zijn); indien deze optie gebruikt wordt, dan moet het aantal voorkomens van het gegeven token niet geteld worden in de huidige versie, maar in de versie die wordt aangeduid door de gegeven commit
Indien het shell script niet de correcte opties of argumenten meekrijgt (twee argumenten, enkel ondersteuning voor de opties -f
en -c
waarbij de laatste met een verplicht argument), dan moet het de gepaste foutboodschap (zie onderstaande voorbeeldsessie) uitschrijven naar standaard error, en moet het shell script eindigen met exit status 1. Anders moet het shell script eindigen met exit status 0. Het shell script moet voor de verwerking van de opties de flexibiliteit aan de dag leggen die gebruikelijk is bij Unix commando’s: volgorde van opties speel geen rol, opties kunnen eventueel samengenomen worden, …
Overal waar het shell script gebruik maakt van git
commando’s, moet alle uitvoer van die commando’s ofwel onderdrukt worden of door het shell script uitgeschreven worden naar standaard error (je mag zelf kiezen welke van beide opties je gebruikt). Indien er een fout optreedt bij het uitvoeren van één van de git
commando’s, dan moet het shell script eindigen met exit status 2.
Onderstaande voorbeeldsessie geeft aan hoe het shell script schuttingtaal
moet kunnen gebruikt worden. Bij aanvang van de sessie was er nog geen lokale kopie van de repository impress.js
aanwezig in de huidige directory.
$ schuttingtaal https://github.com/impress/impress.js goto
Cloning into 'impress.js'...
remote: Counting objects: 1002, done.
remote: Total 1002 (delta 0), reused 0 (delta 0), pack-reused 1002
Receiving objects: 100% (1002/1002), 317.14 KiB | 0 bytes/s, done.
Resolving deltas: 100% (396/396), done.
Checking connectivity... done.
32
$ schuttingtaal https://github.com/impress/impress.js bug
13
$ schuttingtaal git://github.com/impress/impress.js.git fuck
0
$ schuttingtaal -c 1a21865e https://github.com/impress/impress.js goto 2> /dev/null
14
$ schuttingtaal -c 0.5 https://github.com/impress/impress.js goto 2> /dev/null
22
$ schuttingtaal -c master https://github.com/impress/impress.js goto 2> /dev/null
32
$ schuttingtaal -f https://github.com/impress/impress.js goto 2> /dev/null
5
$ schuttingtaal -fc "0.4" https://github.com/impress/impress.js goto 2> /dev/null
1
$ schuttingtaal https://github.com/company/repo
Syntaxis: schuttingtaal [-f] [-c commit] <git-repo> <token>
$ echo $?
1
$ schuttingtaal https://github.com/company/repo fuck
Cloning into 'repo'...
Username for 'https://github.com':
Password for 'https://github.com':
remote: Repository not found.
fatal: Authentication failed for 'https://github.com/company/repo/'
$ echo $?
2
$ schuttingtaal -c xxx https://github.com/impress/impress.js goto
error: pathspec 'xxx' did not match any file(s) known to git.
$ echo $?
2