2. Project management¶
This week I mainly worked on setting up a reliable system for the documentation process of the upcoming weeks. This mostly incorporated web design and working with a version control system.
Since this week was taking place at the same time as week 01, generally topics were kind of overlapping. I documented my final project idea in the week 01 assignment and will use this assignment here to just talk about the version control and website setup (/journey…).
Version control basics¶
Any project, whether large or small, usually spans multiple workdays, multiple iterations or is worked on by multiple people. Version control systems (VCS) are an extremely useful tool for saving and tracking progress of most kinds of such continuous work - we will talk about a few exceptions later.
If you have used Microsoft (MS) Word seriously at some point of your life, you will have at some point come into contact with a condensed form of version control: The “Track Changes” functionality. When using “Track Changes”, MS Word does not only store the actual text you enter, but also the whole history of changes (to an extent). It also saves who made these changes and it allows for resolving conflicts when two people disagree on a certain part of text. A few software cycles back, MS Word actually also allowed for saving different versions of a file under the same name, so the history of a document’s development could be recreated. Nowadays, this feature is somewhat hidden, restricted and/or limited to cloud-stored documents, which is a shame.
While maybe being particularly illustrative in its restricted little text processor environment, this example is of course useless when I want to work on something outside of MS Word. What if I want to track changes in a generic text file? Script files? Setup files? Any programming language’s source code? Enter: Proper Version Control Systems. Over the decades, many of these VCSs were developed, each with their own quirks and design paradigms.
Decentralized vs. Centralized VCSs¶
For some VCSs, centralization is paramount: Users are (by design) not supposed to have their own copy of files, but rather all work on a common set of files. This usually means that any given file can only be worked on by a single user at once, to prevent collisions when users make conflicting changes to the same file. The files might be stored on a central server, meaning that files can only be edited - and changes submitted - when connected to said server.
Other VCSs focus on decentralization and allow multiple users to work on the same files at once by giving access to local file copies. Conflicts (created by conflicting changes made by different users) in these systems are usually not prevented proactively, but dealt with when (or if at all) they come up. To that end, decentralized VCSs often provide tools catered to solving such conflicts.
Git - a VCS poster child¶
In the FabAcademy, we use Git, a decentralized VCS that is extremely popular with programming projects. In the Git model, a collection of tracked files is called a repository (short: “repo”). Repositories can be as simple as a folder in a file explorer containing files - this would be a local repo. At the other end of the spectrum, repos can also be placed somewhere on a network (shared network drive/cloud/website…), making them “remote” repos (short: “remote”). A user can then obtain a local copy of the repo by what’s called “cloning”. Any changes the user makes are generally made to the local repo copy and only afterwards uploaded back (“pushing”) to the remote repository. Because each user works on their own copy of the repo’s files, no immediate conflicts appear. It is only when multiple users change the same piece of text/code and upload it to the remote repo that a problem appears - called a “merge conflict” (a conflict that appears when trying to merge to different versions of the same file). Dealing with and resolving such merge conflicts is one of the key concepts of Git. Another key concept in Git is that of branching: at any point in time, a branch off of the main “tree” of code can be created to safely work on a certain code feature without messing with the already functioning code. When a feature has been implemented and tested in a separate branch, the changes made in this branch (thus the changes containing the necessary code to make that feature work) can be fed back to the main code tree - this is called “merging”.
My Git backstory¶
Thinking of Git spawns mixed feelings for me. I’ve been using Git for a few years for personal projects, mainly offline programming projects without any collaborators. In this context, I’ve been coding, branching, merging and tagging to my heart’s content without Git ever failing me once.
I’ve also used Git briefly in a professional context for collaborating on a larger codebase with a handful of people. Code was stored on a remote repo and branched extensively, as many different features were explored in a research context. In this environment, stuff tended to break on a regular basis. I won’t attribute that to git though - I think it was too many cooks (which, in this example, also only had a brief introduction to cooking…) that spoiled the broth.
Don’t get me wrong - I love Git, but in that context, it was also a love-hate relationship at times. Git was the good friend we love so much we forgive its little tantrums every now and then. Git is just a very powerful tool set - when wielded by the right hands, it can do wonderful things. By design the user has a lot of freedom, which also means the user can break things bad time when not knowing his ways around Git.
It should be said that I’ve always used Git with a GUI (TortoiseGit for personal use, Visual Studio Professional Integration for work use) so far, even though I’m relatively comfortable with the command line. This is how I went into the tutorials and setup of Git, excited to learn about the command line use of it.
Setting up and testing Git¶
- To start out with Git, the first thing to do is to install Git itself. Since I was already running Git via TortoiseGit on this very machine before, I did not actually do this, but I would have downloaded and executed the installer from Git for Windows to install Git and GitBash (a Bash emulator for Windows command line) along with it.
- Afterwards, the user name and email address were set up globally for Git commits:
$ git config --global user.name "Roland Grichnik"
$ git config --global user.email "roland.grichnik@hochschule-rhein-waal.de"
- An RSA SSH key pair (public/private key) was generated and stored in my user directory (
/c/Users/rgr/.ssh/id_rsa
) by running:
$ ssh-keygen -t rsa -C "roland.grichnik@hochschule-rhein-waal.de"
- The public part of the key pair was then copied to the clipboard by running:
$ cat ~/.ssh/id_rsa.pub | clip
- This public key was added to the list of SSH keys in GitLab to allow authorized communication between my machine and the remote repo.
- I created a folder for containing the GitLab repo locally (
/c/Users/rgr/Documents/FabAcademy/website
) and changed over to it, then cloned the remote repo by running:
$ git clone git@gitlab.fabcloud.org:academany/fabacademy/2022/labs/kamplintfort/students/roland-grichnik.git
- After successfully cloning the online repo, I made some changes to the Markdown file
index.md
, staged the changes and committed the changes to the local repo, after checking whether the commit had been set up correctly usinggit status
:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: docs/index.md
$ git commit -m "Test changes made to main page"
[master d867de9] Test changes made to main page
1 file changed, 9 insertions(+), 2 deletions(-)
- I subsequently tried to push the changes from the local repo to the remote on GitLab to verify everything worked:
$ git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 16 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 578 bytes | 578.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
To gitlab.fabcloud.org:academany/fabacademy/2022/labs/kamplintfort/students/roland-grichnik.git
8db2e0f..d867de9 master -> master
- And it did! With everything set up properly now, work on the website could begin!
Website Design¶
Let me precede this section by “I don’t know nothing about web design.” Well, nearly nothing at least. For fun, I put a Joomla! website on my NAS once, just because a plugin for doing so existed. It wasn’t pretty and it didn’t really do anything. And it was not online either. Besides knowing what the acronyms mean, I don’t really know anything about HTML, CSS, JavaScript and all the other web design lingo - but I am eager to learn! I will go through the events here more or less chronologically and try to compile my epiphanies and all the small tidbits of what I learned.
Choices, choices, choices!¶
First things first: Yowzers! So many choices. For everything. Wikis, websites, blogs, content management systems (CMS) - wherever you look, whatever you want to build, there is a system for it. At first, I was a little overwhelmed by what the buffet had on offer. I then narrowed down my options so I’d actually be able to explore a few, too. With the safety net of the - already set-up - Markdown template page (which also seemed reasonable easy to work with), I decided to check out HTML5, as I wanted to at least have looked into HTML at some point. I felt like trying to make a website and not having a look at HTML would be like going to Japan and not eating Sushi once.
HTML5 templates¶
Since I knew I’d only have a week to whip up something usable, I decided to start out with a template as well. On HTML5UP I downloaded a template called “Alpha” and unzipped it to my machine. I then started exploring the file structure in Visual Studio (VS) Code and started changing a few bits of content here and there in the HTML files - change a link title, put a different picture in, create some Assignment specific pages. That kind of stuff. Being comfortable in LaTeX, where text is formatted in a very similar way using tags, really helped keeping track of the code visually. In VS Code I used the extension “HTML Preview” (v0.2.5, by Thomas Haakon Townsend) to immediately display the HTML file with its changes next to the code, which was a really comfortable setup, but: links did not work in HTML Preview. To remedy this, I installed another extension called “Live Server” (v5.7.4, by Ritwick Dey), which runs a lightweight local server. Having the Live Server display the webpage, the HTML links now also worked and took me to the respective sub pages.
Tinkering with changing content, I quickly noticed that a few elements of the page I could not really locate in the HTML file, e.g. the background picture of the page’s top banner. After thinking a bit about what we had learned about CSS in our local session, I realized that the banner was actually an element defined in the linked CSS stylesheet, not the HTML itself. FInding the stylesheet and changing the image link in the banner element therein changed the banner background picture as well - this separation between HTML and CSS, even though they are used to generate the same document, was my first epiphany.
When playing around with sub pages in a subfolder of the website, I then also quickly realized that the CSS stylesheet would need to be linked properly to from HTML files in sub folders (e.g. by adding a “../” to the href path). If this was forgotten, the HTML site would simply load as a blank, unformatted site with minimal styling.
Setting up the Assignment sub pages I quickly got annoyed by the fact that the website’s sidebar was hardcoded into each and every assignment’s sub page. If I added an assignment page, I needed to go into each and every other assignment’s sub page and add the link in the sidebar there. This could not be right. From all my experience in programming, where redundancy is usually enemy #1, I gathered this could not be right. Of course there would have to be a way to import e.g. a common sidebar.html file into my assignment pages and not have to do everything over and over again. Looking for solutions, I encountered the HTML import
function for importing HTML files into other HTML files. But: it didn’t work. I then found out about a nice tool called CanIUse.com that allowed to check whether certain features were supported by certain browsers. Even though we’ve all been there, we all had to use Internet Explorer to use that one website on the intranet, we all had to switch browsers when videos wouldn’t load, it only occurred to me now. Not all browsers are equal. That was my second epiphany.
It seemed like the HTML import
function was not widely supported, so I decided to look into another solution, which was iFrames. iFrames allow displaying an HTML page on another HTML page, like looking through a window on the page. From what I could gather, this seemed to be a little antiquated and not as flexible as I needed it to be, but I might very well just not have looked deep enough. Simply googling on, I found another alternative called jQuery, which could supposedly load the HTML from an external file (Link), but I just couldn’t make it work in my little test setup. I felt like HTML was beginning to get at me. I didn’t feel like reading on, like going to another stackExchange to find another solution for another problem that might suddenly pop up. I decided to have a deeper look at Markdown.
Markdown, MkDocs and Material¶
The provided GitLab repo on Fab Cloud already had a reasonably well looking web page template set up, which - important(!) - was responsive as well (this, as an avid user of browsing on the phone, is one of the few bits of web development lingo I actually knew already…). Non-responsive websites or dedicated mobile sites do give me the creeps these days, so that had been one requirement from the get-go.
Branching the repo¶
To not mess with the provided template, I first branched the repo and pushed the new branch develop
to the remote by running:
$ git checkout -b develop
$ git pull
$ git push origin develop
Subsequently, I changed the CI job on GitLab for the develop
branch by editing its respective .gitlab-ci.yml
, replacing all instances of if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
by if: $CI_COMMIT_BRANCH == "develop"
. This ensured that the CI job would also run when a commit was made on the develop
branch and subsequently published to the website server. The website would always display whatever branch was published the latest now.
Setting up MkDocs¶
With my develop
branch all set up to try out stuff, I looked into the options of the mkdocs.yml
first. I added some of the personal information in there that was still using placeholders and was amazed by the plethora of other options that existed to customize the page. When manipulating the site though, I quickly realized that pushing changes to the remote repo, waiting for the runners on GitLab to do their job and finally waiting for the website to actually update was way too time-consuming.
For working with Markdown locally, I followed the recommendations on the website template and installed MkDocs locally by the running through all the instructions given on the MkDocs installation guide. After also installing the MkDocs Material theme (Material Installation guide) and the mkdocs-git-revision-date-localized-plugin (Plugin Installation guide), an MkDocs server could now be started locally. To do so, following command was executed in the root of the project (where mkdocs.yml
resides):
mkdocs serve
The generated webpage was now reachable by navigating any browser to localhost:8000
. Upon any change to the project files (.md or .yml), the server reacts immediately and shows the changed webpage. Awesome - that was something I could work with.
Customizing MkDocs¶
The Material theme for MkDocs has extensive documentation on its own, describing tons of options to make the page look more to one’s liking. Here’s what I implemented reading through all the setup pages in detail:
- Changed primary and accent color of the color palette
- Added dark mode and a toggle switch to toggle between dark and light mode palettes
- Changed fonts (all fonts from Google Fonts are immediately usable)
- Changed website navigation behavior (header disappears when scrolling down, “back to top” button appears)
- Changed future assignment topics in the sidebar to be greyed out by combining Markdown with html tags (e.g.
# <em style="color:LightSlateGray;opacity:0.3;">Heading text</em>
for a level 1 heading in italics that was also light slate gray with an opacity of 30%) - Adding a link to the GitLab repo in the header
- Adding a Markdown extension for displaying tooltips for abbreviations with a common glossary (see how)
None of that was particularly hard to do. The documentation for MkDocs and the Material theme was very extensive and helpful, even for a beginner like me.
Since I had now pretty much committed to using MkDocs, I stuck with it and wrote my personal AboutMe page in Markdown as well. After doing so, I also uploaded and pushed the FabAcademy student agreement to my repo.
Addendum (what I learnt in later weeks)¶
- Week 03: This week taught me how to do tables in Markdown - a simple tool I hadn’t yet seen a need for.
- Line breaks in tables came in handy to keep columns narrow and be in control of the layout. To do a line break, the HTML tag
<br />
can be used.
- Line breaks in tables came in handy to keep columns narrow and be in control of the layout. To do a line break, the HTML tag
- Week 03: Just writing above bullet point and seeing that the abbreviation “HTML” got a mouseover tooltip without me using the HTML tag
<abbr>ABBREVIATION</abbr>
taught me that the plugin used for abbreviations recognizes them automatically… time to delete a few tags, it is. This will make for easier readable and more manageable Markdown code. :) - Week 03: Tables can actually be used to make sequences of images with captions that autoscale to the page width, which can be handy. Care should be taken for the pictures to have roughly identical dimensions though, so they will be autoscaled to similar proportions. Following snippet will create such table:
| ![](../images/sample-photo.jpg) | ![](../images/sample-photo.jpg) | ![](../images/sample-photo.jpg) |
| :--- | :---: | ---: |
| *I started out loading a sample image...* | *...then another one...* | *...and even a third!* |
I started out loading a sample image… | …then another one… | …and even a third! |
- Week 03: Images (also in tables) can be easily made clickable - to open them in a new tab or just open them in full format - by linking to themselves, as in following snippet:
[![](../images/sample-photo.jpg)](../images/sample-photo.jpg)
I’m clickable! | Me too! | Hey, don’t forget me! |
- Week 04: How to efficiently use ImageMagick to change image sizes and compression on a whole folder of files:
CLI I
andCLI II