apm_read_package_info_file (public)

 apm_read_package_info_file path

Defined in packages/acs-tcl/tcl/apm-xml-procs.tcl

Reads a .info file, returning an array containing the following items:

  • path: a path to the file read
  • mtime: the mtime of the file read
  • provides, embeds, extends, and requires:

    lists of dependency information, containing elements of the form [list $url $version]

  • owners: a list of owners containing elements of the form [list $url $name]
  • files: a list of files in the package, containing elements of the form [list $path $type] NOTE: Files are no longer stored in info files but are always retrieved directly from the filesystem. This element in the array will always be the empty list.
  • callbacks: an array list of callbacks of the package on the form [list callback_type1 proc_name1 callback_type2 proc_name2 ...]
  • Element and attribute values directly from the XML specification: package.key, package.url, package.type package-name, pretty-plural initial-install-p singleton-p auto-mount name (the version name, e.g., 3.3a1), url (the version URL), option, summary, description, release-date, vendor, group, vendor.url, and description.format, maturity, maturity_text.
This routine will typically be called like so:
array set version_properties [apm_read_package_info_file $path]
to populate the version_properties array.

If the .info file cannot be read or parsed, this routine throws a descriptive error.

Parameters:
path

Partial Call Graph (max 5 caller/called nodes):
%3 test_apm__test_info_file apm__test_info_file (test acs-tcl) apm_read_package_info_file apm_read_package_info_file test_apm__test_info_file->apm_read_package_info_file test_files__check_info_files files__check_info_files (test acs-tcl) test_files__check_info_files->apm_read_package_info_file ad_file ad_file (public) apm_read_package_info_file->ad_file apm::package_version::attributes::maturity_int_to_text apm::package_version::attributes::maturity_int_to_text (public) apm_read_package_info_file->apm::package_version::attributes::maturity_int_to_text apm::package_version::attributes::parse_xml apm::package_version::attributes::parse_xml (private) apm_read_package_info_file->apm::package_version::attributes::parse_xml apm_attribute_value apm_attribute_value (public) apm_read_package_info_file->apm_attribute_value apm_log apm_log (public) apm_read_package_info_file->apm_log ad_core_docs_uninstalled_packages_internal ad_core_docs_uninstalled_packages_internal (private) ad_core_docs_uninstalled_packages_internal->apm_read_package_info_file apm::package_version::attributes::set_all_instances_names apm::package_version::attributes::set_all_instances_names (private) apm::package_version::attributes::set_all_instances_names->apm_read_package_info_file apm_build_repository apm_build_repository (private) apm_build_repository->apm_read_package_info_file apm_dependency_check apm_dependency_check (private) apm_dependency_check->apm_read_package_info_file apm_get_package_repository apm_get_package_repository (public) apm_get_package_repository->apm_read_package_info_file

