Example of a systemd service file

Here is an almost-minimal example of a systemd service file, that I use to run the Mastodon bot of my generative art playground Graft.

I made a dedicated user just to run this service, and installed Graft into /home/graft/apps/graft under that username. Now, as root, I edited a file called /etc/systemd/system/graft.service and made it look like this:

[Service]
ExecStart=/home/graft/apps/graft/bot-mastodon
User=graft
Group=graft
WorkingDirectory=/home/graft/apps/graft/
[Install]
WantedBy=multi-user.target

Now I can start the graft service like any other service like this:

sudo systemctl start graft

and find out its status with:

sudo systemctl status graft

If I want it to run on startup I can do:

sudo systemctl enable graft

and it will. Easy!

If I want to look at its output, it’s:

sudo journalctl -u graft

As a reward for reading this far, here’s a little animation you can make with Graft:

If you want the service to be restarted whenever it fails, under [Service] add something like this:

Restart=always
RestartSec=3

More info at: Jon Archer’s blog post.

Installing Flarum on Ubuntu 18.04

I am setting up a forum for sharing levels for my game Rabbit Escape, and I have decided to try and use Flarum, because it looks really usable and responsive, has features we need like liking posts and following authors, and I think it will be reasonably OK to write the custom features we want.

So, I want a dev environment on my local Ubuntu 18.04 machine, and the first step to that is a standard install.

Warning: at the time of writing the Flarum docs say it does not work with PHP 7.2, which is what is included with Ubuntu 18.04, so this may not work. (So far it looks OK for me.)

Here’s how I got it working:

sudo apt install \
    apache2 \
    libapache2-mod-php \
    mariadb-server \
    php-mysql \
    php-json \
    php-gd \
    php-tokenizer \
    php-mbstring \
    php-curl

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

# Get the next line from https://getcomposer.org/download/
# Don't copy it exactly!
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

mkdir $HOME/bin
php composer-setup.php --install-dir=$HOME/bin/ --filename=composer
rm composer-setup.php

cd /var/www/html
sudo mkdir flarum
sudo chown $(whoami) flarum

# Log out and in again here to get composer to be in your PATH
cd flarum
composer create-project flarum/flarum . --stability=beta

sudo chgrp -R www-data .
sudo chmod -R 775 .

sudo a2enmod rewrite 

Next I granted the permissions for Flarum’s .htaccess file to change settings by modifying /etc/apache2/apache2.conf and adding this after the existing <Directory entries:

<Directory "/var/www/html/flarum/">
    AllowOverride All
</Directory>

and restarted Apache:

sudo systemctl restart apache2

Now I created a database in MariaDB:

$ sudo mariadb
MariaDB [(none)]> CREATE USER flarumuser IDENTIFIED BY 'flarumpassword';
MariaDB [(none)]> CREATE DATABASE flarumdb;
MariaDB [(none)]> GRANT ALL ON flarumdb.* TO flarumuser;

and went to http://localhost/flarum in my browser, and entered these details:

MySQL host: localhost
MySQL database: flarumdb
MySQL user: flarumuser
MySQL password: flarumpassword
table prefix: flarum_

Admin user: admin
Admin email: <my email address>
Admin password: adminpassword

Once I typed all those correctly and submitted, I had to wait a while, and then after it printed some details I refreshed the page and saw a local Flarum ready to customise.

Next, I looked into how to get an extension development environment up and running.

If you want to find and share levels for Rabbit Escape, check up on our progress setting up the forum at https://artificialworlds.net/rabbit-escape/levels.

How to write a programming language articles

Recent Overload journal issues contain my new articles on How to Write a Programming Language.

Part 1: How to Write a Programming Language: Part 1, The Lexer

Part 2: How to Write a Programming Language: Part 2, The Parser

PDF of the latest issue: Overload 146 containing part 2.

This is all creative-commons licensed and developed in public at github.com/andybalaam/articles-how-to-write-a-programming-language

Clever Things People Do In Groovy So You Have To Know About Them video

Groovy has lots of interesting syntax that can be used for domain-specific languages, such as Gradle build files, and Jenkinsfiles. I try to demystify the syntax tricks a bit so you have a chance to read and understand what the code is actually doing:

Slides and source code are available.

Related: Gradle: what is a task, and how can I make a task depend on another task?

Ideas on how lexing will work in Pepper3

I am trying to practice documentation-driven development in Pepper3, so every time I start on an area, I will write documentation explaining how it works, and include examples that are automatically verified during the build.

I’ve started work on lexing, since you can’t do much before you do that, but in fact, of course, I need to have a command line interface before I can verify any of the examples, so I’m working on that too.

Lexing is the process that takes a stream of characters (e.g. from a file) and turns it into a stream of “tokens” that are chunks of code like a variable name, a number or a string. (There is more on lexing in my mini programming language, Cell.)

My thoughts so far about lexing are in lexing.md, and current ideas about command line interface are at command_line.md. All very much subject to change.

Headlines:

  • Ordinary programmers can write their own lexing rules.
  • Operators (functions like “+” that find their arguments on their left and right, instead of between brackets like normal functions) are defined at the lexing phase, so any symbol (e.g. “in”) can be an operator if you want.
  • Anything you might want to do with a pepper program, including running it, compiling it, packaging it for an distribution system, should be available as a sub-command of the main pepper3 command line.
  • The command is “pepper3”, never “pepper”. If a new, incompatible version comes out, it will be called “pepper4”, and they will be parallel-installable, with no confusion.