diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2021-08-27 10:59:51 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-08-29 10:39:28 -0400 |
commit | 72df17c659619707e4e5f27b2a51db60848a1d04 (patch) | |
tree | a89dda4f75833c96669446c94fd7e0ff56f19fff | |
parent | 672406773e677e69dba0ccf1c6a116cb2886b60a (diff) | |
download | libgit2-72df17c659619707e4e5f27b2a51db60848a1d04.tar.gz |
remote: introduce git_remote_ready_cb
Introduce a new callback that fires when the remote is ready to connect.
-rw-r--r-- | include/git2/remote.h | 17 | ||||
-rw-r--r-- | src/remote.c | 15 | ||||
-rw-r--r-- | tests/network/remote/remotes.c | 42 | ||||
-rw-r--r-- | tests/online/push_util.h | 2 |
4 files changed, 72 insertions, 4 deletions
diff --git a/include/git2/remote.h b/include/git2/remote.h index 5b67717eb..b75a9911c 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -514,6 +514,18 @@ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, cons typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload); /** + * Callback invoked immediately before we attempt to connect to the + * given url. Callers may change the URL before the connection by + * calling `git_remote_set_instance_url` in the callback. + * + * @param remote The remote to be connected + * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH + * @param payload Payload provided by the caller + * @return 0 on success, or an error + */ +typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload); + +/** * The callback settings structure * * Set the callbacks to be called by the remote when informing the user @@ -598,6 +610,11 @@ struct git_remote_callbacks { git_transport_cb transport; /** + * Callback when the remote is ready to connect. + */ + git_remote_ready_cb remote_ready; + + /** * This will be passed to each of the callbacks in this struct * as the last parameter. */ diff --git a/src/remote.c b/src/remote.c index 236f39aba..8050e65f3 100644 --- a/src/remote.c +++ b/src/remote.c @@ -709,11 +709,19 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int GIT_ASSERT_ARG(remote); GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); - if (direction == GIT_DIRECTION_FETCH) { + if (callbacks && callbacks->remote_ready) { + int status = callbacks->remote_ready(remote, direction, callbacks->payload); + + if (status != 0 && status != GIT_PASSTHROUGH) { + git_error_set_after_callback_function(status, "git_remote_ready_cb"); + return status; + } + } + + if (direction == GIT_DIRECTION_FETCH) url = remote->url; - } else if (direction == GIT_DIRECTION_PUSH) { + else if (direction == GIT_DIRECTION_PUSH) url = remote->pushurl ? remote->pushurl : remote->url; - } if (!url) { git_error_set(GIT_ERROR_INVALID, @@ -722,6 +730,7 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction == GIT_DIRECTION_FETCH ? "fetch" : "push"); return GIT_EINVALID; } + return resolve_url(url_out, url, direction, callbacks); } diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index a962d9293..4a9f5ae72 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -56,6 +56,48 @@ void test_network_remote_remotes__parsing(void) git_buf_dispose(&url); } +static int remote_ready_callback(git_remote *remote, int direction, void *payload) +{ + if (direction == GIT_DIRECTION_PUSH) { + const char *url = git_remote_pushurl(remote); + + cl_assert_equal_p(url, NULL);; + cl_assert_equal_s(payload, "payload"); + return git_remote_set_instance_pushurl(remote, "push_url"); + } + + if (direction == GIT_DIRECTION_FETCH) { + const char *url = git_remote_url(remote); + + cl_assert_equal_s(url, "git://github.com/libgit2/libgit2"); + cl_assert_equal_s(payload, "payload"); + return git_remote_set_instance_url(remote, "fetch_url"); + } + + return -1; +} + +void test_network_remote_remotes__remote_ready(void) +{ + git_buf url = GIT_BUF_INIT; + + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + callbacks.remote_ready = remote_ready_callback; + callbacks.payload = "payload"; + + cl_assert_equal_s(git_remote_name(_remote), "test"); + cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2"); + cl_assert(git_remote_pushurl(_remote) == NULL); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks)); + cl_assert_equal_s(url.ptr, "fetch_url"); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks)); + cl_assert_equal_s(url.ptr, "push_url"); + + git_buf_dispose(&url); +} + static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload) { cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0); diff --git a/tests/online/push_util.h b/tests/online/push_util.h index d829bbc4a..5f669feaf 100644 --- a/tests/online/push_util.h +++ b/tests/online/push_util.h @@ -12,7 +12,7 @@ extern const git_oid OID_ZERO; * @param data pointer to a record_callbacks_data instance */ #define RECORD_CALLBACKS_INIT(data) \ - { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data, NULL } + { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, NULL, data, NULL } typedef struct { char *name; |