apm_dependency_check (private)

 apm_dependency_check [ -callback callback ] [ -initial_install ] \
    [ -pkg_info_all pkg_info_all ] spec_files

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

Check dependencies of all the packages provided.

Switches:
-callback
(defaults to "apm_dummy_callback") (optional)
-initial_install
(boolean) (optional)
Only process spec files with the initial install attribute.
-pkg_info_all
(optional)
If you supply this argument, when a requirement goes unsatisfied, instead of failing, this proc will try to add whatever other packages are needed to the install set. The list of package keys to add will be the third element in the list returned.
Parameters:
spec_files - A list of spec files to be processed.
Returns:
A list whose first element indicates whether dependencies were satisfied (1 if so, 0 otherwise). The second element is the package info list with the packages ordered according to dependencies. Packages that can be installed come first. Any packages that failed the dependency check come last. The third element is a list of package keys on additional packages to install, in order to satisfy dependencies.

Partial Call Graph (max 5 caller/called nodes):
%3 apm_simple_package_install apm_simple_package_install (public) apm_dependency_check apm_dependency_check apm_simple_package_install->apm_dependency_check apm_callback_and_log apm_callback_and_log (public) apm_dependency_check->apm_callback_and_log apm_dependency_provided_p apm_dependency_provided_p (public) apm_dependency_check->apm_dependency_provided_p apm_package_supports_rdbms_p apm_package_supports_rdbms_p (public) apm_dependency_check->apm_package_supports_rdbms_p apm_read_package_info_file apm_read_package_info_file (public) apm_dependency_check->apm_read_package_info_file pkg_info_embeds pkg_info_embeds (private) apm_dependency_check->pkg_info_embeds

Testcases:
No testcase defined.
Source code:
    #### Iterate over the list of info files.
    ## Every time we satisfy another package, remove it from install_pend, and loop again.
    ## If we don't satisfy at least one more package, halt.
    ## install_in - Package info structures for packages that can be installed in a satisfactory order.
    ## install_pend - Stores package info structures for packages that might have their dependencies satisfied
    ##              by packages in the install set.
    ## extra_package_keys - package keys of extra packages to install to satisfy all requirements.

    set extra_package_keys [list]

    set updated_p 1
    set install_in [list]
    foreach spec_file $spec_files {
        if { [catch {
            array set package [apm_read_package_info_file $spec_file]
            if { ($package(initial-install-p) eq "t" || !$initial_install_p)
                 && [apm_package_supports_rdbms_p -package_key $package(package.key)]
             } {
                lappend install_pend [pkg_info_new  $package(package.key)  $spec_file  $package(embeds)  $package(extends)  $package(provides)  $package(requires)  ""]
            }

            # Remove this package from the pkg_info_all list ...
            # either we're already installing it, or it can't be installed
            set counter 0
            foreach pkg_info $pkg_info_all {
                if { [pkg_info_key $pkg_info] eq $package(package.key) } {
                    set pkg_info_all [lreplace $pkg_info_all $counter $counter]
                    break
                }
                incr counter
            }
        } errmsg]} {
            # Failed to parse the specification file.
            apm_callback_and_log $callback "$spec_file could not be parsed correctly.  It is not being installed.
        The error: $errmsg"
        }
    }

    # Outer loop tries to find a package from the pkg_info_all list to add if
    # we're stuck because of unsatisfied dependencies
    set updated_p 1
    while { $updated_p } {

        # Inner loop tries to add another package from the install_pend list
        while { $updated_p && [info exists install_pend] && $install_pend ne ""} {
            set install_in_provides [list]
            set new_install_pend [list]
            set updated_p 0
            # Generate the list of dependencies currently provided by the install set.
            foreach pkg_info $install_in {
                foreach prov [pkg_info_provides $pkg_info] {
                    lappend install_in_provides $prov
                }
            }
            # Now determine if we can add another package to the install set.
            foreach pkg_info $install_pend {
                set satisfied_p 1
                foreach req [concat [pkg_info_embeds $pkg_info] [pkg_info_extends $pkg_info] [pkg_info_requires $pkg_info]] {
                    if {[apm_dependency_provided_p -dependency_list $install_in_provides  [lindex $req 0] [lindex $req 1]] != 1} {
                        # Unsatisfied dependency.
                        set satisfied_p 0
                        # Check to see if we've recorded it already
                        set errmsg "Requires [lindex $req 0] of version >= [lindex $req 1]."
                        if { ![info exists install_error([pkg_info_key $pkg_info])] ||
                             $errmsg ni $install_error([pkg_info_key $pkg_info])} {
                            lappend install_error([pkg_info_key $pkg_info]) $errmsg
                        }
                        lappend new_install_pend $pkg_info
                        break
                    }
                }
                if { $satisfied_p } {
                    # At least one more package was added to the list that can be installed, so repeat.
                    lappend install_in [pkg_info_new  [pkg_info_key $pkg_info]  [pkg_info_spec $pkg_info]  [pkg_info_embeds $pkg_info]  [pkg_info_extends $pkg_info]  [pkg_info_provides $pkg_info]  [pkg_info_requires $pkg_info]  "t"  "Package satisfies dependencies."]
                    set updated_p 1
                }
            }
            set install_pend $new_install_pend
        }

        set updated_p 0

        if { [info exists install_pend] && $install_pend ne "" && [llength $pkg_info_all] > 0 } {
            # Okay, there are some packages that could not be installed

            # Let's find a package, which
            # - have unsatisfied requirements
            # - and we have a package in pkg_info_all which provides what this package requires

            foreach pkg_info $install_pend {
                set satisfied_p 1
                foreach req [concat [pkg_info_embeds $pkg_info] [pkg_info_extends $pkg_info] [pkg_info_requires $pkg_info]] {
                    set counter 0
                    foreach pkg_info_add $pkg_info_all {
                        # Will this package do anything to change whether this requirement has been satisfied?
                        if { [pkg_info_key $pkg_info_add] eq [lindex $req 0]
                             && [apm_dependency_provided_p -dependency_list [pkg_info_provides $pkg_info_add]  [lindex $req 0] [lindex $req 1]] == 1
                         } {

                            # It sure does. Add it to list of packages to install
                            lappend install_pend $pkg_info_add

                            # Add it to list of extra package keys
                            lappend extra_package_keys [pkg_info_key $pkg_info_add]

                            # Remove it from list of packages that we can possibly install
                            set pkg_info_all [lreplace $pkg_info_all $counter $counter]

                            # Note that we've made changes
                            set updated_p 1

                            # Now break out of pkg_info_all loop
                            break
                        }
                        incr counter
                    }
                    if { $updated_p } {
                        break
                    }
                }
                if { $updated_p } {
                    break
                }
            }
        }
    }

    set install_order(order) $install_in
    # Update all of the packages that cannot be installed.
    if { [info exists install_pend] && $install_pend ne "" } {
        foreach pkg_info $install_pend {
            lappend install_in [pkg_info_new [pkg_info_key $pkg_info] [pkg_info_spec $pkg_info]  [pkg_info_embeds $pkg_info] [pkg_info_extends $pkg_info]  [pkg_info_provides $pkg_info] [pkg_info_requires $pkg_info]  "f" $install_error([pkg_info_key $pkg_info])]
        }
        return [list 0 $install_in]
    }

    return [list 1 $install_in $extra_package_keys]
Generic XQL file:
packages/acs-tcl/tcl/apm-install-procs.xql

PostgreSQL XQL file:
packages/acs-tcl/tcl/apm-install-procs-postgresql.xql

Oracle XQL file:
packages/acs-tcl/tcl/apm-install-procs-oracle.xql

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