示例#1
0
/**
 *
 * @param \BoostLibraries $libs The libraries to update.
 * @param string $location The location of the super project in the mirror.
 * @param BoostVersion|string $version The version to update from.
 * @throws RuntimeException
 */
function update_from_git($libs, $location, $version)
{
    $branch = BoostVersion::from($version)->git_ref();
    echo "Updating from {$branch}\n";
    $super_project = new BoostSuperProject($location, $branch);
    $modules = $super_project->get_modules();
    $modules_by_path = array();
    foreach ($modules as $name => $details) {
        $modules_by_path[$details['path']] = $name;
    }
    foreach ($super_project->run_git("ls-tree {$branch} " . implode(' ', array_keys($modules_by_path))) as $line_number => $line) {
        if (!$line) {
            continue;
        }
        if (preg_match("@^160000 commit ([a-zA-Z0-9]+)\t(.*)\$@", $line, $matches)) {
            $modules[$modules_by_path[$matches[2]]]['hash'] = $matches[1];
        } else {
            throw new RuntimeException("Unmatched submodule line: {$line}");
        }
    }
    foreach ($modules as $name => $module) {
        $module_location = "{$location}/{$module['url']}";
        $module_command = "cd '{$module_location}' && git";
        foreach (BoostSuperProject::run_process("{$module_command} ls-tree {$module['hash']} " . "meta/libraries.xml meta/libraries.json") as $entry) {
            try {
                $entry = trim($entry);
                if (preg_match("@^100644 blob ([a-zA-Z0-9]+)\t(.*)\$@", $entry, $matches)) {
                    $hash = $matches[1];
                    $filename = $matches[2];
                    $text = implode("\n", BoostSuperProject::run_process("{$module_command} show {$hash}"));
                    $libs->update(load_from_text($text, $filename, $name, $module['path']), $branch);
                }
            } catch (library_decode_exception $e) {
                echo "Error decoding metadata for module {$name}:\n{$e->content()}\n";
            }
        }
    }
}
function read_metadata_from_modules($path, $location, $hash, $sublibs = array('libs' => true))
{
    // echo "Reading from {$path} - {$location} - {$hash}.\n";
    $super_project = new BoostSuperProject($location, $hash);
    $modules = $super_project->get_modules();
    // Used to quickly set submodule hash.
    $modules_by_path = array();
    foreach ($modules as $name => $details) {
        $modules_by_path[$details['path']] = $name;
    }
    // Store possible metadata files in this array.
    $metadata_files = array();
    // Get a list of everything that's relevant in the superproject+modules.
    foreach ($super_project->run_git("ls-tree {$hash} -r") as $line_number => $line) {
        if (!$line) {
            continue;
        }
        if (preg_match("@^(\\d{6}) (\\w+) ([a-zA-Z0-9]+)\t(.*)\$@", $line, $matches)) {
            switch ($matches[2]) {
                case 'blob':
                    $blob_path = $path ? "{$path}/{$matches['4']}" : $matches[4];
                    if (fnmatch('*/sublibs', $blob_path)) {
                        $sublibs[dirname($blob_path)] = true;
                    } else {
                        if (fnmatch('*/meta/libraries.json', $blob_path)) {
                            $metadata_files[$blob_path] = $matches[3];
                        }
                    }
                    break;
                case 'commit':
                    $modules[$modules_by_path[$matches[4]]]['hash'] = $matches[3];
                    break;
            }
        } else {
            throw new RuntimeException("Unmatched submodule line: {$line}");
        }
    }
    // Process metadata files
    $updated_libs = array();
    foreach ($metadata_files as $metadata_path => $metadata_hash) {
        if (empty($sublibs[dirname(dirname(dirname($metadata_path)))])) {
            echo "Ignoring non-library metadata file: {$metadata_path}.\n";
        } else {
            $text = implode("\n", $super_project->run_git("show {$metadata_hash}"));
            $updated_libs = array_merge($updated_libs, load_from_text($text, $metadata_path, dirname(dirname($metadata_path))));
        }
    }
    // Recurse over submodules
    foreach ($modules as $name => $module) {
        global $quiet;
        $submodule_path = $path ? "{$path}/{$module['path']}" : $module['path'];
        if (!preg_match('@^\\.\\./(\\w+)\\.git$@', $module['url'])) {
            // In quiet mode don't warn about documentation submodules, which
            // libraries have previously included from remote locations.
            if (!$quiet || strpos($submodule_path . '/', '/doc/') === false) {
                echo "Ignoring submodule '{$name}' in '{$location}'.\n";
            }
            continue;
        }
        if (empty($module['hash'])) {
            echo "Missing module in .gitmodule: '{$name}' in '{$location}'.\n";
            continue;
        }
        $updated_libs = array_merge($updated_libs, read_metadata_from_modules($submodule_path, "{$location}/{$module['url']}", $module['hash'], $sublibs));
    }
    return $updated_libs;
}