On Nov 20, 2007, at 7:24 PM, Michael G Schwern wrote:

Syntax-wise, I'd rather see something like this:

        requires:
                external:
                        svn: 1.4.2
                        mysql: 5.0
                        python: 2.1

That way there is no ambiguity about whether a given requires key is a module name or something special. Module names have simple values, special keys have
complex values.  Then there is no name clash.

There's no compelling reason to link "modules" with "simple" and "other stuff" with "complex". Let's decouple them or I think we'll be sorry.

I agree that there needs to be some way of extending our notion of prereq types from the 2 current types (module and 'perl'). I disagree that it should be done in a backwards-incompatible way though. The cardinal rule of syntax extensions must be kept in mind: any new functionality must be a syntax/semantics error in the old system, or else old parsers will continue on their merry way and do The Wrong Thing.

What that means in this context is that if we want old parsers to ignore new META information, we should put it in a new key. If we don't, we should incorporate it into existing keys.

In other words, if we encourage people to change 'requires => perl => 5.6' to 'perl_requires => 5.6', old parsers will happily ignore the new key, and miss an important dependency. That's a problem I don't want anyone, least of all myself, to have to work around.

Also, the omission of the "perl" key from the spec is unfortunate, but it was always intended to be there, it exists in the wild, and parts of the toolchain (M::B itself, for example) already support it. So I would be quite loathe to get rid of it.

When I've been mulling this issue over on my long boring commutes, here's the best proposal I've come up with for prerequisites of different types: explicit type declarations.

 requires:
   mod/Carp: 1.03
   mod/File::Basename: 2.73
   sys/perl: 5.005
   sys/platform: Windows
   bin/wget: 1.10
   bin/gpg: 1.4.5
   lib/tk: 8.4
   lib/cups: 2
   ext/mysql: 5.0
   ext/openssl: 0.9.71

The idea is similar to the protocol at the front of a URI (and I think the role-reversal of slashes and colons is sort of cute, e.g. mod/Foo::Bar::Baz, but we could make the slash almost any character we want).

For both Huffman Coding and legacy reasons, we can support the following abbreviations:

  * The simple string "perl" means "sys/perl".
  * Any other string without a type implies type "mod".

This lets the previous example thin out to:

 requires:
   Carp: 1.03
   File::Basename: 2.73
   perl: 5.005
   sys/platform: Windows
   bin/wget: 1.10
   bin/gpg: 1.4.5
   lib/tk: 8.4
   lib/cups: 2
   ext/mysql: 5.0
   ext/openssl: 0.9.71


Obviously only the mod/* and sys/perl entries have well-defined meanings right now, but the other types can be fleshed out as we figure out how they should best be checked.

The main advantage of this approach, I think, is that if an existing parser sees something it can't figure out the meaning of (or how to satisfy), it will fail. Which is important for something called a "requirement".

Anyway, I'm interested in people's comments.

 -Ken

Reply via email to