Skip to content
This repository was archived by the owner on Jun 19, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ out/
.gradle/
build/

# Nix / direnv
.direnv/
result
result-*

# Python cache
__pycache__/

Expand Down
138 changes: 138 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
description = "uchar element x — reproducible dev environment";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";

flake-parts.url = "github:hercules-ci/flake-parts";

android-nixpkgs = {
url = "github:tadfisher/android-nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs =
{ self, flake-parts, ... }@inputs:
flake-parts.lib.mkFlake { inherit inputs; } (
{ ... }:
{
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];

perSystem =
{ pkgs, system, ... }:
{
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
config.android_sdk.accept_license = true;
overlays = [
(final: prev: {
android = inputs.android-nixpkgs;
})
];
};

formatter = pkgs.alejandra;

devShells.default = import ./nix/shell.nix {
inherit pkgs inputs system;
formatter = pkgs.alejandra;
};
};
}
);
}
81 changes: 81 additions & 0 deletions nix/shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
pkgs,
inputs,
system,
formatter ? pkgs.alejandra,
...
}:
let
isLinux = pkgs.stdenv.isLinux;
pinnedJDK = pkgs.jdk21_headless;

androidCustomPackage = inputs.android-nixpkgs.sdk.${system} (
sdkPkgs: with sdkPkgs; [
cmdline-tools-latest
platform-tools
build-tools-36-0-0
platforms-android-36
emulator
system-images-android-36-google-apis-playstore-x86-64
]
);

androidEmulator = pkgs.androidenv.emulateApp {
name = "emulator";
platformVersion = "36";
abiVersion = "x86_64";
systemImageType = "google_apis_playstore";
configOptions = {
"hw.gpu.enabled" = "yes";
"hw.gpu.mode" = "swiftshader_indirect";
"hw.keyboard" = "yes";
};
};

androidEmulatorNoGPU = pkgs.androidenv.emulateApp {
name = "emulator";
platformVersion = "36";
abiVersion = "x86_64";
systemImageType = "google_apis_playstore";
configOptions = {
"hw.gpu.enabled" = "no";
"hw.keyboard" = "yes";
};
};
in
pkgs.mkShell {
packages = [
pinnedJDK
androidCustomPackage
pkgs.ktlint
pkgs.git
pkgs.coreutils
formatter
]
++ pkgs.lib.optionals isLinux [
(pkgs.writeScriptBin "android-emulator" ''
${androidEmulator}/bin/run-test-emulator
'')
(pkgs.writeScriptBin "android-emulator-no-gpu" ''
${androidEmulatorNoGPU}/bin/run-test-emulator
'')
];

env = {
ANDROID_HOME = "${androidCustomPackage}/share/android-sdk";
ANDROID_SDK_ROOT = "${androidCustomPackage}/share/android-sdk";
JAVA_HOME = pinnedJDK.home;
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidCustomPackage}/share/android-sdk/build-tools/36.0.0/aapt2";
};

shellHook = ''
echo "---------------------------------------------------------------------------------------------------"
echo " Uchar Element X Android dev shell."
echo " JDK: $(java -version 2>&1 | head -1)"
echo " ANDROID_HOME: $ANDROID_HOME"
${pkgs.lib.optionalString isLinux ''
echo " Emulator: run 'android-emulator' else 'android-emulator-no-gpu'"
''}
echo "---------------------------------------------------------------------------------------------------"
'';
}
Loading