Skip to content

Commit f8e07ae

Browse files
committed
feat(realms): v1
1 parent 579490b commit f8e07ae

File tree

8 files changed

+439
-0
lines changed

8 files changed

+439
-0
lines changed

.github/workflows/gno-fmt.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Gno Packages
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- "realms/**"
8+
- ".github/workflows/**"
9+
pull_request:
10+
paths:
11+
- "realms/**"
12+
- ".github/workflows/**"
13+
14+
permissions:
15+
contents: read
16+
17+
env:
18+
GO_VERSION: "1.23.x"
19+
GOBIN: ${{ github.workspace }}/bin
20+
21+
22+
jobs:
23+
fmt:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout this repo
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Go
30+
uses: actions/setup-go@v5
31+
with:
32+
go-version: ${{ env.GO_VERSION }}
33+
cache: true
34+
35+
- name: Ensure deps are downloaded
36+
run: go mod download
37+
38+
- name: Format
39+
working-directory: packages
40+
run: go run github.com/gnolang/gno/gnovm/cmd/gno fmt -diff ./...

.github/workflows/gno-lint.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Gno Packages
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- "realms/**"
8+
- ".github/workflows/**"
9+
pull_request:
10+
paths:
11+
- "realms/**"
12+
- ".github/workflows/**"
13+
14+
permissions:
15+
contents: read
16+
17+
env:
18+
GO_VERSION: "1.23.x"
19+
GOBIN: ${{ github.workspace }}/bin
20+
21+
jobs:
22+
lint:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout this repo
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Go
29+
uses: actions/setup-go@v5
30+
with:
31+
go-version: ${{ env.GO_VERSION }}
32+
cache: true
33+
34+
- name: Ensure deps are downloaded
35+
run: go mod download
36+
37+
- name: Lint
38+
working-directory: packages
39+
run: go run github.com/gnolang/gno/gnovm/cmd/gno lint ./... -v

.github/workflows/gno-test.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Gno Packages
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- "realms/**"
8+
- ".github/workflows/**"
9+
pull_request:
10+
paths:
11+
- "realms/**"
12+
- ".github/workflows/**"
13+
14+
permissions:
15+
contents: read
16+
17+
env:
18+
GO_VERSION: "1.23.x"
19+
GOBIN: ${{ github.workspace }}/bin
20+
21+
jobs:
22+
test:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout this repo
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Go
29+
uses: actions/setup-go@v5
30+
with:
31+
go-version: ${{ env.GO_VERSION }}
32+
cache: true
33+
34+
- name: Ensure deps are downloaded
35+
run: go mod download
36+
37+
- name: Test
38+
working-directory: packages
39+
run: go run github.com/gnolang/gno/gnovm/cmd/gno test ./... -v

realms/api.gno

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package gnit
2+
3+
import (
4+
"gno.land/p/nt/avl"
5+
)
6+
7+
func NewRepository(name string) *Repository {
8+
return &Repository{
9+
identity: Identity{
10+
Name: name,
11+
},
12+
head: "main",
13+
}
14+
}
15+
16+
func (r *Repository) Pull(file string) []byte {
17+
headCommit := r.GetHeadCommit()
18+
if headCommit == nil {
19+
return nil
20+
}
21+
22+
return r.GetFile(headCommit.Hash, file)
23+
}
24+
25+
func (r *Repository) Commit(message string, files map[string][]byte) string {
26+
if r.commits == nil {
27+
r.commits = avl.NewTree()
28+
}
29+
if r.objects == nil {
30+
r.objects = avl.NewTree()
31+
}
32+
if r.refs == nil {
33+
r.refs = avl.NewTree()
34+
}
35+
36+
treeHash := createTreeHash(files)
37+
38+
tree := make(map[string]string)
39+
for path, content := range files {
40+
objectHash := createObjectHash(content)
41+
r.objects.Set(objectHash, content)
42+
tree[path] = objectHash
43+
}
44+
45+
r.objects.Set(treeHash, tree)
46+
47+
timestamp := int64(12345)
48+
49+
commit := &Commit{
50+
Tree: treeHash,
51+
Parents: []string{},
52+
Author: r.identity,
53+
Committer: r.identity,
54+
Message: message,
55+
Timestamp: timestamp,
56+
}
57+
58+
commitHash := createCommitHash(commit)
59+
commit.Hash = commitHash
60+
61+
r.commits.Set(commitHash, commit)
62+
r.refs.Set(r.head, commitHash)
63+
64+
return commitHash
65+
}
66+
67+
func (r *Repository) GetCommit(hash string) *Commit {
68+
if r.commits == nil {
69+
return nil
70+
}
71+
value, exists := r.commits.Get(hash)
72+
if !exists {
73+
return nil
74+
}
75+
return value.(*Commit)
76+
}
77+
78+
func (r *Repository) GetFile(commitHash, path string) []byte {
79+
commit := r.GetCommit(commitHash)
80+
if commit == nil {
81+
return nil
82+
}
83+
84+
treeValue, exists := r.objects.Get(commit.Tree)
85+
if !exists {
86+
return nil
87+
}
88+
89+
tree := treeValue.(map[string]string)
90+
91+
objectHash, exists := tree[path]
92+
if !exists {
93+
return nil
94+
}
95+
96+
fileValue, exists := r.objects.Get(objectHash)
97+
if !exists {
98+
return nil
99+
}
100+
101+
return fileValue.([]byte)
102+
}
103+
104+
func (r *Repository) GetHeadCommit() *Commit {
105+
if r.refs == nil {
106+
return nil
107+
}
108+
109+
commitHash, exists := r.refs.Get(r.head)
110+
if !exists {
111+
return nil
112+
}
113+
114+
return r.GetCommit(commitHash.(string))
115+
}
116+
117+
func (r *Repository) GetCurrentBranch() string {
118+
return r.head
119+
}

