Skip to content

Show Subversion versioned symlinks with hyperlinks to intra-repos targets [Tigris #406] #85

@cmpilato

Description

@cmpilato

Description

If a symlink is versioned, and the target of the symlink is in the same
repository (and expressed as a relative path), ViewVC could display a link to
that target for the users' benefit.

Metadata Imported from Tigris (Issue 406)

  • Creation Date: 2009-04-14 07:23:28
  • Reporter: cmpilato
  • Subcomponent: vclib - Subversion (local)
  • Version: 1.1.0-beta1
  • Milestone: 1.2.0-consid
  • Keywords:
  • Cc:

Comments

2009-05-05 08:02:07 by cmpilato

This is a reasonable request.

2013-03-05 08:35:34 by cmpilato

Created an attachment (id=279)
Incomplete patch for this issue.

2014-06-08 22:57:58 by enderin

Paul Wise has reported this in Debian too: http://bugs.debian.org/689384.

Attachments

viewvc-symlinks.patch.txt - Incomplete patch for this issue.

Posted 2013-03-05 08:35:34 by cmpilato

     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                                                           *
     *   THIS PATCH IS INCOMPLETE AND NOT READY FOR COMMIT!!     *
     *                                                           *
     *   While it sorta kinda does what I want, there are        *
     *   other areas of symlink handling which are not done.     *
     *   For example, ViewVC will try to show a symlink named    *
     *   link-to-photo.jpg in the checkout view, confusing       *
     *   the web browser (which expect a JPEG but finds a        *
     *   text file.  Symlink handling probably really needs      *
     *   more first-class treatment in the vclib layer itself.   *
     *                                                           *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

For issue #406 ("Show Subversion versioned symlinks with hyperlinks to
intra-repos targets"), report symlink targets in the markup view.

* lib/viewvc.py
  (_normalize_repos_path, get_symlink_target_and_links): New helper
    functions.
  (markup_or_annotate): Query for symlink-ness, offering any symlink
    target path and an intra-repos link (if possible) to the
    templates.

* templates/default/file.ezt
  Report any symlink target, possibly linkified.




Index: lib/viewvc.py
===================================================================
--- lib/viewvc.py   (revision 2859)
+++ lib/viewvc.py   (working copy)
@@ -598,6 +598,28 @@

   return path

+def _normalize_repos_path(basedir, path):
+  """Reduce an intra-repository path specification PATH -- which is
+  either absolute or relative to BASEDIR -- to its simplest form,
+  eliminating empty, '.', and '..' path components, and returning the
+  result.  Raise vclib.ItemNotFound if the normalized path peeks above
+  the root or is absolute."""
+
+  if os.path.isabs(path):
+    raise vclib.ItemNotFound(path)
+  
+  path_parts = _path_parts(basedir)
+  for part in _path_parts(path):
+    if part == "..":
+      if not path_parts:
+        # nothing left to pop; this pathspec peeks above the root.
+        raise vclib.ItemNotFound(path)
+      path_parts.pop()
+    elif part and part != ".":
+      path_parts.append(part)
+
+  return _path_join(path_parts)
+
 def _validate_param(name, value):
   """Validate whether the given value is acceptable for the param name.

@@ -1600,6 +1622,36 @@
                                          escape=1)
   return data

+def get_symlink_target_and_links(request, path_parts, rev):
+  # If the vclib implementation can't answer our query, there's nothing to do.
+  if not hasattr(request.repos, 'get_symlink_target'):
+    return None, None
+
+  # If there's no symlink here, there's nothing more to do.
+  target = request.repos.get_symlink_target(path_parts, rev)
+  if not target:
+    return None, None
+
+  # Try to normalize the symlink target into a valid path within the
+  # same repository.  If we can't, we just return the original target
+  # path.  Otherwise, we'll be trying to devise a link URL, too.
+  try:
+    norm_target = _normalize_repos_path(_path_join(request.path_parts[:-1]),
+                                        target)
+    target_type = request.repos.itemtype(_path_parts(norm_target), rev)
+    if target_type == vclib.DIR:
+      target_view = view_directory
+    else:
+      target_view = view_markup
+    return target, request.get_url(view_func=target_view,
+                                   where=norm_target,
+                                   pathtype=target_type,
+                                   params={'pathrev': rev},
+                                   escape=1)
+  except:
+    raise
+    return target, None
+
 def retry_read(src, reqlen=CHUNK_SIZE):
   while 1:
     chunk = src.read(CHUNK_SIZE)
@@ -1853,7 +1905,8 @@
   annotation = 'none'
   revision = None
   mime_type, encoding = calculate_mime_type(request, path, rev)
-
+  target, target_href = get_symlink_target_and_links(request, path, rev)
+  
   # Is this display blocked by 'binary_mime_types' configuration?
   if is_binary_file_mime_type(mime_type, cfg):
     raise debug.ViewVCException('Display of binary file content disabled '
@@ -1951,6 +2004,8 @@
     'lines' : lines,
     'properties' : get_itemprops(request, path, rev),
     'annotation' : annotation,
+    'symlink_target' : target,
+    'symlink_target_href' : target_href,
     }))

   if cfg.options.show_log_in_markup:
Index: templates/default/file.ezt
===================================================================
--- templates/default/file.ezt  (revision 2859)
+++ templates/default/file.ezt  (working copy)
@@ -18,6 +18,10 @@
 [# end]
 [include "include/header.ezt" "annotate"]

+[if-any symlink_target]
+This file is a symbolic link to <span class="vc_symlink_target">[if-any symlink_target_href]<a href="[symlink_target_href]">[end][symlink_target][if-any symlink_target_href]</a>[end]</span>.
+[end]
+
 <table class="auto">
 <tr>
 <td>Revision:</td>

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementFeature requests or other non-defect improvements in functionalitylegacyIssues imported from prior issue trackers

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions