]> gitweb.ps.run Git - ziggit/blob - git.zig
git.zig
[ziggit] / git.zig
1 const std = @import("std");
2
3 const Alloc = std.mem.Allocator;
4
5 const Id = u160;
6 const Commit = struct {
7     author: std.BoundedArray(u8, 64),
8     message: std.BoundedArray(u8, 1024),
9     parent: Id,
10     tree: Id,
11 };
12 const Blob = struct {
13     data: std.BoundedArray(u8, 1024),
14 };
15 const Object = struct {
16     alloc: Alloc,
17
18     // pub fn getCommit(self: *Object) Commit {}
19     // pub fn getBlob(self: *Object) Blob {}
20 };
21 const PackFile = struct {
22     alloc: Alloc,
23
24     pub fn init(alloc: Alloc) PackFile {
25         return .{
26             .alloc = alloc,
27         };
28     }
29     pub fn deinit(self: *PackFile) void {
30         _ = self;
31     }
32     pub fn parse(self: *PackFile, idxReader: std.io.AnyReader, pckReader: anytype) !void {
33         _ = self;
34         var buffer: [16]u8 = undefined;
35         _ = try idxReader.read(&buffer);
36         std.debug.print("{s}\n", .{&buffer});
37         _ = try pckReader.read(&buffer);
38         std.debug.print("{s}\n", .{&buffer});
39     }
40
41     // pub fn init(alloc: Alloc, path: []const u8) PackFile {}
42     // pub fn deinit(self: *PackFile) void {}
43     // pub fn getObject(self: *PackFile, id: Id) Object {}
44 };
45 const Repo = struct {
46     alloc: Alloc,
47     packfile: PackFile,
48
49     head: Id,
50
51     pub fn open(alloc: Alloc, path: []const u8) !Repo {
52         const dir = try std.fs.cwd().openDir(path, .{});
53
54         // read file HEAD
55         const head = try dir.readFileAlloc(alloc, "HEAD", 1024);
56         defer alloc.free(head);
57
58         // read file pointed at by HEAD
59         const headPath = head[5 .. head.len - 1];
60         var idBuffer: [40]u8 = undefined;
61         const idStr = try dir.readFile(headPath, &idBuffer);
62
63         // parse id from file
64         const id = try std.fmt.parseUnsigned(u160, idStr, 16);
65
66         // open any packfiles
67         var packfile = PackFile.init(alloc);
68         if (dir.openDir("objects/pack", .{ .iterate = true })) |packDir| {
69             var packIt = packDir.iterate();
70             while (try packIt.next()) |f| {
71                 if (std.mem.endsWith(u8, f.name, ".idx")) {
72                     const idxFilename = f.name;
73                     var pckFilenameBuffer: [64]u8 = undefined;
74                     const pckFilename = try std.fmt.bufPrint(&pckFilenameBuffer, "{s}.pack", .{idxFilename[0 .. idxFilename.len - 4]});
75
76                     const idxFile = try packDir.openFile(idxFilename, .{});
77                     const pckFile = try packDir.openFile(pckFilename, .{});
78                     defer idxFile.close();
79                     defer pckFile.close();
80
81                     const idxReader = idxFile.reader().any();
82                     const pckReader = pckFile.reader().any();
83
84                     try packfile.parse(idxReader, pckReader);
85                 }
86             }
87         } else |err| {
88             std.debug.print("{}\n", .{err});
89         }
90
91         return .{
92             .alloc = alloc,
93             .packfile = packfile,
94             .head = id,
95         };
96     }
97     pub fn close(self: *Repo) void {
98         self.packfile.deinit();
99     }
100     // pub fn getObject(self: *Repo, id: Id) Object {}
101 };
102
103 test "print HEAD" {
104     var repo = try Repo.open(std.testing.allocator, "../microwindows/.git");
105     defer repo.close();
106
107     std.debug.print("HEAD: {}\n", .{repo.head});
108 }
109
110 // test "list commits" {
111 //     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
112 //     defer repo.close();
113
114 //     const head = repo.getObject(repo.head);
115 //     defer head.deinit();
116
117 //     var c = head.getCommit();
118 //     for (0..3) |_| {
119 //         std.debug.print("{}\n", .{c});
120 //         c = c.parent;
121 //     }
122 // }
123
124 // test "tree" {
125 //     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
126 //     defer repo.close();
127
128 //     const head = repo.getObject(repo.head);
129 //     defer head.deinit();
130
131 //     const commit = head.getCommit();
132
133 //     std.debug.print("{}\n", .{commit.tree});
134 // }
135
136 // test "blob" {
137 //     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
138 //     defer repo.close();
139
140 //     const head = repo.getObject(repo.head);
141 //     defer head.deinit();
142
143 //     const commit = head.getCommit();
144 //     const blob = repo.getBlob(commit.files[0].id);
145
146 //     std.debug.print("{}\n", .{blob});
147 // }