From 81671a3f5d59edb62e64e8e07953f40f4d352caa Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Mon, 29 Jun 2015 13:43:11 +0300 Subject: [PATCH 1/1] Improve gmx help -export Sphinx rebuild behavior Make 'gmx help -export rst' only touch those files whose contents have actually changed. This means that rerunning Sphinx is much faster when, e.g., checking the help text for a single tool after fixes. Use the file output redirection mechanism to capture all output into intermediate buffers, and only write it to a file if that file is missing or has incorrect contents. Update the reference data to avoid future confusion, as the files are now written out in a different order (but the tests pass irrespective of the order of the stuff in the reference data). Change-Id: I41d764e16aa68a5aaa7da879f4b600e268ca70f2 --- src/gromacs/commandline/cmdlinehelpmodule.cpp | 90 +++++++++++++++++-- .../CommandLineHelpModuleTest_ExportsHelp.xml | 28 +++--- 2 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/gromacs/commandline/cmdlinehelpmodule.cpp b/src/gromacs/commandline/cmdlinehelpmodule.cpp index 0ebad1ecfc..3d0020d3cd 100644 --- a/src/gromacs/commandline/cmdlinehelpmodule.cpp +++ b/src/gromacs/commandline/cmdlinehelpmodule.cpp @@ -62,9 +62,12 @@ #include "gromacs/utility/exceptions.h" #include "gromacs/utility/fileredirector.h" #include "gromacs/utility/gmxassert.h" +#include "gromacs/utility/path.h" #include "gromacs/utility/programcontext.h" +#include "gromacs/utility/stringstream.h" #include "gromacs/utility/stringutil.h" #include "gromacs/utility/textreader.h" +#include "gromacs/utility/textstream.h" #include "gromacs/utility/textwriter.h" #include "shellcompletions.h" @@ -491,8 +494,9 @@ class HelpExportReStructuredText : public HelpExportInterface { public: //! Initializes reST exporter. - explicit HelpExportReStructuredText( - const CommandLineHelpModuleImpl &helpModule); + HelpExportReStructuredText( + const CommandLineHelpModuleImpl &helpModule, + FileOutputRedirectorInterface *outputRedirector); virtual void startModuleExport(); virtual void exportModuleHelp( @@ -517,8 +521,9 @@ class HelpExportReStructuredText : public HelpExportInterface }; HelpExportReStructuredText::HelpExportReStructuredText( - const CommandLineHelpModuleImpl &helpModule) - : outputRedirector_(helpModule.outputRedirector_), + const CommandLineHelpModuleImpl &helpModule, + FileOutputRedirectorInterface *outputRedirector) + : outputRedirector_(outputRedirector), binaryName_(helpModule.binaryName_), links_(eHelpOutputFormat_Rst) { @@ -554,8 +559,6 @@ void HelpExportReStructuredText::exportModuleHelp( const std::string &tag, const std::string &displayName) { - // TODO: Ideally, the file would only be touched if it really changes. - // This would make Sphinx reruns much faster. TextOutputStreamPointer file = outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst"); TextWriter writer(file); @@ -783,6 +786,76 @@ void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter) rootTopic_->exportHelp(exporter); } +namespace +{ + +/******************************************************************** + * ModificationCheckingFileOutputStream + */ + +class ModificationCheckingFileOutputStream : public TextOutputStream +{ + public: + ModificationCheckingFileOutputStream( + const char *path, + FileOutputRedirectorInterface *redirector) + : path_(path), redirector_(redirector) + { + } + + virtual void write(const char *str) { contents_.write(str); } + virtual void close() + { + const std::string &newContents = contents_.toString(); + // TODO: Redirect these for unit tests. + if (File::exists(path_)) + { + const std::string originalContents_ + = TextReader::readFileToString(path_); + if (originalContents_ == newContents) + { + return; + } + } + TextWriter writer(redirector_->openTextOutputFile(path_)); + writer.writeString(newContents); + } + + private: + std::string path_; + StringOutputStream contents_; + FileOutputRedirectorInterface *redirector_; +}; + +/******************************************************************** + * ModificationCheckingFileOutputRedirector + */ + +class ModificationCheckingFileOutputRedirector : public FileOutputRedirectorInterface +{ + public: + explicit ModificationCheckingFileOutputRedirector( + FileOutputRedirectorInterface *redirector) + : redirector_(redirector) + { + } + + virtual TextOutputStream &standardOutput() + { + return redirector_->standardOutput(); + } + virtual TextOutputStreamPointer openTextOutputFile(const char *filename) + { + return TextOutputStreamPointer( + new ModificationCheckingFileOutputStream(filename, redirector_)); + } + + private: + FileOutputRedirectorInterface *redirector_; +}; + +} // namespace + /******************************************************************** * CommandLineHelpModule */ @@ -841,10 +914,11 @@ int CommandLineHelpModule::run(int argc, char *argv[]) CommandLineParser(&options).parse(&argc, argv); if (!exportFormat.empty()) { - boost::scoped_ptr exporter; + ModificationCheckingFileOutputRedirector redirector(impl_->outputRedirector_); + boost::scoped_ptr exporter; if (exportFormat == "rst") { - exporter.reset(new HelpExportReStructuredText(*impl_)); + exporter.reset(new HelpExportReStructuredText(*impl_, &redirector)); } else if (exportFormat == "completion") { diff --git a/src/gromacs/commandline/tests/refdata/CommandLineHelpModuleTest_ExportsHelp.xml b/src/gromacs/commandline/tests/refdata/CommandLineHelpModuleTest_ExportsHelp.xml index 40c8fb826d..df3572fa41 100644 --- a/src/gromacs/commandline/tests/refdata/CommandLineHelpModuleTest_ExportsHelp.xml +++ b/src/gromacs/commandline/tests/refdata/CommandLineHelpModuleTest_ExportsHelp.xml @@ -1,20 +1,6 @@ - ` - molecular dynamics simulation suite -* :doc:`test help ` - Print help information -* :doc:`test module ` - First module -* :doc:`test other ` - Second module -]]> - . +]]> + ` - molecular dynamics simulation suite +* :doc:`test help ` - Print help information +* :doc:`test module ` - First module +* :doc:`test other ` - Second module +]]> +