Author: brane
Date: Sun Nov 25 22:27:07 2018
New Revision: 1847441

URL: http://svn.apache.org/viewvc?rev=1847441&view=rev
Log:
Show in-repository sizes of files with 'svn info'.

The file size is only displayed if the target of 'svn info' is a file URL.

With --show-item=repo-size, an error is returned if the target is a single
local path. However, if there are multiple local targets (e.g., in recursive
mode), nothing at all will be printed, since there are no valid results.

* subversion/libsvn_client/info.c
  (DIRENT_FIELDS): Add SVN_DIRENT_SIZE to the mask, otherwise recursive
   queries do not return file sizes, which is inconsistent with the
   non-recursive or single-target case.

* subversion/svn/info-cmd.c
  (info_item_t): Add new enumeration, info_item_repos_size.
  (info_item_map): Map "repos-size" to info_item_repos_size.
  (print_info_xml): If the file size is available, add a "size"
   attribute to the <entry/> node.
  (print_info): Print the file size if it's available.
  (print_info_item): Handle info_item_repos_size.

* subversion/svn/svn.c (svn_cl__options): Describe --show-item=repos-size.

* subversion/tests/cmdline/info_tests.py
  (info_item_size_wc_recursive,
   info_item_size_repos,
   info_item_size_repos_recursive) New test cases.
  (info_item_failures): Test the size-of-WC-target failure mode.

Modified:
    subversion/trunk/subversion/libsvn_client/info.c
    subversion/trunk/subversion/svn/info-cmd.c
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/tests/cmdline/info_tests.py

Modified: subversion/trunk/subversion/libsvn_client/info.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/info.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/info.c (original)
+++ subversion/trunk/subversion/libsvn_client/info.c Sun Nov 25 22:27:07 2018
@@ -167,7 +167,8 @@ build_info_from_dirent(svn_client_info2_
 #define DIRENT_FIELDS (SVN_DIRENT_KIND        | \
                        SVN_DIRENT_CREATED_REV | \
                        SVN_DIRENT_TIME        | \
-                       SVN_DIRENT_LAST_AUTHOR)
+                       SVN_DIRENT_LAST_AUTHOR | \
+                       SVN_DIRENT_SIZE)
 
 
 /* Helper func for recursively fetching svn_dirent_t's from a remote

Modified: subversion/trunk/subversion/svn/info-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/info-cmd.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/info-cmd.c (original)
+++ subversion/trunk/subversion/svn/info-cmd.c Sun Nov 25 22:27:07 2018
@@ -352,6 +352,7 @@ typedef enum
   info_item_relative_url,
   info_item_repos_root_url,
   info_item_repos_uuid,
+  info_item_repos_size,
 
   /* Working copy revision or repository HEAD revision */
   info_item_revision,
@@ -382,6 +383,7 @@ static const info_item_map_t info_item_m
     { MAKE_STRING("relative-url"),        info_item_relative_url },
     { MAKE_STRING("repos-root-url"),      info_item_repos_root_url },
     { MAKE_STRING("repos-uuid"),          info_item_repos_uuid },
+    { MAKE_STRING("repos-size"),          info_item_repos_size },
     { MAKE_STRING("revision"),            info_item_revision },
     { MAKE_STRING("last-changed-revision"),
                                           info_item_last_changed_rev },
@@ -507,21 +509,38 @@ print_info_xml(void *baton,
                apr_pool_t *pool)
 {
   svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool);
-  const char *rev_str;
   print_info_baton_t *const receiver_baton = baton;
 
-  if (SVN_IS_VALID_REVNUM(info->rev))
-    rev_str = apr_psprintf(pool, "%ld", info->rev);
-  else
-    rev_str = apr_pstrdup(pool, _("Resource is not under version control."));
+  const char *const path_str =
+    svn_cl__local_style_skip_ancestor(
+        receiver_baton->path_prefix, target, pool);
+  const char *const kind_str = svn_cl__node_kind_str_xml(info->kind);
+  const char *const rev_str =
+    (SVN_IS_VALID_REVNUM(info->rev)
+     ? apr_psprintf(pool, "%ld", info->rev)
+     : apr_pstrdup(pool, _("Resource is not under version control.")));
 
   /* "<entry ...>" */
-  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
-                        "path", svn_cl__local_style_skip_ancestor(
-                                  receiver_baton->path_prefix, target, pool),
-                        "kind", svn_cl__node_kind_str_xml(info->kind),
-                        "revision", rev_str,
-                        SVN_VA_NULL);
+  if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
+    {
+      const char *const size_str =
+        apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size);
+
+      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
+                            "path", path_str,
+                            "kind", kind_str,
+                            "revision", rev_str,
+                            "size", size_str,
+                            SVN_VA_NULL);
+    }
+  else
+    {
+      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
+                            "path", path_str,
+                            "kind", kind_str,
+                            "revision", rev_str,
+                            SVN_VA_NULL);
+    }
 
   /* "<url> xx </url>" */
   svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL);
@@ -743,6 +762,11 @@ print_info(void *baton,
       break;
     }
 
