classes/phing/Project.php
public function topoSort($rootTarget)
    {
        $rootTarget = (string) $rootTarget;
        $ret = [];
        $state = [];
        $visiting = [];

        // We first run a DFS based sort using the root as the starting node.
        // This creates the minimum sequence of Targets to the root node.
        // We then do a sort on any remaining unVISITED targets.
        // This is unnecessary for doing our build, but it catches
        // circular dependencies or missing Targets on the entire
        // dependency tree, not just on the Targets that depend on the
        // build Target.

        $this->_tsort($rootTarget, $state, $visiting, $ret);

        $retHuman = "";
        for ($i = 0, $_i = count($ret); $i < $_i; $i++) {
            $retHuman .= (string) $ret[$i] . " ";
        }
        $this->log("Build sequence for target '$rootTarget' is: $retHuman", Project::MSG_VERBOSE);

        $keys = array_keys($this->targets);
        while ($keys) {
            $curTargetName = (string) array_shift($keys);
            if (!isset($state[$curTargetName])) {
                $st = null;
            } else {
                $st = (string) $state[$curTargetName];
            }

            if ($st === null) {
                $this->_tsort($curTargetName, $state, $visiting, $ret);
            } elseif ($st === "VISITING") {
                throw new Exception("Unexpected node in visiting state: $curTargetName");
            }
        }

        $retHuman = "";
        for ($i = 0, $_i = count($ret); $i < $_i; $i++) {
            $retHuman .= (string) $ret[$i] . " ";
        }
        $this->log("Complete build sequence is: $retHuman", Project::MSG_VERBOSE);

        return $ret;
    }
public function topoSort($rootTarget)
    {
        $rootTarget = (string) $rootTarget;
        $ret = [];
        $state = [];
        $visiting = [];

        // We first run a DFS based sort using the root as the starting node.
        // This creates the minimum sequence of Targets to the root node.
        // We then do a sort on any remaining unVISITED targets.
        // This is unnecessary for doing our build, but it catches
        // circular dependencies or missing Targets on the entire
        // dependency tree, not just on the Targets that depend on the
        // build Target.

        $this->_tsort($rootTarget, $state, $visiting, $ret);

        $retHuman = "";
        for ($i = 0, $_i = count($ret); $i < $_i; $i++) {
            $retHuman .= (string) $ret[$i] . " ";
        }
        $this->log("Build sequence for target '$rootTarget' is: $retHuman", Project::MSG_VERBOSE);

        $keys = array_keys($this->targets);
        while ($keys) {
            $curTargetName = (string) array_shift($keys);
            if (!isset($state[$curTargetName])) {
                $st = null;
            } else {
                $st = (string) $state[$curTargetName];
            }

            if ($st === null) {
                $this->_tsort($curTargetName, $state, $visiting, $ret);
            } elseif ($st === "VISITING") {
                throw new Exception("Unexpected node in visiting state: $curTargetName");
            }
        }

        $retHuman = "";
        for ($i = 0, $_i = count($ret); $i < $_i; $i++) {
            $retHuman .= (string) $ret[$i] . " ";
        }
        $this->log("Complete build sequence is: $retHuman", Project::MSG_VERBOSE);

        return $ret;
    }
public function topoSort ( $ rootTarget ) { $ rootTarget = ( string ) $ rootTarget ; $ ret = [ ] ; $ state = [ ] ; $ visiting = [ ] ; // We first run a DFS based sort using the root as the starting node. // This creates the minimum sequence of Targets to the root node. // We then do a sort on any remaining unVISITED targets. // This is unnecessary for doing our build, but it catches // circular dependencies or missing Targets on the entire // dependency tree, not just on the Targets that depend on the // build Target. $ this -> _tsort ( $ rootTarget , $ state , $ visiting , $ ret ) ; $ retHuman = "" ; for ( $ i = 0 , $ _i = count ( $ ret ) ; $ i < $ _i ; $ i ++ ) { $ retHuman .= ( string ) $ ret [ $ i ] . " " ; } $ this -> log ( "Build sequence for target '$rootTarget' is: $retHuman" , Project :: MSG_VERBOSE ) ; $ keys = array_keys ( $ this -> targets ) ; while ( $ keys ) { $ curTargetName = ( string ) array_shift ( $ keys ) ; if ( ! isset ( $ state [ $ curTargetName ] ) ) { $ st = null ; } else { $ st = ( string ) $ state [ $ curTargetName ] ; } if ( $ st === null ) { $ this -> _tsort ( $ curTargetName , $ state , $ visiting , $ ret ) ; } elseif ( $ st === "VISITING" ) { throw new Exception ( "Unexpected node in visiting state: $curTargetName" ) ; } } $ retHuman = "" ; for ( $ i = 0 , $ _i = count ( $ ret ) ; $ i < $ _i ; $ i ++ ) { $ retHuman .= ( string ) $ ret [ $ i ] . " " ; } $ this -> log ( "Complete build sequence is: $retHuman" , Project :: MSG_VERBOSE ) ; return $ ret ; }
Topologically sort a set of Targets.

@param  string $rootTarget is the (String) name of the root Target. The sort is
created in such a way that the sequence of Targets until the root
target is the minimum possible such sequence.
@throws BuildException
@throws Exception
@return Target[] targets in sorted order
Topologically sort a set of Targets .