Subject: Re: [bug#50359] [PATCH] import: Add 'generic-git' updater.

From: Sarah Morgensen <[email-masked]>
Date: Sun, 05 Sep 2021 20:14:49 -0700

Hello,

Xinglu Chen <[email-masked]> writes:

>> And this lets us just do something like (untested):
>>
>> (define* (get-version tag #:key prefix suffix delim)
>>   (define delim-rx (regexp-quote (or delim ".")))
>>   (define prefix-rx (or prefix "[^[:digit:]]*"))
>>   (define suffix-rx (or suffix ".*"))
>>   (define version-char-rx
>>    (string-append "[^" delim-rx "[:punct:]]"))
>>
>>   (define tag-rx
>>    (string-append "^" prefix "(" version-char-rx "+("
>>                   delim-rx version-char-rx ")*)" suffix-rx "$"))
>
> This wouldn’t match anything if the version is just a plain number,
> e.g., 1 or 09.

It does, but I had many errors in the definition.  Again, apologies.  I
shouldn't send emails that late, haha.  This method should read:

 --8<---------------cut here---------------start------------->8---
 (define* (get-version tag #:key prefix suffix delim)
   (define delim-rx (regexp-quote (or delim ".")))
   (define prefix-rx (or prefix "[^[:digit:]]*"))
   (define suffix-rx (or suffix ".*"))
   (define version-char-rx
    (string-append "[^" delim-rx "[:punct:]]"))

   (define tag-rx
    (string-append "^" prefix-rx "(" version-char-rx "+("
                   delim-rx version-char-rx "+)*)" suffix-rx "$"))
   (and=> (string-match tag-rx tag)
          (cut match:substring <> 1)))
--8<---------------cut here---------------end--------------->8---

>
> With this, something like “1.4.0rc1-450-g2725ef99d” will result in
> “1.4.0” being returned, which is incorrect.  Changing (cut
> match:substring <> 1) to just ‘match:substring’ would solve the issue,
> but then pre-release tags, which we usually don’t want,  would also get
> matched.  Not sure what the best option would be in this case.
>

With the fixed method above:

scheme@(emacs-guix)> (get-version "8")
$16 = "8"
scheme@(emacs-guix)> (get-version "1.4.0rc1-450-g2725ef99d")
$17 = "1.4.0rc1"

But, we still get:

scheme@(emacs-guix)> (get-version "1.4.0-rc1")
$18 = "1.4.0"

which leads us to what you talked about in your other message.

[...]
>> +(define* (ls-remote-refs url #:key tags?)
>> +  "Return the list of references advertised at Git repository URL.  If TAGS?
>> +is true, limit to only refs/tags."
>> +  (define (ref? ref)
>> +    ;; Like `git ls-remote --refs', only show actual references.
>> +    (and (string-prefix? "refs/" ref)
>> +         (not (string-suffix? "^{}" ref))))
>> +
>> +  (define (tag? ref)
>> +    (string-prefix? "refs/tags/" ref))
>> +
>> +  (define (include? ref)
>> +    (and ref?

This should be:
        (and (ref? ref)

>> +         (or (not tags?) (tag? ref))))
>> +
>> +  (with-libgit2
>> +   (with-temporary-directory
>> +    (lambda (cache-directory)
>> +      (let* ((repository (repository-init cache-directory))
>> +             ;; Create an in-memory remote so we don't touch disk.
>> +             (remote (remote-create-anonymous repository url)))
>> +        (remote-connect remote)
>> +        (remote-disconnect remote)
>> +        (repository-close! repository)
>> +
>> +        (filter include? (map remote-head-name (remote-ls remote))))))))
>>
>
> For some reason it seems to include refs that do and don’t end with
> “^{}”

Sorry, another typo I missed.  See above.

--
Sarah