Opened 13 years ago

Last modified 7 years ago

#16336 new enhancement

Allow multiple ports to satisfy a single dependency

Reported by: rhwood@… Owned by: macports-tickets@…
Priority: Normal Milestone: MacPorts Future
Component: base Version: 1.6.0
Keywords: Cc: vinc17@…, raimue (Rainer Müller), mf2k (Frank Schima), blb@…, febeling@…, ryandesign (Ryan Schmidt), ci42, larryv (Lawrence Velázquez), petrrr
Port:

Description

Currently there is no mechanism to specify that multiple ports may satisfy a single dependency requirement. It would be nice to be able to do so. I can think of two ways this can be done:

OR dependencies
Allow dependencies to be specified in the following fashion:
port:able|baker|charlie
where the pipe is used to separate one or more ports that may satisfy a single dependency. The first port would be used if none of the ports are installed. There should be no limit to the number of pipes, nor should there be any requirement that any pipes be used (ie, no pipes = no alternate dependencies). This should also wotk with bin: and path: type dependencies.
"provides" capability in ports
Use a "provides" key to specify that a port satisfies a particular requirement. Use the name of the port if a provides keyword is not specified. For example, if port able-devel specifies that it provides able then port able-devel would be able satisfy the dependency port:able in another port, without that other port having to be aware of port able-devel

Attachments (4)

base_src_macports1.0_macports.tcl.diff (2.9 KB) - added by blb@… 13 years ago.
diff to base/src/macports1.0/macports.tcl
base_src_port1.0_portdepends.tcl.diff (566 bytes) - added by blb@… 13 years ago.
diff to base/src/port1.0/portdepends.tcl
patch-base_src_port1.0_resources_group_Makefile (576 bytes) - added by febeling@… 13 years ago.
patch for makefile, to install vitual-1.0.tcl as well; apply and run 'sudo make install'
virtual-1.0.tcl (2.3 KB) - added by febeling@… 13 years ago.

Download all attachments as: .zip

Change History (23)

comment:1 Changed 13 years ago by vinc17@…

Cc: vinc17@… added

Cc Me!

comment:2 Changed 13 years ago by raimue (Rainer Müller)

Cc: raimue@… added

Cc Me!

comment:3 Changed 13 years ago by mf2k (Frank Schima)

Cc: macsforever2000@… added

Cc Me!

comment:4 Changed 13 years ago by blb@…

Cc: blb@… added
Component: portsbase
Milestone: MacPorts base enhancements

Will attach an initial attempt at making the port1|port2|port3 method work. Has seen only limited testing so far.

Changed 13 years ago by blb@…

diff to base/src/macports1.0/macports.tcl

Changed 13 years ago by blb@…

diff to base/src/port1.0/portdepends.tcl

comment:5 Changed 13 years ago by febeling@…

Cc: febeling@… added

Cc Me!

comment:6 Changed 13 years ago by febeling@…

I was thinking about this the other day, and one workaround I though of was this:

depends_lib port:able

variant baker conflicts charlie {
  depends_lib-delete port:able
  depends_lib-append port:baker
}
variant charlie conflicts baker {
  depends_lib-delete port:able
  depends_lib-append port:charlie
}

One real downside it probably to compile the conflicts lists by hand, which is error-prone. And I haven't tested it. Maybe it doesn't work ;)

comment:7 Changed 13 years ago by ryandesign (Ryan Schmidt)

Cc: ryandesign@… added

What is the advantage to a "port:a|b|c" syntax? If all these ports provide the same thing, then "path:${prefix}/some/file:a" (where ${prefix}/some/file is a file provided by all three ports) is sufficient, isn't it? We already use this in many places. Anyway, it doesn't solve the problem that each port that depends on, say, a, needs to know that b and c would also work. Most port authors don't take the time to discover this, and also the list of acceptable ports might change over time. For example I might create a -devel port, but then don't really want to have to notify the authors of every port that uses my port to tell them to add the -devel port into their list.

It would be better to do it the second way you suggest, with a "provides" syntax in the port.

comment:8 in reply to:  7 ; Changed 13 years ago by mf2k (Frank Schima)

Replying to ryandesign@macports.org:

What is the advantage to a "port:a|b|c" syntax? If all these ports provide the same thing, then "path:${prefix}/some/file:a" (where ${prefix}/some/file is a file provided by all three ports) is sufficient, isn't it?

Sometimes the dependency requires the entire port, not just a single file. For example, in the bacula port it requires a database be installed (when not using the client-only variant) but it really doesn't matter which precise version it is. To work around this, I had to create variants for each database version which is cumbersome. So instead of creating a variant for postgresql83, postgresql82, postgresql81 AND postgresl80, I decided to only use the latest version. However, it would be better to just have had a "postgresql8" variant which required any of them. The provides keyword would not work in this case.

However, it brings up an issue. If none of the ports are available, which one gets installed? The first one in the list?

I fully agree that the provides keyword is also a great idea. But it seems limited in usefulness to devel type ports only.

