diff --git a/.editorconfig b/.editorconfig index eaf9deba9..8e244d81e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,3 +23,7 @@ indent_size = 2 [Dockerfile] indent_size = 4 + +[*.nix] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index 2b0916509..69f5dd248 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ venv/ *.pem credentials.json .worktrees/ + +# Nix +result diff --git a/flake.nix b/flake.nix index 9bafa47c2..7e5379fa9 100644 --- a/flake.nix +++ b/flake.nix @@ -8,54 +8,44 @@ nixpkgs.url = "nixpkgs/nixos-unstable"; }; - outputs = { flake-utils, fenix, nixpkgs, ... }: - let - nixosModule = { pkgs, ... }: { - nixpkgs.overlays = [ fenix.overlays.default ]; - environment.systemPackages = [ - (pkgs.fenix.stable.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]) - pkgs.rust-analyzer - ]; - }; - in - flake-utils.lib.eachDefaultSystem (system: + outputs = + { + self, + flake-utils, + fenix, + nixpkgs, + }: + flake-utils.lib.eachDefaultSystem ( + system: let pkgs = import nixpkgs { inherit system; - overlays = [ fenix.overlays.default ]; + overlays = [ + fenix.overlays.default + (import ./overlay.nix) + ]; }; - rustToolchain = pkgs.fenix.stable.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]; - in { - packages.default = fenix.packages.${system}.stable.toolchain; + in + { + formatter = pkgs.nixfmt-tree; + + packages = { + default = self.packages.${system}.zeroclaw; + inherit (pkgs) + zeroclaw + zeroclaw-web + ; + }; + devShells.default = pkgs.mkShell { + inputsFrom = [ pkgs.zeroclaw ]; packages = [ - rustToolchain pkgs.rust-analyzer ]; }; - }) // { - nixosConfigurations = { - nixos = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ nixosModule ]; - }; - - nixos-aarch64 = nixpkgs.lib.nixosSystem { - system = "aarch64-linux"; - modules = [ nixosModule ]; - }; - }; + } + ) + // { + overlays.default = import ./overlay.nix; }; } diff --git a/overlay.nix b/overlay.nix new file mode 100644 index 000000000..cf73ff69c --- /dev/null +++ b/overlay.nix @@ -0,0 +1,13 @@ +final: prev: { + zeroclaw-web = final.callPackage ./web/package.nix { }; + + zeroclaw = final.callPackage ./package.nix { + rustToolchain = final.fenix.stable.withComponents [ + "cargo" + "clippy" + "rust-src" + "rustc" + "rustfmt" + ]; + }; +} diff --git a/package.nix b/package.nix new file mode 100644 index 000000000..89b7c84e2 --- /dev/null +++ b/package.nix @@ -0,0 +1,58 @@ +{ + makeRustPlatform, + rustToolchain, + lib, + zeroclaw-web, + removeReferencesTo, +}: +let + rustPlatform = makeRustPlatform { + cargo = rustToolchain; + rustc = rustToolchain; + }; +in +rustPlatform.buildRustPackage (finalAttrs: { + pname = "zeroclaw"; + version = "0.1.7"; + + src = + let + fs = lib.fileset; + in + fs.toSource { + root = ./.; + fileset = fs.unions ( + [ + ./src + ./Cargo.toml + ./Cargo.lock + ./crates + ./benches + ] + ++ (lib.optionals finalAttrs.doCheck [ + ./tests + ./test_helpers + ]) + ); + }; + prePatch = '' + mkdir web + ln -s ${zeroclaw-web} web/dist + ''; + + cargoLock.lockFile = ./Cargo.lock; + + nativeBuildInputs = [ + removeReferencesTo + ]; + + # Since tests run in the official pipeline, no need to run them in the Nix sandbox. + # Can be changed by consumers using `overrideAttrs` on this package. + doCheck = false; + + # Some dependency causes Nix to detect the Rust toolchain to be a runtime dependency + # of zeroclaw. This manually removes any reference to the toolchain. + postFixup = '' + find "$out" -type f -exec remove-references-to -t ${rustToolchain} '{}' + + ''; +}) diff --git a/web/package.nix b/web/package.nix new file mode 100644 index 000000000..0352bd3f2 --- /dev/null +++ b/web/package.nix @@ -0,0 +1,31 @@ +{ buildNpmPackage, lib }: +buildNpmPackage { + pname = "zeroclaw-web"; + version = "0.1.0"; + + src = + let + fs = lib.fileset; + in + fs.toSource { + root = ./.; + fileset = fs.unions [ + ./src + ./index.html + ./package.json + ./package-lock.json + ./tsconfig.json + ./tsconfig.app.json + ./tsconfig.node.json + ./vite.config.ts + ]; + }; + + npmDepsHash = "sha256-H3extDaq4DgNYTUcw57gqwVWc3aPCWjIJEVYRMzdFdM="; + + installPhase = '' + runHook preInstall + cp -r dist $out + runHook postInstall + ''; +} diff --git a/web/src/App.tsx b/web/src/App.tsx index 9393563b4..9f4b77fcc 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -80,7 +80,7 @@ function PairingDialog({ onPair }: { onPair: (code: string) => Promise }) } function AppContent() { - const { isAuthenticated, pair, logout } = useAuth(); + const { isAuthenticated, loading, pair, logout } = useAuth(); const [locale, setLocaleState] = useState('tr'); const setAppLocale = (newLocale: Locale) => {