From 0a74b0dbcc946a58b35a909340e6dc2d5b17bd59 Mon Sep 17 00:00:00 2001 From: Spencer Brower Date: Fri, 12 Jun 2026 15:58:27 -0400 Subject: [PATCH] build: Converted Makefile and flake package. --- .github/workflows/go.yml | 28 ---------- .github/workflows/odin.yml | 31 ++++++++++ .github/workflows/release-please.yml | 2 +- .gitignore | 1 + Makefile | 41 ++++++++------ TODOS.md | 4 ++ cmd/mod.nu | 79 -------------------------- version.odin => cmd_version.odin | 3 +- db_integration_test.odin | 17 +++--- flake.nix | 84 ++++++++++++---------------- 10 files changed, 105 insertions(+), 185 deletions(-) delete mode 100644 .github/workflows/go.yml create mode 100644 .github/workflows/odin.yml delete mode 100644 cmd/mod.nu rename version.odin => cmd_version.odin (91%) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml deleted file mode 100644 index 8549c05..0000000 --- a/.github/workflows/go.yml +++ /dev/null @@ -1,28 +0,0 @@ -# This workflow will build a golang project -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go - -name: Go - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '1.24.6' - - - name: Build - run: go build -v ./... - - - name: Test - run: go test -v ./... diff --git a/.github/workflows/odin.yml b/.github/workflows/odin.yml new file mode 100644 index 0000000..a3efc8e --- /dev/null +++ b/.github/workflows/odin.yml @@ -0,0 +1,31 @@ +name: Odin + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libsodium-dev sqlite3 libsqlite3-dev + + - name: Install Odin + run: | + git clone https://github.com/odin-lang/Odin.git /opt/odin + cd /opt/odin + ./build_odin.sh release + echo "/opt/odin" >> "$GITHUB_PATH" + + - name: Build + run: odin build . -o:speed -out:envr + + - name: Test + run: odin test . diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 5a6a967..5a7cfb2 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -22,4 +22,4 @@ jobs: token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }} # this is a built-in strategy in release-please, see "Action Inputs" # for more options - release-type: go + release-type: odin diff --git a/.gitignore b/.gitignore index db86c1b..f49b1b1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ builds envr envr-go result +version.odin diff --git a/Makefile b/Makefile index fa1fcf2..11de6a4 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ APP_NAME := envr VERSION := $(shell grep 'version = ' flake.nix | head -1 | sed 's/.*version = "\(.*\)";/\1/') BUILD_DIR := builds -LDFLAGS := -X github.com/sbrow/envr/cmd.version=v$(VERSION) -s -w # Binary names LINUX_AMD64_BIN := $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-amd64 @@ -20,26 +19,31 @@ all: release clean $(BUILD_DIR): @mkdir -p $(BUILD_DIR) +# Generate version.odin from flake.nix +version.odin: + @echo 'Generating version.odin (v$(VERSION))...' + @printf 'package main\n\nVERSION :: "$(VERSION)"\n' > version.odin + # Build Linux AMD64 -$(LINUX_AMD64_BIN): $(BUILD_DIR) +$(LINUX_AMD64_BIN): version.odin $(BUILD_DIR) @echo "Building for Linux AMD64..." - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $(LINUX_AMD64_BIN) . + odin build . -target:linux_amd64 -o:speed -out:$(LINUX_AMD64_BIN) @echo "Built $(LINUX_AMD64_BIN)" # Build Linux ARM64 -$(LINUX_ARM64_BIN): $(BUILD_DIR) +$(LINUX_ARM64_BIN): version.odin $(BUILD_DIR) @echo "Building for Linux ARM64..." - GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $(LINUX_ARM64_BIN) . + odin build . -target:linux_arm64 -o:speed -out:$(LINUX_ARM64_BIN) @echo "Built $(LINUX_ARM64_BIN)" # Build Darwin ARM64 (Mac) -$(DARWIN_ARM64_BIN): $(BUILD_DIR) +$(DARWIN_ARM64_BIN): version.odin $(BUILD_DIR) @echo "Building for Darwin ARM64..." - GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $(DARWIN_ARM64_BIN) . + odin build . -target:darwin_arm64 -o:speed -out:$(DARWIN_ARM64_BIN) @echo "Built $(DARWIN_ARM64_BIN)" # Build all binaries -build-linux: $(LINUX_AMD64_BIN) $(LINUX_ARM64_BIN) +build-linux: $(LINUX_AMD64_BIN) # $(LINUX_ARM64_BIN) build-darwin: $(DARWIN_ARM64_BIN) # Compress Linux artifacts with gzip @@ -58,11 +62,12 @@ $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-darwin-arm64.zip: $(DARWIN_ARM64_BIN) # Compress all artifacts compress: $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-amd64.tar.gz \ - $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-arm64.tar.gz \ - $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-darwin-arm64.zip + # $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-arm64.tar.gz \ + # $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-darwin-arm64.zip # Build and compress all release artifacts -release: build-linux build-darwin compress +# release: build-linux build-darwin compress +release: build-linux compress @echo "Release artifacts created:" @ls -la $(BUILD_DIR)/*.tar.gz $(BUILD_DIR)/*.zip 2>/dev/null || echo "No compressed artifacts found" @@ -79,14 +84,14 @@ cleanall: # Show available targets help: @echo "Available targets:" - @echo " all - Build all release artifacts (default)" - @echo " release - Build and compress all release artifacts" - @echo " build-linux - Build Linux binaries only" + @echo " all - Build all release artifacts (default)" + @echo " release - Build and compress all release artifacts" + @echo " build-linux - Build Linux binaries only" @echo " build-darwin - Build Darwin binaries only" - @echo " compress - Compress all built binaries" - @echo " clean - Remove binary files only" - @echo " cleanall - Remove entire build directory" - @echo " help - Show this help message" + @echo " compress - Compress all built binaries" + @echo " clean - Remove binary files only" + @echo " cleanall - Remove entire build directory" + @echo " help - Show this help message" @echo "" @echo "Release artifacts will be created in $(BUILD_DIR)/" @echo "Version: $(VERSION)" diff --git a/TODOS.md b/TODOS.md index 18b9fd4..4d40013 100644 --- a/TODOS.md +++ b/TODOS.md @@ -36,6 +36,8 @@ Note: These todos can wait until all the subcommands have been ported. 35. **prompt.odin:124** — `make([dynamic]bool, len(options))` creates N zero-initialized elements. Works because `false` is the default, but same footgun as original issue 1. Should be `make([dynamic]bool, 0, len(options))`. +39. Lots of memory leaks to fix. + ## LOW 15. **db.odin:115** — `json.unmarshal_string` error not checked. Malformed JSON silently produces empty/partial data. @@ -63,3 +65,5 @@ Note: These todos can wait until all the subcommands have been ported. 27. version --long Odin only prints version; Go also prints commit hash and build date 28. 2 scan tests silently skip Low When fd isn't installed, tests pass without actually testing anything. These should use #assert to be sure that fd is in path. + +38. Try to do all encryption / decryption in memory - only read / write encrypted data to disk. diff --git a/cmd/mod.nu b/cmd/mod.nu deleted file mode 100644 index 679c7ff..0000000 --- a/cmd/mod.nu +++ /dev/null @@ -1,79 +0,0 @@ -# envr command extern definitions for Nushell -# A tool for managing environment files and backups - -export def tracked-paths [] { - ( - ^envr list - | from json - | each { - [$in.directory $in.path] | path join - } - ) -} - -export def untracked-paths [] { - ( - ^envr scan - | from json - ) -} - -# Complete shell types for completion command -def shells [] { - ["bash", "zsh", "fish", "powershell"] -} - -export extern envr [ - ...args: any - --help(-h) # Show help information - --toggle(-t) # Help message for toggle -] - -export extern "envr backup" [ - --help(-h) # Show help for backup command - path: path@untracked-paths # Path to .env file to backup -] -#TODO: envr backup path. - -export extern "envr check" [ - --help(-h) # Show help for check command -] - -export extern "envr completion" [ - shell: string@shells # Shell to generate completion for - --help(-h) # Show help for completion command -] - -export extern "envr edit-config" [ - --help(-h) # Show help for edit-config command -] - -export extern "envr help" [ - command?: string # Show help for specific command -] - -export extern "envr init" [ - --help(-h) # Show help for init command -] - -export extern "envr list" [ - --help(-h) # Show help for list command -] - -export extern "envr remove" [ - --help(-h) # Show help for remove command - path: path@tracked-paths -] - -export extern "envr restore" [ - --help(-h) # Show help for restore command - path: path@tracked-paths -] - -export extern "envr scan" [ - --help(-h) # Show help for scan command -] - -export extern "envr sync" [ - --help(-h) # Show help for sync command -] diff --git a/version.odin b/cmd_version.odin similarity index 91% rename from version.odin rename to cmd_version.odin index 2045e99..1145209 100644 --- a/version.odin +++ b/cmd_version.odin @@ -2,8 +2,6 @@ package main import "core:fmt" -VERSION :: "0.2.0" - cmd_version :: proc(cmd: ^Command) { if has_flag(cmd, "long") || has_flag(cmd, "l") { fmt.printf("envr version %s\n", VERSION) @@ -11,3 +9,4 @@ cmd_version :: proc(cmd: ^Command) { fmt.println(VERSION) } } + diff --git a/db_integration_test.odin b/db_integration_test.odin index 3b63647..4b8d6db 100644 --- a/db_integration_test.odin +++ b/db_integration_test.odin @@ -1,6 +1,5 @@ package main -import "core:encoding/json" import "core:fmt" import "core:os" import "core:path/filepath" @@ -23,7 +22,7 @@ fixture_db_path :: proc() -> string { } fixture_config :: proc() -> Config { - cfg := Config{ + cfg := Config { Keys = make([dynamic]SshKeyPair, 0, 1), } append(&cfg.Keys, fixture_key()) @@ -263,7 +262,11 @@ test_full_db_cycle :: proc(t: ^testing.T) { testing.expect( t, len(plaintext2) == len(original_data), - fmt.tprintf("double round-trip size mismatch: expected %d, got %d", len(original_data), len(plaintext2)), + fmt.tprintf( + "double round-trip size mismatch: expected %d, got %d", + len(original_data), + len(plaintext2), + ), ) os.remove(data_path) @@ -289,12 +292,7 @@ test_ssh_key_parse_from_fixtures :: proc(t: ^testing.T) { } for i in 0 ..< 32 { - testing.expectf( - t, - priv_kp.Public[i] == pub_key[i], - "public key mismatch at byte %d", - i, - ) + testing.expectf(t, priv_kp.Public[i] == pub_key[i], "public key mismatch at byte %d", i) } x25519_pairs, x_ok := ssh_to_x25519([]SshKeyPair{key}) @@ -327,3 +325,4 @@ test_config_load_with_fixture_key :: proc(t: ^testing.T) { fmt.printf(" private key path was: '%s'\n", key.Private) } } + diff --git a/flake.nix b/flake.nix index 29c3f90..93126f4 100644 --- a/flake.nix +++ b/flake.nix @@ -40,7 +40,6 @@ }; treefmt = { - # Used to find the project root projectRootFile = "flake.nix"; settings.global.excludes = [ ".direnv/**" @@ -50,68 +49,57 @@ ".env.local" ]; - - # Format nix files programs.nixpkgs-fmt.enable = true; - # programs.deadnix.enable = true; - - # Format go files - programs.goimports.enable = true; }; - packages.default = pkgs.buildGoModule rec { + packages.default = pkgs.stdenv.mkDerivation rec { pname = "envr"; version = "0.2.0"; src = ./.; - # If the build complains, uncomment this line - # vendorHash = "sha256:0000000000000000000000000000000000000000000000000000"; - vendorHash = "sha256-aC82an6vYifewx4amfXLzk639jz9fF5bD5cF6krY0Ks="; - - nativeBuildInputs = [ pkgs.installShellFiles ]; - ldflags = [ - "-X github.com/sbrow/envr/cmd.version=v${version}" - # "-X github.com/sbrow/envr/cmd.commit=$(git rev-parse HEAD)" - # "-X github.com/sbrow/envr/cmd.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" + nativeBuildInputs = [ + pkgs.unstable.odin + pkgs.pkg-config ]; - - postBuild = '' - # Generate man pages - $GOPATH/bin/docgen -out ./man -format man + + buildInputs = [ + pkgs.libsodium + pkgs.sqlite + ]; + + buildPhase = '' + runHook preBuild + make version.odin + odin build . -o:speed -out:${pname} + runHook postBuild ''; - - postInstall = '' - # Install man pages - installManPage ./man/*.1 + + installPhase = '' + runHook preInstall + install -Dm755 ${pname} $out/bin/${pname} + runHook postInstall ''; }; - devShells.default = pkgs.mkShell - { - buildInputs = with pkgs; [ - fd - nushell - go - gopls + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + fd + nushell - gotools - cobra-cli + libsodium + sqlite + unstable.odin + unstable.ols - age - libsodium - sqlite - unstable.odin - unstable.ols + # Build tools + zip - # Build tools - zip - - # IDE - unstable.helix - typescript-language-server - vscode-langservers-extracted - ]; - }; + # IDE + unstable.helix + typescript-language-server + vscode-langservers-extracted + ]; + }; }; }; }