Commits

Georg Brandl committed 973ff50

Copy stat as well as files for static content.

Comments (0)

Files changed (3)

sphinx/builders/html.py

 
 import os
 import codecs
-import shutil
 import posixpath
 import cPickle as pickle
 from os import path
 
 from sphinx import package_dir, __version__
 from sphinx.util import SEP, os_path, relative_uri, ensuredir, \
-    movefile, ustrftime, copy_static_entry
+    movefile, ustrftime, copy_static_entry, copyfile
 from sphinx.errors import SphinxError
 from sphinx.search import js_index
 from sphinx.theming import Theme
             ensuredir(path.join(self.outdir, '_images'))
             for src, dest in self.images.iteritems():
                 self.info(' '+src, nonl=1)
-                shutil.copyfile(path.join(self.srcdir, src),
-                                path.join(self.outdir, '_images', dest))
+                copyfile(path.join(self.srcdir, src),
+                         path.join(self.outdir, '_images', dest))
             self.info()
 
         # copy downloadable files
             ensuredir(path.join(self.outdir, '_downloads'))
             for src, (_, dest) in self.env.dlfiles.iteritems():
                 self.info(' '+src, nonl=1)
-                shutil.copyfile(path.join(self.srcdir, src),
-                                path.join(self.outdir, '_downloads', dest))
+                copyfile(path.join(self.srcdir, src),
+                         path.join(self.outdir, '_downloads', dest))
             self.info()
 
         # copy static files
             jsfile = path.join(package_dir, 'locale', self.config.language,
                                'LC_MESSAGES', 'sphinx.js')
             if path.isfile(jsfile):
-                shutil.copyfile(jsfile, path.join(self.outdir, '_static',
-                                                  'translations.js'))
+                copyfile(jsfile, path.join(self.outdir, '_static',
+                                           'translations.js'))
         # then, copy over all user-supplied static files
         if self.theme:
             staticdirnames = [path.join(themepath, 'static')
         # last, copy logo file (handled differently)
         if self.config.html_logo:
             logobase = path.basename(self.config.html_logo)
-            shutil.copyfile(path.join(self.confdir, self.config.html_logo),
-                            path.join(self.outdir, '_static', logobase))
+            copyfile(path.join(self.confdir, self.config.html_logo),
+                     path.join(self.outdir, '_static', logobase))
 
         # write build info file
         fp = open(path.join(self.outdir, '.buildinfo'), 'w')
             source_name = path.join(self.outdir, '_sources',
                                     os_path(ctx['sourcename']))
             ensuredir(path.dirname(source_name))
-            shutil.copyfile(self.env.doc2path(pagename), source_name)
+            copyfile(self.env.doc2path(pagename), source_name)
 
     def handle_finish(self):
         self.info(bold('dumping search index... '), nonl=True)
             source_name = path.join(self.outdir, '_sources',
                                     os_path(ctx['sourcename']))
             ensuredir(path.dirname(source_name))
-            shutil.copyfile(self.env.doc2path(pagename), source_name)
+            copyfile(self.env.doc2path(pagename), source_name)
 
     def handle_finish(self):
         # dump the global context
 
         # copy the environment file from the doctree dir to the output dir
         # as needed by the web app
-        shutil.copyfile(path.join(self.doctreedir, ENV_PICKLE_FILENAME),
-                        path.join(self.outdir, ENV_PICKLE_FILENAME))
+        copyfile(path.join(self.doctreedir, ENV_PICKLE_FILENAME),
+                 path.join(self.outdir, ENV_PICKLE_FILENAME))
 
         # touch 'last build' file, used by the web application to determine
         # when to reload its environment and clear the cache

sphinx/builders/latex.py

 """
 
 import os
-import shutil
 from os import path
 
 from docutils import nodes
 from docutils.frontend import OptionParser
 
 from sphinx import package_dir, addnodes
-from sphinx.util import SEP, texescape
+from sphinx.util import SEP, texescape, copyfile
 from sphinx.builders import Builder
 from sphinx.environment import NoUri
 from sphinx.util.console import bold, darkgreen
             self.info(bold('copying images...'), nonl=1)
             for src, dest in self.images.iteritems():
                 self.info(' '+src, nonl=1)
-                shutil.copyfile(path.join(self.srcdir, src),
-                                path.join(self.outdir, dest))
+                copyfile(path.join(self.srcdir, src),
+                         path.join(self.outdir, dest))
             self.info()
 
         # copy additional files
             self.info(bold('copying additional files...'), nonl=1)
             for filename in self.config.latex_additional_files:
                 self.info(' '+filename, nonl=1)
-                shutil.copyfile(path.join(self.confdir, filename),
-                                path.join(self.outdir, path.basename(filename)))
+                copyfile(path.join(self.confdir, filename),
+                         path.join(self.outdir, path.basename(filename)))
             self.info()
 
         # the logo is handled differently
         if self.config.latex_logo:
             logobase = path.basename(self.config.latex_logo)
-            shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
-                            path.join(self.outdir, logobase))
+            copyfile(path.join(self.confdir, self.config.latex_logo),
+                     path.join(self.outdir, logobase))
 
         self.info(bold('copying TeX support files... '), nonl=True)
         staticdirname = path.join(package_dir, 'texinputs')
         for filename in os.listdir(staticdirname):
             if not filename.startswith('.'):
-                shutil.copyfile(path.join(staticdirname, filename),
-                                path.join(self.outdir, filename))
+                copyfile(path.join(staticdirname, filename),
+                         path.join(self.outdir, filename))
         self.info('done')

sphinx/util/__init__.py

 
 
 def movefile(source, dest):
-    # move a file, removing the destination if it exists
+    """Move a file, removing the destination if it exists."""
     if os.path.exists(dest):
         try:
             os.unlink(dest)
     os.rename(source, dest)
 
 
+def copyfile(source, dest):
+    """Copy a file and its modification times, if possible."""
+    shutil.copyfile(source, dest)
+    try: shutil.copystat(source, dest)
+    except shutil.Error: pass
+
+
 def copy_static_entry(source, target, builder, context={}):
     if path.isfile(source):
         if source.lower().endswith('_t'):
             fsrc.close()
             fdst.close()
         else:
-            shutil.copyfile(source, target)
+            copyfile(source, target)
     elif path.isdir(source):
         if source in builder.config.exclude_dirnames:
             return