Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion .mise/tasks/init
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,13 @@ while IFS=$'\t' read -r name url pin track; do
if [ -n "$track" ]; then
sync_to_track "$name" "$mod_path" "$track" || errors=$((errors + 1))
else
git -C "$mod_path" checkout "$pin" 2>&1
git -C "$mod_path" -c advice.detachedHead=false checkout "$pin" 2>&1

actual="$(git -C "$mod_path" rev-parse HEAD)"
if [ "$actual" != "$pin" ]; then
echo " $name: warning — expected $pin, at $actual" >&2
else
echo " $name: pinned ${actual:0:12}"
fi
fi
done < "$MANIFEST"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Manage repo-level dependencies with an encrypted manifest and a gitignored clone
A public observer sees only 'this repo uses modules' — no names, no pinned commits, no count.

![lang: bash](https://img.shields.io/badge/lang-bash-4EAA25?style=flat&logo=gnubash&logoColor=white)
[![tests: 136 passing](https://img.shields.io/badge/tests-136%20passing-brightgreen?style=flat)](test/)
[![tests: 138 passing](https://img.shields.io/badge/tests-138%20passing-brightgreen?style=flat)](test/)
![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=flat)

</div>
Expand Down Expand Up @@ -122,7 +122,7 @@ cd modules && mise trust && mise install
mise run test
```

**136 tests** across 13 suites, using [BATS](https://github.com/bats-core/bats-core). All tests use local git repos in temp directories — no network, no external dependencies.
**138 tests** across 13 suites, using [BATS](https://github.com/bats-core/bats-core). All tests use local git repos in temp directories — no network, no external dependencies.

The `git-mechanics` suite verifies git's behavior around gitignored nested repos. The `merge-driver` suite simulates concurrent pin bumps to validate the manifest merge logic. The `roundtrip` suite drives the full setup → add → lock → fresh-clone → unlock → init path end-to-end with git-crypt.

Expand Down
41 changes: 41 additions & 0 deletions test/init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,47 @@ setup() {
[ "$actual" = "$pin" ]
}

@test "init prints pinned status line for pinned modules" {
modules add "$REMOTE" --name my-repo
git -C "$PARENT" commit -m "add module"

local pin
pin="$(manifest_pin_of "$PARENT/.modules/manifest" "my-repo")"

# Remove clone so init re-clones and checks out
rm -rf "$PARENT/modules/my-repo"

run modules init
[ "$status" -eq 0 ]

# Should print a pinned status line with the short SHA (not the long advice block)
[[ "$output" == *"pinned "* ]]
[[ "$output" == *"my-repo"* ]]
[[ "$output" != *"Note: switching to"* ]]
[[ "$output" != *"detached HEAD"* ]]
}

@test "init preserves real checkout errors for pinned modules" {
modules add "$REMOTE" --name my-repo

# Use a SHA that doesn't exist in the remote
local bad_pin="0000000000000000000000000000000000000000"

# Replace the pin in the manifest directly via awk (TSV: name<tab>url<tab>pin)
local url
url="$(manifest_url_of "$PARENT/.modules/manifest" "my-repo")"
awk -F' ' -v n="my-repo" -v u="$url" -v p="$bad_pin" 'BEGIN{OFS=" "} $1==n{$3=p} 1' "$PARENT/.modules/manifest" > "$PARENT/.modules/manifest.tmp"
mv "$PARENT/.modules/manifest.tmp" "$PARENT/.modules/manifest"
git -C "$PARENT" add .modules/manifest
git -C "$PARENT" commit -m "bad pin"

rm -rf "$PARENT/modules/my-repo"

run modules init
[ "$status" -ne 0 ]
[[ "$output" == *"fatal"* || "$output" == *"paths"* || "$output" == *"not a valid object"* ]]
}

@test "init skips already-cloned untracked modules" {
modules add "$REMOTE" --name my-repo

Expand Down
Loading