--- Begin Message ---
Package: viewvc
Version: 1.0.5-0.1
Severity: normal
Tags: patch
Hello ViewVC maintainer,
Tarball generated from a subversion repository have all files permissions
set to 644. This can break compilation because some script cannot be run.
See upstream tracker: <http://viewvc.tigris.org/issues/show_bug.cgi?id=233>
I am not sure whether the patch in the tracker is totally safe, but it works
for me, and I need that feature.
Please find the patch in quilt format.
Cheers,
Bill
-- System Information:
Debian Release: 4.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-6-686
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Versions of packages viewvc depends on:
ii cvs 1:1.12.13-8 Concurrent Versions System
ii debconf [debconf-2.0] 1.5.11etch1 Debian configuration management sy
ii gawk 1:3.1.5.dfsg-4 GNU awk, a pattern scanning and pr
ii mime-support 3.39-1 MIME files 'mime.types' & 'mailcap
ii python 2.4.4-2 An interactive high-level object-o
ii python-subversion 1.4.2dfsg1-2 Python bindings for Subversion
ii python-support 0.5.6 automated rebuilding support for p
ii rcs 5.7-18 The GNU Revision Control System
ii subversion 1.4.2dfsg1-2 Advanced version control system
Versions of packages viewvc recommends:
ii apache [httpd] 1.3.34-4.1+etch1 versatile, high-performance HTTP s
ii enscript 1.6.4-11 Converts ASCII text to Postscript,
-- debconf information:
* viewvc/forbidden:
* viewvc/svnroots:
* viewvc/cvsroots:
* viewvc/allow_tar: true
* viewvc/defaultroot:
Patch from http://viewvc.tigris.org/issues/show_bug.cgi?id=233
by C. Michael Pilato to fix permission in generated tarballs.
===============================================================
Implement the beginnings of a generic-as-it-gets vclib interface for
item properties, and use it to set the mode for files in generated
tarballs. A poem for issue #233.
* viewvc/lib/vclib/__init__.py
(Repository.itemprops): New.
(ItemProperties): New class for hold properties-related data.
* viewvc/lib/vclib/svn/__init__.py
(SubversionRepository.itemprops, _make_item_properties): New.
* viewvc/lib/viewvc.py
(generate_tarball): Check the executable bit for Subversion files.
* viewvc/lib/vclib/bincvs/__init__.py
(CVSRepository.itemprops): New.
* viewvc/lib/vclib/ccvs/__init__.py
(CCVSRepository.itemprops): New. Duplicate of the
bincvs.CVSRepository implementation, because just using the parent
class implementation didn't seem to work.
Index: viewvc-1.0.5/lib/vclib/__init__.py
===================================================================
--- viewvc-1.0.5.orig/lib/vclib/__init__.py 2008-05-21 20:24:33.000000000
+0200
+++ viewvc-1.0.5/lib/vclib/__init__.py 2008-05-21 21:18:58.000000000 +0200
@@ -133,8 +133,11 @@
These object are sort by their line_number components.
"""
-
+ def itemprops(self, path_paths, rev):
+ """Return an ItemProperties object associated with a versioned item."""
+
+
# ======================================================================
class DirEntry:
"Instances represent items in a directory listing"
@@ -168,6 +171,20 @@
def __cmp__(self, other):
return cmp(self.number, other.number)
+class ItemProperties:
+ """Instances hold information about properties of versioned resources"""
+
+ """Creata a new ItemProperties() item:
+ IS_BINARY: Boolean, whether or not the item is binary (non-text)
+ MODE: chmod()-style file mode
+ PROPS: Dictionary mapping VC-system-specific property names to
+ their values.
+ """
+ def __init__(self, is_binary, mode, props):
+ self.is_binary = is_binary
+ self.mode = mode
+ self.props = props
+
# ======================================================================
class Error(Exception):
Index: viewvc-1.0.5/lib/vclib/bincvs/__init__.py
===================================================================
--- viewvc-1.0.5.orig/lib/vclib/bincvs/__init__.py 2008-05-21
20:24:33.000000000 +0200
+++ viewvc-1.0.5/lib/vclib/bincvs/__init__.py 2008-05-21 21:18:58.000000000
+0200
@@ -283,6 +283,13 @@
if not line or line[0:5] == 'diff ':
break
return fp
+
+ def itemprops(self, path_parts, rev):
+ rcsfile = self.rcsfile(path_parts, 1)
+ mode = os.stat(rcsfile)[stat.ST_MODE]
+ ### TODO: Use keywords to determine binariness.
+ ### TODO: Return a real set of properties (-kflags, e.g.)
+ return vclib.ItemProperties(0, mode, {})
class CVSDirEntry(vclib.DirEntry):
Index: viewvc-1.0.5/lib/vclib/ccvs/__init__.py
===================================================================
--- viewvc-1.0.5.orig/lib/vclib/ccvs/__init__.py 2008-05-21
20:24:33.000000000 +0200
+++ viewvc-1.0.5/lib/vclib/ccvs/__init__.py 2008-05-21 21:18:58.000000000
+0200
@@ -15,6 +15,7 @@
"""
import os
+import stat
import string
import re
import cStringIO
@@ -128,6 +129,15 @@
revision = sink.last and sink.last.string
return cStringIO.StringIO(string.join(sink.sstext.text, "\n")), revision
+ def itemprops(self, path_parts, rev):
+ ### FIXME: Figure out why this has to be duplicated here instead
+ ### of just using the CVSRepository implementation.
+ rcsfile = self.rcsfile(path_parts, 1)
+ mode = os.stat(rcsfile)[stat.ST_MODE]
+ ### TODO: Use keywords to determine binariness.
+ ### TODO: Return a real set of properties (-kflags, e.g.)
+ return vclib.ItemProperties(0, mode, {})
+
class MatchingSink(rcsparse.Sink):
"""Superclass for sinks that search for revisions based on tag or number"""
Index: viewvc-1.0.5/lib/vclib/svn/__init__.py
===================================================================
--- viewvc-1.0.5.orig/lib/vclib/svn/__init__.py 2008-05-21 20:24:33.000000000
+0200
+++ viewvc-1.0.5/lib/vclib/svn/__init__.py 2008-05-21 21:18:58.000000000
+0200
@@ -408,6 +408,19 @@
def get_youngest_revision(svnrepos):
return svnrepos.youngest
+
+def _make_item_properties(item_props):
+ propnames = item_props.keys()
+ mode = core.SVN_PROP_EXECUTABLE in propnames and 0755 or 0644 # Uh-huh.
+ is_binary = core.SVN_PROP_MIME_TYPE in propnames \
+ and core.svn_mime_type_is_binary(
+ item_props[core.SVN_PROP_MIME_TYPE])
+ props = {}
+ for name in propnames: # God save the pool.
+ props[name] = item_props[name]
+ return vclib.ItemProperties(is_binary, mode, props)
+
+
def temp_checkout(svnrepos, path, rev, pool):
"""Check out file revision to temporary file"""
temp = tempfile.mktemp()
@@ -726,6 +739,15 @@
raise vclib.InvalidRevision
raise
+ def itemprops(self, path_parts, rev):
+ path = self._getpath(path_parts)
+ rev = self._getrev(rev)
+ fsroot = self._getroot(rev)
+ props = _make_item_properties(fs.node_proplist(fsroot, path,
+ self.scratch_pool))
+ self._scratch_clear()
+ return props
+
def _getpath(self, path_parts):
return string.join(path_parts, '/')
Index: viewvc-1.0.5/lib/vclib/svn_ra/__init__.py
===================================================================
--- viewvc-1.0.5.orig/lib/vclib/svn_ra/__init__.py 2008-05-21
20:24:33.000000000 +0200
+++ viewvc-1.0.5/lib/vclib/svn_ra/__init__.py 2008-05-21 21:18:58.000000000
+0200
@@ -20,7 +20,8 @@
import tempfile
import popen2
import time
-from vclib.svn import Revision, ChangedPath, _datestr_to_date, _compare_paths,
_cleanup_path
+from vclib.svn import Revision, ChangedPath, _datestr_to_date
+from vclib.svn import _compare_paths, _cleanup_path, _make_item_properties
from svn import core, delta, client, wc, ra
@@ -415,6 +416,15 @@
raise vclib.InvalidRevision
raise
+ def itemprops(self, path_parts, rev):
+ path = self._getpath(path_parts)
+ rev = self._getrev(rev)
+ stream, rev, props = ra.get_file(self.ra_session, path, rev,
+ self.scratch_pool)
+ props = _make_item_properties(props)
+ self._scratch_clear()
+ return props
+
def _getpath(self, path_parts):
return string.join(path_parts, '/')
Index: viewvc-1.0.5/lib/viewvc.py
===================================================================
--- viewvc-1.0.5.orig/lib/viewvc.py 2008-05-21 20:24:40.000000000 +0200
+++ viewvc-1.0.5/lib/viewvc.py 2008-05-21 21:18:58.000000000 +0200
@@ -2947,12 +2947,9 @@
generate_tarball_header(out, dir, mtime=dir_mtime)
del stack[:]
- if cvs:
- info = os.stat(file.path)
- mode = (info[stat.ST_MODE] & 0555) | 0200
- else:
- mode = 0644
-
+ mode = (request.repos.itemprops(rep_path + [file.name],
+ request.pathrev).mode & 0555) | 0200
+
### FIXME: Read the whole file into memory? Bad... better to do
### 2 passes.
fp = request.repos.openfile(rep_path + [file.name], request.pathrev)[0]
--- End Message ---