-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support fetching dependencies over git+http(s) #17277
Conversation
Wow, nice work! Zig can definitely carry a few thousand lines of code if that's all it takes to support downloading from the git protocol! Looking forward to reviewing this soon... |
9426a24
to
52a0f49
Compare
I know you just rebased but I merged #14603 before this one since it was open for quite some time. Would you mind rebasing once more? |
Closes ziglang#14298 This commit adds support for fetching dependencies over git+http(s) using a minimal implementation of the Git protocols and formats relevant to fetching repository data. Git URLs can be specified in `build.zig.zon` as follows: ```zig .xml = .{ .url = "git+https://github.com/ianprime0509/zig-xml#7380d59d50f1cd8460fd748b5f6f179306679e2f", .hash = "122085c1e4045fa9cb69632ff771c56acdb6760f34ca5177e80f70b0b92cd80da3e9", }, ``` The fragment part of the URL may specify a commit ID (SHA1 hash), branch name, or tag. It is an error to omit the fragment: if this happens, the compiler will prompt the user to add it, using the commit ID of the HEAD commit of the repository (that is, the latest commit of the default branch): ``` Fetch Packages... xml... /var/home/ian/src/zig-gobject/build.zig.zon:6:20: error: url field is missing an explicit ref .url = "git+https://github.com/ianprime0509/zig-xml", ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: try .url = "git+https://github.com/ianprime0509/zig-xml#dfdc044f3271641c7d428dc8ec8cd46423d8b8b6", ``` This implementation currently supports only version 2 of Git's wire protocol (documented in [protocol-v2](https://git-scm.com/docs/protocol-v2)), which was first introduced in Git 2.19 (2018) and made the default in 2.26 (2020). The wire protocol behaves similarly when used over other transports, such as SSH and the "Git protocol" (git:// URLs), so it should be reasonably straightforward to support fetching dependencies from such URLs if the necessary transports are implemented (e.g. ziglang#14295).
52a0f49
to
fa945d9
Compare
No worries, I'm definitely happy to see #14603 land 😄 I just rebased once more on top of that, fitting the new Git dependency scheme into the framework that change created. |
I'm playing with this now - trying it out on
Couple notes here -
However, I see that
Looking at that issue, I think I spelled it out pretty reasonably in #16678 (comment). So, once again I think that should not block this PR. I should go implement symlink support in package management, and add it to tar file extraction, and then it should be fairly obvious what to do with this git.zig code. Still playing with it / reviewing the code :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I really like the way you implemented only the bits of the protocol needed to fetch files for the selected commit, and you handled the case of the user not making a stable URL. This is ready to land.
@@ -548,7 +555,7 @@ const FetchLocation = union(enum) { | |||
pub fn deinit(f: *FetchLocation, gpa: Allocator) void { | |||
switch (f.*) { | |||
inline .file, .directory => |path| gpa.free(path), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not your code, I know, but this inline
is not required and should be removed.
@@ -617,7 +690,7 @@ const ReadableResource = struct { | |||
pkg_prog_node: *std.Progress.Node, | |||
) !PackageLocation { | |||
switch (rr.resource) { | |||
inline .file, .http_request => |*r| { | |||
inline .file, .http_request, .git_fetch_stream => |*r| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
playing with this a little, and I noticed that the current working directory changed:
How could this happen? I don't see any calls to std.os.chdir or std.process.changeCurDir |
That's quite odd, I don't recall seeing anything like that happening when I was testing. It's particularly strange that it's changing the working directory of your shell, since even |
Could very well be something unrelated to your changes too, I haven't figured it out yet. |
I tried again with a build of 0.12.0-dev.758+4df7f7c86 on the latest version of this change: kristoff-it/orca-ui-hello-zig#1 (commit I also tried using For what it's worth, I tested this on Linux, though it looks like that's what you're using too. Does your |
Thanks for taking a look! It's gotta be something weird with my environment. Maybe a bug in my terminal?? For me |
Cool, that's the same setup I have with my |
I know Andrew at least sometimes uses my terminal (Ghostty). I don't see how its possible for the directory to change at the terminal emulator layer, but the first step in debugging is denial so maybe? It seems more likely it was somehow the shell... Either way if you find its somehow the terminal I am here paying attention 😄 |
Hey guys, just a quick question: should it also be possible to fetch from private repositories? |
@melhindi no, that isn't currently supported, as the Zig package manager doesn't have a way to obtain the necessary credentials securely (hard-coding them into the URL technically works, but is not at all secure). I haven't seen any proposal for such a design; it would require being able to securely associate HTTP basic auth credentials (username and password) to a package URL. Another option would be to implement #14295, but that is considerably more involved and would also raise its own design questions (e.g. password-protected keys). |
Closes #14298
This commit adds support for fetching dependencies over git+http(s) using a minimal implementation of the Git protocols and formats relevant to fetching repository data.
Git URLs can be specified in
build.zig.zon
as follows:The fragment part of the URL may specify a commit ID (SHA1 hash), branch name, or tag. It is an error to omit the fragment: if this happens, the compiler will prompt the user to add it, using the commit ID of the HEAD commit of the repository (that is, the latest commit of the default branch):
This implementation currently supports only version 2 of Git's wire protocol (documented in
protocol-v2), which was first introduced in Git 2.19 (2018) and made the default in 2.26 (2020).
The wire protocol behaves similarly when used over other transports, such as SSH and the "Git protocol" (git:// URLs), so it should be reasonably straightforward to support fetching dependencies from such URLs if the necessary transports are implemented (e.g. #14295).
The linked issue suggests implementing this first as a third-party fetch plugin, but that capability does not yet exist. If that part is mandatory, it should be straightforward to adapt this change to that framework once it's available.
Some projects where this has been tested:
Since all these projects use GitHub dependencies, I also tried out fetching random repositories from a few other Git hosts, including GitLab, SourceHut, and Gitea, to identify any protocol differences between them (fortunately, the only one found was in the initial capabilities response, and is documented in the comments of
getCapabilities
).Other projects which would be useful to test with this (large numbers of dependencies, large dependency sizes, uncommon Git hosts, etc.) would be welcome.