Skip to content
Merged
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
1 change: 1 addition & 0 deletions changelog.d/68.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow the shallow clone of repos, forces a depth of one, by setting the `-S/--shallow` flag.
21 changes: 14 additions & 7 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub fn main(init: std.process.Init) !void {
\\-p, --path <PATH> Overrides the path set in the GRAB_PATH environment variable.
\\-t, --temp Download repositories to a temporary directory. This will be the OS default temporary directory.
\\-s, --standard Standard clone, normal clone is done using worktrees.
\\-S, --shallow Create a shallow clone with a history of depth one
\\-r, --remote Add remote to existing repo.
\\--log-level <LEVEL> Set the log level. All logs are saved to file. Possible values are (debug, info, warn, error). Defualt level is info.
\\--version Show program's version number and exit
Expand Down Expand Up @@ -115,7 +116,7 @@ pub fn main(init: std.process.Init) !void {
std.log.err("unable to get GRAB_PATH, please set or use --temp or --path", .{});
std.process.exit(1);
}
config.path = .{ .allocated = path };
config.path = .{ .provided = path };
std.log.debug("try to get path from env", .{});
}
if (res.args.remote != 0) {
Expand All @@ -126,6 +127,10 @@ pub fn main(init: std.process.Init) !void {
config.action = .standard;
}

if (res.args.shallow != 0) {
config.shallow = true;
}

try grab.setLocation(init.io, config);

for (res.positionals[0]) |repo| {
Expand All @@ -141,20 +146,22 @@ pub fn main(init: std.process.Init) !void {
std.log.debug("Project Data:\n\tSite: {s}\n\tOwner: {s}\n\tName: {s}\n\tClone: {s}", .{ project.site, project.owner, project.name, project.clone });

switch (config.action) {
.standard => try clone(init.io, allocator, project),
.worktree => try worktree(allocator, init.io, project),
.standard => try clone(init.io, allocator, project, .{ .shallow = config.shallow }),
.worktree => try worktree(allocator, init.io, project, .{ .shallow = config.shallow }),
.remote => try addRemote(allocator, init.io, project),
}
}
std.log.info("Finished", .{});
}

fn clone(io: std.Io, allocator: std.mem.Allocator, project: grab.Project) !void {
const gitOpts = struct { shallow: bool = false };

fn clone(io: std.Io, allocator: std.mem.Allocator, project: grab.Project, opts: gitOpts) !void {
var project_ = project;
const cwd = std.Io.Dir.cwd();
const path = try grab.createPath(io, cwd, &[_][]const u8{ project_.site, project_.owner });
project_.root = path;
grab.clone(allocator, io, project_, .{ .bare = false }) catch |err| switch (err) {
grab.clone(allocator, io, project_, .{ .bare = false, .shallow = opts.shallow }) catch |err| switch (err) {
error.exists => {
std.log.err("Unable to clone: {s}, path not empty", .{project_.name});
std.process.exit(1);
Expand Down Expand Up @@ -188,13 +195,13 @@ fn addRemote(allocator: std.mem.Allocator, io: std.Io, project: grab.Project) !v
std.log.info("successfully added remotes", .{});
}

fn worktree(allocator: std.mem.Allocator, io: std.Io, project: grab.Project) !void {
fn worktree(allocator: std.mem.Allocator, io: std.Io, project: grab.Project, opts: gitOpts) !void {
std.log.debug("Config worktree deployment", .{});
var project_ = project;
const cwd = std.Io.Dir.cwd();
const path = try grab.createPath(io, cwd, &[_][]const u8{ project_.site, project_.owner, project_.name });
project_.root = path;
grab.clone(allocator, io, project_, .{ .bare = true }) catch |err| switch (err) {
grab.clone(allocator, io, project_, .{ .bare = true, .shallow = opts.shallow }) catch |err| switch (err) {
error.exists => {
std.log.err("Unable to clone: {s}, path not empty", .{project_.name});
std.process.exit(1);
Expand Down
30 changes: 23 additions & 7 deletions src/root.zig
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub const Action = enum {

pub const CloneOptions = struct {
bare: bool,
shallow: bool = false,
};

pub const PathSource = union(enum) {
Expand All @@ -61,14 +62,19 @@ pub const PathSource = union(enum) {
pub const Configuration = struct {
path: ?PathSource = .none,
action: Action = .worktree,
shallow: bool = false,

pub fn init() Configuration {
return Configuration{};
}

pub fn deinit(self: *Configuration, allocator: std.mem.Allocator) void {
_ = self;
_ = allocator;
if (self.path) |path| {
switch (path) {
.allocated => |p| allocator.free(p),
.provided, .none => {},
}
}
}

pub fn getPath(self: *const Configuration) ?[]const u8 {
Expand All @@ -86,16 +92,26 @@ pub fn clone(allocator: std.mem.Allocator, io: std.Io, project: Project, opts: C

const path = if (project.root) |root| try root.realPathFileAlloc(io, ".", allocator) else return error.noroot;
defer allocator.free(path);
const cmd = if (opts.bare)
&[_][]const u8{ "git", "-C", path, "clone", "--bare", project.clone, ".bare" }
else
&[_][]const u8{ "git", "-C", path, "clone", project.clone };

var cmd: std.ArrayList([]const u8) = .empty;
defer cmd.deinit(allocator);
try cmd.appendSlice(allocator, &[_][]const u8{ "git", "-C", path, "clone" });

if (opts.shallow) try cmd.append(allocator, "--depth=1");

if (opts.bare) {
try cmd.appendSlice(allocator, &[_][]const u8{ "--bare", project.clone, ".bare" });
} else {
try cmd.append(allocator, project.clone);
}

const result = std.process.run(allocator, io, .{
.argv = cmd,
.argv = cmd.items,
}) catch |err| {
std.log.err("Failed to run git clone: {}", .{err});
return err;
};

defer allocator.free(result.stdout);
defer allocator.free(result.stderr);
if (std.mem.startsWith(u8, result.stderr, "fatal")) {
Expand Down
Loading