/** * * @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; }