realms/api_test.gno

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package gnit
2+
3+
import "testing"
4+
5+
func TestNewRepository(t *testing.T) {
6+
r := NewRepository("foo")
7+
8+
if r.identity.Name != "foo" {
9+
t.Errorf("expected %s, got %s", "foo", r.identity.Name)
10+
}
11+
}
12+
13+
func TestCommit(t *testing.T) {
14+
r := NewRepository("test-repo")
15+
16+
files := map[string][]byte{
17+
"main.go": []byte("package main\n\nfunc main() {\n\tprintln(\"Hello, World!\")\n}"),
18+
"README.md": []byte("# Test Project\n\nThis is a test project."),
19+
}
20+
21+
commitHash := r.Commit("Initial commit", files)
22+
23+
if commitHash == "" {
24+
t.Error("expected non-empty commit hash")
25+
}
26+
27+
commit := r.GetCommit(commitHash)
28+
if commit == nil {
29+
t.Error("expected commit to be stored")
30+
}
31+
32+
if commit.Message != "Initial commit" {
33+
t.Errorf("expected message 'Initial commit', got %s", commit.Message)
34+
}
35+
36+
if commit.Hash != commitHash {
37+
t.Errorf("expected hash %s, got %s", commitHash, commit.Hash)
38+
}
39+
}
40+
41+
func TestGetFile(t *testing.T) {
42+
r := NewRepository("test-repo")
43+
44+
files := map[string][]byte{
45+
"main.go": []byte("package main\n\nfunc main() {\n\tprintln(\"Hello, World!\")\n}"),
46+
"README.md": []byte("# Test Project\n\nThis is a test project."),
47+
}
48+
49+
commitHash := r.Commit("Initial commit", files)
50+
51+
mainContent := r.GetFile(commitHash, "main.go")
52+
if string(mainContent) != string(files["main.go"]) {
53+
t.Errorf("expected %s, got %s", string(files["main.go"]), string(mainContent))
54+
}
55+
56+
readmeContent := r.GetFile(commitHash, "README.md")
57+
if string(readmeContent) != string(files["README.md"]) {
58+
t.Errorf("expected %s, got %s", string(files["README.md"]), string(readmeContent))
59+
}
60+
61+
nonExistentContent := r.GetFile(commitHash, "nonexistent.txt")
62+
if nonExistentContent != nil {
63+
t.Error("expected nil for non-existent file")
64+
}
65+
}
66+
67+
func TestGetCommitNonExistent(t *testing.T) {
68+
r := NewRepository("test-repo")
69+
70+
commit := r.GetCommit("nonexistent-hash")
71+
if commit != nil {
72+
t.Error("expected nil for non-existent commit")
73+
}
74+
}
75+
76+
func TestMultipleCommits(t *testing.T) {
77+
r := NewRepository("test-repo")
78+
79+
files1 := map[string][]byte{
80+
"file1.txt": []byte("First version"),
81+
}
82+
hash1 := r.Commit("First commit", files1)
83+
84+
files2 := map[string][]byte{
85+
"file1.txt": []byte("Second version"),
86+
"file2.txt": []byte("New file"),
87+
}
88+
hash2 := r.Commit("Second commit", files2)
89+
90+
if hash1 == hash2 {
91+
t.Error("expected different hashes for different commits")
92+
}
93+
94+
content1 := r.GetFile(hash1, "file1.txt")
95+
if string(content1) != "First version" {
96+
t.Errorf("expected 'First version', got %s", string(content1))
97+
}
98+
99+
content2 := r.GetFile(hash2, "file1.txt")
100+
if string(content2) != "Second version" {
101+
t.Errorf("expected 'Second version', got %s", string(content2))
102+
}
103+
104+
newFile := r.GetFile(hash2, "file2.txt")
105+
if string(newFile) != "New file" {
106+
t.Errorf("expected 'New file', got %s", string(newFile))
107+
}
108+
}

realms/gnomod.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module = "gno.land/p/gnit"
2+
gno = "0.9"

realms/types.gno

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package gnit
2+
3+
import (
4+
"std"
5+
6+
"gno.land/p/nt/avl"
7+
)
8+
9+
type Repository struct {
10+
identity Identity
11+
12+
head string // current branch name
13+
refs *avl.Tree // branch (string) -> hash
14+
commits *avl.Tree // hash -> []byte
15+
objects *avl.Tree // hash -> Object
16+
}
17+
18+
type Commit struct {
19+
Hash string
20+
Tree string
21+
Parents []string
22+
Author Identity
23+
Committer Identity
24+
Message string
25+
Timestamp int64
26+
}
27+
28+
type Identity struct {
29+
Name string
30+
Email string
31+
Address std.Address
32+
}
33+
34+
// type TreeEntry struct {
35+
// Mode FileMode
36+
// Name string
37+
// Hash string
38+
// }

0 commit comments

Comments
 (0)