@@ -3,12 +3,14 @@ const std = @import("std");
33const Flags = struct {
44 help : bool ,
55 branch : []const u8 ,
6+ path : []const u8 ,
67 remote : []const u8 ,
78
89 pub fn init (allocator : std.mem.Allocator ) ! Flags {
910 var flags = Flags {
1011 .help = false ,
1112 .branch = "main" ,
13+ .path = "." ,
1214 .remote = "origin" ,
1315 };
1416 var args = try std .process .argsWithAllocator (allocator );
@@ -21,6 +23,8 @@ const Flags = struct {
2123 break ;
2224 } else if (std .mem .eql (u8 , arg , "--branch" )) {
2325 flags .branch = try parse (& args );
26+ } else if (std .mem .eql (u8 , arg , "--path" )) {
27+ flags .path = try parse (& args );
2428 } else if (std .mem .eql (u8 , arg , "--remote" )) {
2529 flags .remote = try parse (& args );
2630 } else {
@@ -58,6 +62,7 @@ pub fn main() !void {
5862 \\
5963 \\ --help boolean print these usage details (default: false)
6064 \\ --branch string fetch changes to inspect (default: "main")
65+ \\ --path string show a specific file (default: ".")
6166 \\ --remote string pick an upstream project (default: "origin")
6267 \\
6368 , .{});
@@ -72,7 +77,7 @@ pub fn main() !void {
7277 }
7378 const remote = try origin (proc .stdout , flags .remote );
7479 const project = try repo (remote );
75- const url = try coverage (allocator , project , flags .branch );
80+ const url = try coverage (allocator , project , flags .branch , flags . path );
7681 _ = std .process .Child .run (.{
7782 .allocator = allocator ,
7883 .argv = &[_ ][]const u8 { "open" , url },
@@ -165,24 +170,65 @@ test "repo ssh" {
165170 try std .testing .expectEqualStrings (project , "zimeg/git-coverage" );
166171}
167172
168- fn coverage (allocator : std.mem.Allocator , project : []const u8 , branch : []const u8 ) ! []const u8 {
169- return std .fmt .allocPrint (
170- allocator ,
171- "https://app.codecov.io/gh/{s}/tree/{s}" ,
172- .{ project , branch },
173- );
173+ fn coverage (allocator : std.mem.Allocator , project : []const u8 , branch : []const u8 , path : []const u8 ) ! []const u8 {
174+ const slashes = std .mem .count (u8 , path , "/" );
175+ const encoding = try allocator .alloc (u8 , path .len + slashes * 2 );
176+ defer allocator .free (encoding );
177+ _ = std .mem .replace (u8 , path , "/" , "%2F" , encoding );
178+ const stat = try std .fs .cwd ().statFile (path );
179+ switch (stat .kind ) {
180+ .directory = > return std .fmt .allocPrint (
181+ allocator ,
182+ "https://app.codecov.io/gh/{s}/tree/{s}/{s}" ,
183+ .{ project , branch , encoding },
184+ ),
185+ .file = > return std .fmt .allocPrint (
186+ allocator ,
187+ "https://app.codecov.io/gh/{s}/blob/{s}/{s}" ,
188+ .{ project , branch , encoding },
189+ ),
190+ else = > return error .FileKindMissing ,
191+ }
192+ }
193+
194+ test "coverage project main root" {
195+ const project = "zimeg/git-coverage" ;
196+ const url = try coverage (std .testing .allocator , project , "main" , "." );
197+ defer std .testing .allocator .free (url );
198+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree/main/." );
199+ }
200+
201+ test "coverage project main dir" {
202+ const project = "zimeg/git-coverage" ;
203+ const url = try coverage (std .testing .allocator , project , "main" , "src" );
204+ defer std .testing .allocator .free (url );
205+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree/main/src" );
206+ }
207+
208+ test "coverage project main file" {
209+ const project = "zimeg/git-coverage" ;
210+ const url = try coverage (std .testing .allocator , project , "main" , "src/main.zig" );
211+ defer std .testing .allocator .free (url );
212+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/blob/main/src%2Fmain.zig" );
213+ }
214+
215+ test "coverage project dev root" {
216+ const project = "zimeg/git-coverage" ;
217+ const url = try coverage (std .testing .allocator , project , "dev" , "." );
218+ defer std .testing .allocator .free (url );
219+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree/dev/." );
174220}
175221
176- test "coverage project main " {
222+ test "coverage project dev dir " {
177223 const project = "zimeg/git-coverage" ;
178- const url = try coverage (std .testing .allocator , project , "main " );
224+ const url = try coverage (std .testing .allocator , project , "dev" , "src " );
179225 defer std .testing .allocator .free (url );
180- try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree/main " );
226+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree/dev/src " );
181227}
182228
183- test "coverage project dev" {
229+ test "coverage project dev file " {
184230 const project = "zimeg/git-coverage" ;
185- const url = try coverage (std .testing .allocator , project , "dev" );
231+ const url = try coverage (std .testing .allocator , project , "dev" , "src/main.zig" );
186232 defer std .testing .allocator .free (url );
187- try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/tree /dev" );
233+ try std .testing .expectEqualStrings (url , "https://app.codecov.io/gh/zimeg/git-coverage/blob /dev/src%2Fmain.zig " );
188234}
0 commit comments