function git_file($location, $ref, $path) { foreach (BoostSuperProject::run_process("git -C {$location} ls-tree {$ref} {$path}") as $entry) { if (!preg_match("@^100644 blob ([a-zA-Z0-9]+)\t(.*)\$@", $entry, $matches)) { assert(false); } return BoostSuperProject::run_process("git -C {$location} show {$matches[1]}"); } return false; }
function convert_quickbook_pages($refresh = false) { try { BoostSuperProject::run_process('quickbook --version'); } catch (ProcessError $e) { echo "Problem running quickbook, will not convert quickbook articles.\n"; return; } $bb_parser = new BoostBookParser(); foreach ($this->pages as $page => $page_data) { if ($page_data->page_state || $refresh) { $xml_filename = tempnam(sys_get_temp_dir(), 'boost-qbk-'); try { echo "Converting ", $page, ":\n"; BoostSuperProject::run_process("quickbook --output-file {$xml_filename} -I {$this->root}/feed {$this->root}/{$page}"); $page_data->load($bb_parser->parse($xml_filename), $refresh); } catch (Exception $e) { unlink($xml_filename); throw $e; } unlink($xml_filename); $template_vars = array('history_style' => '', 'full_title_xml' => $page_data->full_title_xml, 'title_xml' => $page_data->title_xml, 'note_xml' => '', 'web_date' => $page_data->web_date(), 'documentation_para' => '', 'download_table' => $page_data->download_table(), 'description_xml' => $page_data->description_xml); if ($page_data->type == 'release' && empty($page_data->flags['released']) && empty($page_data->flags['beta'])) { $template_vars['note_xml'] = <<<EOL <div class="section-note"><p>Note: This release is still under development. Please don't use this page as a source of information, it's here for development purposes only. Everything is subject to change.</p></div> EOL; } if ($page_data->documentation) { $template_vars['documentation_para'] = ' <p><a href="' . html_encode($page_data->documentation) . '">Documentation</a>'; } if (strpos($page_data->location, 'users/history/') === 0) { $template_vars['history_style'] = <<<EOL <style type="text/css"> /*<![CDATA[*/ #content .news-description ul { list-style: none; } #content .news-description ul ul { list-style: circle; } /*]]>*/ </style> EOL; } self::write_template("{$this->root}/{$page_data->location}", __DIR__ . "/templates/entry.php", $template_vars); } } }
function main() { global $quiet; $options = BoostSiteTools\CommandLineOptions::parse(UPDATE_DOC_LIST_USAGE, array('quiet' => false)); $quiet = $options->flags['quiet']; $location = null; $version = null; switch (count($options->positional)) { case 2: $version = $options->positional[1]; case 1: $location = $options->positional[0]; case 0: break; default: echo $options->usage_message(); exit(1); } if ($version) { // BoostVersion dies if version is invalid. $version = BoostVersion::from($version); } $libs = BoostLibraries::from_xml_file(dirname(__FILE__) . '/../doc/libraries.xml'); $updates = array(); if ($location) { $real_location = realpath($location); if ($real_location && !is_dir($real_location)) { echo "Not a directory: {$location}\n"; exit(1); } $location = $real_location; // If this is not a git repo. // TODO: Don't output stderr. exec("cd \"{$location}\" && git rev-parse --git-dir", $output, $return_var); if ($return_var != 0) { if (!$version || !$version->is_numbered_release()) { echo "Error: Release version required for release.\n"; exit(1); } $updates[(string) $version] = read_metadata_from_filesystem($location, $version); } else { if (get_bool_from_array(BoostSuperProject::run_process("cd '{$location}' && git rev-parse --is-bare-repository"))) { if ($version) { $updates[(string) $version] = read_metadata_from_git($location, $version); } else { $updates[(string) 'master'] = read_metadata_from_git($location, 'master'); $updates[(string) 'develop'] = read_metadata_from_git($location, 'develop'); } } else { // TODO: Could get version from the branch in a git checkout. if (!$version) { echo "Error: Version required for local tree.\n"; exit(1); } $updates[(string) $version] = read_metadata_from_filesystem($location, $version); } } } if ($updates) { foreach ($updates as $update_version => $update) { $libs->update($update_version, $update); } } else { $libs->update(); } if (!$quiet) { echo "Writing to disk\n"; } file_put_contents(dirname(__FILE__) . '/../doc/libraries.xml', $libs->to_xml()); $libs->squash_name_arrays(); file_put_contents(dirname(__FILE__) . '/../generated/libraries.txt', serialize($libs)); }
/** * * @param string $location The location of the super project in the mirror. * @param BoostVersion|string $version The version to update from. * @throws RuntimeException */ function read_metadata_from_git($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}"); } } $updated_libs = array(); 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}")); $updated_libs = array_merge($updated_libs, load_from_text($text, $filename, $name, $module['path'])); } } catch (library_decode_exception $e) { echo "Error decoding metadata for module {$name}:\n{$e->content()}\n"; } } } return $updated_libs; }
function convert_quickbook_pages($refresh = false) { try { BoostSuperProject::run_process('quickbook --version'); $have_quickbook = true; } catch (ProcessError $e) { echo "Problem running quickbook, will not convert quickbook articles.\n"; $have_quickbook = false; } $bb_parser = new BoostBookParser(); foreach ($this->pages as $page => $page_data) { if ($page_data->page_state || $refresh) { // Hash the quickbook source $hash = hash('sha256', str_replace("\r\n", "\n", file_get_contents("{$this->root}/{$page}"))); // Get the page from quickbook/read from cache if (array_key_exists($page, $this->page_cache) && (!$have_quickbook || $this->page_cache[$page]['hash'] === $hash)) { $description_xhtml = $this->page_cache[$page]['description_xhtml']; } else { if ($have_quickbook) { $xml_filename = tempnam(sys_get_temp_dir(), 'boost-qbk-'); try { echo "Converting ", $page, ":\n"; BoostSuperProject::run_process("quickbook --output-file {$xml_filename} -I {$this->root}/feed {$this->root}/{$page}"); $values = $bb_parser->parse($xml_filename); $page_data->load_boostbook_data($values, $refresh); $description_xhtml = $values['description_xhtml']; } catch (Exception $e) { unlink($xml_filename); throw $e; } unlink($xml_filename); $this->page_cache[$page] = array('hash' => $hash, 'description_xhtml' => $description_xhtml); } else { echo "Unable to generate page for {$page}.\n"; continue; } } // Set the path where the page should be built. // This can only be done after the quickbook file has been converted, // as the page id is based on the file contents. if (!$page_data->location) { $location_data = $this->get_page_location_data($page_data->qbk_file); $page_data->location = "{$location_data['destination']}/{$page_data->id}.html"; } // Transform links in description if ($page_data->section === 'history') { $doc_prefix = null; if ($page_data->get_release_status() === 'dev' || $page_data->get_release_status() === 'beta') { $doc_prefix = rtrim($page_data->get_documentation() ?: '/doc/libs/master/', '/'); $description_xhtml = BoostSiteTools::transform_links($description_xhtml, function ($x) use($doc_prefix) { return preg_match('@^/(?:libs/|doc/html/)@', $x) ? $doc_prefix . $x : $x; }); } $version = BoostWebsite::array_get($page_data->release_data, 'version'); if ($version && $doc_prefix) { $final_documentation = "/doc/libs/{$version->final_doc_dir()}"; $link_pattern = '@^' . preg_quote($final_documentation, '@') . '/@'; $replace = "{$doc_prefix}/"; $description_xhtml = BoostSiteTools::transform_links($description_xhtml, function ($x) use($link_pattern, $replace) { return preg_replace($link_pattern, $replace, $x); }); } } $description_xhtml = BoostSiteTools::trim_lines($description_xhtml); $page_data->description_xml = $description_xhtml; // Generate the various pages. $template_vars = array('history_style' => '', 'full_title_xml' => $page_data->full_title_xml(), 'title_xml' => $page_data->title_xml, 'note_xml' => '', 'web_date' => $page_data->web_date(), 'documentation_para' => '', 'download_table' => $page_data->download_table(), 'description_xml' => $page_data->description_xml); if ($page_data->get_release_status() === 'dev') { $template_vars['note_xml'] = <<<EOL <div class="section-alert"><p>Note: This release is still under development. Please don't use this page as a source of information, it's here for development purposes only. Everything is subject to change.</p></div> EOL; } if ($page_data->section === 'history' && BoostWebsite::array_get($page_data->release_data, 'documentation')) { $template_vars['documentation_para'] = ' <p><a href="' . html_encode(BoostWebsite::array_get($page_data->release_data, 'documentation')) . '">Documentation</a>'; } if (strpos($page_data->location, 'users/history/') === 0) { $template_vars['history_style'] = <<<EOL <style type="text/css"> /*<![CDATA[*/ #content .news-description ul { list-style: none; } #content .news-description ul ul { list-style: circle; } /*]]>*/ </style> EOL; } self::write_template("{$this->root}/{$page_data->location}", __DIR__ . "/templates/entry.php", $template_vars); $page_data->page_state = null; } } }