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