Subject: [bug#51838] [PATCH v8 00/41] guix: node-build-system: Support compiling add-ons with node-gyp.

From: Philip McGrath <[email-masked]>
Date: Fri, 7 Jan 2022 16:07:26 -0500

Hi,

I'm excited to take a look at this!

On 1/7/22 14:43, Liliana Marie Prikler wrote:
> Hi,
> 
> Am Freitag, dem 07.01.2022 um 11:49 -0500 schrieb Timothy Sample:
>> Liliana Marie Prikler <[email-masked]> writes:
>>> 4. Regexps :)
>>
>> I doubt regex support will be broadly useful here.  Putting the
>> anchors in every package name (e.g., "^tap$") makes for a lot of
>> noise.  My (wild) guess would be that regexes will save us listing
>> two dependencies for one out of every ten Node packages.  Given that,
>> my preference would be to not bother with regex support.
> My reason to include them is that we can already see a number of
> packages requiring typescript(.*) for a number of (.*) -- similarly
> karma and mocha -- in the patch set given by Philip.  I do think
> regexps will be less useful later on and could very well become
> obsolete by the time we have a full bootstrap of everything, but we
> don't have an ETA on that, so for now I'd like to have that capability.

I think I agree with both of you, with all of the countervailing 
considerations.

My base position is that regexps should not be mandatory or default. It 
was very convenient to be able to just copy--paste package names from 
"package.json" into '#:absent-dependencies' (or whatever). I can imagine 
it being useful for tooling, too, to be able to find just from the 
package definition the dependencies which are being deleted, rather than 
having to either download the origins or try to reconstruct names from 
regexps.

But I do know that there are some families of Node.js tools we don't 
have packaged that come as a bunch of related "devDependencies", and I 
can see the convenience of being able to remove, say, "@types/.*", 
"eslint-.*", and ".*-webpack-plugin" succinctly.

Ultimately, I agree with Liliana that the right solution to those 
missing tools is to package them for Guix! My experience so far with 
workarounds like esbuild is that they are very useful for bootstrapping 
and pragmatically producing usable packages, but that trying to replace 
the build tooling of the entire Node.js universe by hand is not a viable 
solution. (To be slightly more specific, I've encountered some problems 
with conflicting expectations about whether to consume and/or produce 
ES6 vs CommonJS modules, for packages that are more like "libraries" 
than "applications".)

I think it would be fine to remove the regexp support, at least for now.

Alternatively, I would also be ok with ...

> 
> I see two potential solutions here.  First is matching the whole string
> as you suggested and discussed below.  Second is opting in to regexp in
> general (there are some ".js" things, that would otherwise require
> escaping).  This would take the form of the user writing
> '("foo" "bar" (regexp "^baz$")) as UNWANTED, and it'd be interpreted as
> the predicates
> (equal? S "foo") ; alternatively string=?
> (equal? S "bar")
> (string-match S "^baz$")
> WDYT?

the second proposal, or a slight variant on it in which the user would 
write:

     `("foo" "bar" ,(make-regexp "baz"))

Since this (either variant) would not change the interpretation of 
strings in the list of dependencies to delete, it could also be added 
later without breaking compatibility.

> 
>>> I think it'd be beneficial if delete-dependencies could delete
>>> dependencies based on their name matching a regexp rather than a
>>> string exactly.  This would make some of your lists shorter
>>> (e.g. "karma.*"), but there might be a debate on whether to use
>>> "^karma.*$" or whether to only consider regexps that match the
>>> dependency fully.
>>
>> If nothing else, I’m certainly on the other side of this debate!  :)
>> If every string is going to be treated as a pattern, we should have
>> it match fully by default.  That is, the anchors should be implicit.
>> For the very rare (never?) case where you want to avoid anything that
>> so much as has “foo” in the name, it’s pretty easy to write
>> ".*foo.*".
> Full string matches are my preference too, but I only found the
> function that does partial match.  Is there an easier solution than
> checking whether the matched string equals the input to string-match?

I also think full string matches are better, regardless of any of the 
above. Here's an implementation that avoids unneeded copies and string 
comparison:

     (define (regexp-match-exact? rx str)
       (define m (regexp-exec rx str))
       (and m
            (= (match:start m) 0)
            (= (match:end m) (string-length str))))

(This should also avoid repeatedly compiling the regexp, as 
'string-match' would do.)

More soon, I hope!

-Philip