summarylogtreecommitdiffstats
path: root/PKGBUILD
blob: ee97fc375ff24ccad0133949ce86deba02699fc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# Maintainer: Callum Parsey <neoninteger@protonmail.com>
pkgname=turtl-core-rs
pkgver=0.1.2
pkgrel=5
pkgdesc="Turtl's logic core, built in Rust"
arch=("i686" "x86_64")
url="https://github.com/turtl/core-rs"
license=("GPL3")
depends=("libsodium" "openssl-1.0")
makedepends=("rust")
checkdepends=("turtl-server")

# Note: Turtl core-rs is versioned but not with Git tags or releases, the only
# way to download a specific core-rs version is using a commit hash that
# contains modifications to the CHANGELOG.md file.
_commithash="774fa361d021d9ef5237d32d09515ab7b2a32ad2"

source=("https://github.com/turtl/core-rs/archive/${_commithash}.tar.gz"
        "config-client.yaml"
        "config-server.yaml"
        "rusqlite.patch"
        "url.patch")
sha256sums=("71c1caf3aeb6245040abb0ee063b574dd6ece6314c60edabbe4299a11df49b68"
            "31791752feae4d5b0a19272bbb15df827bf67bb9df237e45431dc4b15b212c2e"
            "f3c974201d4d7b8bc00e51595cb0738d3772fd3bbd73624abc32536838465308"
            "bbe83ed13302a40db4589966aad01539c1165327dc74ff999a32350fb3c05e92"
            "a5985c5a5af81e59a6caf8eb4046dc7a4f581b50abe0fce7cffb1b3a07bd0d94")

prepare() {
    # This version of core-rs depends on an old version of rusqlite (v0.13.0)
    # which can't be built on current versions of Rust. This patch updates the
    # version of rusqlite used to v0.14.0, the first release to contain the
    # fix that allows it to compile again.
    patch -Np0 -i rusqlite.patch

    # Same with url - it needs to be updated from v1.6.0 to v1.7.2 in order to
    # fix build issues. For now, I chose not to go with the latest version due
    # to the potential for API-breaking changes that would require actual
    # patching on the core-rs source code. The correct fix would be for me to
    # learn Rust, update all of the dependencies for core-rs and then send that
    # as a pull request to its repository.
    patch -Np0 -i url.patch
}

build() {
    # Note: The OpenSSL binding library used by Turtl depends on OpenSSL v1.0,
    # here we specify variables to ensure that version 1.0 is used for
    # building, rather than v1.1 which is included in Arch-based systems and
    # used by default.
    export OPENSSL_INCLUDE_DIR=/usr/include/openssl-1.0
    export OPENSSL_LIB_DIR=/usr/lib/openssl-1.0

    cd "core-rs-${_commithash}"
    cargo build --features sqlite-static --release
}