Testcases:
apm__test_info_file, files__check_info_files
Source code:
    # If the .info file hasn't changed since last read (i.e., has the same
    # mtime), return the cached info list.
    set mtime [ad_file mtime $path]
    if { [nsv_exists apm_version_properties $path] } {
        set cached_version [nsv_get apm_version_properties $path]
        if { [lindex $cached_version 0] == $mtime } {
            return [lindex $cached_version 1]
        }
    }

    # Set the path and mtime in the array.
    set properties(path) $path
    set properties(mtime) $mtime

    apm_log APMDebug "Reading specification file at $path"

    set file [open $path]
    set xml_data [read $file]
    close $file

    if {[catch {set tree [xml_parse -persist $xml_data]} errorMsg]} {
        ns_log error "parsing XML file $path lead to error: $errorMsg"
        return -code error "file: $path\n$errorMsg"
    }

    set root_node [xml_doc_get_first_node $tree]
    apm_log APMDebug "XML: root node is [xml_node_get_name $root_node]"
    set package $root_node

    set root_name [xml_node_get_name $package]

    # Debugging Children
    set root_children [xml_node_get_children $root_node]

    apm_log APMDebug "XML - there are [llength $root_children] child nodes"
    foreach child $root_children {
        apm_log APMDebug "XML - one root child: [xml_node_get_name $child]"
    }

    if { $root_name ne "package" } {
        apm_log APMDebug "XML: the root name is $root_name"
        error "Expected <package> as root node"
    }
    set properties(package.key)          [apm_required_attribute_value $package key]
    set properties(package.url)          [apm_required_attribute_value $package url]
    set properties(package.type)         [apm_attribute_value -default "apm_application" $package type]
    set properties(package-name)         [apm_tag_value $package package-name]
    set properties(initial-install-p)    [apm_tag_value -default "f" $package initial-install-p]
    set properties(auto-mount)           [apm_tag_value -default "" $package auto-mount]
    set properties(singleton-p)          [apm_tag_value -default "f" $package singleton-p]
    set properties(implements-subsite-p) [apm_tag_value -default "f" $package implements-subsite-p]
    set properties(inherit-templates-p)  [apm_tag_value -default "t" $package inherit-templates-p]
    set properties(pretty-plural)        [apm_tag_value -default "$properties(package-name)s" $package pretty-plural]

    set versions [xml_node_get_children_by_name $package version]
    if { [llength $versions] != 1 } {
        error "Package must contain exactly one <version> node"
    }
    set version [lindex $versions 0]

    set properties(name) [apm_required_attribute_value $version name]
    set properties(url)  [apm_required_attribute_value $version url]

    # Set an entry in the properties array for each of these tags.
    set properties(maturity) ""
    foreach property_name { summary description release-date vendor maturity } {
        set properties($property_name) [apm_tag_value $version $property_name]
    }
    set properties(maturity_text) [apm::package_version::attributes::maturity_int_to_text $properties(maturity)]

    apm::package_version::attributes::parse_xml  -parent_node $version  -array properties

    # Set an entry in the properties array for each of these attributes:
    #
    #   <vendor url="...">           -> vendor.url
    #   <description format="...">   -> description.format

    foreach { property_name attribute_name } {
        vendor url
        license url
        description format
    } {
        set node [xml_node_get_first_child_by_name $version $property_name]
        if { $node ne "" } {
            set properties($property_name.$attribute_name) [apm_attribute_value $node $attribute_name]
        } else {
            set properties($property_name.$attribute_name""
        }
    }

    # Build a list of packages to install additionally

    set properties(install) [list]
    foreach node [xml_node_get_children_by_name $version install] {
        set install [apm_attribute_value $node package]
        lappend properties(install) $install
    }

    # We're done constructing the properties array - save the properties into the
    # moby array which we're going to return.

    set properties(properties) [array get properties]

    # Build lists of the services provided by and required by the package.

    set properties(provides) [list]
    set properties(requires) [list]
    set properties(embeds) [list]
    set properties(extends) [list]

    foreach dependency_type { provides requires embeds extends } {
        set dependency_types [xml_node_get_children_by_name $version $dependency_type]

        foreach node $dependency_types {
            set service_uri [apm_required_attribute_value $node url]
            set service_version [apm_required_attribute_value $node version]
            # Package always provides itself, we'll add that below, so don't add it here
            if { $dependency_type ne "provides" || $service_uri ne $properties(package.key) } {
                lappend properties($dependency_type) [list $service_uri $service_version]
            }
        }
    }
    # Package provides itself always
    lappend properties(provides) [list $properties(package.key) $properties(name)]

    set properties(files) [list]

    # Build a list of package callbacks
    array set callback_array {}

    set callbacks_node_list [xml_node_get_children_by_name $version callbacks]
    foreach callbacks_node $callbacks_node_list {

        set callback_node_list [xml_node_get_children_by_name $callbacks_node callback]
        foreach callback_node $callback_node_list {

            set type [apm_attribute_value $callback_node type]
            set proc [apm_attribute_value $callback_node proc]

            if { [llength [array get callback_array $type]] != 0 } {
                # A callback proc of this type already found in the XML file
                ns_log Error "package info file $path contains more than one callback proc of type $type"
                continue
            }

            if {$type ni [apm_supported_callback_types]} {
                # The callback type is not supported
                ns_log Error "package info file $path contains an unsupported callback type $type - ignoring. Valid values are [apm_supported_callback_types]"
                continue
            }

            set callback_array($type$proc
        }
    }

    set properties(callbacks) [array get callback_array]


    # Build a list of the package's owners (if any).

    set properties(owners) [list]
    foreach node [xml_node_get_children_by_name $version owner] {
        set url [apm_attribute_value $node url]
        set name [xml_node_get_content $node]
        lappend properties(owners) [list $name $url]
    }

    # Build a list of the packages parameters (if any)

    set properties(parameters) [list]
    apm_log APMDebug "APM: Reading Parameters"

    foreach node [xml_node_get_children_by_name $version parameters] {
        set parameter_nodes [xml_node_get_children_by_name $node parameter]

        foreach parameter_node $parameter_nodes {
            set default_value [apm_attribute_value $parameter_node default]
            set min_n_values [apm_attribute_value $parameter_node min_n_values]
            set max_n_values [apm_attribute_value $parameter_node max_n_values]
            set description [apm_attribute_value $parameter_node description]
            set section_name [apm_attribute_value $parameter_node section_name]
            set datatype [apm_attribute_value $parameter_node datatype]
            set name [apm_attribute_value $parameter_node name]
            set scope [apm_attribute_value $parameter_node scope]

            if { $scope eq "" } {
                set scope instance
            }

            apm_log APMDebug "APM: Reading parameter $name with default $default_value"
            lappend properties(parameters) [list $name $description $section_name $scope  $datatype $min_n_values $max_n_values $default_value]
        }
    }

    # Release the XML tree
    xml_doc_free $tree

    # Serialize the array into a list.
    set return_value [array get properties]

    # Cache the property info based on $mtime.
    nsv_set apm_version_properties $path [list $mtime $return_value]

    return $return_value
XQL Not present:
PostgreSQL, Oracle
Generic XQL file:
packages/acs-tcl/tcl/apm-xml-procs.xql

[ hide source ] | [ make this the default ]
Show another procedure: