summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2024-10-19 10:04:14 +0200
committerDaniel Weipert <git@mail.dweipert.de>2024-10-19 10:04:14 +0200
commitac93ed4d29dd85409fb4c0cd9c2af266e90777c1 (patch)
tree6a0b4487439bfe068d4b7d412be70d4f90faa2a5
initial commitHEADmain
-rw-r--r--CLI/mysql_db.sh25
-rw-r--r--CLI/reduce-image-sizes.sh36
-rw-r--r--WP/plugin-deploy-script-for-wp-org.php44
-rw-r--r--WP/search-by-title-with-wp-query.php11
-rw-r--r--docker-mailserver-sieve-validation.sh9
-rw-r--r--docker/docker-compose-update-all-running-projects22
-rw-r--r--google-docs-bibliografie-und-abbildungsverzeichnis.js103
-rw-r--r--nix/nix-shell-with-php-composer-nodejs-npm-mysql.nix30
-rw-r--r--refind.conf680
-rw-r--r--stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md320
-rw-r--r--use-sylius-with-homestead-instructions.md31
-rw-r--r--vagrant-bento-box-with-mongodb.Vagrantfile63
12 files changed, 1374 insertions, 0 deletions
diff --git a/CLI/mysql_db.sh b/CLI/mysql_db.sh
new file mode 100644
index 0000000..e5acfb3
--- /dev/null
+++ b/CLI/mysql_db.sh
@@ -0,0 +1,25 @@
+# dump
+mysqldump -p -u $user $db > $db.sql
+
+# dump with prefix (https://stackoverflow.com/a/26514699/6114451)
+mysqldump -p -u $user $db $(mysql -p -u $user -D $db -Bse "show tables like '$prefix%'") > $prefix.sql
+# with date
+$(date +"%Y%m%d_%H%M")
+
+# restore
+mysql -p -u $user $db < $db.sql
+wp db import $db.sql
+
+# wp search-replace
+wp search-replace "$search" "$replace" --recurse-objects --all-tables --dry-run --export=db.sql
+# with date
+--export="db$(date +"%Y%m%d_%H%M").sql"
+
+
+# Unicode Fuckups
+# set locale pre-export/import to circumvent
+export LANG=de_DE.UTF-8
+export LC_ALL=de_DE.UTF-8
+# Links
+https://www.ecosia.org/search?q=mysql%20restore%20db%20unicode
+https://makandracards.com/makandra/595-dumping-and-importing-from-to-mysql-in-an-utf-8-safe-way
diff --git a/CLI/reduce-image-sizes.sh b/CLI/reduce-image-sizes.sh
new file mode 100644
index 0000000..3bad2a2
--- /dev/null
+++ b/CLI/reduce-image-sizes.sh
@@ -0,0 +1,36 @@
+# mogrify -resize 3840x2160 *.jpg
+
+# jpeg to jpg
+find . -type f -iregex ".*\.jpe?g" -exec mogrify -format jpg {} \;
+
+# resize everything to max 4k
+# TODO: also scales up... but shouldn't!
+find . -type f -regextype posix-extended -iregex ".*\.(png|jpe?g|gif|webp)" -exec mogrify -resize 3840x2160 {} \;
+find . -type f -regextype posix-extended -iregex ".*\.(png|jpe?g|gif|webp)" -exec mogrify -resize 1920x1080 {} \;
+find . -type f -regextype posix-extended -iregex ".*\.(png|jpe?g|gif|webp)" -exec mogrify -resize 1200x675 {} \;
+
+# optimize jpg
+find . -type f -iregex ".*\.jpe?g" -exec jpegoptim --strip-all {} \;
+find . -type f -iname "*.jpg" -exec jpegoptim --strip-all {} \;
+
+# optimize png
+find . -type f -iname "*.png" -exec optipng -o5 {} \;
+
+# convert to webp
+find . -type f -regextype posix-extended -iregex ".*\.(png|jpe?g)" -exec convert {} -quality 90 -define webp:lossless=true $(echo {} | cut -d . -f 1).webp \;
+
+# add border to image
+convert $img.png -background none -bordercolor none -border 20 $img.png
+
+# square image for favicon
+# order of things is important
+convert $img -background none -thumbnail 64x64^ -gravity center -extent ${longestside}x${x} $img
+
+# crop image to size - from center
+# https://www.imagemagick.org/discourse-server/viewtopic.php?t=13793
+convert $img -resize 1200x900^ -gravity center -crop 1200x900+0+0 $img
+
+# svg to png
+convert -scale ${x}x${y} -extent 110%x110% -gravity center -background transparent $svg $png
+# https://stackoverflow.com/a/12690135
+convert -density 1200 -resize 200x -background none $svg $png
diff --git a/WP/plugin-deploy-script-for-wp-org.php b/WP/plugin-deploy-script-for-wp-org.php
new file mode 100644
index 0000000..3b66d49
--- /dev/null
+++ b/WP/plugin-deploy-script-for-wp-org.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+
+<?php
+
+$pluginSourcePath = $argv[1] ?? die('source path missing');
+$svnDestinationPath = $argv[2] ?? die('desination path missing');
+
+$pluginSourcePath = realpath($pluginSourcePath) ?: die('source path doesn\'t exist');
+$svnDestinationPath = realpath($svnDestinationPath) ?: die('desination path doesn\'t exist');
+
+if (! file_exists("$pluginSourcePath/composer.json")) {
+ die('plugin is missing a composer.json file');
+}
+if (! is_dir("$svnDestinationPath/.svn")) {
+ die('desination is not a svn repository. initialize it with "svn co https://plugins.svn.wordpress.org/your-plugin" first');
+}
+
+// get composer info
+$composer = json_decode(file_get_contents("$pluginSourcePath/composer.json"));
+
+// set files into deployable state
+chdir($pluginSourcePath);
+exec('composer install --no-dev');
+exec('npm run build'); # if wp-scripts is used # TODO: how to use with .nvmrc?
+
+// bundling deployable files
+exec('composer archive -f zip');
+$zipFilenames = glob('*.zip');
+$zipFilename = $zipFilenames[array_key_last($zipFilenames)];
+exec("unzip $pluginSourcePath/$zipFilename -d $svnDestinationPath/$zipFilename");
+
+// copying files to svn trunk folder
+chdir($svnDestinationPath);
+exec("rsync -av $svnDestinationPath/$zipFilename/ $svnDestinationPath/trunk --delete");
+
+// copy new version to tags
+exec('svn cp trunk tags/' . $composer->version);
+
+// commit
+exec("svn commit -m 'updating to v{$composer->version}'");
+
+// clean up files
+unlink("$pluginSourcePath/$zipFilename");
+exec("rm -rf $svnDestinationPath/$zipFilename"); # feeling dangerous
diff --git a/WP/search-by-title-with-wp-query.php b/WP/search-by-title-with-wp-query.php
new file mode 100644
index 0000000..418f057
--- /dev/null
+++ b/WP/search-by-title-with-wp-query.php
@@ -0,0 +1,11 @@
+<?php
+
+// Add posts_where filter for title_like
+add_filter('posts_where', function ($where, \WP_Query $wp_query) {
+ if ($title = $wp_query->get('title_like')) {
+ global $wpdb;
+ $where .= " AND {$wpdb->posts}.post_title LIKE '" . esc_sql($wpdb->esc_like($title)) . "'";
+ }
+
+ return $where;
+}, 10, 2);
diff --git a/docker-mailserver-sieve-validation.sh b/docker-mailserver-sieve-validation.sh
new file mode 100644
index 0000000..3fa6424
--- /dev/null
+++ b/docker-mailserver-sieve-validation.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+SIEVE_ROOT=$(docker compose exec mailserver bash -c "ls /tmp/docker-mailserver/*.dovecot.sieve");
+SIEVE_INCLUDE=$(docker compose exec mailserver bash -c "ls /tmp/docker-mailserver/sieve-include/*.sieve")
+FILES=$(echo $SIEVE_ROOT; echo $SIEVE_INCLUDE)
+
+for file in $FILES; do
+ docker compose exec mailserver sievec "${file}"
+done
diff --git a/docker/docker-compose-update-all-running-projects b/docker/docker-compose-update-all-running-projects
new file mode 100644
index 0000000..6d6d899
--- /dev/null
+++ b/docker/docker-compose-update-all-running-projects
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+import sys, os
+import subprocess
+
+
+process_docker_ps = subprocess.run(['docker', 'ps', '-q'], stdout=subprocess.PIPE)
+
+container_ids = process_docker_ps.stdout.decode('utf-8').split('\n')
+
+docker_compose_project_paths = []
+for id in container_ids:
+ if id:
+ process_docker_inspect = subprocess.run(['docker', 'inspect', '--format', '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}', id], stdout=subprocess.PIPE)
+ docker_compose_project_paths.append(process_docker_inspect.stdout.decode('utf-8').strip())
+
+docker_compose_project_paths = set(docker_compose_project_paths)
+
+for path in docker_compose_project_paths:
+ subprocess.run(['docker-compose', 'down'], cwd=path)
+ subprocess.run(['docker-compose', 'pull'], cwd=path)
+ subprocess.Popen(['docker-compose', 'up', '-d'], cwd=path)
diff --git a/google-docs-bibliografie-und-abbildungsverzeichnis.js b/google-docs-bibliografie-und-abbildungsverzeichnis.js
new file mode 100644
index 0000000..5070948
--- /dev/null
+++ b/google-docs-bibliografie-und-abbildungsverzeichnis.js
@@ -0,0 +1,103 @@
+function onOpen() {
+ DocumentApp.getUi().createMenu('Verzeichnis-Tools')
+ .addItem('Bibliografie bauen', 'buildBibliografie')
+ .addItem('Abbildungsverzeichnis bauen', 'buildAbbildungsverzeichnis')
+ .addToUi();
+}
+
+function buildBibliografie() {
+ var document = DocumentApp.getActiveDocument();
+ var body = document.getBody();
+
+ var footnotes = document.getFootnotes();
+ var footnotesArray = [];
+ for (var idx in footnotes) {
+ var footnote = footnotes[idx].getFootnoteContents();
+
+ footnotesArray.push(footnote.getText().replace(/^\s?(Vgl\. )?/, ''));
+ }
+
+ footnotesArray.sort();
+
+ var resultText = '';
+ for (var idx in footnotesArray) {
+ resultText += (footnotesArray[idx] + '\n\n');
+ }
+
+ getLastParagraph().appendText('\n\n---Bibliografie-beep-boop---\n\n' + resultText + '---Bibliografie-beep-boop---\n\n');
+}
+
+function buildAbbildungsverzeichnis() {
+ var document = DocumentApp.getActiveDocument();
+ var body = document.getBody();
+
+ var images = getImages();
+ var resultText = '';
+ for (var idx in images) {
+ var image = images[idx];
+
+ resultText += (image.footNote.getText() + '\n\n');
+ }
+
+ getLastParagraph().appendText('\n\n---Abbildungsverzeichnis-beep-boop---\n\n' + resultText + '---Abbildungsverzeichnis-beep-boop---\n\n');
+}
+
+function getImages() {
+ var document = DocumentApp.getActiveDocument();
+ var body = document.getBody();
+
+ var images = body.getImages();
+ var result = [];
+
+ for (var idx in images) {
+ var image = images[idx];
+ var footNote = getFootNote(image);
+ var pageNumber = getPageNumber(image);
+
+ result.push({
+ image,
+ footNote,
+ pageNumber,
+ });
+ }
+
+ return result;
+}
+
+function getFootNote(image) {
+ var paragraph = getImmediateElement(image, DocumentApp.ElementType.PARAGRAPH);
+
+ return paragraph.editAsText();
+}
+
+function getPageNumber(element) {
+ return '00';
+}
+
+function getRangeElement(element) {
+ var document = DocumentApp.getActiveDocument();
+
+ var range = document.newRange();
+ range.addElement(element);
+ range.build();
+ var rangeElements = range.getRangeElements();
+
+ return rangeElements[0];
+}
+
+function getImmediateElement(element, elementType) {
+ var document = DocumentApp.getActiveDocument();
+ var body = document.getBody();
+
+ var foundElement = body.findElement(elementType, getRangeElement(element));
+
+ return foundElement.getElement();
+}
+
+function getLastParagraph() {
+ var document = DocumentApp.getActiveDocument();
+ var body = document.getBody();
+ var paragraphs = body.getParagraphs();
+
+ return paragraphs[paragraphs.length - 1];
+}
diff --git a/nix/nix-shell-with-php-composer-nodejs-npm-mysql.nix b/nix/nix-shell-with-php-composer-nodejs-npm-mysql.nix
new file mode 100644
index 0000000..27249eb
--- /dev/null
+++ b/nix/nix-shell-with-php-composer-nodejs-npm-mysql.nix
@@ -0,0 +1,30 @@
+with (import <nixpkgs> {});
+mkShell {
+ buildInputs = [
+ php
+ phpPackages.composer
+ nodejs
+ mysql80
+ ];
+
+ shellHook = ''
+ MYSQL_DIR=$(pwd)/.nix/mysql
+ MYSQL_SOCKET=$(pwd)/.nix/mysql/mysql.sock
+ MYSQL_ROOT_PASSWORD=123456
+
+ export MYSQL_UNIX_PORT=$MYSQL_SOCKET
+
+ if [ ! -d $MYSQL_DIR ]; then
+ mysqld --initialize-insecure --datadir=$MYSQL_DIR
+ fi
+
+ if ! mysqladmin status --user=root -p$MYSQL_ROOT_PASSWORD; then
+ mysqld --datadir=$MYSQL_DIR --skip-networking &
+
+ sleep 3
+ if ! mysql --user=root -p$MYSQL_ROOT_PASSWORD >> "SELECT 1"; then
+ mysql --user=root <<< "ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';"
+ fi
+ fi
+ '';
+}
diff --git a/refind.conf b/refind.conf
new file mode 100644
index 0000000..b4fd858
--- /dev/null
+++ b/refind.conf
@@ -0,0 +1,680 @@
+#
+# refind.conf
+# Configuration file for the rEFInd boot menu
+#
+
+# Timeout in seconds for the main menu screen. Setting the timeout to 0
+# disables automatic booting (i.e., no timeout). Setting it to -1 causes
+# an immediate boot to the default OS *UNLESS* a keypress is in the buffer
+# when rEFInd launches, in which case that keypress is interpreted as a
+# shortcut key. If no matching shortcut is found, rEFInd displays its
+# menu with no timeout.
+#
+timeout 3
+
+# Normally, when the timeout period has passed, rEFInd boots the
+# default_selection. If the following option is uncommented, though,
+# rEFInd will instead attempt to shut down the computer.
+# CAUTION: MANY COMPUTERS WILL INSTEAD HANG OR REBOOT! Macs and more
+# recent UEFI-based PCs are most likely to work with this feature.
+# Default value is true
+#
+#shutdown_after_timeout
+
+# Whether to store rEFInd's rEFInd-specific variables in NVRAM (1, true,
+# or on) or in files in the "vars" subdirectory of rEFInd's directory on
+# disk (0, false, or off). Using NVRAM works well with most computers;
+# however, it increases wear on the motherboard's NVRAM, and if the EFI
+# is buggy or the NVRAM is old and worn out, it may not work at all.
+# Storing variables on disk is a viable alternative in such cases, or
+# if you want to minimize wear and tear on the NVRAM; however, it won't
+# work if rEFInd is stored on a filesystem that's read-only to the EFI
+# (such as an HFS+ volume), and it increases the risk of filesystem
+# damage. Note that this option affects ONLY rEFInd's own variables,
+# such as the PreviousBoot, HiddenTags, HiddenTools, and HiddenLegacy
+# variables. It does NOT affect Secure Boot or other non-rEFInd
+# variables.
+# Default is true
+#
+#use_nvram false
+
+# Screen saver timeout; the screen blanks after the specified number of
+# seconds with no keyboard input. The screen returns after most keypresses
+# (unfortunately, not including modifier keys such as Shift, Control, Alt,
+# or Option). Setting a value of "-1" causes rEFInd to start up with its
+# screen saver active. The default is 0, which disables the screen saver.
+#
+#screensaver 300
+
+# Hide user interface elements for personal preference or to increase
+# security:
+# banner - the rEFInd title banner (built-in or loaded via "banner")
+# label - boot option text label in the menu
+# singleuser - remove the submenu options to boot macOS in single-user
+# or verbose modes; affects ONLY macOS
+# safemode - remove the submenu option to boot macOS in "safe mode"
+# hwtest - the submenu option to run Apple's hardware test
+# arrows - scroll arrows on the OS selection tag line
+# hints - brief command summary in the menu
+# editor - the options editor (+, F2, or Insert on boot options menu)
+# badges - device-type badges for boot options
+# all - all of the above
+# Default is none of these (all elements active)
+#
+#hideui singleuser
+#hideui all
+
+# Set the name of a subdirectory in which icons are stored. Icons must
+# have the same names they have in the standard directory. The directory
+# name is specified relative to the main rEFInd binary's directory. If
+# an icon can't be found in the specified directory, an attempt is made
+# to load it from the default directory; thus, you can replace just some
+# icons in your own directory and rely on the default for others.
+# Icon files may be in any supported format -- ICNS (*.icns), BMP (*.bmp),
+# PNG (*.png), or JPEG (*.jpg or *.jpeg); however, rEFInd's BMP and JPEG
+# implementations do not support transparency, which is highly desirable
+# in icons.
+# Default is "icons".
+#
+#icons_dir myicons
+#icons_dir icons/snowy
+
+# Use a custom title banner instead of the rEFInd icon and name. The file
+# path is relative to the directory where refind.efi is located. The color
+# in the top left corner of the image is used as the background color
+# for the menu screens. Currently uncompressed BMP images with color
+# depths of 24, 8, 4 or 1 bits are supported, as well as PNG and JPEG
+# images. (ICNS images can also be used, but ICNS has limitations that
+# make it a poor choice for this purpose.) PNG and JPEG support is
+# limited by the underlying libraries; some files, like progressive JPEGs,
+# will not work.
+#
+#banner hostname.bmp
+#banner mybanner.jpg
+#banner icons/snowy/banner-snowy.png
+
+# Specify how to handle banners that aren't exactly the same as the screen
+# size:
+# noscale - Crop if too big, show with border if too small
+# fillscreen - Fill the screen
+# Default is noscale
+#
+#banner_scale fillscreen
+
+# Icon sizes. All icons are square, so just one value is specified. The
+# big icons are used for OS selectors in the first row and the small
+# icons are used for tools on the second row. Drive-type badges are 1/4
+# the size of the big icons. Legal values are 32 and above. If the icon
+# files do not hold icons of the proper size, the icons are scaled to
+# the specified size. The default values are 48 and 128 for small and
+# big icons, respectively.
+#
+#small_icon_size 96
+#big_icon_size 256
+
+# Custom images for the selection background. There is a big one (144 x 144)
+# for the OS icons, and a small one (64 x 64) for the function icons in the
+# second row. If only a small image is given, that one is also used for
+# the big icons by stretching it in the middle. If only a big one is given,
+# the built-in default will be used for the small icons. If an image other
+# than the optimal size is specified, it will be scaled in a way that may
+# be ugly.
+#
+# Like the banner option above, these options take a filename of an
+# uncompressed BMP, PNG, JPEG, or ICNS image file with a color depth of
+# 24, 8, 4, or 1 bits. The PNG or ICNS format is required if you need
+# transparency support (to let you "see through" to a full-screen banner).
+#
+#selection_big selection-big.bmp
+#selection_small selection-small.bmp
+
+# Set the font to be used for all textual displays in graphics mode.
+# For best results, the font must be a PNG file with alpha channel
+# transparency. It must contain ASCII characters 32-126 (space through
+# tilde), inclusive, plus a glyph to be displayed in place of characters
+# outside of this range, for a total of 96 glyphs. Only monospaced fonts
+# are supported. Fonts may be of any size, although large fonts can
+# produce display irregularities.
+# The default is rEFInd's built-in font, Luxi Mono Regular 12 point.
+#
+#font myfont.png
+
+# Use text mode only. When enabled, this option forces rEFInd into text mode.
+# Passing this option a "0" value causes graphics mode to be used. Pasing
+# it no value or any non-0 value causes text mode to be used.
+# Default is to use graphics mode.
+#
+#textonly
+
+# Set the EFI text mode to be used for textual displays. This option
+# takes a single digit that refers to a mode number. Mode 0 is normally
+# 80x25, 1 is sometimes 80x50, and higher numbers are system-specific
+# modes. Mode 1024 is a special code that tells rEFInd to not set the
+# text mode; it uses whatever was in use when the program was launched.
+# If you specify an invalid mode, rEFInd pauses during boot to inform
+# you of valid modes.
+# CAUTION: On VirtualBox, and perhaps on some real computers, specifying
+# a text mode and uncommenting the "textonly" option while NOT specifying
+# a resolution can result in an unusable display in the booted OS.
+# Default is 1024 (no change)
+#
+#textmode 2
+
+# Set the screen's video resolution. Pass this option either:
+# * two values, corresponding to the X and Y resolutions
+# * one value, corresponding to a GOP (UEFI) video mode
+# Note that not all resolutions are supported. On UEFI systems, passing
+# an incorrect value results in a message being shown on the screen to
+# that effect, along with a list of supported modes. On EFI 1.x systems
+# (e.g., Macintoshes), setting an incorrect mode silently fails. On both
+# types of systems, setting an incorrect resolution results in the default
+# resolution being used. A resolution of 1024x768 usually works, but higher
+# values often don't.
+# Default is "0 0" (use the system default resolution, usually 800x600).
+#
+#resolution 1024 768
+#resolution 1440 900
+#resolution 3
+
+# Enable touch screen support. If active, this feature enables use of
+# touch screen controls (as on tablets). Note, however, that not all
+# tablets' EFIs provide the necessary underlying support, so this
+# feature may not work for you. If it does work, you should be able
+# to launch an OS or tool by touching it. In a submenu, touching
+# anywhere launches the currently-selection item; there is, at present,
+# no way to select a specific submenu item. This feature is mutually
+# exclusive with the enable_mouse feature. If both are uncommented,
+# the one read most recently takes precedence.
+#
+#enable_touch
+
+# Enable mouse support. If active, this feature enables use of the
+# computer's mouse. Note, however, that not all computers' EFIs
+# provide the necessary underlying support, so this feature may not
+# work for you. If it does work, you should be able to launch an
+# OS or tool by clicking it with the mouse pointer. This feature
+# is mutually exclusive with the enable_touch feature. If both
+# are uncommented, the one read most recently takes precedence.
+#
+#enable_mouse
+
+# Size of the mouse pointer, in pixels, per side.
+# Default is 16
+#
+#mouse_size
+
+# Speed of mouse tracking. Higher numbers equate to faster
+# mouse movement. This option requires that enable_mouse be
+# uncommented.
+# Legal values are between 1 and 32. Default is 4.
+#
+#mouse_speed 4
+
+# Launch specified OSes in graphics mode. By default, rEFInd switches
+# to text mode and displays basic pre-launch information when launching
+# all OSes except macOS. Using graphics mode can produce a more seamless
+# transition, but displays no information, which can make matters
+# difficult if you must debug a problem. Also, on at least one known
+# computer, using graphics mode prevents a crash when using the Linux
+# kernel's EFI stub loader. You can specify an empty list to boot all
+# OSes in text mode.
+# Valid options:
+# osx - macOS
+# linux - A Linux kernel with EFI stub loader
+# elilo - The ELILO boot loader
+# grub - The GRUB (Legacy or 2) boot loader
+# windows - Microsoft Windows
+# Default value: osx
+#
+#use_graphics_for osx,linux
+
+# Which non-bootloader tools to show on the tools line, and in what
+# order to display them:
+# shell - the EFI shell (requires external program; see rEFInd
+# documentation for details)
+# memtest - the memtest86 program, in EFI/tools, EFI/memtest86,
+# EFI/memtest, EFI/tools/memtest86, or EFI/tools/memtest
+# gptsync - the (dangerous) gptsync.efi utility (requires external
+# program; see rEFInd documentation for details)
+# gdisk - the gdisk partitioning program
+# apple_recovery - boots the Apple Recovery HD partition, if present
+# windows_recovery - boots an OEM Windows recovery tool, if present
+# (see also the windows_recovery_files option)
+# mok_tool - makes available the Machine Owner Key (MOK) maintenance
+# tool, MokManager.efi, used on Secure Boot systems
+# csr_rotate - adjusts Apple System Integrity Protection (SIP)
+# policy. Requires "csr_values" to be set.
+# install - an option to install rEFInd from the current location
+# to another ESP
+# bootorder - adjust the EFI's (NOT rEFInd's) boot order
+# about - an "about this program" option
+# hidden_tags - manage hidden tags
+# exit - a tag to exit from rEFInd
+# shutdown - shuts down the computer (a bug causes this to reboot
+# many UEFI systems)
+# reboot - a tag to reboot the computer
+# firmware - a tag to reboot the computer into the firmware's
+# user interface (ignored on older computers)
+# fwupdate - a tag to update the firmware; launches the fwupx64.efi
+# (or similar) program
+# netboot - launch the ipxe.efi tool for network (PXE) booting
+# Default is shell,memtest,gdisk,apple_recovery,windows_recovery,mok_tool,about,hidden_tags,shutdown,reboot,firmware,fwupdate
+#
+#showtools shell, bootorder, gdisk, memtest, mok_tool, apple_recovery, windows_recovery, about, hidden_tags, reboot, exit, firmware, fwupdate
+
+# Tool binaries to be excluded from the tools line, even if the
+# general class is specified in showtools. This enables trimming an
+# overabundance of tools, as when you see multiple mok_tool entries
+# after installing multiple Linux distributions.
+# Just as with dont_scan_files, you can specify a filename alone, a
+# full pathname, or a volume identifier (filesystem label, partition
+# name, or partition GUID) and a full pathname.
+# Default is an empty list (nothing is excluded)
+#
+#dont_scan_tools ESP2:/EFI/ubuntu/mmx64.efi,gptsync_x64.efi
+
+# Boot loaders that can launch a Windows restore or emergency system.
+# These tend to be OEM-specific.
+# Default is LRS_ESP:/EFI/Microsoft/Boot/LrsBootmgr.efi
+#
+#windows_recovery_files LRS_ESP:/EFI/Microsoft/Boot/LrsBootmgr.efi
+
+# Directories in which to search for EFI drivers. These drivers can
+# provide filesystem support, give access to hard disks on plug-in
+# controllers, etc. In most cases none are needed, but if you add
+# EFI drivers and you want rEFInd to automatically load them, you
+# should specify one or more paths here. rEFInd always scans the
+# "drivers" and "drivers_{arch}" subdirectories of its own installation
+# directory (where "{arch}" is your architecture code); this option
+# specifies ADDITIONAL directories to scan.
+# Default is to scan no additional directories for EFI drivers
+#
+#scan_driver_dirs EFI/tools/drivers,drivers
+
+# Which types of boot loaders to search, and in what order to display them:
+# internal - internal EFI disk-based boot loaders
+# external - external EFI disk-based boot loaders
+# optical - EFI optical discs (CD, DVD, etc.)
+# netboot - EFI network (PXE) boot options
+# hdbios - BIOS disk-based boot loaders
+# biosexternal - BIOS external boot loaders (USB, eSATA, etc.)
+# cd - BIOS optical-disc boot loaders
+# manual - use stanzas later in this configuration file
+# Note that the legacy BIOS options require firmware support, which is
+# not present on all computers.
+# The netboot option is experimental and relies on the ipxe.efi and
+# ipxe_discover.efi program files.
+# On UEFI PCs, default is internal,external,optical,manual
+# On Macs, default is internal,hdbios,external,biosexternal,optical,cd,manual
+#
+#scanfor internal,external,optical,manual
+#scanfor manual,external,optical,hdbios,biosexternal,cd,netboot
+scanfor manual,external,optical
+
+# By default, rEFInd relies on the UEFI firmware to detect BIOS-mode boot
+# devices. This sometimes doesn't detect all the available devices, though.
+# For these cases, uefi_deep_legacy_scan results in a forced scan and
+# modification of NVRAM variables on each boot. Adding "0", "off", or
+# "false" resets to the default value. This token has no effect on Macs or
+# when no BIOS-mode options are set via scanfor.
+# Default is unset (or "uefi_deep_legacy_scan false")
+#
+#uefi_deep_legacy_scan
+
+# Delay for the specified number of seconds before scanning disks.
+# This can help some users who find that some of their disks
+# (usually external or optical discs) aren't detected initially,
+# but are detected after pressing Esc.
+# The default is 0.
+#
+#scan_delay 5
+
+# When scanning volumes for EFI boot loaders, rEFInd always looks for
+# macOS's and Microsoft Windows' boot loaders in their normal locations,
+# and scans the root directory and every subdirectory of the /EFI directory
+# for additional boot loaders, but it doesn't recurse into these directories.
+# The also_scan_dirs token adds more directories to the scan list.
+# Directories are specified relative to the volume's root directory. This
+# option applies to ALL the volumes that rEFInd scans UNLESS you include
+# a volume name and colon before the directory name, as in "myvol:/somedir"
+# to scan the somedir directory only on the filesystem named myvol. If a
+# specified directory doesn't exist, it's ignored (no error condition
+# results). The default is to scan the "boot" directory in addition to
+# various hard-coded directories.
+#
+#also_scan_dirs boot,ESP2:EFI/linux/kernels
+
+# Partitions (or whole disks, for legacy-mode boots) to omit from scans.
+# For EFI-mode scans, you normally specify a volume by its label, which you
+# can obtain in an EFI shell by typing "vol", from Linux by typing
+# "blkid /dev/{devicename}", or by examining the disk's label in various
+# OSes' file browsers. It's also possible to identify a partition by its
+# unique GUID (aka its "PARTUUID" in Linux parlance). (Note that this is
+# NOT the partition TYPE CODE GUID.) This identifier can be obtained via
+# "blkid" in Linux or "diskutil info {partition-id}" in macOS.
+# For legacy-mode scans, you can specify any subset of the boot loader
+# description shown when you highlight the option in rEFInd.
+# The default is "LRS_ESP".
+#
+#dont_scan_volumes "Recovery HD"
+
+# Directories that should NOT be scanned for boot loaders. By default,
+# rEFInd doesn't scan its own directory, the EFI/tools directory, the
+# EFI/memtest directory, the EFI/memtest86 directory, or the
+# com.apple.recovery.boot directory. Using the dont_scan_dirs option
+# enables you to "blacklist" other directories; but be sure to use "+"
+# as the first element if you want to continue blacklisting existing
+# directories. You might use this token to keep EFI/boot/bootx64.efi out
+# of the menu if that's a duplicate of another boot loader or to exclude
+# a directory that holds drivers or non-bootloader utilities provided by
+# a hardware manufacturer. If a directory is listed both here and in
+# also_scan_dirs, dont_scan_dirs takes precedence. Note that this
+# blacklist applies to ALL the filesystems that rEFInd scans, not just
+# the ESP, unless you precede the directory name by a filesystem name or
+# partition unique GUID, as in "myvol:EFI/somedir" to exclude EFI/somedir
+# from the scan on the myvol volume but not on other volumes.
+#
+#dont_scan_dirs ESP:/EFI/boot,EFI/Dell,EFI/memtest86
+
+# Files that should NOT be included as EFI boot loaders (on the
+# first line of the display). If you're using a boot loader that
+# relies on support programs or drivers that are installed alongside
+# the main binary or if you want to "blacklist" certain loaders by
+# name rather than location, use this option. Note that this will
+# NOT prevent certain binaries from showing up in the second-row
+# set of tools. Most notably, various Secure Boot and recovery
+# tools are present in this list, but may appear as second-row
+# items.
+# The file may be specified as a bare name (e.g., "notme.efi"), as
+# a complete pathname (e.g., "/EFI/somedir/notme.efi"), or as a
+# complete pathname with volume (e.g., "SOMEDISK:/EFI/somedir/notme.efi"
+# or 2C17D5ED-850D-4F76-BA31-47A561740082:/EFI/somedir/notme.efi").
+# OS tags hidden via the Delete or '-' key in the rEFInd menu are
+# added to this list, but stored in NVRAM.
+# The default is shim.efi,shim-fedora.efi,shimx64.efi,PreLoader.efi,
+# TextMode.efi,ebounce.efi,GraphicsConsole.efi,MokManager.efi,HashTool.efi,
+# HashTool-signed.efi,bootmgr.efi,fb{arch}.efi
+# (where "{arch}" is the architecture code, like "x64").
+# If you want to keep these defaults but add to them, be sure to
+# specify "+" as the first item in the new list; if you don't, then
+# items from the default list are likely to appear.
+#
+#dont_scan_files shim.efi,MokManager.efi
+
+# Scan for Linux kernels that lack a ".efi" filename extension. This is
+# useful for better integration with Linux distributions that provide
+# kernels with EFI stub loaders but that don't give those kernels filenames
+# that end in ".efi", particularly if the kernels are stored on a
+# filesystem that the EFI can read. When set to "1", "true", or "on", this
+# option causes all files in scanned directories with names that begin with
+# "vmlinuz", "bzImage", or "kernel" to be included as loaders, even if they
+# lack ".efi" extensions. Passing this option a "0", "false", or "off" value
+# causes kernels without ".efi" extensions to NOT be scanned.
+# Default is "true" -- to scan for kernels without ".efi" extensions.
+#
+#scan_all_linux_kernels false
+
+# Combine all Linux kernels in a given directory into a single entry.
+# When so set, the kernel with the most recent time stamp will be launched
+# by default, and its filename will appear in the entry's description.
+# To launch other kernels, the user must press F2 or Insert; alternate
+# kernels then appear as options on the sub-menu.
+# Default is "true" -- kernels are "folded" into a single menu entry.
+#
+#fold_linux_kernels false
+
+# Comma-delimited list of strings to treat as if they were numbers for the
+# purpose of kernel version number detection. These strings are matched on a
+# first-found basis; that is, if you want to treat both "linux-lts" and
+# "linux" as version strings, they MUST be specified as "linux-lts,linux",
+# since if you specify it the other way, both vmlinuz-linux and
+# vmlinuz-linux-lts will return with "linux" as the "version string," which
+# is not what you'd want. Also, if the kernel or initrd file includes both a
+# specified string and digits, the "version string" includes both. For
+# instance, "vmlinuz-linux-4.8" would yield a version string of "linux-4.8".
+# This option is intended for Arch and other distributions that don't include
+# version numbers in their kernel filenames, but may provide other uniquely
+# identifying strings for multiple kernels. If this feature causes problems
+# (say, if your kernel filename includes "linux" but the initrd filename
+# doesn't), be sure this is set to an empty string
+# (extra_kernel_version_strings "") or comment out the option to disable it.
+# Default is no extra version strings
+#
+#extra_kernel_version_strings linux-lts,linux
+
+# Set the maximum number of tags that can be displayed on the screen at
+# any time. If more loaders are discovered than this value, rEFInd shows
+# a subset in a scrolling list. If this value is set too high for the
+# screen to handle, it's reduced to the value that the screen can manage.
+# If this value is set to 0 (the default), it's adjusted to the number
+# that the screen can handle.
+#
+#max_tags 0
+
+# Set the default menu selection. The available arguments match the
+# keyboard accelerators available within rEFInd. You may select the
+# default loader using:
+# - A digit between 1 and 9, in which case the Nth loader in the menu
+# will be the default.
+# - A "+" symbol at the start of the string, which refers to the most
+# recently booted loader.
+# - Any substring that corresponds to a portion of the loader's title
+# (usually the OS's name, boot loader's path, or a volume or
+# filesystem title).
+# You may also specify multiple selectors by separating them with commas
+# and enclosing the list in quotes. (The "+" option is only meaningful in
+# this context.)
+# If you follow the selector(s) with two times, in 24-hour format, the
+# default will apply only between those times. The times are in the
+# motherboard's time standard, whether that's UTC or local time, so if
+# you use UTC, you'll need to adjust this from local time manually.
+# Times may span midnight as in "23:30 00:30", which applies to 11:30 PM
+# to 12:30 AM. You may specify multiple default_selection lines, in which
+# case the last one to match takes precedence. Thus, you can set a main
+# option without a time followed by one or more that include times to
+# set different defaults for different times of day.
+# The default behavior is to boot the previously-booted OS.
+#
+#default_selection 1
+#default_selection Microsoft
+#default_selection "+,bzImage,vmlinuz"
+#default_selection Maintenance 23:30 2:00
+#default_selection "Maintenance,macOS" 1:00 2:30
+
+# Enable VMX bit and lock the CPU MSR if unlocked.
+# On some Intel Apple computers, the firmware does not lock the MSR 0x3A.
+# The symptom on Windows is Hyper-V not working even if the CPU
+# meets the minimum requirements (HW assisted virtualization and SLAT)
+# DO NOT SET THIS EXCEPT ON INTEL CPUs THAT SUPPORT VMX! See
+# http://www.thomas-krenn.com/en/wiki/Activating_the_Intel_VT_Virtualization_Feature
+# for more on this subject.
+# The default is false: Don't try to enable and lock the MSR.
+#
+#enable_and_lock_vmx false
+
+# Tell a Mac's EFI that macOS is about to be launched, even when it's not.
+# This option causes some Macs to initialize their hardware differently than
+# when a third-party OS is launched normally. In some cases (particularly on
+# Macs with multiple video cards), using this option can cause hardware to
+# work that would not otherwise work. On the other hand, using this option
+# when it is not necessary can cause hardware (such as keyboards and mice) to
+# become inaccessible. Therefore, you should not enable this option if your
+# non-Apple OSes work correctly; enable it only if you have problems with
+# some hardware devices. When needed, a value of "10.9" usually works, but
+# you can experiment with other values. This feature has no effect on
+# non-Apple computers.
+# The default is inactive (no macOS spoofing is done).
+#
+#spoof_osx_version 10.9
+
+# Set the CSR values for Apple's System Integrity Protection (SIP) feature.
+# Values are one-byte (two-character) hexadecimal numbers. These values
+# define which specific security features are enabled. Below are the codes
+# for what the values mean. Add them up (in hexadecimal!) to set new values.
+# Apple's "csrutil enable" and "csrutil disable" commands set values of 10
+# and 77, respectively.
+# CSR_ALLOW_UNTRUSTED_KEXTS 0x01
+# CSR_ALLOW_UNRESTRICTED_FS 0x02
+# CSR_ALLOW_TASK_FOR_PID 0x04
+# CSR_ALLOW_KERNEL_DEBUGGER 0x08
+# CSR_ALLOW_APPLE_INTERNAL 0x10
+# CSR_ALLOW_UNRESTRICTED_DTRACE 0x20
+# CSR_ALLOW_UNRESTRICTED_NVRAM 0x40
+#
+#csr_values 10,77
+
+# Include a secondary configuration file within this one. This secondary
+# file is loaded as if its options appeared at the point of the "include"
+# token itself, so if you want to override a setting in the main file,
+# the secondary file must be referenced AFTER the setting you want to
+# override. Note that the secondary file may NOT load a tertiary file.
+#
+#include manual.conf
+include themes/refind-theme-regular.conf
+
+# Sample manual configuration stanzas. Each begins with the "menuentry"
+# keyword followed by a name that's to appear in the menu (use quotes
+# if you want the name to contain a space) and an open curly brace
+# ("{"). Each entry ends with a close curly brace ("}"). Common
+# keywords within each stanza include:
+#
+# volume - identifies the filesystem from which subsequent files
+# are loaded. You can specify the volume by filesystem
+# label, by partition label, or by partition GUID number
+# (but NOT yet by filesystem UUID number).
+# loader - identifies the boot loader file
+# initrd - Specifies an initial RAM disk file
+# icon - specifies a custom boot loader icon
+# ostype - OS type code to determine boot options available by
+# pressing Insert. Valid values are "MacOS", "Linux",
+# "Windows", and "XOM". Case-sensitive.
+# graphics - set to "on" to enable graphics-mode boot (useful
+# mainly for MacOS) or "off" for text-mode boot.
+# Default is auto-detected from loader filename.
+# options - sets options to be passed to the boot loader; use
+# quotes if more than one option should be passed or
+# if any options use characters that might be changed
+# by rEFInd parsing procedures (=, /, #, or tab).
+# disabled - use alone or set to "yes" to disable this entry.
+#
+# Note that you can use either DOS/Windows/EFI-style backslashes (\)
+# or Unix-style forward slashes (/) as directory separators. Either
+# way, all file references are on the ESP from which rEFInd was
+# launched.
+# Use of quotes around parameters causes them to be interpreted as
+# one keyword, and for parsing of special characters (spaces, =, /,
+# and #) to be disabled. This is useful mainly with the "options"
+# keyword. Use of quotes around parameters that specify filenames is
+# permissible, but you must then use backslashes instead of slashes,
+# except when you must pass a forward slash to the loader, as when
+# passing a root= option to a Linux kernel.
+
+# Below are several sample boot stanzas. All are disabled by default.
+# Find one similar to what you need, copy it, remove the "disabled" line,
+# and adjust the entries to suit your needs.
+
+menuentry "Linux - Manjaro" {
+ loader /EFI/Linux/Manjaro/grubx64.efi
+}
+
+menuentry "MacOS - El Capitan" {
+ volume "Macintosh HD"
+ loader /System/Library/CoreServices/boot.efi
+}
+
+menuentry "Windows - 10" {
+ loader /EFI/Microsoft/Boot/bootmgfw.efi
+ icon /EFI/refind/themes/refind-theme-regular/icons/128-48/os_win.png
+}
+
+menuentry "Arch Linux" {
+ icon /EFI/refind/themes/refind-theme-regular/icons/128-48/os_arch.png
+ volume "Arch Linux"
+ loader /boot/vmlinuz-linux
+ initrd /boot/initramfs-linux.img
+ options "root=UUID=358425af-ecfe-4a2c-9dec-85783d4f3866 rw add_efi_memmap"
+}
+
+# A sample entry for a Linux 3.13 kernel with EFI boot stub support
+# on a partition with a GUID of 904404F8-B481-440C-A1E3-11A5A954E601.
+# This entry includes Linux-specific boot options and specification
+# of an initial RAM disk. Note uses of Linux-style forward slashes.
+# Also note that a leading slash is optional in file specifications.
+menuentry Linux {
+ icon EFI/refind/icons/os_linux.png
+ volume 904404F8-B481-440C-A1E3-11A5A954E601
+ loader bzImage-3.3.0-rc7
+ initrd initrd-3.3.0.img
+ options "ro root=UUID=5f96cafa-e0a7-4057-b18f-fa709db5b837"
+ disabled
+}
+
+# Below is a more complex Linux example, specifically for Arch Linux.
+# This example MUST be modified for your specific installation; if nothing
+# else, the PARTUUID code must be changed for your disk. Because Arch Linux
+# does not include version numbers in its kernel and initrd filenames, you
+# may need to use manual boot stanzas when using fallback initrds or
+# multiple kernels with Arch. This example is modified from one in the Arch
+# wiki page on rEFInd (https://wiki.archlinux.org/index.php/rEFInd).
+menuentry "Arch Linux" {
+ icon /EFI/refind/icons/os_arch.png
+ volume "Arch Linux"
+ loader /boot/vmlinuz-linux
+ initrd /boot/initramfs-linux.img
+ options "root=PARTUUID=5028fa50-0079-4c40-b240-abfaf28693ea rw add_efi_memmap"
+ submenuentry "Boot using fallback initramfs" {
+ initrd /boot/initramfs-linux-fallback.img
+ }
+ submenuentry "Boot to terminal" {
+ add_options "systemd.unit=multi-user.target"
+ }
+ disabled
+}
+
+# A sample entry for loading Ubuntu using its standard name for
+# its GRUB 2 boot loader. Note uses of Linux-style forward slashes
+menuentry Ubuntu {
+ loader /EFI/ubuntu/grubx64.efi
+ icon /EFI/refind/icons/os_linux.png
+ disabled
+}
+
+# A minimal ELILO entry, which probably offers nothing that
+# auto-detection can't accomplish.
+menuentry "ELILO" {
+ loader \EFI\elilo\elilo.efi
+ disabled
+}
+
+# Like the ELILO entry, this one offers nothing that auto-detection
+# can't do; but you might use it if you want to disable auto-detection
+# but still boot Windows....
+menuentry "Windows 7" {
+ loader \EFI\Microsoft\Boot\bootmgfw.efi
+ disabled
+}
+
+# EFI shells are programs just like boot loaders, and can be
+# launched in the same way. You can pass a shell the name of a
+# script that it's to run on the "options" line. The script
+# could initialize hardware and then launch an OS, or it could
+# do something entirely different.
+menuentry "Windows via shell script" {
+ icon \EFI\refind\icons\os_win.png
+ loader \EFI\tools\shell.efi
+ options "fs0:\EFI\tools\launch_windows.nsh"
+ disabled
+}
+
+# Mac OS is normally detected and run automatically; however,
+# if you want to do something unusual, a manual boot stanza may
+# be the way to do it. This one does nothing very unusual, but
+# it may serve as a starting point. Note that you'll almost
+# certainly need to change the "volume" line for this example
+# to work.
+menuentry "My macOS" {
+ icon \EFI\refind\icons\os_mac.png
+ volume "macOS boot"
+ loader \System\Library\CoreServices\boot.efi
+ disabled
+}
diff --git a/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md b/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md
new file mode 100644
index 0000000..aca7af4
--- /dev/null
+++ b/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md
@@ -0,0 +1,320 @@
+I can't get bazel to build an android app when everything is setup in my local environment with `nix-shell`.
+
+When I try to build, I get the following error:
+
+```sh
+$ bazel build //app/java:dnsproxy
+ERROR: [...]/WORKSPACE:12:23: fetching android_sdk_repository rule //external:androidsdk: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager.
+ERROR: Analysis of target '//app/java:dnsproxy' failed; build aborted: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager.
+INFO: Elapsed time: 0.169s
+INFO: 0 processes.
+FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured)
+```
+
+The `sdkmanager` tells me, that the correct versions are installed.
+
+```sh
+$ sdkmanager --list_installed
+[=======================================] 100% Fetch remote repository...
+Installed packages:
+ Path | Version | Description | Location
+ ------- | ------- | ------- | -------
+ build-tools;33.0.1 | 33.0.1 | Android SDK Build-Tools 33.0.1 | build-tools/33.0.1
+ cmdline-tools;8.0 | 8.0 | Android SDK Command-line Tools | cmdline-tools/8.0
+ patcher;v4 | 1 | SDK Patch Applier v4 | patcher/v4
+ platform-tools | 33.0.3 | Android SDK Platform-Tools | platform-tools
+ platforms;android-31 | 1 | Android SDK Platform 31 | platforms/android-31
+```
+
+The necessary environment variables are set and everything seems fine.
+
+```sh
+$ echo $ANDROID_HOME
+/nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk
+
+$ which sdkmanager
+/nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/bin/sdkmanager
+```
+
+The paths to everything are there.
+
+```sh
+$ ls -lah /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk/build-tools
+Permissions Size User Date Modified Name
+lrwxrwxrwx 101 root 1 1月 1970 33.0.1 -> /nix/store/ycc7k5p19ih0ky3pj0zviqk6mkghzgn7-build-tools-33.0.1/libexec/android-sdk/build-tools/33.0.1
+
+$ ls -lah /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk/platforms
+Permissions Size User Date Modified Name
+lrwxrwxrwx 97 root 1 1月 1970 android-31 -> /nix/store/20bc5fca6vkgyddhjm7l68ams9ccqr6y-platforms-31/libexec/android-sdk/platforms/android-31
+```
+
+I found this Pull Request: https://github.com/bazelbuild/bazel/pull/12626
+There was an issue with symlink detection in bazel causing the exact problem I'm having right now,
+but that has been fixed for some time now.
+
+Following are the `.nix`, and bazel files I try to build with.
+
+**shell.nix**
+```nix
+with (import <nixpkgs> {
+ config.allowUnfree = true;
+ config.android_sdk.accept_license = true;
+});
+let
+ jdk = jdk11;
+ android-composition = androidenv.composeAndroidPackages {
+ platformVersions = ["31"];
+ };
+in
+mkShell rec {
+ name = "android-shell";
+
+ buildInputs = [
+ jdk
+ android-composition.androidsdk
+ bazel
+ ];
+
+ JAVA_HOME = jdk.home;
+ ANDROID_SDK_ROOT = "${android-composition.androidsdk}/libexec/android-sdk";
+ ANDROID_HOME = "${ANDROID_SDK_ROOT}";
+}
+```
+
+**WORKSPACE**
+```starlark
+# Load the Android build rules
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+http_archive(
+ name = "build_bazel_rules_android",
+ urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"],
+ sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
+ strip_prefix = "rules_android-0.1.1",
+)
+
+# Configure Android SDK Path
+load("@build_bazel_rules_android//android:rules.bzl", "android_sdk_repository")
+android_sdk_repository(
+ name = "androidsdk",
+)
+```
+
+**app/java/BUILD**
+```starlark
+load("@build_bazel_rules_android//android:rules.bzl", "android_library", "android_binary")
+
+android_library(
+ name = "main",
+ srcs = glob(["src/*.java"]),
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["res/**"]),
+)
+
+android_binary(
+ name = "dnsproxy",
+ manifest = "AndroidManifest.xml",
+ deps = [":main"],
+)
+```
+
+**versions**
+```sh
+$ nix --version
+nix (Nix) 2.15.0
+
+$ nix-channel --list
+nixpkgs https://nixos.org/channels/nixpkgs-unstable
+
+$ bazel --version
+bazel 6.1.2- (@non-git)
+
+$ uname -a
+Linux archbook 6.2.13-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 26 Apr 2023 20:50:14 +0000 x86_64 GNU/Linux
+```
+
+I tried a host of different approaches I found scattered around the internet, like [`buildFHSUserEnv`](https://nixos.wiki/wiki/Android#Building_Android_on_NixOS), but I get the exact same error there.
+
+I don't know whether it's still a bazel issue, or a nix package issue or something else entirely and I can't think of anything else that I could check or try to get this to work.
+
+
+PS:
+
+Response to [comment](https://stackoverflow.com/questions/76142628/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment#comment134299657_76142628):
+
+`strace` returns the same environment variables with the same paths as above.
+
+
+Response to [comment](https://stackoverflow.com/questions/76142628/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment#comment134311204_76142628):
+
+I examined the mentioned links and came to the conclusion that I was using an [old guide](https://developer.android.com/codelabs/bazel-android-intro) from https://developer.android.com. Loading the android build rules from https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip doesn't seem to be necessary anymore.
+[This](https://bazel.build/start/android-app) seems to be a more recent guide from https://bazel.build, so the new file contents are
+
+**WORKSPACE**
+```starlark
+android_sdk_repository(
+ name = "androidsdk",
+)
+```
+
+**app/java/BUILD**
+```starlark
+android_library(
+ name = "main",
+ srcs = glob(["src/*.java"]),
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["res/**"]),
+)
+
+android_binary(
+ name = "dnsproxy",
+ manifest = "AndroidManifest.xml",
+ deps = [":main"],
+)
+```
+
+But I'm still getting the same error, that no build tools are installed.
+
+```sh
+ERROR: [...]/WORKSPACE:1:23: fetching android_sdk_repository rule //external:androidsdk: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager.
+```
+
+I'm still not sure whether this is more a nix or a bazel issue.
+
+
+PPS:
+
+I tried copying and symlinking a `30.0.3` build-tools folder to the `/nix/store` path that my `$ANDROID_HOME` reports. Copying the directory there resulted in a new error message, so it seems like it found the build-tools finally. Symlinking it produced the same error about the missing build-tools as before.
+
+The new error with `bazel v6` is:
+
+```sh
+$ bazel build //app/java:dnsproxy
+Starting local Bazel server and connecting to it...
+INFO: Analyzed target //app/java:dnsproxy (57 packages loaded, 942 targets configured).
+INFO: Found 1 target...
+ERROR: [...]/app/java/BUILD:1:16: Desugaring app/java/libmain.jar for Android failed: Worker process returned an unparseable WorkResponse!
+
+Did you try to print something to stdout? Workers arent allowed to do this, as it breaks the protocol between Bazel and the worker process.
+
+---8<---8<--- Start of response ---8<---8<---
+#
+# There is insufficient memory for the Java Runtime Environment to continue.
+# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
+# An error report file with more information is saved as:
+# [...]/.cache/bazel/_bazel_dweipert/139e0de675811190a7e9267b6c7ce3c8/execroot/__main__/hs_err_pid128444.log
+---8<---8<--- End of response ---8<---8<---
+
+---8<---8<--- Exception details ---8<---8<---
+com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.
+ at com.google.protobuf.InvalidProtocolBufferException.truncatedMessage(InvalidProtocolBufferException.java:107)
+ at com.google.protobuf.CodedInputStream$StreamDecoder.readRawBytesSlowPathOneChunk(CodedInputStream.java:2970)
+ at com.google.protobuf.CodedInputStream$StreamDecoder.readBytesSlowPath(CodedInputStream.java:3021)
+ at com.google.protobuf.CodedInputStream$StreamDecoder.readBytes(CodedInputStream.java:2432)
+ at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:514)
+ at com.google.protobuf.GeneratedMessageV3$Builder.parseUnknownField(GeneratedMessageV3.java:863)
+ at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$Builder.mergeFrom(WorkerProtocol.java:3037)
+ at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$1.parsePartialFrom(WorkerProtocol.java:3333)
+ at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$1.parsePartialFrom(WorkerProtocol.java:3325)
+ at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:215)
+ at com.google.protobuf.AbstractParser.parsePartialDelimitedFrom(AbstractParser.java:255)
+ at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:267)
+ at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:272)
+ at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:48)
+ at com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(GeneratedMessageV3.java:382)
+ at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse.parseDelimitedFrom(WorkerProtocol.java:2810)
+ at com.google.devtools.build.lib.worker.ProtoWorkerProtocol.getResponse(ProtoWorkerProtocol.java:46)
+ at com.google.devtools.build.lib.worker.SingleplexWorker.getResponse(SingleplexWorker.java:141)
+ at com.google.devtools.build.lib.worker.WorkerSpawnRunner.executeRequest(WorkerSpawnRunner.java:715)
+ at com.google.devtools.build.lib.worker.WorkerSpawnRunner.execInWorkerClassic(WorkerSpawnRunner.java:575)
+ at com.google.devtools.build.lib.worker.WorkerSpawnRunner.execInWorker(WorkerSpawnRunner.java:359)
+ at com.google.devtools.build.lib.worker.WorkerSpawnRunner.exec(WorkerSpawnRunner.java:205)
+ at com.google.devtools.build.lib.exec.SpawnRunner.execAsync(SpawnRunner.java:301)
+ at com.google.devtools.build.lib.exec.AbstractSpawnStrategy.exec(AbstractSpawnStrategy.java:152)
+ at com.google.devtools.build.lib.exec.AbstractSpawnStrategy.exec(AbstractSpawnStrategy.java:112)
+ at com.google.devtools.build.lib.actions.SpawnStrategy.beginExecution(SpawnStrategy.java:47)
+ at com.google.devtools.build.lib.exec.SpawnStrategyResolver.beginExecution(SpawnStrategyResolver.java:64)
+ at com.google.devtools.build.lib.analysis.actions.SpawnAction.beginExecution(SpawnAction.java:352)
+ at com.google.devtools.build.lib.actions.Action.execute(Action.java:133)
+ at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$5.execute(SkyframeActionExecutor.java:957)
+ at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$ActionRunner.continueAction(SkyframeActionExecutor.java:1124)
+ at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$ActionRunner.run(SkyframeActionExecutor.java:1082)
+ at com.google.devtools.build.lib.skyframe.ActionExecutionState.runStateMachine(ActionExecutionState.java:160)
+ at com.google.devtools.build.lib.skyframe.ActionExecutionState.getResultOrDependOnFuture(ActionExecutionState.java:93)
+ at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.executeAction(SkyframeActionExecutor.java:516)
+ at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.checkCacheAndExecuteIfNeeded(ActionExecutionFunction.java:827)
+ at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.computeInternal(ActionExecutionFunction.java:323)
+ at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.compute(ActionExecutionFunction.java:161)
+ at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:571)
+ at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:382)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
+ at java.base/java.lang.Thread.run(Thread.java:829)
+---8<---8<--- End of exception details ---8<---8<---
+
+---8<---8<--- Start of log, file at [...]/.cache/bazel/_bazel_dweipert/139e0de675811190a7e9267b6c7ce3c8/bazel-workers/worker-1-Desugar.log ---8<---8<---
+OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000600000000, 8589934592, 0) failed; error='Not enough space' (errno=12)
+---8<---8<--- End of log ---8<---8<---
+Target //app/java:dnsproxy failed to build
+Use --verbose_failures to see the command lines of failed build steps.
+INFO: Elapsed time: 12.429s, Critical Path: 2.73s
+INFO: 17 processes: 12 internal, 5 linux-sandbox.
+FAILED: Build did NOT complete successfully
+```
+
+I tried older bazel versions in-between when trying to figure out what works and what not,
+so I tried that here as well. With `bazel v5` I get a different error:
+
+```sh
+$ bazel build //app/java:dnsproxy
+Starting local Bazel server and connecting to it...
+INFO: Analyzed target //app/java:dnsproxy (57 packages loaded, 1164 targets configured).
+INFO: Found 1 target...
+ERROR: [...]/app/java/BUILD:8:15: Building deploy jar app/java/dnsproxy_deploy.jar failed: (Exit 1): singlejar_cc_bin failed: error executing command bazel-out/k8-opt-exec-2B5CBBC6/bin/external/remote_java_tools/singlejar_cc_bin @bazel-out/k8-fastbuild/bin/app/java/dnsproxy_deploy.jar-0.params
+
+Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
+singlejar_cc_bin: external/remote_java_tools/java_tools/src/tools/singlejar/singlejar_main.cc:27: Desugar checking not currently supported in Bazel.
+Target //app/java:dnsproxy failed to build
+Use --verbose_failures to see the command lines of failed build steps.
+INFO: Elapsed time: 17.899s, Critical Path: 7.33s
+INFO: 40 processes: 13 internal, 26 linux-sandbox, 1 worker.
+FAILED: Build did NOT complete successfully
+```
+
+With `bazel v4` I actually get a working environment and I could run `bazel build` without errors.
+
+With `bazel v4` I get a similar error to before, it's just now complaining about the platforms not being installed.
+Here it's the same with the build-tools. The platforms are there, but they are symlinks.
+So I tried copying instead of symlinking a directory there and that then actually ran without errors.
+
+**bazel v4 with error**
+```sh
+$ bazel build //app/java:dnsproxy
+ERROR: Error fetching repository: [...]/WORKSPACE:1:23: android_sdk_repository requires that at least one Android SDK Platform is installed in the Android SDK. Please install an Android SDK Platform through the Android SDK manager.
+ERROR: Analysis of target '//app/java:dnsproxy' failed; build aborted: android_sdk_repository requires that at least one Android SDK Platform is installed in the Android SDK. Please install an Android SDK Platform through the Android SDK manager.
+INFO: Elapsed time: 0.183s
+INFO: 0 processes.
+FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured)
+```
+
+**bazel v4 without error**
+```sh
+$ bazel build //app/java:dnsproxy
+Starting local Bazel server and connecting to it...
+INFO: Analyzed target //app/java:dnsproxy (35 packages loaded, 631 targets configured).
+INFO: Found 1 target...
+Target //app/java:dnsproxy up-to-date:
+ bazel-bin/app/java/dnsproxy_deploy.jar
+ bazel-bin/app/java/dnsproxy_unsigned.apk
+ bazel-bin/app/java/dnsproxy.apk
+INFO: Elapsed time: 9.581s, Critical Path: 1.51s
+INFO: 16 processes: 13 internal, 3 linux-sandbox.
+INFO: Build completed successfully, 16 total actions
+```
+
+I tried to investigate the version differences and noticed for the pull request I mentioned above (https://github.com/bazelbuild/bazel/pull/12626), that it only concerns the `platforms` and not the `build-tools`.
+Under tag `6.1.2` I found this line: https://github.com/bazelbuild/bazel/blob/6.1.2/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java#LL376C68-L376C68
+Here the `Dirent.Type.SYMLINK` check is missing, so it makes sense that I got that error.
+
+The OOM issue with `v6` I found here: https://github.com/bazelbuild/bazel/issues/17665
+
+So it looks like I have to bring that up in the [bazel issues](https://github.com/bazelbuild/bazel/issues).
diff --git a/use-sylius-with-homestead-instructions.md b/use-sylius-with-homestead-instructions.md
new file mode 100644
index 0000000..d6aa0dd
--- /dev/null
+++ b/use-sylius-with-homestead-instructions.md
@@ -0,0 +1,31 @@
+## Install Sylius
+
+Although generally not advisable, you have to adjust your memory_limit in your php.ini to 2G.
+You can find out which file to edit with `php --info | grep php.ini`.
+After that you can install sylius with `composer create-project sylius/sylius-standard`.
+
+## Install Homestead
+Change to the sylius directory and run
+```
+composer require --dev laravel/homestead:dev-master
+./vendor/bin/homestead make
+```
+edit the .env file and set the DATABASE_URL to
+`DATABSE_URL=mysql://homestead:secret@127.0.0.1/homestead`
+
+
+copy the below contents to after.sh
+```
+# set memory_limit to 2G for composer
+sudo sed -i "s/memory_limit = .*/memory_limit = 2G/" "/etc/php/7.3/cli/php.ini"
+sudo sed -i "s/memory_limit = .*/memory_limit = 2G/" "/etc/php/7.4/cli/php.ini"
+```
+
+then run
+```
+vagrant up
+vagrant ssh
+cd code
+php bin/console sylius:install
+yarn install && yarn build
+```
diff --git a/vagrant-bento-box-with-mongodb.Vagrantfile b/vagrant-bento-box-with-mongodb.Vagrantfile
new file mode 100644
index 0000000..9e595a1
--- /dev/null
+++ b/vagrant-bento-box-with-mongodb.Vagrantfile
@@ -0,0 +1,63 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# All Vagrant configuration is done below. The "2" in Vagrant.configure
+# configures the configuration version (we support older styles for
+# backwards compatibility). Please don't change it unless you know what
+# you're doing.
+Vagrant.configure("2") do |config|
+ # The most common configuration options are documented and commented below.
+ # For a complete reference, please see the online documentation at
+ # https://docs.vagrantup.com.
+
+ # Every Vagrant development environment requires a box. You can search for
+ # boxes at https://vagrantcloud.com/search.
+ config.vm.box = "bento/ubuntu-18.04"
+
+ # Disable automatic box update checking. If you disable this, then
+ # boxes will only be checked for updates when the user runs
+ # `vagrant box outdated`. This is not recommended.
+ # config.vm.box_check_update = false
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+ # NOTE: This will enable public access to the opened port
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
+ config.vm.network "forwarded_port", guest: 27017, host: 27017
+
+ # Create a private network, which allows host-only access to the machine
+ # using a specific IP.
+ config.vm.network "private_network", ip: "192.168.33.10"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ #
+ config.vm.provider "virtualbox" do |vb|
+ # Display the VirtualBox GUI when booting the machine
+ #vb.gui = true
+ # Customize the amount of memory on the VM:
+ vb.memory = "1024"
+ end
+ # View the documentation for the provider you are using for more
+ # information on available options.
+
+ # Enable provisioning with a shell script. Additional provisioners such as
+ # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
+ # documentation for more information about their specific syntax and use.
+ config.vm.provision "shell", inline: <<-SHELL
+ # install mongodb
+ wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
+ echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
+ sudo apt-get update
+ sudo apt-get install -y mongodb-org
+
+ # listen to all interfaces
+ sudo sed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf
+
+ # enable mongod
+ sudo service mongod start
+ sudo systemctl enable mongod.service
+ SHELL
+end