function package_releases($type, $project_id)
{
    global $wd_err_msg;
    $rel_node_join = '';
    $where_args = array();
    if ($type == 'tag') {
        $where = " AND (label.type = %d) AND (f.filepath IS NULL OR f.filepath = '')";
        $where_args[] = VERSIONCONTROL_OPERATION_TAG;
        // label.type
        $plural = t('tags');
    } elseif ($type == 'branch') {
        $rel_node_join = " INNER JOIN {node} nr ON prn.nid = nr.nid";
        $where = " AND (label.type = %d) AND ((f.filepath IS NULL) OR (f.filepath = '') OR (nr.status = 1))";
        $where_args[] = VERSIONCONTROL_OPERATION_BRANCH;
        // label.type
        $plural = t('branches');
        if (empty($project_id)) {
            wd_msg("Starting to package all snapshot releases.");
        } else {
            wd_msg("Starting to package snapshot releases for project id: @project_id.", array('@project_id' => $project_id), l(t('view'), 'node/' . $project_id));
        }
    } else {
        wd_err("ERROR: package_releases() called with unknown type: %type", array('%type' => $type));
        return;
    }
    $args = array();
    $args[] = (int) _project_release_get_api_vid();
    if (!empty($project_id)) {
        $where .= ' AND prn.pid = %d';
        $where_args[] = $project_id;
    }
    $args = array_merge($args, $where_args);
    $result = db_query("\n    SELECT pp.uri, prn.nid AS release_nid, prn.pid AS project_nid, prn.version,\n      prn.version_major, td.tid, vpp.directory, vpp.repo_id,\n      label.label_id, label.name AS label_name, label.type AS label_type\n    FROM {project_release_nodes} prn\n      {$rel_node_join}\n      LEFT JOIN {project_release_file} prf ON prn.nid = prf.nid\n      LEFT JOIN {files} f ON prf.fid = f.fid\n      INNER JOIN {term_node} tn ON prn.nid = tn.nid\n      INNER JOIN {term_data} td ON tn.tid = td.tid\n      INNER JOIN {project_projects} pp ON prn.pid = pp.nid\n      INNER JOIN {node} np ON prn.pid = np.nid\n      INNER JOIN {project_release_projects} prp ON prp.nid = prn.pid\n      INNER JOIN {versioncontrol_project_projects} vpp ON prn.pid = vpp.nid\n      INNER JOIN {versioncontrol_release_labels} vrl ON prn.nid = vrl.release_nid\n      INNER JOIN {versioncontrol_labels} label ON vrl.label_id = label.label_id\n    WHERE np.status = 1 AND prp.releases = 1 AND td.vid = %d\n      {$where}\n    ORDER BY pp.uri", $args);
    $num_built = 0;
    $num_considered = 0;
    $project_nids = array();
    // Determine the list of sufficient VCS backends, in order to avoid errors
    // in edge cases. (In the common case, unsupported backends don't generate
    // releases with VCS integration, but who knows what might happen.)
    $backends = versioncontrol_get_backends();
    $supported_backends = array();
    foreach ($backends as $vcs => $backend) {
        if (versioncontrol_release_is_supported_backend($vcs)) {
            $supported_backends[] = $vcs;
        }
    }
    // Read everything out of the query immediately so that we don't leave the
    // query object/connection open while doing other queries.
    $releases = array();
    while ($release = db_fetch_object($result)) {
        $releases[] = $release;
    }
    foreach ($releases as $release) {
        // Fetch the repository where the project is located.
        $repositories = versioncontrol_get_repositories(array('repo_ids' => array($release->repo_id), 'vcs' => $supported_backends));
        if (empty($repositories)) {
            $num_considered++;
            continue;
        }
        $repository = reset($repositories);
        // first item
        $wd_err_msg = array();
        $version = $release->version;
        $release_nid = $release->release_nid;
        $tid = $release->tid;
        $project = array('uri' => $release->uri, 'nid' => $release->project_nid, 'repo_id' => $release->directory, 'directory' => $release->directory);
        $label = array('label_id' => $release->label_id, 'name' => $release->label_name, 'type' => $release->label_type);
        $major = $release->version_major;
        $version = escapeshellcmd($version);
        db_query("DELETE FROM {project_release_package_errors} WHERE nid = %d", $release_nid);
        $built = package_release($release_nid, $project, $repository, $version, $label);
        if ($built) {
            $num_built++;
            $project_nids[$project['nid']][$tid][$major] = TRUE;
        }
        $num_considered++;
        if (count($wd_err_msg)) {
            db_query("INSERT INTO {project_release_package_errors} (nid, messages) values (%d, '%s')", $release_nid, serialize($wd_err_msg));
        }
    }
    if (!empty($num_built) || $type == 'branch') {
        if (!empty($project_id)) {
            wd_msg("Done packaging releases for @uri from !plural: !num_built built, !num_considered considered.", array('@uri' => $uri, '!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered));
        } else {
            wd_msg("Done packaging releases from !plural: !num_built built, !num_considered considered.", array('!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered));
        }
    }
    // Finally, for each project/tid/major triple we packaged, check to see if
    // the supported/recommended settings are sane now that new tarballs have
    // been generated and release nodes published.
    foreach ($project_nids as $pid => $tids) {
        foreach ($tids as $tid => $majors) {
            foreach ($majors as $major => $value) {
                project_release_check_supported_versions($pid, $tid, $major, FALSE);
            }
        }
    }
}
 /**
  * @see Serializable::unserialize().
  */
 public function unserialize($serialized)
 {
     foreach (unserialize($serialized) as $prop => $val) {
         $this->{$prop} = $val;
     }
     // And stripped out data members.
     $this->backend = versioncontrol_get_backends($this->vcs);
     unset($this->vcs);
     $this->repository = $this->backend->loadEntity('repo', $this->repo_id);
 }
 /**
  * Fulfills Serializable::unserialize() interface.
  *
  * @param string $string_rep
  */
 public function unserialize($string_rep)
 {
     foreach (unserialize($string_rep) as $prop => $val) {
         $this->{$prop} = $val;
     }
     // And add the backend, which was stripped out.
     $this->backend = versioncontrol_get_backends($this->vcs);
 }