From 0c8387ce023d625e84008e2d9e46e4b24e17aeb6 Mon Sep 17 00:00:00 2001 From: Martin Wurm Date: Tue, 13 Feb 2024 11:00:12 +0100 Subject: [PATCH] oops i made a website now i only need to fix the nix bit --- .direnv/bin/nix-direnv-reload | 8 + .direnv/nix-profile-.4195.809cca784b9f | 1 + .direnv/nix-profile-.4195.809cca784b9f.rc | 1856 +++++++++++++++++++++ .envrc | 1 + archetypes/default.md | 5 + assets/css/custom.css | 26 + assets/icons/auth.svg | 1 + assets/icons/git.svg | 1 + assets/icons/monitoring.svg | 1 + config/_default/module.toml | 2 + content/legal_notice.md | 16 + content/privacy.md | 261 +++ default.nix | 23 + go.mod | 5 + go.sum | 2 + hugo.toml | 29 + static/android-chrome-192x192.png | Bin 0 -> 1042 bytes static/android-chrome-512x512.png | Bin 0 -> 2349 bytes static/apple-touch-icon.png | Bin 0 -> 2349 bytes static/favicon-16x16.png | Bin 0 -> 642 bytes static/favicon-32x32.png | Bin 0 -> 676 bytes static/favicon.ico | Bin 0 -> 318 bytes static/logo_big.png | Bin 0 -> 39900 bytes 23 files changed, 2238 insertions(+) create mode 100755 .direnv/bin/nix-direnv-reload create mode 120000 .direnv/nix-profile-.4195.809cca784b9f create mode 100644 .direnv/nix-profile-.4195.809cca784b9f.rc create mode 100644 .envrc create mode 100644 archetypes/default.md create mode 100644 assets/css/custom.css create mode 100644 assets/icons/auth.svg create mode 100644 assets/icons/git.svg create mode 100644 assets/icons/monitoring.svg create mode 100644 config/_default/module.toml create mode 100644 content/legal_notice.md create mode 100644 content/privacy.md create mode 100644 default.nix create mode 100644 go.mod create mode 100644 go.sum create mode 100644 hugo.toml create mode 100644 static/android-chrome-192x192.png create mode 100644 static/android-chrome-512x512.png create mode 100644 static/apple-touch-icon.png create mode 100644 static/favicon-16x16.png create mode 100644 static/favicon-32x32.png create mode 100644 static/favicon.ico create mode 100644 static/logo_big.png diff --git a/.direnv/bin/nix-direnv-reload b/.direnv/bin/nix-direnv-reload new file mode 100755 index 0000000..186ac96 --- /dev/null +++ b/.direnv/bin/nix-direnv-reload @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +dir="$(realpath $(dirname ${BASH_SOURCE[0]})/../..)" +_nix_direnv_force_reload=1 direnv exec "$dir" true +direnv reload +# direnv reload updates the mtime of .envrc. Also update the timestamp of the +# profile_rc file to keep track that we actually are up to date. +touch $dir/.direnv/{nix,flake}-profile-*.rc + diff --git a/.direnv/nix-profile-.4195.809cca784b9f b/.direnv/nix-profile-.4195.809cca784b9f new file mode 120000 index 0000000..3c42208 --- /dev/null +++ b/.direnv/nix-profile-.4195.809cca784b9f @@ -0,0 +1 @@ +/nix/store/yh8plh4ww2rk9085gg552ivcr0ykfma7-brokentech.cloud-0.1-env \ No newline at end of file diff --git a/.direnv/nix-profile-.4195.809cca784b9f.rc b/.direnv/nix-profile-.4195.809cca784b9f.rc new file mode 100644 index 0000000..d85a141 --- /dev/null +++ b/.direnv/nix-profile-.4195.809cca784b9f.rc @@ -0,0 +1,1856 @@ +unset shellHook +PATH=${PATH:-} +nix_saved_PATH="$PATH" +XDG_DATA_DIRS=${XDG_DATA_DIRS:-} +nix_saved_XDG_DATA_DIRS="$XDG_DATA_DIRS" +AR='ar' +export AR +AS='as' +export AS +BASH='/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash' +CC='gcc' +export CC +CONFIG_SHELL='/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash' +export CONFIG_SHELL +CXX='g++' +export CXX +HOSTTYPE='x86_64' +HOST_PATH='/nix/store/m38gwq0w8w7qyjn9s00balyp7cv3m5p9-coreutils-9.3/bin:/nix/store/01znf87kiw5xx1dj0f7djrnrbg84ij28-findutils-4.9.0/bin:/nix/store/vq4vmndw555m7ld2bi6pq8kr348qvb6a-diffutils-3.10/bin:/nix/store/rwa7qyds01qzxvq7zq3kgnkrzzpw4s66-gnused-4.9/bin:/nix/store/n062zcsmfl9gfp6vfkcg0asb8jjwmy5i-gnugrep-3.11/bin:/nix/store/4v7m4yx07b3anmbznfhihjc8xiizyna9-gawk-5.2.2/bin:/nix/store/mi3pm67ps7c7k11aqki9182ygzg8j503-gnutar-1.35/bin:/nix/store/5c0ancqnpi0cf1h49mv13w68a950s9z0-gzip-1.13/bin:/nix/store/q5cv7r1sh3s4niyq7vm6h1j74394naxs-bzip2-1.0.8-bin/bin:/nix/store/bh7sbl99ygfvw9w96936nrhw46jmcmqq-gnumake-4.4.1/bin:/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin:/nix/store/mbh9gx43gsc5av019vsdkazbyiic3f0f-patch-2.7.6/bin:/nix/store/3q6fnwcm677l1q60vkhcf9m1gxhv83jm-xz-5.4.4-bin/bin:/nix/store/a5s2dmba16pw8l52f496gw0b7nli7mbn-file-5.45/bin' +export HOST_PATH +IFS=' +' +IN_NIX_SHELL='impure' +export IN_NIX_SHELL +LD='ld' +export LD +LINENO='76' +MACHTYPE='x86_64-pc-linux-gnu' +NIX_BINTOOLS='/nix/store/qcg3rpl1l103zb1xfsw40wm9j5hzrp7y-binutils-wrapper-2.40' +export NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1' +export NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES='16' +export NIX_BUILD_CORES +NIX_CC='/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0' +export NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1' +export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE=' -frandom-seed=yh8plh4ww2' +export NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE='1' +export NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE='fortify fortify3 stackprotector pic strictoverflow format relro bindnow' +export NIX_HARDENING_ENABLE +NIX_LDFLAGS='-rpath /home/mart-w/git/brokentech.cloud/outputs/out/lib ' +export NIX_LDFLAGS +NIX_NO_SELF_RPATH='1' +NIX_STORE='/nix/store' +export NIX_STORE +NM='nm' +export NM +OBJCOPY='objcopy' +export OBJCOPY +OBJDUMP='objdump' +export OBJDUMP +OLDPWD='' +export OLDPWD +OPTERR='1' +OSTYPE='linux-gnu' +PATH='/nix/store/0ccvrxf7fim2gh568d2r7jhd4lk6q6ag-git-2.42.0/bin:/nix/store/wmnf7h6fzmq3daap5xa8dd6hmda8ipdd-go-1.21.5/bin:/nix/store/4fvxh7j7kn4szlrf6bvbpc4b6s2jl771-hugo-0.120.3/bin:/nix/store/h3ayxf5dk1gdf3s5716fh1ys815qxxag-patchelf-0.15.0/bin:/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0/bin:/nix/store/f94yr35af3xdiscbj6cp6kafvmn55gv9-gcc-12.3.0/bin:/nix/store/vksrk76p5cfbjxb0n95vdkxy7fl2cbcm-glibc-2.38-27-bin/bin:/nix/store/m38gwq0w8w7qyjn9s00balyp7cv3m5p9-coreutils-9.3/bin:/nix/store/qcg3rpl1l103zb1xfsw40wm9j5hzrp7y-binutils-wrapper-2.40/bin:/nix/store/idiaraknw071d20nlqp49s18gbvw4wa0-binutils-2.40/bin:/nix/store/m38gwq0w8w7qyjn9s00balyp7cv3m5p9-coreutils-9.3/bin:/nix/store/01znf87kiw5xx1dj0f7djrnrbg84ij28-findutils-4.9.0/bin:/nix/store/vq4vmndw555m7ld2bi6pq8kr348qvb6a-diffutils-3.10/bin:/nix/store/rwa7qyds01qzxvq7zq3kgnkrzzpw4s66-gnused-4.9/bin:/nix/store/n062zcsmfl9gfp6vfkcg0asb8jjwmy5i-gnugrep-3.11/bin:/nix/store/4v7m4yx07b3anmbznfhihjc8xiizyna9-gawk-5.2.2/bin:/nix/store/mi3pm67ps7c7k11aqki9182ygzg8j503-gnutar-1.35/bin:/nix/store/5c0ancqnpi0cf1h49mv13w68a950s9z0-gzip-1.13/bin:/nix/store/q5cv7r1sh3s4niyq7vm6h1j74394naxs-bzip2-1.0.8-bin/bin:/nix/store/bh7sbl99ygfvw9w96936nrhw46jmcmqq-gnumake-4.4.1/bin:/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin:/nix/store/mbh9gx43gsc5av019vsdkazbyiic3f0f-patch-2.7.6/bin:/nix/store/3q6fnwcm677l1q60vkhcf9m1gxhv83jm-xz-5.4.4-bin/bin:/nix/store/a5s2dmba16pw8l52f496gw0b7nli7mbn-file-5.45/bin' +export PATH +PS4='+ ' +RANLIB='ranlib' +export RANLIB +READELF='readelf' +export READELF +SIZE='size' +export SIZE +SOURCE_DATE_EPOCH='315532800' +export SOURCE_DATE_EPOCH +STRINGS='strings' +export STRINGS +STRIP='strip' +export STRIP +XDG_DATA_DIRS='/nix/store/0ccvrxf7fim2gh568d2r7jhd4lk6q6ag-git-2.42.0/share:/nix/store/wmnf7h6fzmq3daap5xa8dd6hmda8ipdd-go-1.21.5/share:/nix/store/4fvxh7j7kn4szlrf6bvbpc4b6s2jl771-hugo-0.120.3/share:/nix/store/h3ayxf5dk1gdf3s5716fh1ys815qxxag-patchelf-0.15.0/share' +export XDG_DATA_DIRS +__structuredAttrs='' +export __structuredAttrs +buildInputs='' +export buildInputs +buildPhase='hugo +' +export buildPhase +builder='/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash' +export builder +cmakeFlags='' +export cmakeFlags +configureFlags='' +export configureFlags +defaultBuildInputs='' +defaultNativeBuildInputs='/nix/store/h3ayxf5dk1gdf3s5716fh1ys815qxxag-patchelf-0.15.0 /nix/store/v5qyd49a256y44pz75qnsp9741mg336k-update-autotools-gnu-config-scripts-hook /nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh /nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh /nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh /nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh /nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh /nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh /nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh /nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh /nix/store/wzdsbnv2ba3nj91aql8jjdddfmkkdh7h-patch-shebangs.sh /nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh /nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh /nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh /nix/store/wmknncrif06fqxa16hpdldhixk95nds0-strip.sh /nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0' +depsBuildBuild='' +export depsBuildBuild +depsBuildBuildPropagated='' +export depsBuildBuildPropagated +depsBuildTarget='' +export depsBuildTarget +depsBuildTargetPropagated='' +export depsBuildTargetPropagated +depsHostHost='' +export depsHostHost +depsHostHostPropagated='' +export depsHostHostPropagated +depsTargetTarget='' +export depsTargetTarget +depsTargetTargetPropagated='' +export depsTargetTargetPropagated +doCheck='' +export doCheck +doInstallCheck='' +export doInstallCheck +dontAddDisableDepTrack='1' +export dontAddDisableDepTrack +declare -a envBuildBuildHooks=() +declare -a envBuildHostHooks=() +declare -a envBuildTargetHooks=() +declare -a envHostHostHooks=('ccWrapper_addCVars' 'bintoolsWrapper_addLDVars' ) +declare -a envHostTargetHooks=('ccWrapper_addCVars' 'bintoolsWrapper_addLDVars' ) +declare -a envTargetTargetHooks=() +declare -a fixupOutputHooks=('if [ -z "${dontPatchELF-}" ]; then patchELF "$prefix"; fi' 'if [[ -z "${noAuditTmpdir-}" && -e "$prefix" ]]; then auditTmpdir "$prefix"; fi' 'if [ -z "${dontGzipMan-}" ]; then compressManPages "$prefix"; fi' '_moveLib64' '_moveSbin' '_moveSystemdUserUnits' 'patchShebangsAuto' '_pruneLibtoolFiles' '_doStrip' ) +guess='16' +initialPath='/nix/store/m38gwq0w8w7qyjn9s00balyp7cv3m5p9-coreutils-9.3 /nix/store/01znf87kiw5xx1dj0f7djrnrbg84ij28-findutils-4.9.0 /nix/store/vq4vmndw555m7ld2bi6pq8kr348qvb6a-diffutils-3.10 /nix/store/rwa7qyds01qzxvq7zq3kgnkrzzpw4s66-gnused-4.9 /nix/store/n062zcsmfl9gfp6vfkcg0asb8jjwmy5i-gnugrep-3.11 /nix/store/4v7m4yx07b3anmbznfhihjc8xiizyna9-gawk-5.2.2 /nix/store/mi3pm67ps7c7k11aqki9182ygzg8j503-gnutar-1.35 /nix/store/5c0ancqnpi0cf1h49mv13w68a950s9z0-gzip-1.13 /nix/store/q5cv7r1sh3s4niyq7vm6h1j74394naxs-bzip2-1.0.8-bin /nix/store/bh7sbl99ygfvw9w96936nrhw46jmcmqq-gnumake-4.4.1 /nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15 /nix/store/mbh9gx43gsc5av019vsdkazbyiic3f0f-patch-2.7.6 /nix/store/3q6fnwcm677l1q60vkhcf9m1gxhv83jm-xz-5.4.4-bin /nix/store/a5s2dmba16pw8l52f496gw0b7nli7mbn-file-5.45' +installPhase='mkdir -p $out +cp -r ./public/* $out +' +export installPhase +mesonFlags='' +export mesonFlags +name='brokentech.cloud-0.1-env' +export name +nativeBuildInputs='/nix/store/0ccvrxf7fim2gh568d2r7jhd4lk6q6ag-git-2.42.0 /nix/store/wmnf7h6fzmq3daap5xa8dd6hmda8ipdd-go-1.21.5 /nix/store/4fvxh7j7kn4szlrf6bvbpc4b6s2jl771-hugo-0.120.3' +export nativeBuildInputs +out='/home/mart-w/git/brokentech.cloud/outputs/out' +export out +outputBin='out' +outputDev='out' +outputDevdoc='REMOVE' +outputDevman='out' +outputDoc='out' +outputInclude='out' +outputInfo='out' +outputLib='out' +outputMan='out' +outputs='out' +export outputs +patches='' +export patches +pkg='/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0' +declare -a pkgsBuildBuild=() +declare -a pkgsBuildHost=('/nix/store/0ccvrxf7fim2gh568d2r7jhd4lk6q6ag-git-2.42.0' '/nix/store/wmnf7h6fzmq3daap5xa8dd6hmda8ipdd-go-1.21.5' '/nix/store/4fvxh7j7kn4szlrf6bvbpc4b6s2jl771-hugo-0.120.3' '/nix/store/h3ayxf5dk1gdf3s5716fh1ys815qxxag-patchelf-0.15.0' '/nix/store/v5qyd49a256y44pz75qnsp9741mg336k-update-autotools-gnu-config-scripts-hook' '/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh' '/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh' '/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh' '/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh' '/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh' '/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh' '/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh' '/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh' '/nix/store/wzdsbnv2ba3nj91aql8jjdddfmkkdh7h-patch-shebangs.sh' '/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh' '/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh' '/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh' '/nix/store/wmknncrif06fqxa16hpdldhixk95nds0-strip.sh' '/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0' '/nix/store/qcg3rpl1l103zb1xfsw40wm9j5hzrp7y-binutils-wrapper-2.40' ) +declare -a pkgsBuildTarget=() +declare -a pkgsHostHost=() +declare -a pkgsHostTarget=() +declare -a pkgsTargetTarget=() +declare -a postFixupHooks=('_makeSymlinksRelativeInAllOutputs' '_multioutPropagateDev' ) +declare -a postUnpackHooks=('_updateSourceDateEpochFromSourceRoot' ) +declare -a preConfigureHooks=('_multioutConfig' ) +preConfigurePhases=' updateAutotoolsGnuConfigScriptsPhase' +declare -a preFixupHooks=('_moveToShare' '_multioutDocs' '_multioutDevs' ) +prefix='/home/mart-w/git/brokentech.cloud/outputs/out' +declare -a propagatedBuildDepFiles=('propagated-build-build-deps' 'propagated-native-build-inputs' 'propagated-build-target-deps' ) +propagatedBuildInputs='' +export propagatedBuildInputs +declare -a propagatedHostDepFiles=('propagated-host-host-deps' 'propagated-build-inputs' ) +propagatedNativeBuildInputs='' +export propagatedNativeBuildInputs +declare -a propagatedTargetDepFiles=('propagated-target-target-deps' ) +shell='/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash' +export shell +src='/nix/store/g81rlq9426bn2a0s0kinpjaxi17zx1p7-brokentech.cloud' +export src +stdenv='/nix/store/kv5wkk7xgc8paw9azshzlmxraffqcg0i-stdenv-linux' +export stdenv +strictDeps='' +export strictDeps +system='x86_64-linux' +export system +declare -a unpackCmdHooks=('_defaultUnpack' ) +version='0.1' +export version +_accumFlagsArray () +{ + + local name; + if [ -n "$__structuredAttrs" ]; then + for name in "$@"; + do + local -n nameref="$name"; + flagsArray+=(${nameref+"${nameref[@]}"}); + done; + else + for name in "$@"; + do + local -n nameref="$name"; + case "$name" in + *Array) + flagsArray+=(${nameref+"${nameref[@]}"}) + ;; + *) + flagsArray+=(${nameref-}) + ;; + esac; + done; + fi +} +_activatePkgs () +{ + + local hostOffset targetOffset; + local pkg; + for hostOffset in "${allPlatOffsets[@]}"; + do + local pkgsVar="${pkgAccumVarVars[hostOffset + 1]}"; + for targetOffset in "${allPlatOffsets[@]}"; + do + (( hostOffset <= targetOffset )) || continue; + local pkgsRef="${pkgsVar}[$targetOffset - $hostOffset]"; + local pkgsSlice="${!pkgsRef}[@]"; + for pkg in ${!pkgsSlice+"${!pkgsSlice}"}; + do + activatePackage "$pkg" "$hostOffset" "$targetOffset"; + done; + done; + done +} +_addRpathPrefix () +{ + + if [ "${NIX_NO_SELF_RPATH:-0}" != 1 ]; then + export NIX_LDFLAGS="-rpath $1/lib ${NIX_LDFLAGS-}"; + fi +} +_addToEnv () +{ + + local depHostOffset depTargetOffset; + local pkg; + for depHostOffset in "${allPlatOffsets[@]}"; + do + local hookVar="${pkgHookVarVars[depHostOffset + 1]}"; + local pkgsVar="${pkgAccumVarVars[depHostOffset + 1]}"; + for depTargetOffset in "${allPlatOffsets[@]}"; + do + (( depHostOffset <= depTargetOffset )) || continue; + local hookRef="${hookVar}[$depTargetOffset - $depHostOffset]"; + if [[ -z "${strictDeps-}" ]]; then + local visitedPkgs=""; + for pkg in "${pkgsBuildBuild[@]}" "${pkgsBuildHost[@]}" "${pkgsBuildTarget[@]}" "${pkgsHostHost[@]}" "${pkgsHostTarget[@]}" "${pkgsTargetTarget[@]}"; + do + if [[ "$visitedPkgs" = *"$pkg"* ]]; then + continue; + fi; + runHook "${!hookRef}" "$pkg"; + visitedPkgs+=" $pkg"; + done; + else + local pkgsRef="${pkgsVar}[$depTargetOffset - $depHostOffset]"; + local pkgsSlice="${!pkgsRef}[@]"; + for pkg in ${!pkgsSlice+"${!pkgsSlice}"}; + do + runHook "${!hookRef}" "$pkg"; + done; + fi; + done; + done +} +_allFlags () +{ + + export system pname name version; + for varName in $(awk 'BEGIN { for (v in ENVIRON) if (v ~ /^[a-z][a-zA-Z0-9_]*$/) print v }'); + do + if (( "${NIX_DEBUG:-0}" >= 1 )); then + printf "@%s@ -> %q\n" "${varName}" "${!varName}" 1>&2; + fi; + args+=("--subst-var" "$varName"); + done +} +_assignFirst () +{ + + local varName="$1"; + local _var; + local REMOVE=REMOVE; + shift; + for _var in "$@"; + do + if [ -n "${!_var-}" ]; then + eval "${varName}"="${_var}"; + return; + fi; + done; + echo; + echo "error: _assignFirst: could not find a non-empty variable whose name to assign to ${varName}."; + echo " The following variables were all unset or empty:"; + echo " $*"; + if [ -z "${out:-}" ]; then + echo ' If you do not want an "out" output in your derivation, make sure to define'; + echo ' the other specific required outputs. This can be achieved by picking one'; + echo " of the above as an output."; + echo ' You do not have to remove "out" if you want to have a different default'; + echo ' output, because the first output is taken as a default.'; + echo; + fi; + return 1 +} +_callImplicitHook () +{ + + local def="$1"; + local hookName="$2"; + if declare -F "$hookName" > /dev/null; then + "$hookName"; + else + if type -p "$hookName" > /dev/null; then + source "$hookName"; + else + if [ -n "${!hookName:-}" ]; then + eval "${!hookName}"; + else + return "$def"; + fi; + fi; + fi +} +_defaultUnpack () +{ + + local fn="$1"; + local destination; + if [ -d "$fn" ]; then + destination="$(stripHash "$fn")"; + if [ -e "$destination" ]; then + echo "Cannot copy $fn to $destination: destination already exists!"; + echo "Did you specify two \"srcs\" with the same \"name\"?"; + return 1; + fi; + cp -pr --reflink=auto -- "$fn" "$destination"; + else + case "$fn" in + *.tar.xz | *.tar.lzma | *.txz) + xz -d < "$fn" | tar xf - --warning=no-timestamp + ;; + *.tar | *.tar.* | *.tgz | *.tbz2 | *.tbz) + tar xf "$fn" --warning=no-timestamp + ;; + *) + return 1 + ;; + esac; + fi +} +_doStrip () +{ + + local -ra flags=(dontStripHost dontStripTarget); + local -ra debugDirs=(stripDebugList stripDebugListTarget); + local -ra allDirs=(stripAllList stripAllListTarget); + local -ra stripCmds=(STRIP STRIP_FOR_TARGET); + local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET); + stripDebugList=${stripDebugList[*]:-lib lib32 lib64 libexec bin sbin}; + stripDebugListTarget=${stripDebugListTarget[*]:-}; + stripAllList=${stripAllList[*]:-}; + stripAllListTarget=${stripAllListTarget[*]:-}; + local i; + for i in ${!stripCmds[@]}; + do + local -n flag="${flags[$i]}"; + local -n debugDirList="${debugDirs[$i]}"; + local -n allDirList="${allDirs[$i]}"; + local -n stripCmd="${stripCmds[$i]}"; + local -n ranlibCmd="${ranlibCmds[$i]}"; + if [[ -n "${dontStrip-}" || -n "${flag-}" ]] || ! type -f "${stripCmd-}" 2> /dev/null 1>&2; then + continue; + fi; + stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags[*]:--S -p}"; + stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags[*]:--s -p}"; + done +} +_eval () +{ + + if declare -F "$1" > /dev/null 2>&1; then + "$@"; + else + eval "$1"; + fi +} +_makeSymlinksRelative () +{ + + local symlinkTarget; + if [ "${dontRewriteSymlinks-}" ] || [ ! -e "$prefix" ]; then + return; + fi; + while IFS= read -r -d '' f; do + symlinkTarget=$(readlink "$f"); + if [[ "$symlinkTarget"/ != "$prefix"/* ]]; then + continue; + fi; + if [ ! -e "$symlinkTarget" ]; then + echo "the symlink $f is broken, it points to $symlinkTarget (which is missing)"; + fi; + echo "rewriting symlink $f to be relative to $prefix"; + ln -snrf "$symlinkTarget" "$f"; + done < <(find $prefix -type l -print0) +} +_makeSymlinksRelativeInAllOutputs () +{ + + local output; + for output in $(getAllOutputNames); + do + prefix="${!output}" _makeSymlinksRelative; + done +} +_moveLib64 () +{ + + if [ "${dontMoveLib64-}" = 1 ]; then + return; + fi; + if [ ! -e "$prefix/lib64" -o -L "$prefix/lib64" ]; then + return; + fi; + echo "moving $prefix/lib64/* to $prefix/lib"; + mkdir -p $prefix/lib; + shopt -s dotglob; + for i in $prefix/lib64/*; + do + mv --no-clobber "$i" $prefix/lib; + done; + shopt -u dotglob; + rmdir $prefix/lib64; + ln -s lib $prefix/lib64 +} +_moveSbin () +{ + + if [ "${dontMoveSbin-}" = 1 ]; then + return; + fi; + if [ ! -e "$prefix/sbin" -o -L "$prefix/sbin" ]; then + return; + fi; + echo "moving $prefix/sbin/* to $prefix/bin"; + mkdir -p $prefix/bin; + shopt -s dotglob; + for i in $prefix/sbin/*; + do + mv "$i" $prefix/bin; + done; + shopt -u dotglob; + rmdir $prefix/sbin; + ln -s bin $prefix/sbin +} +_moveSystemdUserUnits () +{ + + if [ "${dontMoveSystemdUserUnits:-0}" = 1 ]; then + return; + fi; + if [ ! -e "${prefix:?}/lib/systemd/user" ]; then + return; + fi; + local source="$prefix/lib/systemd/user"; + local target="$prefix/share/systemd/user"; + echo "moving $source/* to $target"; + mkdir -p "$target"; + ( shopt -s dotglob; + for i in "$source"/*; + do + mv "$i" "$target"; + done ); + rmdir "$source"; + ln -s "$target" "$source" +} +_moveToShare () +{ + + if [ -n "$__structuredAttrs" ]; then + if [ -z "${forceShare-}" ]; then + forceShare=(man doc info); + fi; + else + forceShare=(${forceShare:-man doc info}); + fi; + if [[ -z "$out" ]]; then + return; + fi; + for d in "${forceShare[@]}"; + do + if [ -d "$out/$d" ]; then + if [ -d "$out/share/$d" ]; then + echo "both $d/ and share/$d/ exist!"; + else + echo "moving $out/$d to $out/share/$d"; + mkdir -p $out/share; + mv $out/$d $out/share/; + fi; + fi; + done +} +_multioutConfig () +{ + + if [ "$(getAllOutputNames)" = "out" ] || [ -z "${setOutputFlags-1}" ]; then + return; + fi; + if [ -z "${shareDocName:-}" ]; then + local confScript="${configureScript:-}"; + if [ -z "$confScript" ] && [ -x ./configure ]; then + confScript=./configure; + fi; + if [ -f "$confScript" ]; then + local shareDocName="$(sed -n "s/^PACKAGE_TARNAME='\(.*\)'$/\1/p" < "$confScript")"; + fi; + if [ -z "$shareDocName" ] || echo "$shareDocName" | grep -q '[^a-zA-Z0-9_-]'; then + shareDocName="$(echo "$name" | sed 's/-[^a-zA-Z].*//')"; + fi; + fi; + prependToVar configureFlags --bindir="${!outputBin}"/bin --sbindir="${!outputBin}"/sbin --includedir="${!outputInclude}"/include --oldincludedir="${!outputInclude}"/include --mandir="${!outputMan}"/share/man --infodir="${!outputInfo}"/share/info --docdir="${!outputDoc}"/share/doc/"${shareDocName}" --libdir="${!outputLib}"/lib --libexecdir="${!outputLib}"/libexec --localedir="${!outputLib}"/share/locale; + prependToVar installFlags pkgconfigdir="${!outputDev}"/lib/pkgconfig m4datadir="${!outputDev}"/share/aclocal aclocaldir="${!outputDev}"/share/aclocal +} +_multioutDevs () +{ + + if [ "$(getAllOutputNames)" = "out" ] || [ -z "${moveToDev-1}" ]; then + return; + fi; + moveToOutput include "${!outputInclude}"; + moveToOutput lib/pkgconfig "${!outputDev}"; + moveToOutput share/pkgconfig "${!outputDev}"; + moveToOutput lib/cmake "${!outputDev}"; + moveToOutput share/aclocal "${!outputDev}"; + for f in "${!outputDev}"/{lib,share}/pkgconfig/*.pc; + do + echo "Patching '$f' includedir to output ${!outputInclude}"; + sed -i "/^includedir=/s,=\${prefix},=${!outputInclude}," "$f"; + done +} +_multioutDocs () +{ + + local REMOVE=REMOVE; + moveToOutput share/info "${!outputInfo}"; + moveToOutput share/doc "${!outputDoc}"; + moveToOutput share/gtk-doc "${!outputDevdoc}"; + moveToOutput share/devhelp/books "${!outputDevdoc}"; + moveToOutput share/man "${!outputMan}"; + moveToOutput share/man/man3 "${!outputDevman}" +} +_multioutPropagateDev () +{ + + if [ "$(getAllOutputNames)" = "out" ]; then + return; + fi; + local outputFirst; + for outputFirst in $(getAllOutputNames); + do + break; + done; + local propagaterOutput="$outputDev"; + if [ -z "$propagaterOutput" ]; then + propagaterOutput="$outputFirst"; + fi; + if [ -z "${propagatedBuildOutputs+1}" ]; then + local po_dirty="$outputBin $outputInclude $outputLib"; + set +o pipefail; + propagatedBuildOutputs=`echo "$po_dirty" | tr -s ' ' '\n' | grep -v -F "$propagaterOutput" | sort -u | tr '\n' ' ' `; + set -o pipefail; + fi; + if [ -z "$propagatedBuildOutputs" ]; then + return; + fi; + mkdir -p "${!propagaterOutput}"/nix-support; + for output in $propagatedBuildOutputs; + do + echo -n " ${!output}" >> "${!propagaterOutput}"/nix-support/propagated-build-inputs; + done +} +_overrideFirst () +{ + + if [ -z "${!1-}" ]; then + _assignFirst "$@"; + fi +} +_pruneLibtoolFiles () +{ + + if [ "${dontPruneLibtoolFiles-}" ] || [ ! -e "$prefix" ]; then + return; + fi; + find "$prefix" -type f -name '*.la' -exec grep -q '^# Generated by .*libtool' {} \; -exec grep -q "^old_library=''" {} \; -exec sed -i {} -e "/^dependency_libs='[^']/ c dependency_libs='' #pruned" \; +} +_updateSourceDateEpochFromSourceRoot () +{ + + if [ -n "$sourceRoot" ]; then + updateSourceDateEpoch "$sourceRoot"; + fi +} +activatePackage () +{ + + local pkg="$1"; + local -r hostOffset="$2"; + local -r targetOffset="$3"; + (( hostOffset <= targetOffset )) || exit 1; + if [ -f "$pkg" ]; then + source "$pkg"; + fi; + if [[ -z "${strictDeps-}" || "$hostOffset" -le -1 ]]; then + addToSearchPath _PATH "$pkg/bin"; + fi; + if (( hostOffset <= -1 )); then + addToSearchPath _XDG_DATA_DIRS "$pkg/share"; + fi; + if [[ "$hostOffset" -eq 0 && -d "$pkg/bin" ]]; then + addToSearchPath _HOST_PATH "$pkg/bin"; + fi; + if [[ -f "$pkg/nix-support/setup-hook" ]]; then + source "$pkg/nix-support/setup-hook"; + fi +} +addEnvHooks () +{ + + local depHostOffset="$1"; + shift; + local pkgHookVarsSlice="${pkgHookVarVars[$depHostOffset + 1]}[@]"; + local pkgHookVar; + for pkgHookVar in "${!pkgHookVarsSlice}"; + do + eval "${pkgHookVar}s"'+=("$@")'; + done +} +addToSearchPath () +{ + + addToSearchPathWithCustomDelimiter ":" "$@" +} +addToSearchPathWithCustomDelimiter () +{ + + local delimiter="$1"; + local varName="$2"; + local dir="$3"; + if [[ -d "$dir" && "${!varName:+${delimiter}${!varName}${delimiter}}" != *"${delimiter}${dir}${delimiter}"* ]]; then + export "${varName}=${!varName:+${!varName}${delimiter}}${dir}"; + fi +} +appendToVar () +{ + + local -n nameref="$1"; + local useArray type; + if [ -n "$__structuredAttrs" ]; then + useArray=true; + else + useArray=false; + fi; + if declare -p "$1" 2> /dev/null | grep -q '^'; then + type="$(declare -p "$1")"; + if [[ "$type" =~ "declare -A" ]]; then + echo "appendToVar(): ERROR: trying to use appendToVar on an associative array, use variable+=([\"X\"]=\"Y\") instead." 1>&2; + return 1; + else + if [[ "$type" =~ "declare -a" ]]; then + useArray=true; + else + useArray=false; + fi; + fi; + fi; + shift; + if $useArray; then + nameref=(${nameref+"${nameref[@]}"} "$@"); + else + nameref="${nameref-} $*"; + fi +} +auditTmpdir () +{ + + local dir="$1"; + [ -e "$dir" ] || return 0; + echo "checking for references to $TMPDIR/ in $dir..."; + local i; + find "$dir" -type f -print0 | while IFS= read -r -d '' i; do + if [[ "$i" =~ .build-id ]]; then + continue; + fi; + if isELF "$i"; then + if { + printf :; + patchelf --print-rpath "$i" + } | grep -q -F ":$TMPDIR/"; then + echo "RPATH of binary $i contains a forbidden reference to $TMPDIR/"; + exit 1; + fi; + fi; + if isScript "$i"; then + if [ -e "$(dirname "$i")/.$(basename "$i")-wrapped" ]; then + if grep -q -F "$TMPDIR/" "$i"; then + echo "wrapper script $i contains a forbidden reference to $TMPDIR/"; + exit 1; + fi; + fi; + fi; + done +} +bintoolsWrapper_addLDVars () +{ + + local role_post; + getHostRoleEnvHook; + if [[ -d "$1/lib64" && ! -L "$1/lib64" ]]; then + export NIX_LDFLAGS${role_post}+=" -L$1/lib64"; + fi; + if [[ -d "$1/lib" ]]; then + local -a glob=($1/lib/lib*); + if [ "${#glob[*]}" -gt 0 ]; then + export NIX_LDFLAGS${role_post}+=" -L$1/lib"; + fi; + fi +} +buildPhase () +{ + + runHook preBuild; + if [[ -z "${makeFlags-}" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then + echo "no Makefile or custom buildPhase, doing nothing"; + else + foundMakefile=1; + local flagsArray=(${enableParallelBuilding:+-j${NIX_BUILD_CORES}} SHELL=$SHELL); + _accumFlagsArray makeFlags makeFlagsArray buildFlags buildFlagsArray; + echoCmd 'build flags' "${flagsArray[@]}"; + make ${makefile:+-f $makefile} "${flagsArray[@]}"; + unset flagsArray; + fi; + runHook postBuild +} +ccWrapper_addCVars () +{ + + local role_post; + getHostRoleEnvHook; + if [ -d "$1/include" ]; then + export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include"; + fi; + if [ -d "$1/Library/Frameworks" ]; then + export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks"; + fi +} +checkPhase () +{ + + runHook preCheck; + if [[ -z "${foundMakefile:-}" ]]; then + echo "no Makefile or custom checkPhase, doing nothing"; + runHook postCheck; + return; + fi; + if [[ -z "${checkTarget:-}" ]]; then + if make -n ${makefile:+-f $makefile} check > /dev/null 2>&1; then + checkTarget=check; + else + if make -n ${makefile:+-f $makefile} test > /dev/null 2>&1; then + checkTarget=test; + fi; + fi; + fi; + if [[ -z "${checkTarget:-}" ]]; then + echo "no check/test target in ${makefile:-Makefile}, doing nothing"; + else + local flagsArray=(${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL=$SHELL); + _accumFlagsArray makeFlags makeFlagsArray; + if [ -n "$__structuredAttrs" ]; then + flagsArray+=("${checkFlags[@]:-VERBOSE=y}"); + else + flagsArray+=(${checkFlags:-VERBOSE=y}); + fi; + _accumFlagsArray checkFlagsArray; + flagsArray+=(${checkTarget}); + echoCmd 'check flags' "${flagsArray[@]}"; + make ${makefile:+-f $makefile} "${flagsArray[@]}"; + unset flagsArray; + fi; + runHook postCheck +} +compressManPages () +{ + + local dir="$1"; + if [ -L "$dir"/share ] || [ -L "$dir"/share/man ] || [ ! -d "$dir/share/man" ]; then + return; + fi; + echo "gzipping man pages under $dir/share/man/"; + find "$dir"/share/man/ -type f -a '!' -regex '.*\.\(bz2\|gz\|xz\)$' -print0 | while IFS= read -r -d '' f; do + if gzip -c -n "$f" > "$f".gz; then + rm "$f"; + else + rm "$f".gz; + fi; + done; + find "$dir"/share/man/ -type l -a '!' -regex '.*\.\(bz2\|gz\|xz\)$' -print0 | sort -z | while IFS= read -r -d '' f; do + local target; + target="$(readlink -f "$f")"; + if [ -f "$target".gz ]; then + ln -sf "$target".gz "$f".gz && rm "$f"; + fi; + done +} +configurePhase () +{ + + runHook preConfigure; + : "${configureScript=}"; + if [[ -z "$configureScript" && -x ./configure ]]; then + configureScript=./configure; + fi; + if [ -z "${dontFixLibtool:-}" ]; then + export lt_cv_deplibs_check_method="${lt_cv_deplibs_check_method-pass_all}"; + local i; + find . -iname "ltmain.sh" -print0 | while IFS='' read -r -d '' i; do + echo "fixing libtool script $i"; + fixLibtool "$i"; + done; + CONFIGURE_MTIME_REFERENCE=$(mktemp configure.mtime.reference.XXXXXX); + find . -executable -type f -name configure -exec grep -l 'GNU Libtool is free software; you can redistribute it and/or modify' {} \; -exec touch -r {} "$CONFIGURE_MTIME_REFERENCE" \; -exec sed -i s_/usr/bin/file_file_g {} \; -exec touch -r "$CONFIGURE_MTIME_REFERENCE" {} \;; + rm -f "$CONFIGURE_MTIME_REFERENCE"; + fi; + if [[ -z "${dontAddPrefix:-}" && -n "$prefix" ]]; then + prependToVar configureFlags "${prefixKey:---prefix=}$prefix"; + fi; + if [[ -f "$configureScript" ]]; then + if [ -z "${dontAddDisableDepTrack:-}" ]; then + if grep -q dependency-tracking "$configureScript"; then + prependToVar configureFlags --disable-dependency-tracking; + fi; + fi; + if [ -z "${dontDisableStatic:-}" ]; then + if grep -q enable-static "$configureScript"; then + prependToVar configureFlags --disable-static; + fi; + fi; + fi; + if [ -n "$configureScript" ]; then + local -a flagsArray; + _accumFlagsArray configureFlags configureFlagsArray; + echoCmd 'configure flags' "${flagsArray[@]}"; + $configureScript "${flagsArray[@]}"; + unset flagsArray; + else + echo "no configure script, doing nothing"; + fi; + runHook postConfigure +} +consumeEntire () +{ + + if IFS='' read -r -d '' "$1"; then + echo "consumeEntire(): ERROR: Input null bytes, won't process" 1>&2; + return 1; + fi +} +distPhase () +{ + + runHook preDist; + local flagsArray=(); + _accumFlagsArray distFlags distFlagsArray; + flagsArray+=(${distTarget:-dist}); + echo 'dist flags: %q' "${flagsArray[@]}"; + make ${makefile:+-f $makefile} "${flagsArray[@]}"; + if [ "${dontCopyDist:-0}" != 1 ]; then + mkdir -p "$out/tarballs"; + cp -pvd ${tarballs[*]:-*.tar.gz} "$out/tarballs"; + fi; + runHook postDist +} +dumpVars () +{ + + if [ "${noDumpEnvVars:-0}" != 1 ]; then + export 2> /dev/null >| "$NIX_BUILD_TOP/env-vars" || true; + fi +} +echoCmd () +{ + + printf "%s:" "$1"; + shift; + printf ' %q' "$@"; + echo +} +exitHandler () +{ + + exitCode="$?"; + set +e; + if [ -n "${showBuildStats:-}" ]; then + read -r -d '' -a buildTimes < <(times); + echo "build times:"; + echo "user time for the shell ${buildTimes[0]}"; + echo "system time for the shell ${buildTimes[1]}"; + echo "user time for all child processes ${buildTimes[2]}"; + echo "system time for all child processes ${buildTimes[3]}"; + fi; + if (( "$exitCode" != 0 )); then + runHook failureHook; + if [ -n "${succeedOnFailure:-}" ]; then + echo "build failed with exit code $exitCode (ignored)"; + mkdir -p "$out/nix-support"; + printf "%s" "$exitCode" > "$out/nix-support/failed"; + exit 0; + fi; + else + runHook exitHook; + fi; + return "$exitCode" +} +findInputs () +{ + + local -r pkg="$1"; + local -r hostOffset="$2"; + local -r targetOffset="$3"; + (( hostOffset <= targetOffset )) || exit 1; + local varVar="${pkgAccumVarVars[hostOffset + 1]}"; + local varRef="$varVar[$((targetOffset - hostOffset))]"; + local var="${!varRef}"; + unset -v varVar varRef; + local varSlice="$var[*]"; + case "${!varSlice-}" in + *" $pkg "*) + return 0 + ;; + esac; + unset -v varSlice; + eval "$var"'+=("$pkg")'; + if ! [ -e "$pkg" ]; then + echo "build input $pkg does not exist" 1>&2; + exit 1; + fi; + function mapOffset () + { + local -r inputOffset="$1"; + local -n outputOffset="$2"; + if (( inputOffset <= 0 )); then + outputOffset=$((inputOffset + hostOffset)); + else + outputOffset=$((inputOffset - 1 + targetOffset)); + fi + }; + local relHostOffset; + for relHostOffset in "${allPlatOffsets[@]}"; + do + local files="${propagatedDepFilesVars[relHostOffset + 1]}"; + local hostOffsetNext; + mapOffset "$relHostOffset" hostOffsetNext; + (( -1 <= hostOffsetNext && hostOffsetNext <= 1 )) || continue; + local relTargetOffset; + for relTargetOffset in "${allPlatOffsets[@]}"; + do + (( "$relHostOffset" <= "$relTargetOffset" )) || continue; + local fileRef="${files}[$relTargetOffset - $relHostOffset]"; + local file="${!fileRef}"; + unset -v fileRef; + local targetOffsetNext; + mapOffset "$relTargetOffset" targetOffsetNext; + (( -1 <= hostOffsetNext && hostOffsetNext <= 1 )) || continue; + [[ -f "$pkg/nix-support/$file" ]] || continue; + local pkgNext; + read -r -d '' pkgNext < "$pkg/nix-support/$file" || true; + for pkgNext in $pkgNext; + do + findInputs "$pkgNext" "$hostOffsetNext" "$targetOffsetNext"; + done; + done; + done +} +fixLibtool () +{ + + local search_path; + for flag in $NIX_LDFLAGS; + do + case $flag in + -L*) + search_path+=" ${flag#-L}" + ;; + esac; + done; + sed -i "$1" -e "s^eval \(sys_lib_search_path=\).*^\1'${search_path:-}'^" -e 's^eval sys_lib_.+search_path=.*^^' +} +fixupPhase () +{ + + local output; + for output in $(getAllOutputNames); + do + if [ -e "${!output}" ]; then + chmod -R u+w "${!output}"; + fi; + done; + runHook preFixup; + local output; + for output in $(getAllOutputNames); + do + prefix="${!output}" runHook fixupOutput; + done; + recordPropagatedDependencies; + if [ -n "${setupHook:-}" ]; then + mkdir -p "${!outputDev}/nix-support"; + substituteAll "$setupHook" "${!outputDev}/nix-support/setup-hook"; + fi; + if [ -n "${setupHooks:-}" ]; then + mkdir -p "${!outputDev}/nix-support"; + local hook; + for hook in ${setupHooks[@]}; + do + local content; + consumeEntire content < "$hook"; + substituteAllStream content "file '$hook'" >> "${!outputDev}/nix-support/setup-hook"; + unset -v content; + done; + unset -v hook; + fi; + if [ -n "${propagatedUserEnvPkgs:-}" ]; then + mkdir -p "${!outputBin}/nix-support"; + printWords $propagatedUserEnvPkgs > "${!outputBin}/nix-support/propagated-user-env-packages"; + fi; + runHook postFixup +} +genericBuild () +{ + + export GZIP_NO_TIMESTAMPS=1; + if [ -f "${buildCommandPath:-}" ]; then + source "$buildCommandPath"; + return; + fi; + if [ -n "${buildCommand:-}" ]; then + eval "$buildCommand"; + return; + fi; + if [ -z "${phases[*]:-}" ]; then + phases="${prePhases[*]:-} unpackPhase patchPhase ${preConfigurePhases[*]:-} configurePhase ${preBuildPhases[*]:-} buildPhase checkPhase ${preInstallPhases[*]:-} installPhase ${preFixupPhases[*]:-} fixupPhase installCheckPhase ${preDistPhases[*]:-} distPhase ${postPhases[*]:-}"; + fi; + for curPhase in ${phases[*]}; + do + runPhase "$curPhase"; + done +} +getAllOutputNames () +{ + + if [ -n "$__structuredAttrs" ]; then + echo "${!outputs[*]}"; + else + echo "$outputs"; + fi +} +getHostRole () +{ + + getRole "$hostOffset" +} +getHostRoleEnvHook () +{ + + getRole "$depHostOffset" +} +getRole () +{ + + case $1 in + -1) + role_post='_FOR_BUILD' + ;; + 0) + role_post='' + ;; + 1) + role_post='_FOR_TARGET' + ;; + *) + echo "binutils-wrapper-2.40: used as improper sort of dependency" 1>&2; + return 1 + ;; + esac +} +getTargetRole () +{ + + getRole "$targetOffset" +} +getTargetRoleEnvHook () +{ + + getRole "$depTargetOffset" +} +getTargetRoleWrapper () +{ + + case $targetOffset in + -1) + export NIX_BINTOOLS_WRAPPER_TARGET_BUILD_x86_64_unknown_linux_gnu=1 + ;; + 0) + export NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1 + ;; + 1) + export NIX_BINTOOLS_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu=1 + ;; + *) + echo "binutils-wrapper-2.40: used as improper sort of dependency" 1>&2; + return 1 + ;; + esac +} +installCheckPhase () +{ + + runHook preInstallCheck; + if [[ -z "${foundMakefile:-}" ]]; then + echo "no Makefile or custom installCheckPhase, doing nothing"; + else + if [[ -z "${installCheckTarget:-}" ]] && ! make -n ${makefile:+-f $makefile} "${installCheckTarget:-installcheck}" > /dev/null 2>&1; then + echo "no installcheck target in ${makefile:-Makefile}, doing nothing"; + else + local flagsArray=(${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL=$SHELL); + _accumFlagsArray makeFlags makeFlagsArray installCheckFlags installCheckFlagsArray; + flagsArray+=(${installCheckTarget:-installcheck}); + echoCmd 'installcheck flags' "${flagsArray[@]}"; + make ${makefile:+-f $makefile} "${flagsArray[@]}"; + unset flagsArray; + fi; + fi; + runHook postInstallCheck +} +installPhase () +{ + + runHook preInstall; + if [[ -z "${makeFlags-}" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then + echo "no Makefile or custom installPhase, doing nothing"; + runHook postInstall; + return; + else + foundMakefile=1; + fi; + if [ -n "$prefix" ]; then + mkdir -p "$prefix"; + fi; + local flagsArray=(${enableParallelInstalling:+-j${NIX_BUILD_CORES}} SHELL=$SHELL); + _accumFlagsArray makeFlags makeFlagsArray installFlags installFlagsArray; + if [ -n "$__structuredAttrs" ]; then + flagsArray+=("${installTargets[@]:-install}"); + else + flagsArray+=(${installTargets:-install}); + fi; + echoCmd 'install flags' "${flagsArray[@]}"; + make ${makefile:+-f $makefile} "${flagsArray[@]}"; + unset flagsArray; + runHook postInstall +} +isELF () +{ + + local fn="$1"; + local fd; + local magic; + exec {fd}< "$fn"; + read -r -n 4 -u "$fd" magic; + exec {fd}>&-; + if [ "$magic" = 'ELF' ]; then + return 0; + else + return 1; + fi +} +isMachO () +{ + + local fn="$1"; + local fd; + local magic; + exec {fd}< "$fn"; + read -r -n 4 -u "$fd" magic; + exec {fd}>&-; + if [[ "$magic" = $(echo -ne "\xfe\xed\xfa\xcf") || "$magic" = $(echo -ne "\xcf\xfa\xed\xfe") ]]; then + return 0; + else + if [[ "$magic" = $(echo -ne "\xfe\xed\xfa\xce") || "$magic" = $(echo -ne "\xce\xfa\xed\xfe") ]]; then + return 0; + else + if [[ "$magic" = $(echo -ne "\xca\xfe\xba\xbe") || "$magic" = $(echo -ne "\xbe\xba\xfe\xca") ]]; then + return 0; + else + return 1; + fi; + fi; + fi +} +isScript () +{ + + local fn="$1"; + local fd; + local magic; + exec {fd}< "$fn"; + read -r -n 2 -u "$fd" magic; + exec {fd}>&-; + if [[ "$magic" =~ \#! ]]; then + return 0; + else + return 1; + fi +} +mapOffset () +{ + + local -r inputOffset="$1"; + local -n outputOffset="$2"; + if (( inputOffset <= 0 )); then + outputOffset=$((inputOffset + hostOffset)); + else + outputOffset=$((inputOffset - 1 + targetOffset)); + fi +} +moveToOutput () +{ + + local patt="$1"; + local dstOut="$2"; + local output; + for output in $(getAllOutputNames); + do + if [ "${!output}" = "$dstOut" ]; then + continue; + fi; + local srcPath; + for srcPath in "${!output}"/$patt; + do + if [ ! -e "$srcPath" ] && [ ! -L "$srcPath" ]; then + continue; + fi; + if [ "$dstOut" = REMOVE ]; then + echo "Removing $srcPath"; + rm -r "$srcPath"; + else + local dstPath="$dstOut${srcPath#${!output}}"; + echo "Moving $srcPath to $dstPath"; + if [ -d "$dstPath" ] && [ -d "$srcPath" ]; then + rmdir "$srcPath" --ignore-fail-on-non-empty; + if [ -d "$srcPath" ]; then + mv -t "$dstPath" "$srcPath"/*; + rmdir "$srcPath"; + fi; + else + mkdir -p "$(readlink -m "$dstPath/..")"; + mv "$srcPath" "$dstPath"; + fi; + fi; + local srcParent="$(readlink -m "$srcPath/..")"; + if [ -n "$(find "$srcParent" -maxdepth 0 -type d -empty 2> /dev/null)" ]; then + echo "Removing empty $srcParent/ and (possibly) its parents"; + rmdir -p --ignore-fail-on-non-empty "$srcParent" 2> /dev/null || true; + fi; + done; + done +} +patchELF () +{ + + local dir="$1"; + [ -e "$dir" ] || return 0; + echo "shrinking RPATHs of ELF executables and libraries in $dir"; + local i; + while IFS= read -r -d '' i; do + if [[ "$i" =~ .build-id ]]; then + continue; + fi; + if ! isELF "$i"; then + continue; + fi; + echo "shrinking $i"; + patchelf --shrink-rpath "$i" || true; + done < <(find "$dir" -type f -print0) +} +patchPhase () +{ + + runHook prePatch; + local -a patchesArray; + if [ -n "$__structuredAttrs" ]; then + patchesArray=(${patches:+"${patches[@]}"}); + else + patchesArray=(${patches:-}); + fi; + for i in "${patchesArray[@]}"; + do + echo "applying patch $i"; + local uncompress=cat; + case "$i" in + *.gz) + uncompress="gzip -d" + ;; + *.bz2) + uncompress="bzip2 -d" + ;; + *.xz) + uncompress="xz -d" + ;; + *.lzma) + uncompress="lzma -d" + ;; + esac; + local -a flagsArray; + if [ -n "$__structuredAttrs" ]; then + flagsArray=("${patchFlags[@]:--p1}"); + else + flagsArray=(${patchFlags:--p1}); + fi; + $uncompress < "$i" 2>&1 | patch "${flagsArray[@]}"; + done; + runHook postPatch +} +patchShebangs () +{ + + local pathName; + local update; + while [[ $# -gt 0 ]]; do + case "$1" in + --host) + pathName=HOST_PATH; + shift + ;; + --build) + pathName=PATH; + shift + ;; + --update) + update=true; + shift + ;; + --) + shift; + break + ;; + -* | --*) + echo "Unknown option $1 supplied to patchShebangs" 1>&2; + return 1 + ;; + *) + break + ;; + esac; + done; + echo "patching script interpreter paths in $@"; + local f; + local oldPath; + local newPath; + local arg0; + local args; + local oldInterpreterLine; + local newInterpreterLine; + if [[ $# -eq 0 ]]; then + echo "No arguments supplied to patchShebangs" 1>&2; + return 0; + fi; + local f; + while IFS= read -r -d '' f; do + isScript "$f" || continue; + read -r oldInterpreterLine < "$f"; + read -r oldPath arg0 args <<< "${oldInterpreterLine:2}"; + if [[ -z "${pathName:-}" ]]; then + if [[ -n $strictDeps && $f == "$NIX_STORE"* ]]; then + pathName=HOST_PATH; + else + pathName=PATH; + fi; + fi; + if [[ "$oldPath" == *"/bin/env" ]]; then + if [[ $arg0 == "-S" ]]; then + arg0=${args%% *}; + args=${args#* }; + newPath="$(PATH="${!pathName}" command -v "env" || true)"; + args="-S $(PATH="${!pathName}" command -v "$arg0" || true) $args"; + else + if [[ $arg0 == "-"* || $arg0 == *"="* ]]; then + echo "$f: unsupported interpreter directive \"$oldInterpreterLine\" (set dontPatchShebangs=1 and handle shebang patching yourself)" 1>&2; + exit 1; + else + newPath="$(PATH="${!pathName}" command -v "$arg0" || true)"; + fi; + fi; + else + if [[ -z $oldPath ]]; then + oldPath="/bin/sh"; + fi; + newPath="$(PATH="${!pathName}" command -v "$(basename "$oldPath")" || true)"; + args="$arg0 $args"; + fi; + newInterpreterLine="$newPath $args"; + newInterpreterLine=${newInterpreterLine%${newInterpreterLine##*[![:space:]]}}; + if [[ -n "$oldPath" && ( "$update" == true || "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ) ]]; then + if [[ -n "$newPath" && "$newPath" != "$oldPath" ]]; then + echo "$f: interpreter directive changed from \"$oldInterpreterLine\" to \"$newInterpreterLine\""; + escapedInterpreterLine=${newInterpreterLine//\\/\\\\}; + timestamp=$(stat --printf "%y" "$f"); + sed -i -e "1 s|.*|#\!$escapedInterpreterLine|" "$f"; + touch --date "$timestamp" "$f"; + fi; + fi; + done < <(find "$@" -type f -perm -0100 -print0) +} +patchShebangsAuto () +{ + + if [[ -z "${dontPatchShebangs-}" && -e "$prefix" ]]; then + if [[ "$output" != out && "$output" = "$outputDev" ]]; then + patchShebangs --build "$prefix"; + else + patchShebangs --host "$prefix"; + fi; + fi +} +prependToVar () +{ + + local -n nameref="$1"; + local useArray type; + if [ -n "$__structuredAttrs" ]; then + useArray=true; + else + useArray=false; + fi; + if declare -p "$1" 2> /dev/null | grep -q '^'; then + type="$(declare -p "$1")"; + if [[ "$type" =~ "declare -A" ]]; then + echo "prependToVar(): ERROR: trying to use prependToVar on an associative array." 1>&2; + return 1; + else + if [[ "$type" =~ "declare -a" ]]; then + useArray=true; + else + useArray=false; + fi; + fi; + fi; + shift; + if $useArray; then + nameref=("$@" ${nameref+"${nameref[@]}"}); + else + nameref="$* ${nameref-}"; + fi +} +printLines () +{ + + (( "$#" > 0 )) || return 0; + printf '%s\n' "$@" +} +printWords () +{ + + (( "$#" > 0 )) || return 0; + printf '%s ' "$@" +} +recordPropagatedDependencies () +{ + + declare -ra flatVars=(depsBuildBuildPropagated propagatedNativeBuildInputs depsBuildTargetPropagated depsHostHostPropagated propagatedBuildInputs depsTargetTargetPropagated); + declare -ra flatFiles=("${propagatedBuildDepFiles[@]}" "${propagatedHostDepFiles[@]}" "${propagatedTargetDepFiles[@]}"); + local propagatedInputsIndex; + for propagatedInputsIndex in "${!flatVars[@]}"; + do + local propagatedInputsSlice="${flatVars[$propagatedInputsIndex]}[@]"; + local propagatedInputsFile="${flatFiles[$propagatedInputsIndex]}"; + [[ -n "${!propagatedInputsSlice}" ]] || continue; + mkdir -p "${!outputDev}/nix-support"; + printWords ${!propagatedInputsSlice} > "${!outputDev}/nix-support/$propagatedInputsFile"; + done +} +runHook () +{ + + local hookName="$1"; + shift; + local hooksSlice="${hookName%Hook}Hooks[@]"; + local hook; + for hook in "_callImplicitHook 0 $hookName" ${!hooksSlice+"${!hooksSlice}"}; + do + _eval "$hook" "$@"; + done; + return 0 +} +runOneHook () +{ + + local hookName="$1"; + shift; + local hooksSlice="${hookName%Hook}Hooks[@]"; + local hook ret=1; + for hook in "_callImplicitHook 1 $hookName" ${!hooksSlice+"${!hooksSlice}"}; + do + if _eval "$hook" "$@"; then + ret=0; + break; + fi; + done; + return "$ret" +} +runPhase () +{ + + local curPhase="$*"; + if [[ "$curPhase" = unpackPhase && -n "${dontUnpack:-}" ]]; then + return; + fi; + if [[ "$curPhase" = patchPhase && -n "${dontPatch:-}" ]]; then + return; + fi; + if [[ "$curPhase" = configurePhase && -n "${dontConfigure:-}" ]]; then + return; + fi; + if [[ "$curPhase" = buildPhase && -n "${dontBuild:-}" ]]; then + return; + fi; + if [[ "$curPhase" = checkPhase && -z "${doCheck:-}" ]]; then + return; + fi; + if [[ "$curPhase" = installPhase && -n "${dontInstall:-}" ]]; then + return; + fi; + if [[ "$curPhase" = fixupPhase && -n "${dontFixup:-}" ]]; then + return; + fi; + if [[ "$curPhase" = installCheckPhase && -z "${doInstallCheck:-}" ]]; then + return; + fi; + if [[ "$curPhase" = distPhase && -z "${doDist:-}" ]]; then + return; + fi; + if [[ -n $NIX_LOG_FD ]]; then + echo "@nix { \"action\": \"setPhase\", \"phase\": \"$curPhase\" }" >&"$NIX_LOG_FD"; + fi; + showPhaseHeader "$curPhase"; + dumpVars; + local startTime=$(date +"%s"); + eval "${!curPhase:-$curPhase}"; + local endTime=$(date +"%s"); + showPhaseFooter "$curPhase" "$startTime" "$endTime"; + if [ "$curPhase" = unpackPhase ]; then + [ -n "${sourceRoot:-}" ] && chmod +x "${sourceRoot}"; + cd "${sourceRoot:-.}"; + fi +} +showPhaseFooter () +{ + + local phase="$1"; + local startTime="$2"; + local endTime="$3"; + local delta=$(( endTime - startTime )); + (( delta < 30 )) && return; + local H=$((delta/3600)); + local M=$((delta%3600/60)); + local S=$((delta%60)); + echo -n "$phase completed in "; + (( H > 0 )) && echo -n "$H hours "; + (( M > 0 )) && echo -n "$M minutes "; + echo "$S seconds" +} +showPhaseHeader () +{ + + local phase="$1"; + echo "Running phase: $phase" +} +stripDirs () +{ + + local cmd="$1"; + local ranlibCmd="$2"; + local paths="$3"; + local stripFlags="$4"; + local excludeFlags=(); + local pathsNew=; + [ -z "$cmd" ] && echo "stripDirs: Strip command is empty" 1>&2 && exit 1; + [ -z "$ranlibCmd" ] && echo "stripDirs: Ranlib command is empty" 1>&2 && exit 1; + local pattern; + if [ -n "${stripExclude:-}" ]; then + for pattern in "${stripExclude[@]}"; + do + excludeFlags+=(-a '!' '(' -name "$pattern" -o -wholename "$prefix/$pattern" ')'); + done; + fi; + local p; + for p in ${paths}; + do + if [ -e "$prefix/$p" ]; then + pathsNew="${pathsNew} $prefix/$p"; + fi; + done; + paths=${pathsNew}; + if [ -n "${paths}" ]; then + echo "stripping (with command $cmd and flags $stripFlags) in $paths"; + local striperr; + striperr="$(mktemp --tmpdir="$TMPDIR" 'striperr.XXXXXX')"; + find $paths -type f "${excludeFlags[@]}" -a '!' -path "$prefix/lib/debug/*" -print0 | xargs -r -0 -n1 -- realpath -z | sort -u -z | xargs -r -0 -n1 -P "$NIX_BUILD_CORES" -- $cmd $stripFlags 2> "$striperr" || exit_code=$?; + [[ "$exit_code" = 123 || -z "$exit_code" ]] || ( cat "$striperr" 1>&2 && exit 1 ); + rm "$striperr"; + find $paths -name '*.a' -type f -exec $ranlibCmd '{}' \; 2> /dev/null; + fi +} +stripHash () +{ + + local strippedName casematchOpt=0; + strippedName="$(basename -- "$1")"; + shopt -q nocasematch && casematchOpt=1; + shopt -u nocasematch; + if [[ "$strippedName" =~ ^[a-z0-9]{32}- ]]; then + echo "${strippedName:33}"; + else + echo "$strippedName"; + fi; + if (( casematchOpt )); then + shopt -s nocasematch; + fi +} +substitute () +{ + + local input="$1"; + local output="$2"; + shift 2; + if [ ! -f "$input" ]; then + echo "substitute(): ERROR: file '$input' does not exist" 1>&2; + return 1; + fi; + local content; + consumeEntire content < "$input"; + if [ -e "$output" ]; then + chmod +w "$output"; + fi; + substituteStream content "file '$input'" "$@" > "$output" +} +substituteAll () +{ + + local input="$1"; + local output="$2"; + local -a args=(); + _allFlags; + substitute "$input" "$output" "${args[@]}" +} +substituteAllInPlace () +{ + + local fileName="$1"; + shift; + substituteAll "$fileName" "$fileName" "$@" +} +substituteAllStream () +{ + + local -a args=(); + _allFlags; + substituteStream "$1" "$2" "${args[@]}" +} +substituteInPlace () +{ + + local -a fileNames=(); + for arg in "$@"; + do + if [[ "$arg" = "--"* ]]; then + break; + fi; + fileNames+=("$arg"); + shift; + done; + for file in "${fileNames[@]}"; + do + substitute "$file" "$file" "$@"; + done +} +substituteStream () +{ + + local var=$1; + local description=$2; + shift 2; + while (( "$#" )); do + case "$1" in + --replace) + pattern="$2"; + replacement="$3"; + shift 3; + local savedvar; + savedvar="${!var}"; + eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'; + if [ "$pattern" != "$replacement" ]; then + if [ "${!var}" == "$savedvar" ]; then + echo "substituteStream(): WARNING: pattern '$pattern' doesn't match anything in $description" 1>&2; + fi; + fi + ;; + --subst-var) + local varName="$2"; + shift 2; + if ! [[ "$varName" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then + echo "substituteStream(): ERROR: substitution variables must be valid Bash names, \"$varName\" isn't." 1>&2; + return 1; + fi; + if [ -z ${!varName+x} ]; then + echo "substituteStream(): ERROR: variable \$$varName is unset" 1>&2; + return 1; + fi; + pattern="@$varName@"; + replacement="${!varName}"; + eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}' + ;; + --subst-var-by) + pattern="@$2@"; + replacement="$3"; + eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'; + shift 3 + ;; + *) + echo "substituteStream(): ERROR: Invalid command line argument: $1" 1>&2; + return 1 + ;; + esac; + done; + printf "%s" "${!var}" +} +unpackFile () +{ + + curSrc="$1"; + echo "unpacking source archive $curSrc"; + if ! runOneHook unpackCmd "$curSrc"; then + echo "do not know how to unpack source archive $curSrc"; + exit 1; + fi +} +unpackPhase () +{ + + runHook preUnpack; + if [ -z "${srcs:-}" ]; then + if [ -z "${src:-}" ]; then + echo 'variable $src or $srcs should point to the source'; + exit 1; + fi; + srcs="$src"; + fi; + local -a srcsArray; + if [ -n "$__structuredAttrs" ]; then + srcsArray=("${srcs[@]}"); + else + srcsArray=($srcs); + fi; + local dirsBefore=""; + for i in *; + do + if [ -d "$i" ]; then + dirsBefore="$dirsBefore $i "; + fi; + done; + for i in "${srcsArray[@]}"; + do + unpackFile "$i"; + done; + : "${sourceRoot=}"; + if [ -n "${setSourceRoot:-}" ]; then + runOneHook setSourceRoot; + else + if [ -z "$sourceRoot" ]; then + for i in *; + do + if [ -d "$i" ]; then + case $dirsBefore in + *\ $i\ *) + + ;; + *) + if [ -n "$sourceRoot" ]; then + echo "unpacker produced multiple directories"; + exit 1; + fi; + sourceRoot="$i" + ;; + esac; + fi; + done; + fi; + fi; + if [ -z "$sourceRoot" ]; then + echo "unpacker appears to have produced no directories"; + exit 1; + fi; + echo "source root is $sourceRoot"; + if [ "${dontMakeSourcesWritable:-0}" != 1 ]; then + chmod -R u+w -- "$sourceRoot"; + fi; + runHook postUnpack +} +updateAutotoolsGnuConfigScriptsPhase () +{ + + if [ -n "${dontUpdateAutotoolsGnuConfigScripts-}" ]; then + return; + fi; + for script in config.sub config.guess; + do + for f in $(find . -type f -name "$script"); + do + echo "Updating Autotools / GNU config script to a newer upstream version: $f"; + cp -f "/nix/store/7lk76vdawbx478qq9lvi3mgf73rvcyhd-gnu-config-2023-09-19/$script" "$f"; + done; + done +} +updateSourceDateEpoch () +{ + + local path="$1"; + local -a res=($(find "$path" -type f -not -newer "$NIX_BUILD_TOP/.." -printf '%T@ %p\0' | sort -n --zero-terminated | tail -n1 --zero-terminated | head -c -1)); + local time="${res[0]//\.[0-9]*/}"; + local newestFile="${res[1]}"; + if [ "${time:-0}" -gt "$SOURCE_DATE_EPOCH" ]; then + echo "setting SOURCE_DATE_EPOCH to timestamp $time of file $newestFile"; + export SOURCE_DATE_EPOCH="$time"; + local now="$(date +%s)"; + if [ "$time" -gt $((now - 60)) ]; then + echo "warning: file $newestFile may be generated; SOURCE_DATE_EPOCH may be non-deterministic"; + fi; + fi +} +PATH="$PATH${nix_saved_PATH:+:$nix_saved_PATH}" +XDG_DATA_DIRS="$XDG_DATA_DIRS${nix_saved_XDG_DATA_DIRS:+:$nix_saved_XDG_DATA_DIRS}" +export NIX_BUILD_TOP="$(mktemp -d -t nix-shell.XXXXXX)" +export TMP="$NIX_BUILD_TOP" +export TMPDIR="$NIX_BUILD_TOP" +export TEMP="$NIX_BUILD_TOP" +export TEMPDIR="$NIX_BUILD_TOP" +eval "$shellHook" diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..0a722d7 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix; diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..c6f3fce --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +title = '{{ replace .File.ContentBaseName "-" " " | title }}' +date = {{ .Date }} +draft = true ++++ diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..04a9b2e --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,26 @@ +.link-auth { + background: rgb(229, 92, 0); +} + +.link-git { + background: rgb(139, 69, 19); +} + +.link-monitoring { + background: rgb(205, 55, 0); +} + +.link-legal { + background: none; + height: 1rem; + opacity: 70%; + font-size: 90%; +} + +.link-legal:hover { + text-decoration: underline; +} + +header > .rounded-full { + border-radius: 0; +} diff --git a/assets/icons/auth.svg b/assets/icons/auth.svg new file mode 100644 index 0000000..5c33af7 --- /dev/null +++ b/assets/icons/auth.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/git.svg b/assets/icons/git.svg new file mode 100644 index 0000000..d26c63c --- /dev/null +++ b/assets/icons/git.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/monitoring.svg b/assets/icons/monitoring.svg new file mode 100644 index 0000000..7d3b0fe --- /dev/null +++ b/assets/icons/monitoring.svg @@ -0,0 +1 @@ + diff --git a/config/_default/module.toml b/config/_default/module.toml new file mode 100644 index 0000000..920d1f1 --- /dev/null +++ b/config/_default/module.toml @@ -0,0 +1,2 @@ +[[imports]] +path = "github.com/jpanther/lynx" diff --git a/content/legal_notice.md b/content/legal_notice.md new file mode 100644 index 0000000..2956746 --- /dev/null +++ b/content/legal_notice.md @@ -0,0 +1,16 @@ ++++ +title = 'Legal Notice' +date = 2024-02-13T07:31:09+01:00 ++++ + +The following information is provided in accordance with § 5 TMG of German Law. + +## Contact Details +Martin Wurm +c/o Chaos Computer Club Darmstadt e. V. +Wilhelminenstraße 17 +64283 Darmstadt + +webmaster@mart-w.de + +Last changed: 13th February, 2024. diff --git a/content/privacy.md b/content/privacy.md new file mode 100644 index 0000000..1b5c0df --- /dev/null +++ b/content/privacy.md @@ -0,0 +1,261 @@ ++++ +title = 'Privacy Policy' +date = 2024-02-13T07:45:42+01:00 ++++ + +The website that brought you here is part of the Broken Tech Cloud family of +websites hosted by me, mart-w . This privacy policy explains +how those websites collect the personal data they collect from you if you +interact with them. + +## To Make it Short +I have no interest in collecting any more data about you than absolutely +necessary, and the data I do have to collect I treat with the utmost respect +for your privacy. This includes measures such as: + +* Sparse data collection. +* Regular pruning of collected data. +* Encryption. +* No sharing data with third parties whatsoever, except when it’s necessary +to provide the services you use. +* No inclusion of third-party assets like externally hosted CAPTCHA or +analytics solutions. + +You can always reach out to me to ask questions about the handling of your +personal data and to make use of your rights laid out in the EU General Data +Protection Regulation (GDPR). Please direct those requests at privacy@mart-w.de. + +## What Data Is Collected? +### Logging +When you use the services provided by me, some of your actions will be temporarily +recorded in log files together with basic, but nevertheless personally identifiable +information, such as your IP address or username. Examples of events being logged +might be: + +* You making a request against one of my webservers, in which case your IP will +be stored together with the exact time and date of your request and the requested +resource. +* You performing an action on one of my services, for example playing media, +changing sensitive settings, or trying to access resources you are not allowed to +access. In those cases a user ID that is directly linkable to you may be stored, +together with information about the event that took place. + +It is in my legitimate interest to record this logging data in order to detect +and mitigate security risks, prevent abuse of my services, and identify issues +affecting the functionality of my services. I do reserve the right to use +automated tools to detect anomalies in the log data. However, those logs will +never be reviewed manually for any other reason than the ones I just provided. + +In some cases, there can be a legitimate interest or even a legal obligation to +keep log files for an extended amount of time, for example during investigations +by national authorities or in the aftermath of a cybersecurity incident. In all +other cases, log files will be deleted automatically **after 7 days at the latest. +Due to technical limitations, some of the log files are stored unencrypted until +they are deleted. + +## Identity Data +My services make use of a central Identity Provider (IDP), which manages your +access to the various services and provides identity information to them in case +this is necessary. When you create an account, the following data about you will +be stored: + +* Your username. +* Your display name. +* Your email address. +* A unique identifier (UUID) linked to your account. +* Which groups you’re being assigned to, and, by proxy, your access rights across +my different services. +* Information about your active sessions. +* Your chosen login credentials in an undecryptably encrypted format. + +Optionally, you can provide the IDP with additional profile information which +will be stored alongside your other information. This includes data such as: + +* Your legal name. +* Your pronouns. +* Your profile picture. + +The purpose for the collection of this data is to provide a secure and consistent +login solution and to keep your profile information up-to-date across all connected +services. For that reason, this data will be retained **indefinitely** unless you +request deletion of your account and thus also forfeit your access to my other +services. + +## Application-Specific Data +Using your IDP account or even by other means, you can access a variety of +different services. In general, those services will not store any data about +you until you log into them for the first time. One exception to this rule +are services that employ federation mechanisms in order to interface with other +similar services. In those cases, it might be that you interact with my services +indirectly through another service you’re signed up to. + +### Jellyfin +Jellyfin is a media server. If you decide to make use of this service, it will +store the following information about you: + +* Profile information, including: + * Your username. + * Your unique user ID. + * What libraries you may access. + * Whether you have administrative rights. + * Optionally your profile picture. +* Your watch, read, and listen history. +* Any playlists you create. + +The mentioned profile information will largely be provided by the IDP and thus +mirror your information stored there. All information connected to your Jellyfin +account is required to provide the service, and will be retained **indefinitely** +unless you request your account to be deleted. + +### Forgejo +Forgejo ist a Git forge, i.e. a platform that can be used to store and manage +version-controlled projects and collaborate on them. If you decide to make use +of this service, it will store the following information about you: + +* Profile information, including: + * Your username. + * Your email address. + * What groups and organisations you belong to. + * What resources you have access to. + * Whether you have administrative rights. + * Optionally: + * Your legal name. + * Your biography text. + * Your website's URL. + * Your location. + * Your profile picture. + * Any additional information you choose to add to your account. +* Your repositories and all data stored in them. +* Your contributions to other repositories. +* A log of all interactions you have made with your own or other repositories. + +The mentioned profile information will largely be provided by the IDP and thus +mirror your information stored there. All information connected to your Forgejo +account is required to provide the service, and will be retained **indefinitely** +unless you request your account to be deleted. Notice that, while I can and will +delete your own repositories together with your account, **your contributions to +other projects cannot be removed and will be retained indefinitely.** This is +necessary due to the way Git functions. + +#### Federation +Forgejo supports a feature called federation, which lets you contribute to +projects hosted on different Git forges and also lets users from those forges +contribute to your projects. If you are a user of my Forgejo instance, this means +that some of your data can be shared with other forges in order to facilitate +this cross-instance collaboration. There is currently no way for you to opt out +of this. If you do not consent to your data being shared in that manner, you +cannot use my Forgejo instance at this point. + +The federation feature also implies that your data can end up stored on my forge +even if you don’t have an account on it, by means of collaborating on projects +hosted on my instance through an account you have on another instance. Again, as +noted earlier, those contributions cannot be removed due to the inner workings +of Git. If you do not consent to your data being shared with and stored on my +instance, please get into contact with the administrator of your instance, as it +is their responsibility to manage federation on their instance and inform their +users adequately about their data being shared. + +### Matrix +Matrix is a federated chat application. You cannot currently join my Matrix +instance as a user. However, similar to the case with Forgejo, the fact that +Matrix employs federation means that data related to you can end up processed +and stored on my instance. This can include, but is not limited to: + +* Your user ID. +* Your unencrypted messages, if you don’t use encryption and either text me or +are a member of a chat group that I am also a part of. +* Your encrypted messages, if you use encryption and either text me or are a +member of a chat group that I am also a part of. +* Metadata such as timestamps of your messages and what groups you are a member of. + +If you do not consent to me storing and processing your data, please reach out +to the administrator of your instance, as it is their responsibility to manage +federation on their instance and inform their users adequately about their data +being shared. Sadly, due to the way Matrix works on a technical level, I cannot +delete your data after it has been shared with my instance and it will be +retained **indefinitely.** + +## How Is Your Data Stored? +Your data is stored securely and, as far as technically possible, encrypted +on my own servers at home in Darmstadt, Germany. The applicable data retention +periods depend on both the kind of data and the service it is linked to. +Therefore, you can find information on that in the chapters relevant to the +respective services. + +### Backups +Please keep in mind that, to ensure recovery after disasters, cybersecurity +incidents, data loss due to human error or other other events, regular backups +of all stored data (except for most logs) are made and sent off-site for safe +keeping. All such backups are securely encrypted so that nobody except for me +is able to access the data. However, as a consequence of those backups existing, +it may happen that data is retained in this encrypted state for **up to one year** +after it has been superficially deleted from the live servers. + +## Marketing +Your personal information is not used for any kinds of marketing purposes. + +## Cookies +Cookies are text files placed on your computer to collect standard Internet +log information and visitor behavior information. When you visit my websites, +I may collect information from you automatically through cookies or similar technology. + +For further information, visit https://allaboutcookies.org/. + +### How Are Cookies Used? +On my services, the use of cookies is reserved only to keep session information +(i.e. keep you logged in) and to enhance the security of my services. Therefore, +all cookies that your web browser will receive from my web services are integral +to their functionality and cannot be avoided. + +### How to Manage Cookies +You can set your browser not to accept cookies, and the above website tells you +how to remove cookies from your browser. However, in a few cases, some of our +website features may not function as a result. + +## Your Rights +Under the GDPR, you are entitled to the following: + +The right to access +: You have the right to request a copy of your personal data. + +The right to rectification +: You have the right to request that I correct any information you believe is +inaccurate. You also have the right to request that I complete the information +you believe is incomplete. + +The right to erasure +: You have the right to request that I erase your peronal data, under certain +conditions. + +The right to restrict processing +: You have the right to request that I restrict the processing of your personal +data, under certain conditions. + +The right to object to processing +: You have the right to object to my processing of your personal data, under +certain conditions. + +The right to data portability +: You have the right to request that I transfer the data that I have collected +to another organisation, or directly to your, under certain conditions. + +If you make a request, I have one month to respond to you. + +## Privacy Policies of Other Websites +My websites contain links to other websites. This privacy policy applies only to +my websites, so if you click on a link to another website, you should read their +privacy policy. + +## Changes to This Privacy Policy +This privacy policy is under regular review and any updates will be placed on +this web page. This privacy policy was last updated on the 13th February, 2024. + +## How to Contact Me +If you have any questions about this privacy policy, the data I hold on you, or +you would like to exercise one of your data protection rights, please get in +touch with me. Either email me at privacy@mart-w.de or write to me at: + +Martin Wurm +c/o Chaos Computer Club Darmstadt e. V. +Wilhelminenstraße 17 +64283 Darmstadt diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..c263c4e --- /dev/null +++ b/default.nix @@ -0,0 +1,23 @@ +{pkgs ? import {}}: +with pkgs; + stdenv.mkDerivation rec { + name = "brokentech.cloud-${version}"; + version = "0.1"; + + src = ./.; + + nativeBuildInputs = [ + git + go + hugo + ]; + + buildPhase = '' + hugo + ''; + + installPhase = '' + mkdir -p $out + cp -r ./public/* $out + ''; + } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f082f26 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.brokentech.cloud/mart-w/brokentech.cloud + +go 1.21.5 + +require github.com/jpanther/lynx v1.3.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..60c803d --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/jpanther/lynx v1.3.1 h1:s3u2mC2VU8SgJ/Jlk7PbdrmLy1T63QvuwGQbvS9QqdI= +github.com/jpanther/lynx v1.3.1/go.mod h1:nUK1+IfScKhRA3/jBH+YCYfpO3znP5Nsm6ROFGpma44= diff --git a/hugo.toml b/hugo.toml new file mode 100644 index 0000000..bdb3a24 --- /dev/null +++ b/hugo.toml @@ -0,0 +1,29 @@ +baseURL = "https://brokentech.cloud/" +languageCode = "en-gb" +defaultContentLanguage = "en" + +title = "The Broken Tech Cloud" +copyright = "© 2024 mart-w" + +enableEmoji = true +disableKinds = ["taxonomy", "term"] + +[author] +name = "The Broken Tech Cloud" +headline = "Making innocent web apps cloud since 2021" +image = "logo_big.png" + +links = [ + { auth = { href = "https://accounts.brokentech.cloud", text = "Log in to stuff" } }, + { git = { href = "https://git.brokentech.cloud", text = "Look at some code" } }, + { monitoring = { href = "https://status.brokentech.cloud", text = "See what’s most broken" } }, + { link = { href = "https://mart-w.de/", text = "Read up on the admin" } }, + { mastodon = { href = "https://chaos.social/@mart_w", text = "Yell at the admin" } }, + { legal = { href = "/legal_notice", text = "Legal Notice" } }, + { legal = { href = "/privacy", text = "Privacy Policy" } }, +] + +[module] +[module.hugoVersion] +extended = false +min = "0.86.1" diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..56d2ab585102d95614e51d208320b24503368e45 GIT binary patch literal 1042 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;U~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+dJZrCMwG$^;5e1k8Q&fc;U#>VOumg<%<24?el1pK)ozk{uRY>sZ2>6& zPgy9>9w!Hmy)zv4pV3M7n>6W##lCkBAHR;Bl3r@}{W-@<%Wg)yi5ACrF00*Bn0Ipv z@44Sc62qp1J}Q1xI9bo*&xz8bkIm1qPG_AbX?A&KAp6)pssU05qdETGagLC$6I#W7J*&{*FdxCked(1lqXaBaGQ|q2A*L?E%z;DUgU@?h3tiP`9xi{;# zMJ>anE1{p*EG$@#aZTBK@8MnBw|oCqFS~i4znrURMaiS9%)n@2OY(Mi0n!W%|F1ZP zd;-#(1s;*b3=G`DAk4@xYmNj^kiEpy*OmPR6ECN^fDMPSE&~G-zo(01NX4zUcTcZv zHV|=e?6@Okx}zaLOyq%q@MQ6XF@fX zF1r5Wv}RfglLLbSg8%~u0}BHa17ib&1H*;c6MnPr+--Y$lf~&j%CD(Yu_79y|)yr*H^fGu2!07{bkLy@?IZ? jJ4}t}0RWCu5V62WKGE4sq^hc}6~y&)^>bP0l+XkKu)Ju7 literal 0 HcmV?d00001 diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..d1efd00d9d90fcb3e212ac07231aed4ca16b66ab GIT binary patch literal 2349 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe)8TQZ%U13aCb6$*;-(=u~X z85lGs)=sqbIP4&EG(LE#)>^(Yfx;63bKg8*e-yDgpoME;SjN?ZPcG?aT$-?ChXvO< zR(5-_)qHyAc3JJm)mA~ z9XaY#7Rs~7$$?|<42S(^bdvohO?qLm@7=@4uVbgAm)d=Q&au+6o6&Bf#W9}CYWEc8 z-Q2=^?)QvsyZc6*=x05SF6a|Te3D-Okxk~uWNhm z&H8Oo%W&yR=qEM{3zlPCQ}*6_c-Qvr-oMq$Zryxm=ZGy}u` zD~=(bfHY@;M`SSr1Gg{;GcwGYBLNg-FY)wsWq-lM%W1*0eq!-jpoo^Ii(^Q|t+zKC zGY>oPI9yzDCu^P~vq`cgbB0%Gi`voxnW}uo<4#B9ZRJ45Qvg2fo?+K;CMTQ0z(2J2 zA6s1{BZB|~Lj%x676t|dAjQbQz`?-a0Av9Z9DXTMl>fMM>o2p>=5o9LyY!+N3@%@L z?;qOAjn_(IozVbvD~jVWTrHC(c`)w$^X-ZZ%6Gq?7Kj0A!0k;3pe#YJHvko(*a_5y zA@)G$G)LO&d%yp1ywCstX8zy9tT;myLod)g;#|R)z=9cX7DtSlZYq7V+h6_d_ig*% z?0Q&Shp<5bXczAAz$1k)q5)_GFgyw-q_S)-eP3JG@_l>#xAXrV0s|69G-Bvg02)Dz zD;gLKm@pHjOp@fm9Kn0?pTGax0W^p@5lFy|`H^l6ze~>7{pYY|pl1mCT-*Eor{J^v ze-CI7yr7^%PuUE|Bis(82&N_AvynjLkr*R;GJ#q4`(Gm#20XbHN75qT5}+=O5&|gp zfW@$uVdl+i3<>jAN&V$50j5P_k|WlnMuKM>>^YPZHl4`{p0Rq>ANEJMW0ZhvNU#!Q z(jNVugl#}u8)mLLWqts6!GzU&h;YY9DfpcM%$bychX3D~cTTi$kq*2Js&5%QUHx3v IIVCg!0EHuzV*mgE literal 0 HcmV?d00001 diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dcc0965927ddcd5c0288dd862e45bae43990f865 GIT binary patch literal 2349 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe)8TQZ%U13aCb6$*;-(=u~X z85lGs)=sqbIP4&EG(LE#)>^(Yfx;63bKg8*e-yDgpoME;SjN?ZPcG?aT$-?ChXvO< zR(5-_)qHyAc3JJm)mA~ z9XaY#7Rs~7$$?|<42S(^bdvohO?qLm@7=@4uVbgAm)d=Q&au+6o6&Bf#W9}CYWEc8 z-Q2=^?)QvsyZc6*=x05SF6a|Te3D-Okxk~uWNhm z&H8Oo%W&yR=qEM{3zlPCQ}*6_c-Qvr-oMq$Zryxm=ZGy}u` zD~=(bfHY@;M`SSr1Gg{;GcwGYBLNg-FY)wsWq-lM%V{AM?RxAFP(;hq#WAGf*4rD6 znTH*C94@Z7lQqwg*(BMLIm4^8MQv$;OjSPPai=5lwsIijDF7dK&#-GalatM0;2+xi zkF73}kwJigp#f+j3j>1!kYZ$D;9y{I0J4Ay4!;yB%75Is^_SUbbGhCBU3$?B2A8kB z_YZC5#%m?9&S(I-6~*xwu9iuYJQ#QW`F2GH<-6Zc3&a35;P$2iP?n(A8-R*X>;&q< z5PP6=nj`J?z2AR0-sk^+Gym^lR-7SH)Q}9{- zzXvo3UQp1Xr)-Af5pD-k1k)1m*+?MrNQ{v^nZPXj{jU)V1D@Q9BWV$E2~ZbC2>}#) zz+za-F!Sa$hJ<;mr2g`j0MjBd$q{Q(Bf+x`_8iIyo6h6}&se?c5BnqBF-pKSBv=VD zX^(zS!Zx6-4Kr7rGCzR3V8ZG>M7U$56#UKr=1fXJ!~bv0J11JWNC#d9)wc|uu6{1- HoD!M<_)3&> literal 0 HcmV?d00001 diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..6d35fcb10224e16cca16c154de4edb0f684f0f93 GIT binary patch literal 642 zcmV-|0)737P)EX>4Tx04R}tkv&MmKpe$iQ>7}c4t5Z6$WWc^;0NMZt5Adrp;l;vxAeOiU6f~aKKJJcsX2=QK9M-a4AUmwAfDN@ z4bJ<-VOEq?;&bA0lP*a7$aTfzH_io@1)do;)2VslFtJ!@W2KE*(bR~ii6g3}Q@)V# zSmnIMSu0mr^Pc>L!JNLb%ypV0NMI35kRU=q6(y8mBTB1IiiH&I$2<6kUB5&wg=bb;{@U#SDLpQP7X zTI2{A*aj}HTbi;5TgF`bEpEsfnQH+W`%qu&Pfp3tkv_WRpcrf_XwHBf@5 cBrNE4t*xat!hb94J^%m!07*qoM6N<$f>b#d@c;k- literal 0 HcmV?d00001 diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..8fa5bf7d2f1b6721304278a9250df318439b8106 GIT binary patch literal 676 zcmV;V0$crwP)EX>4Tx04R}tkv&MmKpe$iQ>7}c4t5Z6$WWc^;0NMZt5Adrp;l;vxAeOiU6f~aKKJJcsX2=QK9M-a4AUmwAfDN@ z4bJ<-VOEq?;&bA0lP*a7$aTfzH_io@1)do;)2VslFtJ!@W2KE*(bR~ii6g3}Q@)V# zSmnIMSu0mr^Pc>L!JNLb%ypV0NMI35kRU=q6(y8mBTB1IiiH&I$2<6kUB5&wg=bb;{@U#SDLpQP7X zTI2{A*aj}HTbi;5TgF&TAS8CkIt-Fw7^wqPN^KJQL!yp+j_-1p1ZcQI2#gO* z4KM(h$Uu&y@>j?##2ArMLe6skVg2Dr9HxjYcgyQQzl@sOO5KW@7p-}BGt~`n>FH}< aowL@t=e2tBy8}Kmu(NgJ|L;&|)%ykX3?%pf literal 0 HcmV?d00001 diff --git a/static/logo_big.png b/static/logo_big.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa94d17680f71ef4b52ff792782bb07fc730884 GIT binary patch literal 39900 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 M*t-5sQ1qGq0|ThXy8r+H literal 0 HcmV?d00001