133 lines
4.4 KiB
Bash
Executable File
133 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Exit immediately if the script encounters a non-zero status.
|
|
set -e
|
|
|
|
# If set, Bash includes filenames beginning with a `.` in the results of
|
|
# filename expansion. The filenames `.` and `..` must always be matched
|
|
# explicitly, even if dotglob is set.
|
|
shopt -s dotglob
|
|
|
|
# ============================================================
|
|
# PROLOGUE
|
|
# ============================================================
|
|
|
|
# Create a new top-level directory as fallback in case $BUILD (defined below)
|
|
# is ever empty.
|
|
mkdir -p "/tmp/bs.phoenix"
|
|
|
|
# Create an intermediate build directory. The final step of this script will
|
|
# copy the content from this directory to $OUT.
|
|
BUILD=$(mktemp -d -p "/tmp/bs.phoenix")
|
|
|
|
if [ -z "$BUILD" ]; then
|
|
>&2 echo "Failed to create temp directory."
|
|
exit 1
|
|
fi
|
|
|
|
# Deletes the intermediate build directory on exit. We use a concatenation of
|
|
# the intermediate directory with the basename of the generated temp directory
|
|
# to ensure we never evaluate to root (i.e. `/`). That should never actually
|
|
# happen but a good habit to establish nonetheless.
|
|
function cleanup {
|
|
rm -r "/tmp/bs.phoenix/$(basename "$BUILD")"
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
# ============================================================
|
|
# ENVIRONMENT
|
|
# ============================================================
|
|
|
|
if [ -z "$MODULE" ]; then
|
|
MODULE_ARG=
|
|
else
|
|
MODULE_ARG="--module '$MODULE'"
|
|
fi
|
|
|
|
# ============================================================
|
|
# BUILD
|
|
# ============================================================
|
|
|
|
# Copy template contents over to the intermediate build directory.
|
|
cp -r template/* "$BUILD"
|
|
|
|
# Explicitly set permissions on all copied template files.
|
|
find "$BUILD" -type f -execdir chmod 644 {} +
|
|
find "$BUILD" -type d -execdir chmod 755 {} +
|
|
chmod 755 "$BUILD"/.githooks/pre-commit
|
|
|
|
# Generate a new project with the specified name using `mix`. Generate in a
|
|
# subdirectory to avoid interactive conflict resolution.
|
|
nix develop "$BUILD" \
|
|
--command bash \
|
|
-c "mix phx.new $BUILD/bs.project --app '$APP' $MODULE_ARG"
|
|
|
|
# Copy the generated files into the intermediate build directory.
|
|
mv -f "$BUILD"/bs.project/* "$BUILD"
|
|
rmdir "$BUILD"/bs.project
|
|
|
|
# Overwrite the generated README in favor of that defined in our template.
|
|
cp template/README.md "$BUILD"
|
|
chmod 644 "$BUILD"/README.md
|
|
|
|
# Include additional build files for our assets. Group into subdirectory so
|
|
# the `chmod` command can take advantage of globbing.
|
|
mkdir -p "$BUILD"/bs.assets
|
|
cp assets/* "$BUILD"/bs.assets
|
|
chmod 644 "$BUILD"/bs.assets/*
|
|
mv "$BUILD"/bs.assets/* "$BUILD"/assets
|
|
rmdir "$BUILD"/bs.assets
|
|
|
|
# Create a new database cluster.
|
|
nix develop "$BUILD" --command bash -c "pg_ctl initdb -D $BUILD/db"
|
|
|
|
# ============================================================
|
|
# REWRITES
|
|
# ============================================================
|
|
|
|
# The mix generator would fail if $APP did not consist of just lowercase ASCII
|
|
# letters, numbers, or underscores. Thus $APP is safe to interpolate into the
|
|
# following command.
|
|
for file in flake.nix assets/{package.json,package-lock.json,node-packages.nix}
|
|
do
|
|
sed -i "s/<APP>/$APP/g" "$BUILD/$file"
|
|
done
|
|
|
|
# Allow specifying a custom path to our :esbuild and :tailwind configs.
|
|
# Typically when building a Phoenix application, Mix will download
|
|
# esbuild/tailwind binaries on demand. Within nix environments this is not
|
|
# possible. Instead, specify them directly with these environment variables.
|
|
sed -i \
|
|
'42 s/$/,/;
|
|
43 i \ \ path: System.get_env("MIX_ESBUILD_PATH")
|
|
s/version: \"0.17.11\"/version: \"0.19.7\"/
|
|
54 s/$/,/;
|
|
55 i \ \ path: System.get_env("MIX_TAILWIND_PATH")
|
|
s/version: \"3.3.2\"/version: \"3.3.5\"/' \
|
|
"$BUILD/config/config.exs"
|
|
|
|
# By default Phoenix generates a postgres configuration with assumed username
|
|
# `postgres`. This flake encourages a local postgres database with username
|
|
# `$(whoami)`. Reflect this in the config.
|
|
sed -i "s/username: \"postgres\"/username: \"$(whoami)\"/g" "$BUILD/config/dev.exs"
|
|
|
|
# Append an additional rule to `.gitignore` to ignore the database cluster.
|
|
cat <<EOF >> "$BUILD"/.gitignore
|
|
# The default location of the generated database cluster.
|
|
/db/
|
|
|
|
# Directory used by \`direnv\` to hold \`use flake\`-generated profiles.
|
|
/.direnv/
|
|
|
|
# A symlink produced by default when running \`nix build\`.
|
|
/result
|
|
EOF
|
|
|
|
# ============================================================
|
|
# EPILOGUE
|
|
# ============================================================
|
|
|
|
# Success! Copy contents to target directory.
|
|
cp -a "$BUILD"/* "$OUT"
|