hooks.c
From: Kevin Pilch-Bisson <kevin_at_pilch-bisson.net>
Date: 2001-09-21 21:57:05 CEST
I think there is something wrong with my wc. I'm about to re-checkout, but
I just tried to commit hooks.c, but in case it didn't work, here it is to
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Kevin Pilch-Bisson http://www.pilch-bisson.net "Historically speaking, the presences of wheels in Unix has never precluded their reinvention." - Larry Wall ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* hooks.c : running repository hooks and sentinels * * ==================================================================== * Copyright (c) 2000-2001 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */ #include <stdio.h> #include <string.h> #include <ctype.h> #include "apr_pools.h" #include "apr_file_io.h" #include "svn_pools.h" #include "svn_error.h" #include "svn_path.h" #include "svn_delta.h" #include "svn_fs.h" #include "svn_repos.h" /* In the code below, "hook" is sometimes used indiscriminately to mean either hook or sentinel. */ /*** Hook drivers. ***/ static svn_error_t * run_cmd_with_output (const char *cmd, const char **args, apr_wait_t *status, apr_pool_t *pool) { apr_file_t *outhandle, *errhandle; apr_status_t apr_err; /* Get an apr_file_t representing stdout and stderr. */ apr_err = apr_file_open_stdout (&outhandle, pool); if (apr_err) return svn_error_create (apr_err, 0, NULL, pool, "run_cmd_with_output: can't open handle to stdout"); apr_err = apr_file_open_stderr (&errhandle, pool); if (apr_err) return svn_error_create (apr_err, 0, NULL, pool, "run_cmd_with_output: can't open handle to stderr"); return svn_io_run_cmd (".", cmd, args, status, NULL, outhandle, errhandle, pool); } /* Run the start-commit hook for FS. Use POOL for any temporary allocations. If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE. */ static svn_error_t * run_start_commit_hook (svn_fs_t *fs, const char *user, apr_pool_t *pool) { enum svn_node_kind kind; const char *hook = svn_fs_start_commit_hook (fs, pool); if ((! svn_io_check_path (svn_stringbuf_create (hook, pool), &kind, pool)) && (kind == svn_node_file)) { apr_wait_t status; svn_error_t *err; const char *args[4]; args[0] = hook; args[1] = svn_fs_repository (fs, pool); args[2] = user; args[3] = NULL; if ((err = run_cmd_with_output (hook, args, &status, pool))) { return svn_error_createf (SVN_ERR_REPOS_HOOK_FAILURE, 0, err, pool, "run_start_commit_hook: error running cmd `%s'", hook); } } return SVN_NO_ERROR; } /* Run the pre-commit hook for FS. Use POOL for any temporary allocations. If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE. */ static svn_error_t * run_pre_commit_hook (svn_fs_t *fs, const char *txn_name, apr_pool_t *pool) { enum svn_node_kind kind; const char *hook = svn_fs_pre_commit_hook (fs, pool); if ((! svn_io_check_path (svn_stringbuf_create (hook, pool), &kind, pool)) && (kind == svn_node_file)) { svn_error_t *err; apr_wait_t status; const char *args[4]; args[0] = hook; args[1] = svn_fs_repository (fs, pool); args[2] = txn_name; args[3] = NULL; if ((err = run_cmd_with_output (hook, args, &status, pool))) { return svn_error_createf (SVN_ERR_REPOS_HOOK_FAILURE, 0, err, pool, "run_pre_commit_hook: error running cmd `%s'", hook); } if (status != 0) { return svn_error_create (SVN_ERR_REPOS_HOOK_FAILURE, 0, err, pool, "pre-commit hook return non-zero status. Aborting txn."); } } return SVN_NO_ERROR; } /* Run the post-commit hook for FS. Use POOL for any temporary allocations. If the hook fails, run SVN_ERR_REPOS_HOOK_FAILURE. */ static svn_error_t * run_post_commit_hook (svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool) { enum svn_node_kind kind; const char *hook = svn_fs_post_commit_hook (fs, pool); if ((! svn_io_check_path (svn_stringbuf_create (hook, pool), &kind, pool)) && (kind == svn_node_file)) { svn_error_t *err; apr_wait_t status; const char *args[4]; args[0] = hook; args[1] = svn_fs_repository (fs, pool); args[2] = apr_psprintf (pool, "%lu", rev); args[3] = NULL; if ((err = run_cmd_with_output (hook, args, &status, pool))) { return svn_error_createf (SVN_ERR_REPOS_HOOK_FAILURE, 0, err, pool, "run_post_commit_hook: error running cmd `%s'", hook); } } return SVN_NO_ERROR; } /*** Public interface. ***/ svn_error_t * svn_repos_fs_commit_txn (const char **conflict_p, svn_revnum_t *new_rev, svn_fs_txn_t *txn) { svn_fs_t *fs = svn_fs_txn_fs (txn); apr_pool_t *pool = svn_fs_txn_pool (txn); /* Run pre-commit hooks. */ { const char *txn_name; SVN_ERR (svn_fs_txn_name (&txn_name, txn, pool)); SVN_ERR (run_pre_commit_hook (fs, txn_name, pool)); } /* Commit. */ SVN_ERR (svn_fs_commit_txn (conflict_p, new_rev, txn)); /* Run post-commit hooks. */ SVN_ERR (run_post_commit_hook (fs, *new_rev, pool)); return SVN_NO_ERROR; } svn_error_t * svn_repos_fs_begin_txn_for_commit (svn_fs_txn_t **txn_p, svn_fs_t *fs, svn_revnum_t rev, const char *author, svn_string_t *log_msg, apr_pool_t *pool) { /* Run start-commit hooks. */ SVN_ERR (run_start_commit_hook (fs, author, pool)); /* Begin the transaction. */ SVN_ERR (svn_fs_begin_txn (txn_p, fs, rev, pool)); /* We pass the author and log message to the filesystem by adding them as properties on the txn. Later, when we commit the txn, these properties will be copied into the newly created revision. */ { svn_string_t log_prop_name = { SVN_PROP_REVISION_LOG, sizeof(SVN_PROP_REVISION_LOG) - 1}; svn_string_t author_prop_name = { SVN_PROP_REVISION_AUTHOR, sizeof(SVN_PROP_REVISION_AUTHOR) - 1}; /* User (author). */ { svn_string_t val; val.data = author; val.len = strlen (author); SVN_ERR (svn_fs_change_txn_prop (*txn_p, &author_prop_name, &val, pool)); } /* Log message. */ if (log_msg != NULL) SVN_ERR (svn_fs_change_txn_prop (*txn_p, &log_prop_name, log_msg, pool)); } return SVN_NO_ERROR; } svn_error_t * svn_repos_fs_begin_txn_for_update (svn_fs_txn_t **txn_p, svn_fs_t *fs, svn_revnum_t rev, const char *author, apr_pool_t *pool) { /* ### someday, we might run a read-hook here. */ /* Begin the transaction. */ SVN_ERR (svn_fs_begin_txn (txn_p, fs, rev, pool)); /* We pass the author to the filesystem by adding it as a property on the txn. */ { svn_string_t author_prop_name = { SVN_PROP_REVISION_AUTHOR, sizeof(SVN_PROP_REVISION_AUTHOR) - 1}; /* User (author). */ { svn_string_t val; val.data = author; val.len = strlen (author); SVN_ERR (svn_fs_change_txn_prop (*txn_p, &author_prop_name, &val, pool)); } } return SVN_NO_ERROR; } /* * local variables: * eval: (load-file "../svn-dev.el") * end: * vim:ts=4:sw=4:expandtab:tw=80:fo=tcroq * vim:isk=a-z,A-Z,48-57,_,.,-,> * vim:cino=>1s,e0,n0,f0,{.5s,}0,^-.5s,=.5s,t0,+1s,c3,(0,u0,\:0 */
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.