[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Issue 3942 - Provide new subcommand on svnadmin to create a lock

From: Noorul Islam K M <noorul_at_collab.net>
Date: Fri, 15 Jul 2011 18:28:17 +0530

Noorul Islam K M <noorul_at_collab.net> writes:

> From: http://subversion.tigris.org/issues/show_bug.cgi?id=3942
> =======================================================================
> The svnadmin command currently allows you to list and remove locks. It
> would be useful if you could also create locks. Suggested syntax would
> be something like:
>
> svnadmin lock REPOS PATH USERNAME COMMENT-FILE TOKEN
>
> Where COMMENT-FILE is handled similar to svnadmin setrevprop TOKEN would
> be optional. If not provided a lock token would be generated.
>
> The reason I would like this subcommand is that it would make it
> possible to build a system for synchronizing locks between a master and
> slave. A post-lock hook on master could send this info to slaves and
> they could use it to create the lock on the slaves (with the same lock
> token). It seems like it would be possible for someone to use this
> command to store lock information along with a dumpfile and recreate
> them after restoring repository from a dump. That is not my goal, but I
> think it is another possible usage.
>
> Buddied by: cmpilato
> ========================================================================
>
> I would like to work on this enhancement. If someone else is already
> working on this please let me know.
>

As first step I implemented the following syntax.

svnadmin lock REPOS PATH USERNAME COMMENT-FILE

I will add the optional TOKEN argument later. I hope I am progressing in
the right direction.

Log
[[[

Fix issue #3942. Add new sub command 'lock' for 'svnadmin'. The
following syntax is implemented in this patch.

svnadmin lock REPOS PATH USERNAME COMMENT-FILE

The command locks the PATH by USERNAME setting comment from
COMMENT-FILE.

The optional TOKEN argument mentioned in issue tracker will be
implemented in another patch.

* subversion/svnadmin/main.c
  (svn_opt_subcommand_t): New sub command.
  (svn_opt_subcommand_desc2_t): Add description.
  (subcommand_lock): Implement it.

* subversion/tests/cmdline/svnadmin_tests.py
  (lock): New test for 'lock' sub command.
  (test_list): Add new test.

Patch by: Noorul Islam K M <noorul{_AT_}collab.net>
]]]

Thanks and Regards
Noorul

Index: subversion/tests/cmdline/svnadmin_tests.py
===================================================================
--- subversion/tests/cmdline/svnadmin_tests.py (revision 1146981)
+++ subversion/tests/cmdline/svnadmin_tests.py (working copy)
@@ -1381,6 +1381,51 @@
     'STDERR', expected_stderr, errput):
     raise svntest.Failure
 
+def lock(sbox):
+ "svnadmin lock tests"
+ sbox.build(create_wc=False)
+
+ comment_path = os.path.join(svntest.main.temp_dir, "comment")
+ svntest.main.file_write(comment_path, "dummy comment")
+
+ invalid_comment_path = os.path.join(svntest.main.temp_dir, "invalid_comment")
+ svntest.main.file_write(invalid_comment_path, "character is invalid")
+
+ # Test illegal character in comment file.
+ expected_error = "svnadmin: E130004: Lock comment contains " + \
+ "illegal characters"
+ svntest.actions.run_and_verify_svnadmin(None, None,
+ expected_error, "lock",
+ sbox.repo_dir,
+ "iota", "jrandom",
+ invalid_comment_path)
+
+ # Test locking path.
+ expected_output = "iota locked by user 'jrandom'."
+ svntest.actions.run_and_verify_svnadmin(None, expected_output,
+ None, "lock",
+ sbox.repo_dir,
+ "iota", "jrandom",
+ comment_path)
+
+ # Test locking already locked path.
+ expected_error = "svnadmin: E160035: Path '/iota' is already " + \
+ "locked by user 'jrandom' in filesystem"
+ svntest.actions.run_and_verify_svnadmin(None, None,
+ expected_error, "lock",
+ sbox.repo_dir,
+ "iota", "jrandom",
+ comment_path)
+
+ # Test locking non-existent path.
+ expected_error = "svnadmin: E160042: Path '/non-existent' " + \
+ "doesn't exist in HEAD revision"
+ svntest.actions.run_and_verify_svnadmin(None, None,
+ expected_error, "lock",
+ sbox.repo_dir,
+ "non-existent", "jrandom",
+ comment_path)
+
 ########################################################################
 # Run the tests
 
