layout: true name: inverse class: center, middle, inverse .footnote[ \#pkgsrccon ### [@schmonz](https://twitter.com/schmonz) ] --- layout: true name: twitterhandle .footnote[ \#pkgsrccon ### [@schmonz](https://twitter.com/schmonz) ] --- template: inverse # Rehabilitating pkglint ## Amitai Schlair, The NetBSD Project ### pkgsrcCon Berlin 2013/03/23 --- layout: false template: twitterhandle .left-column[ ## Why pkglint? ] .right-column[ ### [PR pkg/46570 infelicities in pkglint](http://gnats.netbsd.org/46570) "A good start would be rewriting it not in perl." ] -- .right-column[ ### [Things You Should Never Do, Part I](http://www.joelonsoftware.com/articles/fog0000000069.html) "When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years of programming work." ] -- .right-column[ "It's important to remember that when you start from scratch there is absolutely no reason to believe that you are going to do a better job than you did the first time." ] --- .left-column[ ## (How pkglint?) ] .right-column[ ### Local `git` $ echo .git >> ~/.cvsignore $ echo CVS >> ~/.gitignore_global $ cd $PKGSRCDIR/pkgtools/pkglint $ git init $ git add . $ git commit -am 'Add pkglint to git for offline hacking.' $ git checkout -b rehab $ cd $PKGSRCDIR/pkgtools/pkglint $ git checkout master $ cvs update $ git commit -am 'Track upstream changes from pkgsrc CVS.' $ git checkout rehab $ git rebase master $ vi files/pkglint.t files/pkglint.pl && make test && make clean $ git commit -am 'More cool stuff on my branch.' ] --- .left-column[ ## Why me? ] .right-column[ ### I've been writing a lot of Perl lately ### I know a way to revive legacy code ] --- .left-column[ ## TDD ] .right-column[ ### Test-Driven Development * Misnomer! * Design technique (happens to result in automated tests) * Programmer documentation (happens to be executable) TDD leads to code that _looks like_ it was written by someone careful, skillful, and tasteful. ] --- .left-column[ ## "TED" ] .right-column[ ### "Test-Eventually Development" * We didn't write pkglint test-first * Design suffered * Programmer documentation suffered Whether or not we decide to rewrite pkglint, first we have to understand and document its current behavior. Never too late to test first. Just a bit more difficult. ] --- .left-column[ ## Retrofit ] .right-column[ ### In `pkgsrc-current` * Convert to ["modulino"](http://www.drdobbs.com/scripts-as-modules/184416165) * Add a [test script](http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/pkgtools/pkglint/files/pkglint.t) * Hook it up to `make test` (just barely) * Write a few tests (very simple) * Prove that they fail when they should Approved-by: `wiz` ] --- .left-column[ ## Retrofit ] .right-column[ ### In my `git` * Add ["characterization tests"](https://en.wikipedia.org/wiki/Characterization_test) over a few mature packages * Extract some Perl classes to separate files * Fix `make test` (no custom settings needed) * Deepen an existing test to prepare for [refactoring](https://en.wikipedia.org/wiki/Refactoring) * Change huge `if/elsif/else` block to dispatch table * Fix a bug (!) found during refactoring Planning to merge to `pkgsrc`. In the meantime, see [GitHub](https://github.com/schmonz/pkglint/tree/rehab). ] --- template: inverse # A bit of the old code-reading --- .left-column[ ## Why does this matter? ] .right-column[ ### pkglint isn't such a big deal ### But `pkgsrc/mk` is ] -- .right-column[ Gradually... * Cover infrastructure code with automated tests * Gain shared understanding of complex internals * Freely and safely change them for the better * Keep what makes `pkgsrc` special * Push `pkgsrc` forward ] --- .left-column[ ## "A bit more difficult" ] .right-column[ ### "Never too late to test first" * Tangle of implementation languages * Tangle of dependencies * Progress won't be fast * The alternative is worse * We'll have to work together * We'll have to be patient and persistent ] --- template: inverse # FIN