-
all right everyone let's get started
-
with the next lecture so today we're
-
gonna that tackle the topic of meta
-
programming and this title is a little
-
weird it's not entirely clear what we
-
mean by meta programming we couldn't
-
really come up with a better name for
-
this lecture because this lecture is
-
about the processes that surround the
-
work that you do when working with
-
software it is not about programming
-
itself necessarily but about the process
-
this can be things like how your system
-
is built how it's tested how you add
-
dependencies to your software that sort
-
of stuff that becomes really relevant
-
when you build larger pieces of software
-
but they're not really programming in
-
and of themselves
-
so the first thing we're going to talk
-
about in this lecture is the notion of
-
build systems so how many of you have
-
used a build system before or know what
-
it is okay so about 1/2 of you so for
-
the rest of you the the central idea
-
behind a build system is that you're
-
writing a paper you're writing software
-
you're like working on a class whatever
-
it might be and you have a bunch of
-
commands that you like either written
-
down in your shell history or you wrote
-
them down in a document somewhere that
-
you know you have to run if you want to
-
do a particular thing so for example
-
like there are a sequence of commands so
-
you need to run in order to build your
-
paper or build your thesis or just to
-
run the tests for whatever class you're
-
currently in and a build system sort of
-
idea is that you want to encode these
-
rules for what commands to run in order
-
to build particular targets into a tool
-
that can do it for you and in particular
-
you're going to teach this tool about
-
the dependencies between those different
-
artifacts that you might build there are
-
a lot of different types of tools of
-
this kind and many of them are built for
-
particular purposes particularly
-
languages some of them are built for
-
building like papers some of them are
-
built for building software some of them
-
are built for particularly programming
-
languages like Java or some some tools
-
even have built in tools for for builds
-
so NPM for example you might be aware if
-
you've done Nodejs development has a
-
bunch of built-in tools for doing
-
tracking of dependencies and building
-
them and building all of the dependent
-
stuff of your software but more
-
generally these are known as build
-
systems and at their core they all
-
function in a very similar way and that
-
is you have a number of targets these
-
are the things that you want to build
-
these are things like paper dot PDF but
-
they can also be more abstract things
-
like run the test suite or build the
-
binary for this program then you have a
-
bunch of dependencies and dependencies
-
are things that need to be built in
-
order for this thing to be built and
-
then you have rules that define how do
-
you go from a complete list of
-
dependencies to the given target so an
-
example of this might be in order to
-
build my paper dot PDF I need a bunch of
-
like plot images they're gonna go into
-
the paper so they need to be built but
-
then once they have been built how do i
-
construct the paper given those files so
-
that is what a rule is it's a sequence
-
of command so you run to get from one to
-
the other how you encode these rules
-
differs between different tools in this
-
particular class we're gonna focus on a
-
tool called make make is a tool that you
-
will find on almost any system that you
-
log in today like it'll be on Mac OS
-
it'll be on basically every Linux and
-
BSD system and you can pretty easily get
-
it on Windows um it's not great for very
-
complex software but it works really
-
well for anything that's sort of simple
-
to medium complexity now when you run
-
make to make user command you can run on
-
the command line and when you type make
-
and this is an empty directory if I type
-
make it just has no target specified and
-
no make file found stop and so it
-
helpfully tells you that it stopped
-
running but also tells you that no make
-
file was found make will look for a file
-
literally called make file in the
-
current directory and that is where you
-
encode these targets dependencies and
-
rules so let's try to write one let's
-
imagine that I'm writing this
-
hypothetical paper and so I'm gonna make
-
a make file and then this make file I'm
-
going to say that my paper dog PDF the
-
hands-on that's what the : here
-
indicates paper dot text was going to be
-
a little attack file and plot data dot
-
PNG and the command in order to build
-
this is going to be PDF latex of paper
-
dot Tex so for those of you who are not
-
familiar with this particular way of
-
building documents the tech is a really
-
handy programming language for documents
-
it's a really ugly language and it's a
-
pain to work with but it produces pretty
-
nice documents and the tool you use to
-
go from a tech file to PDF is PDF latex
-
and here I'm saying that I also depend
-
on this plot plot data PNG that's gonna
-
be included in my document and what I'm
-
really saying here is if either of those
-
two dependencies change I want you to
-
build paper PDF they both need to be
-
present and should they ever change I
-
wanted to rebuild it but I haven't
-
really told it how to generate this plot
-
data PNG so I might want to rule for
-
that as well
-
so I'm gonna define another target here
-
and it's gonna be it's gonna look like
-
this plot - % & % means and make is any
-
string sort of a wildcard pattern but
-
the cool thing is a you go and repeat
-
this pattern in the dependencies so I
-
can say that plot - % dot PNG is going
-
to depend on % dott data or debt that is
-
a common sort of suffix for data files
-
and it's also going to depend on some
-
script that's gonna actually plot this
-
for me and the rules for to go from one
-
to the other
-
these can be multiple lines but in my
-
particular case they're just one line
-
I'm gonna explain what this is in a
-
little second alright so here we're
-
gonna say that in order to go from a
-
wildcard dot dot file that matches the
-
wildcard in the target and a plot dot
-
python file run the python file with - i
-
which is going to be like the way we
-
take the mark what the input is in our
-
python file I'll show it to you later
-
dollarz star
-
is a special variable that is defined
-
for you and make file rules that matches
-
whatever the percentile was so if I do
-
plot to PNG then it's going to look for
-
food dot that and it dollars stars can
-
expand to foo so this will produce the
-
same file name as the one we matched
-
here and dollar act as a special
-
variable that means the name of the
-
target right so the output file and
-
hopefully what plotter py will do is
-
that it will take whatever the data is
-
here it will produce a PNG somehow and
-
it will write it into the file indicated
-
by the dollar at all right so now we
-
have a make file let's see what happens
-
if the only file in this directory is
-
the make file and we run make one says
-
no rule to make target paper dot tex
-
needed by paper dot PDF stop so what
-
it's saying here is first of all it
-
looked at the first rule of our file the
-
first target and when you give make no
-
arguments it tries to build whatever the
-
first target is this is known as the
-
default goal so in this case it tried to
-
helpfully build paper dot PDF for us and
-
then it looked up the dependencies and
-
it said well in order to build paper dot
-
PDF I need paper Tex and I need this PNG
-
file and I can't find paper dot X and I
-
don't have a rule for generating paper
-
dot X and therefore I'm gonna exit this
-
isn't nothing more I can do
-
so let's try to make some files here
-
let's just make like an empty paper dot
-
X and then type make so now it says no
-
rule to make target plot data dot PNG
-
needed by paper to PDF right so now it's
-
it knows that it has one dependency but
-
it doesn't know how to get the other one
-
it knows it as a target that matches but
-
it can't actually find its dependencies
-
and so it ends up doing nothing at all
-
it still still needs us to generate this
-
PNG for the input for the PNG so let's
-
actually put some useful stuff into
-
these files let's say that luckily I
-
have one from earlier plot da py to here
-
so let's so good well this text file is
-
this is what text looks like it's not
-
very pretty but
-
see I'm defining an empty document I'm
-
going to include graphics which is the
-
way you include a an image file I'm
-
going to include plot data dot PNG and
-
this is of course why we want a
-
dependency of peda paper dot PDF to be
-
the PNG file plot the py is also not
-
very interesting it just part imports a
-
bunch libraries it parses the - ion - Oh
-
arguments it loads data from the I
-
argument it uses library called
-
matplotlib which is very handy for just
-
quickly plotting data and it's gonna
-
plot the first column of the data as X's
-
and the second column of the data as Y's
-
so we're just going to have a data file
-
that's two columns x and y on every line
-
and then it saves that as a figure into
-
whatever the given - oh value is okay so
-
we need a data file that's going to be
-
data dot because we want plot data dot
-
PNG and our rules said that the way you
-
go from that pattern to the dot file the
-
dot that file is just by whatever
-
follows plot so if we want plot - data
-
then we want data dot that and then this
-
file we're just gonna put in some linear
-
coordinates because why not
-
that's not linear all right and now what
-
happens if we're gonna make well mmm
-
okay so what just happened well make
-
first ran plata py with the correct
-
files to generate the PNG file and then
-
it ran PDF latex paper dot text and all
-
the stuff we see below is is the output
-
from that tool if you wanted to we
-
silence the effort from this tools we
-
don't have to like have it mess with all
-
our output but in general you notice
-
that it ran the two commands then it
-
write the random perhaps unsurprisingly
-
in the right order and if we now do LS
-
in the current directory we see that we
-
have a bunch of files that were
-
generated by PDF latex but in particular
-
we have the PNG file which was generated
-
and we have the paper dot PDF and if we
-
open the paper - a PDF file we see that
-
it has one image which has the straight
-
line
-
perhaps in and of itself not a very
-
surprising or interesting result but
-
where this gets really handy is I can do
-
things like if I type make again make
-
just says paper dot PDF is up to date it
-
does no work whenever you run make it
-
tries to do the minimal amount of work
-
in order to produce whatever you ask it
-
to produce in this case none of the
-
dependencies have changed so there's no
-
reason to rebuild the paper or to
-
rebuild the plot if I now let's say I'm
-
gonna edit paper dog texts I'm gonna add
-
hello here an hour and make then if we
-
scroll up we'll see it didn't run plot
-
op py again because I didn't need to
-
none of the dependencies change but it
-
did run PDF latex again and indeed if we
-
open the paper analysis hello over there
-
on the other hand if I were to change
-
say the data file and make this point 8
-
an hour and make then now it plots again
-
because the data changed and it
-
regenerates the PDF because the plot
-
changed and indeed the paper turns out
-
the way we expected it to so that's not
-
to say that this particular pipeline is
-
very interesting because it's not it's
-
only true very very straightforward
-
targets and rules but this can come in
-
really handy when you start building
-
larger pieces of software or there might
-
be dependencies you might even imagine
-
that if you're writing a paper one of
-
your targets might be producing this
-
data file in the first place right so
-
one of the makefile
-
targets might be run my experiment right
-
run my benchmark and stick the the data
-
points that come out into this file and
-
then plot the results and then and then
-
and then and then all the way until you
-
end up with a final paper and what's
-
nice about this is first of all you
-
don't have to remember all the commands
-
to run you don't have to write them down
-
anywhere but also the tool takes care of
-
doing the minimal amount of work needed
-
often you'll find things like they'll be
-
too there'll be sub commands to make
-
like make tests right which is going to
-
compile your entire piece of software
-
and also run the tests there might be
-
things like make release
-
which builds it with optimizations
-
turned on and creates a tarball and
-
uploads that somewhere right so it's
-
gonna do the whole pipeline for you the
-
idea is to reduce the effort that you
-
have to do as any part of your build
-
process now what we saw here was a very
-
straightforward example of dependencies
-
right so we saw here that you could
-
declare files as dependencies but you
-
Kosar declare sort of transitive
-
dependencies right I depend on this
-
thing which is generated by this other
-
target very often when you work with
-
dependencies in the in the larger area
-
of software you'll find that your your
-
system ends up having many different
-
types of dependencies some of these are
-
files like we saw here some of them are
-
programs right like this sort of
-
implicitly depends on Python being
-
installed on my machine some of it might
-
be libraries right you might depend on
-
something like matplotlib which we
-
depend on here some of them might be
-
system libraries like open SSL or open
-
SSH or like low-level crypto libraries
-
and you don't necessarily declare all of
-
them very often there's sort of an an
-
assumption about what is installed on
-
the given system what you'll find is
-
that for most places where you have
-
dependencies there are tools for
-
managing those dependencies for you and
-
very often these systems you might
-
depend on are stored in what are known
-
as repositories so repository is just a
-
collection of things usually related
-
that you can install that's basically
-
all a repository is and you might be
-
familiar with some of them already
-
right so some examples of repositories
-
are pi PI which is a well-known
-
repository for Python packages rubygems
-
which is similar for ruby crates or io
-
for rust NPM for nodejs
-
but other things the repositories too
-
right like there are positives for
-
cryptographic keys like key base there
-
are repositories for system installed
-
packages like if you ever use the apt
-
tool in Ubuntu or in Debian you are
-
interacting with a package repository
-
where people who have written like
-
programs and libraries upload them so
-
that you can then install them
-
similarly you might have repositories
-
are entirely open right so the Ubuntu
-
repositories for example are usually
-
provided by the Ubuntu developers but in
-
Arch Linux there might there is
-
something called the arch user
-
repository where users can just share
-
their own libraries and their own
-
packages themselves. Very often,
-
repositories are either sort of managed
-
or they are just entirely open and you
-
should often be aware of this because if
-
you're using an entirely open repository
-
maybe the security guarantees you get
-
from that are less than what you get in
-
a controlled repository one thing you'll
-
notice if you start using repositories
-
is a very often software is versioned
-
and what I mean by version well you
-
might have seen this for stuff like
-
browsers right where there might be
-
something like starting like Chrome
-
version 64 dot zero dot two zero one 903
-
24 right this is a version number it
-
might there's a dot here this is one
-
kind of version number. But, sometimes, if
-
you start, I don't know, like Photoshop or
-
you start any other tool, there might be
-
other kind of versions that are, like,
-
8.1 dot seven right these version
-
numbers are usually numerical but not
-
always sometimes they have hashes in
-
them for example to refer to git commits
-
but you might wonder why do we have
-
these why is it even important that you
-
add a number to software that you
-
release the primary reason for this is
-
because it enables me to know whether my
-
software would break imagine that I have
-
a dependency on a library that Jose has
-
written right and Jose is constantly
-
doing changes to his library because he
-
wants to make it better and he decides
-
that one of the functions that his
-
library exposes has a bad name so he
-
renames it my software suddenly stops
-
working right because I my library calls
-
a function on Jose's library but that
-
function no longer exists depending on
-
which version people have installed of
-
Jose's library versions helps
-
because I can say I depend on this
-
version of Jose's library and there has
-
to be some rules around what is Jose
-
allowed to do within a given version if
-
he makes a change that I can no longer
-
rely on his version has to change in
-
some way
-
there are many thoughts on exactly how
-
this should work like what are the rules
-
for publishing new versions how do they
-
change the version numbers um some of
-
them are just dictated by time so for
-
example if you look at browsers they
-
very often have time versions that look
-
like this they have a version number on
-
the far left that's just like which
-
release and then they have sort of an
-
incremental number that is usually zero
-
and then they have a date at the end
-
right so this is March 24th 2019 for
-
some reason and usually that will
-
indicate that this is version 64 of
-
Firefox from this date and then if they
-
release sort of patches or hot fixes for
-
security bugs they might increment the
-
date but keep the version of the at the
-
left the same and people have strong
-
strong opinions on exactly what the
-
scheme should be and you sort of depend
-
on knowing what schemes other people use
-
right if I don't know what scheme Jose
-
is using for changing his versions
-
maybe I just have to say you have to run
-
like eight one seven of Jose's software
-
otherwise I cannot build my software but
-
this is a problem, too, right?
-
Imagine that, Jose, as a responsible
-
developer of his library, and he finds
-
the security bug and he fixes it but it
-
doesn't change the external interfaces
-
library no functions changed no types
-
change then I want people to be building
-
my software with his new version and it
-
just so happens that building mine works
-
just fine with his new version because
-
that particular version didn't change
-
anything I depended on so one attempted
-
solution to this is something called
-
semantic versioning. So, in semantic
-
versioning, we give each of the numbers
-
separated by dots in a version number, a
-
particular meaning. And, we give a
-
contract for when you have to increment
-
the different numbers
-
in particular in semantic versioning we
-
call this the major version we call this
-
the minor version and we call this the
-
patch version and the rules around this
-
are as follows if you make a change to
-
whatever your software is and and the
-
change you made is entirely backwards
-
compatible right like it does not add
-
anything it does not remove anything it
-
does not rename anything externally it
-
is as if nothing changed then you only
-
increment the patch number nothing else
-
so usually security fixes for example
-
will increment the patch number if you
-
add something to your library I'm just
-
gonna call them libraries because
-
usually libraries are the things where
-
this matters so for a library if you add
-
something to the library you increment
-
the minor version and you set the patch
-
to zero so in this case if we were to do
-
a minor release the next minor release
-
version number would be eight to zero
-
and the reason we do this is because I
-
might have a dependency on a feature the
-
josè added in a 2-0 which means you
-
can't build my software with eight one
-
seven that would not be okay
-
even though if you if I had written it
-
towards eight one seven you could run it
-
with a 2-0 the reverse is not true
-
because it might not have been added yet
-
and then finally the major version you
-
increment if you make a backwards
-
incompatible change where if my software
-
used to work with whatever version you
-
had and then you make a change that
-
means that my software might no longer
-
work such as removing a function or
-
renaming it then you increment the major
-
version and set minor and patch to zero
-
so the next major version here would be
-
nine zero zero taken together these
-
allow us to do really nice things when
-
setting what our dependencies are in
-
particular if I depend on a
-
particular version of someone's library
-
rather than saying it has to be exactly
-
this version what I'm really saying is
-
it has to be the same major version and
-
at least the same minor version and the
-
patch can be whatever this means that if
-
I have a dependency on Jose software
-
then any later release that is still
-
within the same major is fine that
-
includes keep in mind an earlier version
-
assuming that the minor is the same
-
imagine that you are saw on some older
-
computer that has like version eight one
-
three in theory my software should work
-
just fine with eight one three as well
-
it might have whatever bug the Jose
-
fixed in between like whatever security
-
issue but this has the nice property
-
that now you can share dependencies
-
between many different pieces of
-
software on your machine if you have
-
version eight-30 installed and there are
-
bunch of different software that like
-
one requires eight one seven one
-
requires eight two four one requires
-
eight zero one all of them can use the
-
same version of that dependencies you
-
only needed installed once one of the
-
most common or one of the most familiar
-
perhaps examples of this kind of
-
semantic versioning is if you look at
-
the Python versioning so many of you may
-
have come across this where python 3 and
-
python 2 are not compatible with one
-
another they're not backwards compatible
-
if you write code in Python 2 you try to
-
run in Python 3 it might not work there
-
are some cases where it will but that is
-
more accidental than anything else and
-
Python actually follows semantic
-
versioning at least mostly and so if you
-
write software that runs on Python 3.5
-
then it should also work in 3.6 3.7 and
-
3.8 it will not necessarily work in
-
Python 4 although that will hopefully be
-
a long time away but if you write code
-
for Python 3.5 it will it will possibly
-
not run on Python 3.4 so one thing you
-
will see many software projects do is
-
they try to bring the version
-
requirements they have as low as
-
possible if you can depend on major
-
and then minor in patch zero zero that
-
is the best possible dependency you can
-
have because it is completely liberal as
-
to which version of that major you're
-
depending on sometimes this is hard
-
right sometimes you genuinely need a
-
feature that was added but the lower you
-
can get the better it is for those who
-
want to depend on your software in turn
-
when working with these sort of
-
dependency management systems or in with
-
versioning in general you'll often come
-
across this notion of lock files you
-
might have seen this where like you try
-
to do something and it says like cannot
-
reconcile versions or you get an error
-
like lock file already exists these are
-
often somewhat different topics but in
-
general the notion of a lock file is to
-
make sure that you don't accidentally
-
update something the lock file at its
-
core is really just a list of your
-
dependencies and which version of them
-
you are currently using right so my
-
version string might be eight one seven
-
and the latest version like on the
-
internet somewhere might be a three zero
-
but whatever is installed on my system
-
is not necessarily one of those two it
-
might be like eight two four or
-
something like that and the lock file
-
will then say dependency josè version
-
eight to four and the reason you want to
-
lock file there can be many one of them
-
is that you might want your builds to be
-
fast if every single time you try to
-
build your project whatever tool you
-
were using download the latest version
-
and then compile it and then compile
-
your thing you might wait for a really
-
long time each time depending on the
-
release cycle of your dependencies if
-
you use a lock file then unless the
-
version
-
unless you've updated the version in
-
your lock file it'll just use whatever
-
it built previously for that dependency
-
and your sort of development cycle can
-
be a lot faster another reason to use
-
lock files is to get reproducible builds
-
imagine that I produce some kind of
-
security related software and I very
-
carefully audited my dependencies and I
-
produce like a signed binary of like
-
here is thus like a sworn statement for
-
me that this
-
version is secure if I didn't include a
-
lock file then by the time someone else
-
installs my program they might get a
-
later version of their pendency and
-
maybe that later version as I've been
-
hacked somehow or just has some other
-
security vulnerability that I haven't
-
had a chance to look at yet right and a
-
lock file basically allows me to freeze
-
the ecosystem as of this version that I
-
have checked the extreme version of this
-
is something called ven during when you
-
vendor your dependencies it really just
-
mean you copy/paste of them ven during
-
means take whatever dependency you care
-
about and copy it into your project
-
because that way you are entirely sure
-
that you will get that version of that
-
dependency it also means that you can
-
like make modifications to it on your
-
own but it has the downsides that now
-
you no longer get these benefits of
-
versioning right you no longer have the
-
advantage that if there are newer
-
releases of that software your users
-
might get them automatically like for
-
example when Hosea fixes his security
-
issues not that he has any of course one
-
thing you'll notice is that when talking
-
about this I've been talking about sort
-
of bigger processes around your systems
-
these are things like testing they're
-
things like checking your dependency
-
versions
-
they're also things are just setting up
-
build systems and often you don't just
-
want a local build system you want to
-
build process that includes other types
-
of systems or you want them to run even
-
when your computer is not necessarily on
-
and this is why as you start working a
-
larger and larger project you will see
-
people use this idea of continuous
-
integration and continuous integration
-
systems are essentially a cloud build
-
system the idea is that you have your
-
project stored on the internet somewhere
-
and you have set it up with some kind of
-
service that is running an ongoing thing
-
you for your project whatever it might
-
be and continuous integration can be all
-
sorts of stuff it can be stuff like
-
releasing your library to pi PI
-
automatically whenever you push to a
-
particular branch it could be things
-
like
-
run your test suite whenever someone
-
submits a pull request or it could be
-
check your code style every time you
-
commit there all sorts of things you
-
could do with continuous integration and
-
the easiest way to think about them is
-
that they're sort of event triggered
-
actions so whenever a particular event
-
happens for your a possibly for your
-
project a particular action takes place
-
where the action is usually some kind of
-
script some sequence of programs they're
-
gonna be invoked and they're gonna do
-
something this is really an umbrella
-
term that encapsulate a lot of different
-
types of services so some continuous
-
integration services are very general
-
things like Travis CI or Azure pipelines
-
or github actions are all very broad CI
-
platforms they're built to let you write
-
what you want to happen whenever any
-
event that you define happens very broad
-
systems there are some more specialized
-
systems that deal with things like
-
continuous integration coverage testing
-
so like annotate your code and show you
-
have no tests that test this piece of
-
code and they're built only for that
-
purpose or they're built only for
-
testing browser-based libraries or
-
something like that and so often you can
-
find CI tools that are built for the
-
particular project you're working on or
-
you can use one of these broader
-
providers and one thing that's nice is
-
that many of them are actually free
-
especially for open source software or
-
if you're a student you can often get
-
them for free as well in general the way
-
you use the CI system is that you add a
-
file to your repository and this file is
-
often known as a recipe and what the
-
recipe specifies is this sort of
-
dependency cycle again sort of what we
-
saw with make files it's not quite the
-
same the events instead of being files
-
might be something like when someone
-
pushes a commit or when a commit
-
contains a particular message or when
-
someone submits a pull request or
-
continuously write one example of a
-
continuous integration service that's
-
not tied to any particular change to
-
your code is something called the
-
dependable
-
you can find this on github and the
-
dependent bots is something that you
-
hook up to your your repository and it
-
will just scan whether there are newer
-
versions available of your dependencies
-
that you're not using so for example if
-
I was depending on eight one seven and I
-
had a lock file that locked it to eight
-
two four and then eight three zero is
-
released the dependable will go you
-
should update your log file and then
-
submit the pull request to your
-
repository with that update this is a
-
continuous integration service it's not
-
tied to me changing anything but to the
-
ecosystem at large changing often these
-
CI systems integrate the back into your
-
project as well so very often these CI
-
services will provide things like little
-
badges so let me give an example so for
-
example here's a project I've worked on
-
recently that has continuous integration
-
set up so this project you'll notice
-
it's readme if I can zoom in here with
-
that chrome bean nope nope that's much
-
larger than I wanted here you'll see
-
that at the top of the the repositories
-
page they're a bunch of these badges and
-
they display very various types of
-
information you'll notice that I have
-
dependable running right so the
-
dependencies are currently up to date it
-
tells me about whether the test suite is
-
currently passing on the master branch
-
it tells me how much of the code is
-
coverage by tests and it tells me what
-
is the latest version of this library
-
and what is the latest version of the
-
documentation of the library that's
-
available online and all of these are
-
managed by various continues continuous
-
integration services another example
-
that some of you might find useful or
-
might even be familiar with is the
-
notion of github pages so github pages
-
is a really nice service the github
-
provides which lets you set up a CI
-
action that builds your repository as a
-
blog essentially it's it runs a static
-
site generator called Jekyll
-
and Jeckle just takes a bunch of
-
markdown files and then produces a
-
complete website and that as a part of
-
get up pages they will also upload that
-
to get up servers and make it available
-
at a particular domain and this is
-
actually how the class website works
-
class website is not a bunch of like
-
HTML pages that we manage instead
-
there's a repository missing semester so
-
if you look at the missing semester
-
repository you will see if i zoom out a
-
little here that this just has a bunch
-
of markdown files right it has saket
-
20/20 metaprogramming md so this is the
-
if I go to raw here this is the raw
-
markdown for today's lecture so this is
-
the way that I write the lecture notes
-
and then I commit that to the repository
-
we have and I push it and whenever a
-
push happens the github pages CI is
-
gonna run the build script for github
-
pages and produces the website for our
-
class without me having to do any
-
additional steps to make that happen and
-
so yeah sorry good yeah so so Jekyll
-
it's using a tool called Jekyll which is
-
a tool that takes a directory structure
-
that contains markdown files and
-
produces a website it produces like HTML
-
files and then as a part of the action
-
it takes those files and uploads them to
-
github servers add a particular domain
-
and usually that's the domain under like
-
github I oh that they control and then I
-
have set missing semester to point to
-
the github domain I want to give you one
-
aside on testing because it's something
-
that many of you may be familiar with
-
from before right you have a rough idea
-
of what testing is you
-
run the test before you've seen a test
-
fail you know like the basics of it or
-
maybe you've never seen a test fail in
-
case congratulations but as you as you
-
get to more advanced projects though
-
you'll find that people have a lot of
-
terminology around testing and testing
-
is a pretty like deep subject that you
-
could spend many many hours trying to
-
understand the ins and outs of and I'm
-
not going to go through it in
-
excruciating detail but there are a
-
couple of words that I think it's useful
-
to know what mean and the first of these
-
is a test suite so a test suite is a
-
very straightforward name for all of the
-
tests in a program it's really just a
-
suite of tests it's a large collection
-
of tests that usually are run as a unit
-
and there are different types of tests
-
that often make up a test suite the
-
first of these is what's known as a unit
-
test a unit test is a often usually
-
fairly small test of self-contained
-
tests the tests a single feature what
-
exactly a feature might mean is a little
-
bit up to the project but the idea is
-
that should be sort of a micro test that
-
only tests a very particular thing then
-
you have the larger tests that are known
-
as integration tests integration tests
-
try to test the interaction between
-
different subsystems of a program so
-
this might be something like an example
-
of a unit test might be if you're
-
writing an HTML parser to the unit test
-
might be test that it can parse an HTML
-
tag an integration test might be here's
-
an HTML document parse it right so that
-
is going to be the interview the
-
integration of multiple of the
-
subsystems of the parser you also have a
-
notion of regression tests regression
-
tests are tests that test things that
-
were broken in the past so imagine that
-
someone submits some kind of issue to
-
you and says your library breaks if I
-
give it a marquee tag and that makes you
-
sad so you want to fix it so you fix
-
your parser to now support marquee tags
-
but then you want to add a test to your
-
test suite
-
the checks that you can parse marquee
-
tags the reason for this is so that in
-
the future you don't accidentally
-
reintroduce that bug. So that is what
-
a regression tests are for and over time
-
your project is gonna build up more and
-
more of these, and they're nice because
-
they prevent your project from
-
regressing to earlier bugs. The last one
-
I want to mention is a concept called
-
mocking. So mocking is the idea of being
-
able to replace parts of your system
-
with a sort of dummy version of itself
-
that behaves in a way that you control. A
-
common example of this is you're writing
-
something that does, oh I don't know, file
-
copying over SSH. Right? This is a tool
-
that you've written that does file
-
copying over SSH there are many things
-
you might want to mock here. For example,
-
when running your test suite you
-
probably don't actually care that
-
there's a network there. Right? You don't
-
need to have to like set up TCP ports
-
and stuff, so instead you're gonna mock
-
the network. The way this usually works
-
is that, somewhere in your library, you
-
have something that like opens a
-
connection, or reads from the connection,
-
or writes to the connection, and you're
-
gonna overwrite those functions
-
internally in your library with
-
functions that you've written just for
-
the purposes of testing, where the read
-
function just like returns the data, and
-
the write function just drops the data
-
on the floor, or something like that.
-
Similarly, you can write a mocking
-
function for the SSH functionality. You
-
could write something that does not
-
actually do encryption, it doesn't talk
-
to the network: it just like takes bytes
-
in here and just magically they pop out
-
the other side, and you can ignore
-
everything that's between, because for
-
the purpose of copying a file, if you
-
just wanted to test that functionality,
-
the stuff below doesn't matter for that
-
test, and you might mock it away. Usually,
-
in any given language, there are tools
-
that let you build these kind of mocking
-
abstractions pretty easily. That is the
-
end of what I wanted to talk about
-
metaprogramming, but this is a very, very
-
broad subject. Things like continuous
-
integration, build systems, there are so
-
many out there
-
that can let you do so many interesting
-
things with your projects, so I highly
-
recommend that you start looking into it
-
a little. The exercises are sort of all
-
over the place, and I mean that in a good
-
way. They're intended to try to just show
-
you the kind of possibilities that exist
-
for build working with these kind of
-
processes so for example the last
-
exercise has you write one of these
-
continuous integration actions yourself
-
where it you decide what the event be
-
and you decide what the action be but
-
try to actually build one and this can
-
be something that you might find useful
-
in your project the example I given the
-
exercises is try to build an action that
-
runs like right good or pro Slynt one of
-
the linters result for the english
-
language on your repository and if you
-
do like we could enable that for the
-
class repository so that our lecture
-
notes are actually well written right
-
and this is one other thing that's nice
-
about this kind of continuous
-
integration testing is that you can
-
collaborate between projects if you
-
write one I can use it in my project and
-
there's a really handy feature where you
-
can build this ecosystem of improving
-
everything any questions about any of
-
the stuff we record today yeah so the
-
question is why do we have both make and
-
see make what do they do and is there a
-
reason for them to talk together so so
-
see make I don't actually know what the
-
tagline for C make is anymore but it's
-
sort of like a better make for C as the
-
name implies C make generally
-
understands the layout of C projects a
-
little bit better than make Falls do
-
they're sort of built to try to parse
-
out what the structure of your
-
dependencies are what the rules from
-
going to one to the other is it also
-
integrates a little bit nicer with
-
things like system libraries so C may
-
can do things like detect
-
given libraries available on your
-
computer or if it's available at
-
multiple different paths it tries to
-
find which of those paths it's present
-
on on this system and then link it
-
appropriately so see make is a little
-
bit smarter than make is make will only
-
do whatever you put in the make file not
-
entirely true there are things called
-
implicit rules that are like built-in
-
rules in make but they're pretty dumb
-
whereas emic tries to be able to be a
-
larger build system that is opinionated
-
by default to work for C projects
-
similarly there's a tool called maven so
-
maven and ant which is another project
-
they are both built for Java projects
-
they understand how Java code interacts
-
with one another how you structure Java
-
programs and they're built for that task
-
very often at least when I use make I
-
use make sort of at the top and then
-
make my call other tools that build
-
whatever subsystem they know how to
-
build right like my make file might call
-
cargo to build a rust program and then
-
call see make to build some like see
-
dependency of that but then at the top
-
like I'm gonna do some stuff at the end
-
after the programs have built and that
-
might just be like run a benchmark which
-
is in the rust code and then like plot
-
it using the C code or something like
-
that right so for me make you sort of
-
the glue at the top that I might write
-
usually if your make file gets very
-
large there's a better tool would you'll
-
find it like big companies for example
-
is they often have one build system that
-
manages all of their software so if you
-
look at Google for example they have
-
this open source system called basil and
-
I don't think Google literally uses
-
basil inside of Google but it's sort of
-
based on what they use internally and it
-
really just its intended to manage the
-
entire build of everything Google has
-
and basil in particular is built to be I
-
think they call it like a polyglot build
-
framework so the idea is that it works
-
for many different languages there's
-
like an implement there's a module for
-
basil for this language and that
-
language in that language but they all
-
integrate with the same basil framework
-
which then knows how to integrate
-
dependencies between different libraries
-
and different languages get a question
-
sure
-
so when you say expressions you mean the
-
things in this file or yeah so these are
-
so make files are their own language
-
they are it's a pretty weird language
-
like it has a lot of weird exceptions in
-
many ways it's weird just like bash is
-
weird but in different ways which is
-
even worse like when you're writing a
-
make file you sort of you can sort of
-
think like you're writing bash but
-
you're not because it's broken in
-
different ways but but it is its own
-
language and the way that make files are
-
generally structured is that you have a
-
sequence of I think they call them
-
directives so every like the this thing
-
oops this thing is a directive and this
-
is a directive and every directive has a
-
colon somewhere and everything to the
-
left of the colon is a target and
-
everything to the right of the colon is
-
right of the colon is a dependency and
-
then all of the lines below that line
-
are the sequence of operations known as
-
the rules for once you have the
-
dependencies how do you build these
-
targets notice that make is very
-
particular that you must use a tab to
-
indent the rules if you do not make will
-
not work if they must be tabs they
-
cannot be four eight spaces must be tabs
-
and like you can have multiple
-
operations here I like I can do echo
-
hello or whatever and then they would
-
first run this and then run this there's
-
a there's an exercise for today's
-
lecture that has you try to extend this
-
make file with a couple of other targets
-
that you might find interesting that
-
goes into a little bit more detail
-
there's also some ability to execute
-
external commands to like determine what
-
the dependencies might be if your
-
dependencies are not like a static list
-
of files but it's a little limited
-
usually once you've started needing that
-
sort of stuff you might want to move to
-
a more advanced build system yeah so the
-
question is what happens if I have let's
-
say that I have library a and library B
-
and they both depend on library see but
-
library a depends on like 4.0.1 and
-
library B depends on 3 dot 4 dot 7 so
-
they both depend on C and so ideally
-
we'd like to reuse see but they depend
-
on different major versions of C what do
-
we do well what happens in this case
-
depends entirely on the system that
-
you're using the language that you're
-
using in some cases the tool would just
-
be like well I'll just pick for which
-
sort of implies that they're not really
-
using semantic versioning in some cases
-
the tool will say this is not possible
-
like if you do this it's an error and
-
the tool will tell you you either need
-
to upgrade be like have B use a newer
-
version of C or you need to downgrade a
-
you do not get to do this and
-
compilation will fail some tools are
-
gonna build two versions of C and then
-
like when it builds a it will use the
-
major four version of C and when it
-
builds B will use the major three
-
version of C one thing you end up with
-
is really weird conditions here were
-
like if C has dependencies then now you
-
have to build all of C's dependencies
-
twice to 1 for 3 and 1 for 4 and maybe
-
they share and maybe they don't you can
-
end up in particularly weird situations
-
if imagine that the library see like
-
imagine that
-
library see like rights to a file like
-
rights to some like file on disk some
-
cache stuff if you run your application
-
now and like a does something to call
-
like C dot save and B to something like
-
C adult load then suddenly your your
-
application of the bottom is not going
-
to work because the format is different
-
right
-
so these situations are often very
-
problematic and and most tools that
-
support semantic versioning will reject
-
this kind of configuration for exactly
-
that reason but it's so easy to shoot
-
yourself in the foot all right we will
-
see you again tomorrow for security keep
-
in mind again if you haven't done the
-
survey the question I care the most
-
about in the survey is what you would
-
like us to cover in the last two
-
lectures so the last two lectures are
-
for you to choose what you want us to
-
talk about and to give any questions you
-
want us to answer so please like add
-
that if you can and that's it see you
-
tomorrow