On 1/12/2023 11:27, Frank Stock wrote:
Section 6.4.1 has an interesting bullet…
"Ports API - API for Portfile parsing and execution”

I would like to extract information from a Portfile such as, version, license, 
add_users, startupitem, post-destroot, etc. for analysis/processing in a 
Node.js app.
Thought I might be able to use a Tcl Interpreter such as npm tcl or npm tcl-js 
to load from base/src/port1.0/ and obtain what I want using mportinfo.

But I confess, being a newbie to Tcl as well as MacPorts internals, after a day 
of “grep”, I still haven’t figured out how (or even if its possible) to load 
the API into an interpreter outside MacPorts?

Are there better ways to accomplish my goal of extracting Portfile info?
Wish I could just use “port info acme”, but add_users and post-destroot are 
some of the required pieces of info I need.

Portfiles can contain arbitrary Tcl code and rely heavily on the code in MacPorts base, so no, there's not really any way to correctly evaluate them without using the macports API. There are quite a few examples in the macports-contrib repo. Basic usage goes like this:

package require macports
mportinit

set portname python311
# Look up the port name in the PortIndex
lassign [mportlookup $portname] - infolist
array set portinfo $infolist

# Use the porturl and subport from the index to open the Portfile
set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] ""]

# Update the portinfo array with information that is not in the index
array set portinfo [mportinfo $mport]


At this point you have a portinfo array containing all the public information about the port. For internals like add_users you would have to use a private API like _mportkey:

_mportkey $mport add_users

That can get you the values of Portfile variables, but note that post-destroot is not a variable, it's a procedure.

It is possible to get at the Portfile interpreter and run arbitrary code in it, but needless to say at that point it's totally unsupported and subject to change without notice, you're on your own, etc.

set workername [ditem_key $mport workername]
$workername eval [list info procs]

- Josh

Reply via email to