refspec: add public parsing api#4519
Conversation
|
|
||
| int git_refspec_parse(git_refspec **refspec, const char *input, int is_fetch) { | ||
| git_refspec *new_refspec; | ||
| if (refspec == NULL || input == NULL) { |
|
|
||
| is_fetch = !!is_fetch; | ||
| new_refspec = git__malloc(sizeof(git_refspec)); | ||
| if (new_refspec == NULL) { |
There was a problem hiding this comment.
GITERR_CHECK_ALLOC is what you want here.
| } | ||
|
|
||
| void git_refspec_free(git_refspec *refspec) { | ||
| if (refspec == NULL) { |
There was a problem hiding this comment.
I'd be tempted to say that this test is not needed : git_refspec__free already handles it, and git__free doesn't care about NULL.
| return -1; | ||
| } | ||
|
|
||
| is_fetch = !!is_fetch; |
There was a problem hiding this comment.
I'd move that inside the git_refspec__parse call.
|
It'd be 😍 if you squashed those commits, too ! |
3de7e01 to
5127cd5
Compare
|
@tiennou Done! |
pks-t
left a comment
There was a problem hiding this comment.
I'm a bit on the edge whether that API makes sense to expose. Not saying that it shouldn't, but I still would like to know of a certain use case where it would be handy. I'm especially coming from the angle that we have no functions exposed which make real use of the refspec.
I'd definitly like to see a test, though. While the new function mostly wraps the exisitng git_refspec__parse, it's still 14 lines of new code which are never being exercised.
| * @param refspec a pointer to hold the refspec handle | ||
| * @param input the refspec string | ||
| * @param is_fetch is this a refspec for a fetch | ||
| * @return 0 if the refspec string could be parsed, 1 otherwise |
There was a problem hiding this comment.
1 otherwise is a bit weird. We always return -1 for errors.
There was a problem hiding this comment.
Sorry the function is actually returning -1, but this is obviously a documentation error.
| memset(refspec, 0x0, sizeof(git_refspec)); | ||
| } | ||
|
|
||
| int git_refspec_parse(git_refspec **refspec, const char *input, int is_fetch) { |
There was a problem hiding this comment.
Well, this is definitly is a bit more than a "simple wrapper", regarding it has 14 lines of code. So it should be worth a test
There was a problem hiding this comment.
While you're fixing up this PR with @pks-t 's changes, please put this { on a newline to match our code formatting rules. (Thanks!)
There was a problem hiding this comment.
Ah, thanks! I noticed this, but forgot to write a comment
There was a problem hiding this comment.
I'll push some tests right away.
There was a problem hiding this comment.
@pks-t About the tests, would a simple valid/not-valid parsing case be sufficient (testing object creation) and a simple comment that the logic should already be tested in the internal version of the api suffice?
| new_refspec = git__malloc(sizeof(git_refspec)); | ||
| GITERR_CHECK_ALLOC(new_refspec); | ||
|
|
||
| if (!git_refspec__parse(new_refspec, input, is_fetch)) { |
There was a problem hiding this comment.
You shouldn't pass is_fetch as, as git_refspe__parse accepts a bool. So instead of moving is_fetch = !!is_fetch into git_refspec__parse, you should have that here.
There was a problem hiding this comment.
@tiennou mentioned to move that line away. But I can move it back here.
There was a problem hiding this comment.
Sorry, coding style is always a soft thing and different people have different views :P
There was a problem hiding this comment.
On another note: you could also just move it into the git_refspec__parse line, without first assigning it to itself.
| return 0; | ||
| } | ||
|
|
||
| void git_refspec_free(git_refspec *refspec) { |
There was a problem hiding this comment.
Sorry, didn't noticed that. Should be fixed.
Same. @cynecx, understanding your motivations here would help us get more excited about this. As I'm sure you can imagine, every new API we add is something else that we have to maintain, so we're loathe to add new public API unless it's warranted. We don't want to just expose API for the sake of completeness. So understanding what you're trying to do (and how this helps you do it) is nice so that we know that we should take on this future maintenance burden in order to help you build your software. 😃 |
|
Sorry about the delay. @pks-t @ethomson Well, I am currently developing a custom git remote handler which accepts a command which accepts a refspec as an argument (and my handler obviously uses libgit2). I was actually aiming for reducing code duplication by reusing parsing code which already exists in libgit2. That's my main motivation here, I am not sure if this will convince you but it would definitely offload some parsing logic, which is always good IMO. |
pks-t
left a comment
There was a problem hiding this comment.
Thanks for your scenario, makes sense to me. Disregarding the micro-nit about !!is_fetch, which you might fix if you feel like it, the only thing missing now is a test for this. As you proposed, two simple tests exercising a succeeding and failing parse should be sufficient.
| new_refspec = git__malloc(sizeof(git_refspec)); | ||
| GITERR_CHECK_ALLOC(new_refspec); | ||
|
|
||
| if (!git_refspec__parse(new_refspec, input, is_fetch)) { |
There was a problem hiding this comment.
On another note: you could also just move it into the git_refspec__parse line, without first assigning it to itself.
|
Sorry about the long delay. I've just rebased the branch and added a small test. |
pks-t
left a comment
There was a problem hiding this comment.
No worries about the delay, we're usually not the quickest either ;) There's two small nits about out-parameter sanitization and cl_git_pass/cl_git_fail, which is why I also added some minor style recommendations. You don't necessarily need to address the style issues, but I'd be happy if you did :) I'd also ask you to squash the commits together afterwards, as I expect this to be the last round of reviews.
Thanks for your work!
|
|
||
| spec = NULL; | ||
|
|
||
| error = git_refspec_parse(&spec, "", 0); |
There was a problem hiding this comment.
You can get rid of the error for this and all the following invocations, as we're always using cl_git_pass and cl_git_fail to check for errors when the invoked function is conforming to libgit2's error style. So:
cl_git_fail(git_refspec_parse(&spec, "", 0));
cl_git_fail(git_refspec_parse(&spec, ":::", 0));
cl_git_pass(git_refspec_pares(&spec, "HEAD:", 1));
| { | ||
| git_refspec *new_refspec; | ||
| assert(refspec && input); | ||
|
|
There was a problem hiding this comment.
I'd like to make sure that we always sanitize the out parameter. So the first thing this function does should be *refspec = NULL.
| GITERR_CHECK_ALLOC(new_refspec); | ||
|
|
||
| is_fetch = !!is_fetch; | ||
| if (git_refspec__parse(new_refspec, input, is_fetch) != 0) { |
There was a problem hiding this comment.
You could just pull the !!is_fetch into this function. So if (git_refspec__parse(new_refspec, input, !!is_fetch) != 0)
| memset(refspec, 0x0, sizeof(git_refspec)); | ||
| } | ||
|
|
||
| int git_refspec_parse(git_refspec **refspec, const char *input, int is_fetch) |
There was a problem hiding this comment.
Minor nit that doesn't need addressing: we usually name out-parameters out or similar. In case you rename it to out, you could also just rename new_refspec to refspec.
6798dfa to
6dede7c
Compare
|
I've squashed them and addressed the styling issues :) |
Fix typo Fix some type issues More fixes Address requested changes Add test Fix naming Fix condition and tests Address requested changes Fix typo
|
ping. |
|
Kicking CI as it had some spurious failures. |
|
Thanks for your contribution! |
This PR adds public apis for parsing refspec strings. This already exists but they are all internal.
I am not sure if tests are required here because I guess that the internal api must have tests already and this PR just adds trivial wrapping. But I am happy to add tests if it's really requested.