comment:9 in reply to:  8 Changed 13 years ago by raimue (Rainer Müller)

Replying to macsforever2000@macports.org:

Sometimes the dependency requires the entire port, not just a single file. For example, in the bacula port it requires a database be installed (when not using the client-only variant) but it really doesn't matter which precise version it is. To work around this, I had to create variants for each database version which is cumbersome. So instead of creating a variant for postgresql83, postgresql82, postgresql81 AND postgresl80, I decided to only use the latest version. However, it would be better to just have had a "postgresql8" variant which required any of them. The provides keyword would not work in this case.

So all ports could specify provides postgresql8 as well, but can they be installed at the same time?

We would need some way to express if multiple ports providing the same thing can be installed. For example, python24 and python25 can be installed at the same time, mysql5 and mysql5-devel can not. These are different use cases, maybe we can solve this with only one solution or we need both methods.

However, it brings up an issue. If none of the ports are available, which one gets installed? The first one in the list?

Sounds reasonable.

I fully agree that the provides keyword is also a great idea. But it seems limited in usefulness to devel type ports only.

Just as a note, the OR method requires changing each dependent when adding new ports which would satisfy the dependency.

comment:10 Changed 13 years ago by ryandesign (Ryan Schmidt)

It might be easier to discuss this issue on the mailing list instead of in the ticket notes.

comment:11 Changed 13 years ago by mf2k (Frank Schima)

Actually a few of us had a discussion on the IRC forum about it today. I don't see a problem with using the trac which keeps the discussion conveniently available right here on the ticket.

As another example in favor of allowing OR in dependencies, the meld port requires py25-gtk and py25-gnome. But py-gtk or py26-gtk pr py30-gtk would also work. Same for py25-gnome.

Another topic that came up is that the "provides" keyword could solve the issue of a dependency requiring a variant. The implementation might be a little tricky though. Ideally each variant would automatically create a "provides" token that can then be referenced. For example, py25-scipy requires swig currently. But it really requires swig +python25. So swig with the python25 variant would have an automatic provides "swig+python25" which could then be referenced in py25-scipy.

comment:12 Changed 13 years ago by blb@…

Concerning one way vs. the other, a provides-based method would be a better way to go long-term, but I believe this requires quite a few changes throughout base. On the other hand, using | for dependencies has a patch here, now.

comment:13 Changed 13 years ago by febeling@…

In my earlier comment I described how we could get Virtual Packages using conflicting variants. The idea is, to spell it out, that the dependent port depends on the virtual port, and that virtual port can be installed using one of several ways, depending on how you specify (mutually exclusive) variants. The variants drive setup a dependency the the implementing port. I think ORed dependencies and Virtual Packages are alternative solutions to the same problem. Virtual Packages have the advantage of hiding "Implementation" (the actual package) behind and "Interface" (virtual package). At least Debian uses this approach as well [1], but I think others as well.

I'm not sure which approach will be better in the long run. And we should probably have only one, not both. But I have tried to implement this as a port group and I find the result quite reasonable, because it does not require changes to the core workings, i.e., not very intrusive, and the resulting "virtual" portfile is short [2], here the postgresql example. And you can list virtual packages, if we put them all into a category "virtual", which is what my patch does. So now we have both options really open for discussion. One disadvantage is that it is very explicit, resulting in portfiles proper, instead of just symbols or names. Which have to be kept current and all. Just have a look. Patch follows.

[1] http://www.debian.org/doc/FAQ/ch-pkg_basics.en.html#s-virtual

[2] http://pastie.org/257239

Changed 13 years ago by febeling@…

patch for makefile, to install vitual-1.0.tcl as well; apply and run 'sudo make install'

Changed 13 years ago by febeling@…

Attachment: virtual-1.0.tcl added

comment:14 Changed 13 years ago by febeling@…

Maybe there is an argument for both ORed Dependencies and Virtual Ports.

Virtual Ports: abstract over versions, like the hypothetical "postressql" offering postgresql 7 through 83, and possible packages like mailtranportagent or webserver, satiesfied by a number of implementations.

ORed Dependencies: suppose an application needs an RDBMS, but it can put up with mysql{4,5}, sqlite, postgresql, but not every conceivable RDBMS obviously. So there would a situation where VP does not work but OD does.

So maybe there can be both approaches.

comment:15 Changed 7 years ago by petrrr

Cc: Peter.Danecek@… added

Cc Me!

comment:16 Changed 7 years ago by ci42

Cc: ciserlohn@… added

Cc Me!

comment:17 Changed 7 years ago by larryv (Lawrence Velázquez)

Cc: larryv@… added

Cc Me!

comment:18 Changed 7 years ago by mf2k (Frank Schima)

Cc: mf2k@… added; macsforever2000@… removed

comment:19 Changed 7 years ago by petrrr

Cc: petr@… added; Peter.Danecek@… removed
Note: See TracTickets for help on using tickets.