Files
fressh/flake.nix
EthanShoeDev fffc3b103c flake fmt
2025-10-07 14:51:08 -04:00

248 lines
7.3 KiB
Nix

{
description = "Expo RN devshells (local emulator / remote AVD)";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
android-nixpkgs = {
url = "github:tadfisher/android-nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
nixConfig = {
extra-substituters = [
"https://android-nixpkgs.cachix.org"
"https://nix-community.cachix.org"
];
extra-trusted-public-keys = [
"android-nixpkgs.cachix.org-1:2lZoPmwoyTVGaNDHqa6A32tdn8Gc0aMWBRrfXN1H3dQ="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
outputs = {
self,
nixpkgs,
android-nixpkgs,
fenix,
...
}: let
systems = ["x86_64-linux" "aarch64-darwin" "x86_64-darwin"];
overlays = [
android-nixpkgs.overlays.default
];
forAllSystems = f:
nixpkgs.lib.genAttrs systems (
system:
f {
pkgs = import nixpkgs {
inherit system overlays;
config.allowUnfree = true; # emulator is unfree
};
}
);
in {
devShells = forAllSystems (
{pkgs}: let
fen = fenix.packages.${pkgs.system};
rustToolchain = fen.combine [
(fen.stable.withComponents [
"cargo"
"clippy"
"rust-src"
"rustc"
"rustfmt"
])
fen.targets.aarch64-linux-android.stable.rust-std
fen.targets.armv7-linux-androideabi.stable.rust-std
fen.targets.x86_64-linux-android.stable.rust-std
fen.targets.i686-linux-android.stable.rust-std
fen.targets.aarch64-apple-ios.stable.rust-std
fen.targets.aarch64-apple-ios-sim.stable.rust-std
];
defaultPkgs = with pkgs; [
# System
bash
git
pkg-config
jq
starship
# JS
nodejs_22
turbo
nodePackages.pnpm
yarn
watchman
# Rust
rustToolchain
cargo-ndk
# Android build helpers
jdk17
gradle_8
scrcpy
# Misc
cmake
ninja
just
alejandra
clang-tools
];
mkShellFn =
if pkgs.stdenv.isDarwin
then pkgs.mkShellNoCC
else pkgs.mkShell;
ndkId = "27-1-12297006"; # nix flake show github:tadfisher/android-nixpkgs | grep ndk
ndkAttr = "ndk-${ndkId}";
ndkVer = builtins.replaceStrings ["-"] ["."] ndkId;
defaultAndroidPkgs = sdk: let
ndkPkg = builtins.getAttr ndkAttr sdk;
in
with sdk; [
cmdline-tools-latest
platform-tools
platforms-android-36
platforms-android-35
build-tools-35-0-0
build-tools-36-0-0
cmake-3-22-1
ndkPkg
];
makeAndroidSdk = mode: let
androidSdk = pkgs.androidSdk (
sdk:
if mode == "full"
then
(with sdk;
[
emulator
system-images-android-36-1-google-apis-x86-64 # nix flake show github:tadfisher/android-nixpkgs | grep system-images-android-36
]
++ (defaultAndroidPkgs sdk))
else if mode == "remote"
then (defaultAndroidPkgs sdk)
else throw "makeAndroidSdk: unknown mode '${mode}'. Use \"full\" or \"remote\"."
);
sdkRoot = "${androidSdk}/share/android-sdk";
in {inherit androidSdk sdkRoot;};
fullAndroidSdk = makeAndroidSdk "full";
remoteAndroidSdk = makeAndroidSdk "remote";
starshipToml = pkgs.writeText "starship.toml" ''
# project-scoped Starship config (no files under ~/.config)
add_newline = false
format = "$nix_shell$directory$rust$python$cmd_duration$character"
[nix_shell]
disabled = false
format = "[$symbol]($style) "
symbol = "nix-fressh "
pure_msg = ""
impure_msg = "(impure) "
style = "bold cyan"
[directory]
format = "[$path]($style) "
truncation_length = 0
truncate_to_repo = false
home_symbol = "~"
[character]
success_symbol = "[](bold green) "
error_symbol = "[](bold red) "
'';
starshipBootstrap = pkgs.writeText "fressh-starship-bootstrap.sh" ''
if [[ -n ''${__FRESSH_STARSHIP_INIT-} ]]; then
if [[ -n ''${FRESSH_OLD_PROMPT_COMMAND:-} ]]; then
PROMPT_COMMAND=''${FRESSH_OLD_PROMPT_COMMAND}
else
unset PROMPT_COMMAND
fi
unset FRESSH_OLD_PROMPT_COMMAND
return
fi
__FRESSH_STARSHIP_INIT=1
if [[ -n ''${FRESSH_OLD_PROMPT_COMMAND:-} ]]; then
PROMPT_COMMAND=''${FRESSH_OLD_PROMPT_COMMAND}
else
unset PROMPT_COMMAND
fi
if [[ ''${TERM_PROGRAM:-} == "vscode" ]] && command -v code >/dev/null; then
if ! declare -F __vsc_prompt_cmd_original >/dev/null; then
. "$(code --locate-shell-integration-path bash)"
fi
fi
unset FRESSH_OLD_PROMPT_COMMAND
if command -v starship >/dev/null; then
eval "$(starship init bash)"
if [[ -t 1 ]]; then
local __fressh_first_prompt
__fressh_first_prompt="$(STARSHIP_SHELL=bash starship prompt 2>/dev/null)"
if [[ -n "''${__fressh_first_prompt}" ]]; then
PS1="''${__fressh_first_prompt}"
fi
unset __fressh_first_prompt
fi
fi
'';
commonAndroidInit = sdkRoot: ''
unset ANDROID_SDK_ROOT
unset ANDROID_HOME
export ANDROID_SDK_ROOT="${sdkRoot}"
export ANDROID_HOME="${sdkRoot}"
export PATH="$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk/${ndkVer}"
export ANDROID_NDK_HOME="$ANDROID_NDK_ROOT"
export ANDROID_NDK="$ANDROID_NDK_ROOT"
export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=${sdkRoot}/build-tools/36.0.0/aapt2 -Dorg.gradle.project.android.builder.sdkDownload=false"
export STARSHIP_CONFIG=${starshipToml}
export STARSHIP_CACHE="$PWD/.starship-cache"
mkdir -p "$STARSHIP_CACHE"
export FRESSH_DEVENV=1
export FRESSH_STARSHIP_PREINIT=${starshipBootstrap}
export FRESSH_OLD_PROMPT_COMMAND=''${PROMPT_COMMAND:-}
export PROMPT_COMMAND=". \"$FRESSH_STARSHIP_PREINIT\""
'';
in {
default = mkShellFn {
packages = defaultPkgs ++ [remoteAndroidSdk.androidSdk];
shellHook =
commonAndroidInit remoteAndroidSdk.sdkRoot;
};
android-emulator = mkShellFn {
packages = defaultPkgs ++ [fullAndroidSdk.androidSdk];
shellHook =
commonAndroidInit fullAndroidSdk.sdkRoot;
};
}
);
formatter = forAllSystems (
{pkgs}:
pkgs.alejandra
);
};
}