@@ -1410,6 +1455,7 @@
               hotcopy_symlink,
               load_bad_props,
               verify_non_utf8_paths,
+ lock,
              ]
 
 if __name__ == '__main__':
Index: subversion/svnadmin/main.c
===================================================================
--- subversion/svnadmin/main.c (revision 1146981)
+++ subversion/svnadmin/main.c (working copy)
@@ -40,6 +40,7 @@
 #include "svn_props.h"
 #include "svn_time.h"
 #include "svn_user.h"
+#include "svn_xml.h"
 
 #include "private/svn_opt_private.h"
 
@@ -152,6 +153,7 @@
   subcommand_load,
   subcommand_list_dblogs,
   subcommand_list_unused_dblogs,
+ subcommand_lock,
   subcommand_lslocks,
   subcommand_lstxns,
   subcommand_pack,
@@ -356,6 +358,11 @@
    {'q', svnadmin__ignore_uuid, svnadmin__force_uuid,
     svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook,
     svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M'} },
+
+ {"lock", subcommand_lock, {0}, N_
+ ("usage: svnadmin lock REPOS_PATH PATH USERNAME COMMENT-FILE\n\n"
+ "Lock PATH by USERNAME setting comments from COMMENT-FILE.\n"),
+ {0} },
 
   {"lslocks", subcommand_lslocks, {0}, N_
    ("usage: svnadmin lslocks REPOS_PATH [PATH-IN-REPOS]\n\n"
@@ -1378,7 +1385,74 @@
                            opt_state->clean_logs, pool);
 }
 
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_lock(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_access_t *access;
+ apr_array_header_t *args;
+ const char *username;
+ const char *lock_path;
+ const char *comment_file_name;
+ char *comment;
+ svn_stringbuf_t *file_contents;
+ const char *lock_path_utf8;
+ svn_lock_t *lock;
+ svn_revnum_t revnum;
+ apr_pool_t *subpool = svn_pool_create(pool);
 
+ /* Expect three more arguments: PATH USERNAME COMMENT-FILE */
+ SVN_ERR(parse_args(&args, os, 3, 3, pool));
+ lock_path = APR_ARRAY_IDX(args, 0, const char *);
+ username = APR_ARRAY_IDX(args, 1, const char *);
+ comment_file_name = APR_ARRAY_IDX(args, 2, const char *);
+ SVN_ERR(target_arg_to_dirent(&comment_file_name, comment_file_name, pool));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Create an access context describing the user. */
+ SVN_ERR(svn_fs_create_access(&access, username, pool));
+
+ /* Attach the access context to the filesystem. */
+ SVN_ERR(svn_fs_set_access(fs, access));
+
+ SVN_ERR(svn_stringbuf_from_file2(&file_contents, comment_file_name, pool));
+ comment = file_contents->data;
+
+ /* Enforce that the comment be xml-escapable. */
+ if (comment)
+ {
+ if (! svn_xml_is_xml_safe(comment, strlen(comment)))
+ return svn_error_create
+ (SVN_ERR_XML_UNESCAPABLE_DATA, NULL,
+ _("Lock comment contains illegal characters"));
+ }
+
+ SVN_ERR(svn_fs_youngest_rev(&revnum, fs, subpool));
+
+ SVN_ERR(svn_utf_cstring_to_utf8(&lock_path_utf8, lock_path, subpool));
+
+ SVN_ERR(svn_repos_fs_lock(&lock, repos, lock_path_utf8,
+ NULL, /* token */
+ comment,
+ 0, /* is_dav_comment */
+ 0, /* No expiration time. */
+ revnum,
+ FALSE, subpool));
+
+ SVN_ERR(svn_cmdline_printf(subpool,
+ _("%s locked by user '%s'.\n"),
+ lock_path, username));
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 subcommand_lslocks(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
Received on 2011-07-15 15:00:33 CEST

This is an archived mail posted to the Subversion Dev mailing list.