Week 02 of 2024

Development log of Tad Notes

Setup a Rust Cargo project

On by Tad Lispy

new file mode 100644
index 0000000..5330b9c
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,28 @@
+shopt -s globstar
+
+watch_file **/*.nix
+watch_file flake.lock
+watch_file rust-toolchain.toml
+
+use_flake() {
+    mkdir -p "$(direnv_layout_dir)"
+    eval "$(nix print-dev-env --profile "$(direnv_layout_dir)/flake-profile")"
+}
+
+if (nix help flake &> /dev/null)
+then
+    # Nix with flakes support
+    use flake
+
+elif command -v lorri
+then
+    # Lorri is installed
+    eval "$(lorri direnv)"
+
+else
+    # Standard nix - going to be slooow
+    use nix
+
+fi
+
+source_env_if_exists .envrc.private
new file mode 100644
index 0000000..e426355
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+.direnv/
+/target/
+/result
+/public/
+/dist/
+/web/
+/build-image
+/.cargo-home/
new file mode 100644
index 0000000..e047bd7
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "denote-tools"
+version = "0.1.0"
new file mode 100644
index 0000000..a4f51ad
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "denote-tools"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
new file mode 100644
index 0000000..04a5076
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,102 @@
+name := bevy-animated-sprite-playground
+
+include Makefile.d/defaults.mk
+
+all: ## Build the program (DEFAULT)
+all: test build
+.PHONY: all
+
+build: $(shell find src/)
+build: Cargo.lock
+build:
+	cargo build --release
+.PHONY: build
+
+test:
+	cargo test
+.PHONY: test
+
+install: ## Install the program in the ${prefix} directory
+install: prefix ?= $(out)
+install: build
+	test $(prefix)
+	mkdir --parents $(prefix)
+	cp --recursive $</* $(prefix)/
+.PHONY: install
+
+
+### DEVELOPMENT
+
+develop: ## Rebuild and run a development version of the program
+develop:
+	cargo run --features bevy/dynamic
+.PHONY: develop
+
+clean: ## Remove all build artifacts
+clean:
+	git clean -dfX \
+		--exclude='!.envrc.private'
+.PHONY: clean
+
+help: ## Print this help message
+help:
+	@
+	echo "Useage: make [ goals ]"
+	echo
+	echo "Available goals:"
+	echo
+	cat $(MAKEFILE_LIST) | awk -f Makefile.d/make-goals.awk
+.PHONY: help
+
+
+### NIX SPECIFIC
+
+export nix := nix --experimental-features "nix-command flakes"
+export nix-cache-name := software-garden
+
+result: ## Build the program using Nix
+result:
+	cachix use $(nix-cache-name)
+	$(nix) build --print-build-logs
+
+nix-cache: ## Push Nix binary cache to Cachix
+nix-cache: result
+	$(nix) flake archive --json \
+	| jq --raw-output '.path, (.inputs | to_entries [] .value.path)' \
+	| cachix push $(nix-cache-name)
+
+	$(nix) path-info --recursive \
+	| cachix push $(nix-cache-name)
+
+
+### OCI BUILD IMAGE RELATED
+
+build-image: ## Create an OCI image with build environment (to be used in CI)
+build-image: flake.nix
+build-image: flake.lock
+build-image: rust-toolchain.toml
+build-image:
+	nix build \
+		--print-build-logs \
+		.#docker-image
+	cp --dereference result $@
+
+load-build-image: ## Load the OCI image using Podman
+load-build-image: build-image
+	gzip --decompress $^ --to-stdout | podman image load
+.PHONY: load-build-image
+
+build-inside-container: ## Build the program in an OCI container (e.g. to test CI)
+build-inside-container: load-build-image
+	# We need to know the project name to know which image to load. Can we do better?
+	test $${project_name}
+	podman run \
+		--rm \
+		--interactive \
+		--tty \
+		--volume ${PWD}:/src \
+		--workdir /src \
+		--entrypoint make \
+		localhost/$(project_name)-build-image \
+		public
+.PHONY: build-inside-container
new file mode 100644
index 0000000..1a788da
--- /dev/null
+++ b/Makefile.d/defaults.mk
@@ -0,0 +1,39 @@
+# Default settings for Make
+
+# Always use strict bash
+SHELL := bash
+.SHELLFLAGS := -eu -o pipefail -c
+.ONESHELL:
+
+# If a recipe fails, delete it's targets to avoid broken state
+.DELETE_ON_ERROR:
+
+# Allow $$(variables) to be expanded in a second pass
+.SECONDEXPANSION:
+
+# Warn about undefined variables and
+# TODO: How to make it an error, like in bash strict mode?
+# TODO: Consider https://www.artificialworlds.net/blog/2015/04/22/treat-warnings-as-errors-in-a-gnu-makefile/
+MAKEFLAGS += --warn-undefined-variables
+MAKEFLAGS += --warn-undefined-functions
+
+# Remove implicit rules - no magic please
+# See https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
+MAKEFLAGS += --no-builtin-rules
+
+# Helper functions
+
+define slugify
+$(shell \
+	echo $(1) \
+		| tr '[:upper:]' '[:lower:]' \
+		| tr --squeeze-repeats --complement '[:alnum:]\n' '-' \
+)
+endef
+
+# General purpose variables
+
+author = $(shell git config user.name)
+
+timestamp = $(shell date '+%s')
+
new file mode 100644
index 0000000..ca79030
--- /dev/null
+++ b/Makefile.d/make-goals.awk
@@ -0,0 +1,4 @@
+# Section header
+match($0, /^### (.+)/, matches)        { printf "\n\n%s:\n\n", matches[1] }
+# Goal with description
+match($0, /^(.+):.* ## (.+)/, matches) { printf "  %-30s %s\n", matches[1], matches[2]}
new file mode 100644
index 0000000..c17601f
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,130 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1701680307,
+        "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_2": {
+      "inputs": {
+        "systems": "systems_2"
+      },
+      "locked": {
+        "lastModified": 1681202837,
+        "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1705133751,
+        "narHash": "sha256-rCIsyE80jgiOU78gCWN3A0wE0tR2GI5nH6MlS+HaaSQ=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "9b19f5e77dd906cb52dade0b7bd280339d2a1f3d",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1681358109,
+        "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs",
+        "rust-overlay": "rust-overlay"
+      }
+    },
+    "rust-overlay": {
+      "inputs": {
+        "flake-utils": "flake-utils_2",
+        "nixpkgs": "nixpkgs_2"
+      },
+      "locked": {
+        "lastModified": 1705198720,
+        "narHash": "sha256-/pzqqQQ1aU4llyaCDVjhPjQWIWpcRxFCsiDzl0lcAIk=",
+        "owner": "oxalica",
+        "repo": "rust-overlay",
+        "rev": "71d1d01578272b2294f6993b1860dfb22e4baac3",
+        "type": "github"
+      },
+      "original": {
+        "owner": "oxalica",
+        "repo": "rust-overlay",
+        "type": "github"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_2": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
new file mode 100644
index 0000000..aac49e1
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,53 @@
+{
+  description = "Tools complementing Denote note taking system";
+
+  inputs = {
+    nixpkgs.url      = "github:NixOS/nixpkgs/nixos-unstable";
+    rust-overlay.url = "github:oxalica/rust-overlay";
+    flake-utils.url  = "github:numtide/flake-utils";
+  };
+
+  outputs = { self, nixpkgs, rust-overlay, flake-utils }:
+    flake-utils.lib.eachDefaultSystem (system:
+      let
+        project-name = "denote-tools";
+        overlays = [ (import rust-overlay) ];
+        pkgs = import nixpkgs {
+          inherit system overlays;
+        };
+        buildInputs = with pkgs; [
+        ];
+        nativeBuildInputs = with pkgs; [
+          (rust-bin.fromRustupToolchainFile ./rust-toolchain.toml)
+          gcc
+          pkg-config
+          gnumake
+          findutils
+          gzip
+          lld
+          rustPlatform.bindgenHook
+        ];
+      in
+      {
+        devShell = pkgs.mkShell {
+          inherit buildInputs nativeBuildInputs;
+          name = "${project-name}-develpoment-shell";
+          packages = with pkgs; [
+            pkgs.rust-analyzer
+            pkgs.jq
+          ];
+          project_name = project-name; # Expose as an environment variable for make
+        };
+        defaultPackage = pkgs.rustPlatform.buildRustPackage {
+          name = project-name;
+          version = "1.0.0";
+          src = ./.;
+          cargoLock = {
+            lockFile = ./Cargo.lock;
+          };
+
+          inherit buildInputs nativeBuildInputs;
+        };
+      }
+    );
+}
new file mode 100644
index 0000000..cebc13d
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,4 @@
+[toolchain]
+channel = "stable"
+components = [ "rust-src" ]
+profile = "default"
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}