Opinionated Android 15+ Linux Terminal Setup
android linux command-line-tools

setup nix flake

+296
+35
.devcontainer/devcontainer.json
··· 1 + // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 + // README at: https://github.com/devcontainers/templates/tree/main/src/rust 3 + { 4 + "name": "Rust", 5 + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 + "image": "mcr.microsoft.com/devcontainers/rust:1-1-bookworm", 7 + "features": { 8 + "ghcr.io/devcontainers/features/github-cli:1": {}, 9 + "ghcr.io/devcontainers/features/nix:1": {} 10 + }, 11 + 12 + // Use 'mounts' to make the cargo cache persistent in a Docker Volume. 13 + // "mounts": [ 14 + // { 15 + // "source": "devcontainer-cargo-cache-${devcontainerId}", 16 + // "target": "/usr/local/cargo", 17 + // "type": "volume" 18 + // } 19 + // ] 20 + 21 + // Features to add to the dev container. More info: https://containers.dev/features. 22 + // "features": {}, 23 + 24 + // Use 'forwardPorts' to make a list of ports inside the container available locally. 25 + // "forwardPorts": [], 26 + 27 + // Use 'postCreateCommand' to run commands after the container is created. 28 + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" 29 + 30 + // Configure tool-specific properties. 31 + // "customizations": {}, 32 + 33 + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 34 + // "remoteUser": "root" 35 + }
+116
flake.lock
··· 1 + { 2 + "nodes": { 3 + "advisory-db": { 4 + "flake": false, 5 + "locked": { 6 + "lastModified": 1755283329, 7 + "narHash": "sha256-33bd+PHbon+cgEiWE/zkr7dpEF5E0DiHOzyoUQbkYBc=", 8 + "owner": "rustsec", 9 + "repo": "advisory-db", 10 + "rev": "61aac2116c8cb7cc80ff8ca283eec7687d384038", 11 + "type": "github" 12 + }, 13 + "original": { 14 + "owner": "rustsec", 15 + "repo": "advisory-db", 16 + "type": "github" 17 + } 18 + }, 19 + "crane": { 20 + "locked": { 21 + "lastModified": 1755537552, 22 + "narHash": "sha256-Tg+P8kFIneqnQLT8E0QqlCrldtdLo1n1y619/mxRD44=", 23 + "owner": "ipetkov", 24 + "repo": "crane", 25 + "rev": "3c40c97e1881fff381e4615e82557b333edf65c4", 26 + "type": "github" 27 + }, 28 + "original": { 29 + "owner": "ipetkov", 30 + "repo": "crane", 31 + "type": "github" 32 + } 33 + }, 34 + "fenix": { 35 + "inputs": { 36 + "nixpkgs": [ 37 + "nixpkgs" 38 + ], 39 + "rust-analyzer-src": [] 40 + }, 41 + "locked": { 42 + "lastModified": 1755585599, 43 + "narHash": "sha256-tl/0cnsqB/Yt7DbaGMel2RLa7QG5elA8lkaOXli6VdY=", 44 + "owner": "nix-community", 45 + "repo": "fenix", 46 + "rev": "6ed03ef4c8ec36d193c18e06b9ecddde78fb7e42", 47 + "type": "github" 48 + }, 49 + "original": { 50 + "owner": "nix-community", 51 + "repo": "fenix", 52 + "type": "github" 53 + } 54 + }, 55 + "flake-utils": { 56 + "inputs": { 57 + "systems": "systems" 58 + }, 59 + "locked": { 60 + "lastModified": 1731533236, 61 + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 62 + "owner": "numtide", 63 + "repo": "flake-utils", 64 + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 65 + "type": "github" 66 + }, 67 + "original": { 68 + "owner": "numtide", 69 + "repo": "flake-utils", 70 + "type": "github" 71 + } 72 + }, 73 + "nixpkgs": { 74 + "locked": { 75 + "lastModified": 1755615617, 76 + "narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=", 77 + "owner": "NixOS", 78 + "repo": "nixpkgs", 79 + "rev": "20075955deac2583bb12f07151c2df830ef346b4", 80 + "type": "github" 81 + }, 82 + "original": { 83 + "owner": "NixOS", 84 + "ref": "nixos-unstable", 85 + "repo": "nixpkgs", 86 + "type": "github" 87 + } 88 + }, 89 + "root": { 90 + "inputs": { 91 + "advisory-db": "advisory-db", 92 + "crane": "crane", 93 + "fenix": "fenix", 94 + "flake-utils": "flake-utils", 95 + "nixpkgs": "nixpkgs" 96 + } 97 + }, 98 + "systems": { 99 + "locked": { 100 + "lastModified": 1681028828, 101 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 102 + "owner": "nix-systems", 103 + "repo": "default", 104 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 105 + "type": "github" 106 + }, 107 + "original": { 108 + "owner": "nix-systems", 109 + "repo": "default", 110 + "type": "github" 111 + } 112 + } 113 + }, 114 + "root": "root", 115 + "version": 7 116 + }
+145
flake.nix
··· 1 + { 2 + description = "Oh My Droid - Opinionated Android 15+ Linux Terminal Setup"; 3 + 4 + inputs = { 5 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 + 7 + crane = { 8 + url = "github:ipetkov/crane"; 9 + inputs.nixpkgs.follows = "nixpkgs"; 10 + }; 11 + 12 + fenix = { 13 + url = "github:nix-community/fenix"; 14 + inputs.nixpkgs.follows = "nixpkgs"; 15 + inputs.rust-analyzer-src.follows = ""; 16 + }; 17 + 18 + flake-utils.url = "github:numtide/flake-utils"; 19 + 20 + advisory-db = { 21 + url = "github:rustsec/advisory-db"; 22 + flake = false; 23 + }; 24 + }; 25 + 26 + outputs = { self, nixpkgs, crane, fenix, flake-utils, advisory-db, ... }: 27 + flake-utils.lib.eachDefaultSystem (system: 28 + let 29 + pkgs = import nixpkgs { 30 + inherit system; 31 + }; 32 + 33 + inherit (pkgs) lib; 34 + 35 + craneLib = crane.mkLib pkgs; 36 + src = craneLib.cleanCargoSource ./.; 37 + 38 + # Common arguments can be set here to avoid repeating them later 39 + commonArgs = { 40 + inherit src; 41 + 42 + pname = "oh-my-droid"; 43 + version = "0.1.0"; 44 + 45 + buildInputs = [ 46 + # Add additional build inputs here 47 + ] ++ lib.optionals pkgs.stdenv.isDarwin [ 48 + # Additional darwin specific inputs can be set here 49 + pkgs.libiconv 50 + pkgs.darwin.Security 51 + ]; 52 + 53 + # Additional environment variables can be set directly 54 + # MY_CUSTOM_VAR = "some value"; 55 + }; 56 + 57 + craneLibLLvmTools = craneLib.overrideToolchain 58 + (fenix.packages.${system}.complete.withComponents [ 59 + "cargo" 60 + "llvm-tools" 61 + "rustc" 62 + ]); 63 + 64 + # Build *just* the cargo dependencies, so we can reuse 65 + # all of that work (e.g. via cachix) when running in CI 66 + cargoArtifacts = craneLib.buildDepsOnly commonArgs; 67 + 68 + # Build the actual crate itself, reusing the dependency 69 + # artifacts from above. 70 + oh-my-droid = craneLib.buildPackage (commonArgs // { 71 + inherit cargoArtifacts; 72 + }); 73 + 74 + in 75 + { 76 + checks = { 77 + # Build the crate as part of `nix flake check` for convenience 78 + inherit oh-my-droid; 79 + 80 + # Run clippy (and deny all warnings) on the crate source, 81 + # again, resuing the dependency artifacts from above. 82 + # 83 + # Note that this is done as a separate derivation so that 84 + # we can block the CI if there are issues here, but not 85 + # prevent downstream consumers from building our crate by itself. 86 + oh-my-droid-clippy = craneLib.cargoClippy (commonArgs // { 87 + inherit cargoArtifacts; 88 + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; 89 + }); 90 + 91 + oh-my-droid-doc = craneLib.cargoDoc (commonArgs // { 92 + inherit cargoArtifacts; 93 + }); 94 + 95 + # Check formatting 96 + oh-my-droid-fmt = craneLib.cargoFmt { 97 + inherit src; 98 + }; 99 + 100 + # Audit dependencies 101 + oh-my-droid-audit = craneLib.cargoAudit { 102 + inherit src advisory-db; 103 + }; 104 + 105 + # Run tests with cargo-nextest 106 + # Consider setting `doCheck = false` on `oh-my-droid` if you do not want 107 + # the tests to run twice 108 + oh-my-droid-nextest = craneLib.cargoNextest (commonArgs // { 109 + inherit cargoArtifacts; 110 + partitions = 1; 111 + partitionType = "count"; 112 + }); 113 + } // lib.optionalAttrs (system == "x86_64-linux") { 114 + # NB: cargo-tarpaulin only supports x86_64 systems 115 + # Check code coverage (note: this will not upload coverage anywhere) 116 + oh-my-droid-coverage = craneLib.cargoTarpaulin (commonArgs // { 117 + inherit cargoArtifacts; 118 + }); 119 + }; 120 + 121 + packages = { 122 + default = oh-my-droid; 123 + oh-my-droid-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // { 124 + inherit cargoArtifacts; 125 + }); 126 + }; 127 + 128 + apps.default = flake-utils.lib.mkApp { 129 + drv = oh-my-droid; 130 + }; 131 + 132 + devShells.default = pkgs.mkShell { 133 + inputsFrom = builtins.attrValues self.checks.${system}; 134 + 135 + # Additional dev-shell environment variables can be set directly 136 + # MY_CUSTOM_DEVELOPMENT_VAR = "something else"; 137 + 138 + # Extra inputs can be added here 139 + nativeBuildInputs = with pkgs; [ 140 + cargo 141 + rustc 142 + ]; 143 + }; 144 + }); 145 + }