check() {
    cd "core-rs-${_commithash}"

    # NOTE: The integration tests need to link to the already-built turtl_core
    # library and used to do so automatically, however this does not work
    # anymore. Upstream bug or deprecated funtionality in Rust?
    # To work around this, we temporarily set LD_PRELOAD_PATH to the directory
    # containing turtl_core.so to allow the dynamic linking to occur.
    export LD_LIBRARY_PATH="${srcdir}/core-rs-${_commithash}/target/release:${LD_LIBRARY_PATH}"

    # Determine the capabilities of the terminal this script is running in
    reset="$(tput sgr0 2> /dev/null)"
    if [ "$?" -eq 0 ]; then
        bold="$(tput bold 2> /dev/null)"

        numColours="$(tput colors)"
        if [ "$numColours" -ge 8 ]; then
            blue="$(tput setaf 4)"
        fi
    fi

    # Echoes a blue arrow followed by a bolded log message, much like the
    # verbose printing that makepkg itself does
    log() {
        echo -e "${reset}  ${bold}${blue}->${reset} ${bold}$@${reset}"
    }

    # Create the directories for the PostgreSQL database cluster, Turtl server
    # copy and Turtl server upload contents. Copy the core-rs and server
    # configuration files, initialize the database cluster and start a
    # PostgreSQL server instance within it.
    init_database() {
        log "Creating directories and copying configuration files..."
        mkdir turtl-db turtl-server turtl-server/config turtl-uploads
        cp ../config-client.yaml config.yaml
        cp ../config-server.yaml turtl-server/config/config.yaml

        log "Initializing PostgreSQL database cluster..."
        initdb -D turtl-db -A trust

        log "Starting PostgreSQL server..."
        pg_ctl start -D turtl-db -o "-c unix_socket_directories=/tmp"
    }

    # Copy the Turtl server executable files into our temporary directory. This
    # allows us to run the server with our own configuration file rather than
    # having to patch a user-controlled configuration. Then create a user and
    # database for the Turtl server to use, populate this database with the
    # test suite data, and finally start running the Turtl server as a
    # background task. Sleep for 2 seconds to ensure the server is up before
    # continuing.
    configure_turtl_server() {
        log "Copying Turtl server files..."
        cd turtl-server
        cp -r /usr/share/webapps/turtl/controllers controllers
        cp -r /usr/share/webapps/turtl/helpers helpers
        cp -r /usr/share/webapps/turtl/models models
        cp -r /usr/share/webapps/turtl/node_modules node_modules
        mkdir plugins
        cp -r /usr/share/webapps/turtl/scripts scripts
        cp -r /usr/share/webapps/turtl/tools tools
        cp /usr/share/webapps/turtl/server.js server.js

        log "Configuring database for Turtl server..."
        psql -h /tmp -d postgres -c "CREATE USER turtl WITH PASSWORD 'turtl'"
        psql -h /tmp -d postgres -c "CREATE DATABASE turtl"
        scripts/init-db.sh
        node tools/populate-test-data.js

        log "Starting Turtl server..."
        node server.js &
        sleep 2
        cd ..
    }

    # Run the cargo test suite for core-rs.
    # Note: The 'migrate' test requires a deprecated Lisp-based Turtl server to
    # be running, in order to test how the client can migrate data from an old
    # server to a new NodeJS-based server. As the Lisp server is not run from
    # this PKGBUILD check() function, the test will fail. To work around this,
    # (at least for now) we just skip the test.
    run_tests() {
        log "Building and running unit tests..."
        cargo test --features sqlite-static --release -- --test-threads 1

        log "Building and running integration tests..."
        cd integration-tests
        cargo test --release -- --skip migrate
        cd ..
    }

    # Send SIGTERM to the Turtl server task to make it quit
    stop_turtl_server() {
        log "Stopping Turtl server..."
        kill %1
    }

    # Shut down the PostgreSQL server. There is a directory change in here just
    # in case the function was called as a result of an error during
    # configure_turtl_server() in which the directory is not the same as what
    # is expected here.
    stop_database() {
        cd "$srcdir/core-rs-${_commithash}"
        log "Stopping PostgreSQL server..."
        pg_ctl stop -D turtl-db
    }

    # Delete the created folders for the Turtl server and database, as they
    # are no longer necessary.
    remove_dirs() {
        log "Cleaning up..."
        rm -rf turtl-db turtl-server turtl-uploads config.yaml
    }

    # The default behaviour in makepkg is that, if a command returns with a
    # non-zero exit status, the script will stop execution and makepkg will
    # exit. This means that if a command such as 'make test-st' fails, the
    # script will exit before the database/Turtl servers have been shut down,
    # meaning they will keep running. By trapping errors like this, it is
    # possible to override makepkg's default behaviour and run the necessary
    # shutdown routines should a command fail. In the below examples, if an
    # error occurs during the configure_turtl_server() step (i.e. the
    # temporary directories and database cluster have been created, and the SQL
    # server is running) the proper shutdown routines are run from the trap to
    # stop the SQL server and clean up the directories.

    trap "remove_dirs" ERR
    init_database
    trap - ERR

    trap "stop_database; remove_dirs" ERR
    configure_turtl_server
    trap - ERR

    trap "stop_turtl_server; stop_database; remove_dirs" ERR
    run_tests
    trap - ERR

    stop_turtl_server
    stop_database
    remove_dirs
}

package() {
    cd "core-rs-${_commithash}"
    install -Dm 755 target/release/libturtl_core.so -t "${pkgdir}/usr/lib"
}