package skillpack import ( "context" "os" "os/exec" "path/filepath" "testing" ) func writePack(t *testing.T, dir string) { t.Helper() if err := os.MkdirAll(filepath.Join(dir, "scripts"), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, ManifestName), []byte(goodManifest), 0o644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "scripts", "fill.py"), []byte("print('hi')\n"), 0o644); err != nil { t.Fatal(err) } } func TestDirSource(t *testing.T) { dir := t.TempDir() writePack(t, dir) tree, ref, err := DirSource{Path: dir}.Fetch(context.Background(), "") if err != nil { t.Fatal(err) } if ref != tree.Digest() { t.Errorf("dir resolved ref should be the content digest") } p, err := LoadPack(tree) if err != nil { t.Fatal(err) } if p.Manifest.Name != "pdf-processing" || len(p.Bundled) != 1 { t.Errorf("loaded pack wrong: name=%q bundled=%v", p.Manifest.Name, p.Bundled) } } func TestDirSource_NotADir(t *testing.T) { f := filepath.Join(t.TempDir(), "file") os.WriteFile(f, []byte("x"), 0o644) if _, _, err := (DirSource{Path: f}).Fetch(context.Background(), ""); err == nil { t.Fatal("expected error for non-directory source") } } // TestGitSource drives a real local git repo (no network) to exercise clone + // checkout + subpath + SHA resolution. Skipped when git is unavailable. func TestGitSource(t *testing.T) { if _, err := exec.LookPath("git"); err != nil { t.Skip("git not installed") } repo := t.TempDir() git := func(args ...string) { t.Helper() cmd := exec.Command("git", args...) cmd.Dir = repo cmd.Env = append(os.Environ(), "GIT_AUTHOR_NAME=t", "GIT_AUTHOR_EMAIL=t@t", "GIT_COMMITTER_NAME=t", "GIT_COMMITTER_EMAIL=t@t") if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("git %v: %v: %s", args, err, out) } } git("init", "-q", "-b", "main") // pack lives under packs/pdf/ sub := filepath.Join(repo, "packs", "pdf") writePack(t, sub) git("add", "-A") git("commit", "-q", "-m", "add pack") src := GitSource{URL: repo, Subpath: "packs/pdf"} tree, sha, err := src.Fetch(context.Background(), "main") if err != nil { t.Fatal(err) } if len(sha) != 40 { t.Errorf("resolved ref should be a full SHA, got %q", sha) } if _, ok := tree[ManifestName]; !ok { t.Errorf("subpath tree missing SKILL.md; got %v", tree.Paths()) } if _, ok := tree[".git"]; ok { t.Error(".git leaked into the tree") } p, err := LoadPack(tree) if err != nil { t.Fatal(err) } if p.Manifest.Name != "pdf-processing" { t.Errorf("name = %q", p.Manifest.Name) } }