+  if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
+    SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
+                               apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT,
+                                            info->size)));
+
   if (info->wc_info)
     {
       switch (info->wc_info->schedule)
@@ -1083,11 +1107,12 @@ print_info_item(void *baton,
                   apr_pool_t *pool)
 {
   print_info_baton_t *const receiver_baton = baton;
+  const char *const actual_target_path =
+    (!receiver_baton->target_is_path ? info->URL
+     : svn_cl__local_style_skip_ancestor(
+         receiver_baton->path_prefix, target, pool));
   const char *const target_path =
-    (!receiver_baton->multiple_targets ? NULL
-     : (!receiver_baton->target_is_path ? info->URL
-        : svn_cl__local_style_skip_ancestor(
-            receiver_baton->path_prefix, target, pool)));
+    (receiver_baton->multiple_targets ? actual_target_path : NULL);
 
   if (receiver_baton->start_new_line)
     SVN_ERR(svn_cmdline_fputs("\n", stdout, pool));
@@ -1116,6 +1141,32 @@ print_info_item(void *baton,
       SVN_ERR(print_info_item_string(info->repos_UUID, target_path, pool));
       break;
 
+    case info_item_repos_size:
+      if (info->kind != svn_node_file)
+        {
+          receiver_baton->start_new_line = FALSE;
+          return SVN_NO_ERROR;
+        }
+
+      if (info->size == SVN_INVALID_FILESIZE)
+        {
+          if (receiver_baton->multiple_targets)
+            {
+              receiver_baton->start_new_line = FALSE;
+              return SVN_NO_ERROR;
+            }
+
+          return svn_error_createf(
+              SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+              _("can't show in-repository size of working copy file '%s'"),
+              actual_target_path);
+        }
+
+      SVN_ERR(print_info_item_string(
+                  apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size),
+                  target_path, pool));
+      break;
+
     case info_item_revision:
       SVN_ERR(print_info_item_revision(info->rev, target_path, pool));
       break;

Modified: subversion/trunk/subversion/svn/svn.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Sun Nov 25 22:27:07 2018
@@ -444,6 +444,10 @@ const apr_getopt_option_t svn_cl__option
                           "                             "
                           "   'repos-uuid' UUID of repository\n"
                           "                             "
+                          "   'repos-size' for files, the size of TARGET\n"
+                          "                             "
+                          "                in the repository\n"
+                          "                             "
                           "   'revision'   specified or implied revision\n"
                           "                             "
                           "   'last-changed-revision'\n"

Modified: subversion/trunk/subversion/tests/cmdline/info_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/info_tests.py?rev=1847441&r1=1847440&r2=1847441&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/info_tests.py Sun Nov 25 22:27:07 
2018
@@ -716,6 +716,59 @@ def info_item_uncommmitted(sbox):
     sbox.ospath('newfile'), sbox.ospath('newdir'))
 
 
+def info_item_size_wc_recursive(sbox):
+  "recursive '--show-item=repos-size' on local path"
+
+  sbox.build(read_only=True)
+
+  svntest.actions.run_and_verify_svn(
+    [], [],
+    'info', '--show-item=repos-size', '--recursive',
+    sbox.ospath(''))
+
+
+def info_item_size_repos(sbox):
+  "non-recursive '--show-item=repos-size' on file URL"
+
+  sbox.build(read_only=True)
+
+  svntest.actions.run_and_verify_svn(
+    "25\n", [],
+    'info', '--show-item=repos-size',
+    sbox.repo_url + "/iota")
+
+  svntest.actions.run_and_verify_svn(
+    "25", [],
+    'info', '--show-item=repos-size', '--no-newline',
+    sbox.repo_url + "/iota")
+
+
+def info_item_size_repos_recursive(sbox):
+  "recursive '--show-item=repos-size' on dir URL"
+
+  sbox.build(read_only=True)
+
+  expected_output = svntest.verify.UnorderedOutput([
+    "25         " + sbox.repo_url + "/iota\n",
+    "27         " + sbox.repo_url + "/A/B/lambda\n",
+    "25         " + sbox.repo_url + "/A/B/E/beta\n",
+    "26         " + sbox.repo_url + "/A/B/E/alpha\n",
+    "23         " + sbox.repo_url + "/A/mu\n",
+    "26         " + sbox.repo_url + "/A/D/gamma\n",
+    "23         " + sbox.repo_url + "/A/D/G/pi\n",
+    "24         " + sbox.repo_url + "/A/D/G/rho\n",
+    "24         " + sbox.repo_url + "/A/D/G/tau\n",
+    "26         " + sbox.repo_url + "/A/D/H/omega\n",
+    "24         " + sbox.repo_url + "/A/D/H/psi\n",
+    "24         " + sbox.repo_url + "/A/D/H/chi\n",
+  ])
+
+  svntest.actions.run_and_verify_svn(
+    expected_output, [],
+    'info', '--show-item=repos-size', '--recursive',
+    sbox.repo_url)
+
+
 def info_item_failures(sbox):
   "failure modes of 'svn info --show-item'"
 
@@ -746,6 +799,11 @@ def info_item_failures(sbox):
     'info', '--show-item=revision', '--no-newline',
     sbox.ospath('A'), sbox.ospath('iota'))
 
+  svntest.actions.run_and_verify_svn(
+    None, (r".*E200007: can't show in-repository size.*"),
+    'info', '--show-item=repos-size',
+    sbox.ospath('iota'))
+
 
 ########################################################################
 # Run the tests
@@ -767,6 +825,9 @@ test_list = [ None,
               info_item_simple_multiple,
               info_item_url,
               info_item_uncommmitted,
+              info_item_size_wc_recursive,
+              info_item_size_repos,
+              info_item_size_repos_recursive,
               info_item_failures,
              ]
 


Reply via email to