|
svn commit: r13123 - in trunk/subversion: clients/cmdline include libsvn_cl: msg#00292version-control.subversion.svn
Author: sussman Date: Tue Feb 22 17:21:31 2005 New Revision: 13123 Added: trunk/subversion/libsvn_client/info.c (contents, props changed) Modified: trunk/subversion/clients/cmdline/info-cmd.c trunk/subversion/include/svn_client.h Log: Reorganize 'svn info' codepath, in preparation to make it work on URLs. This change is all about pushing code from info-cmd.c down into libsvn_client. After this, the plan is to: - make the feature work on URLs, - port the change to the locking branch and add lock info to output. * subversion/include/svn_client.h (svn_client_info): new public API declaration. (svn_info_t): new structure type. (svn_info_receiver_t): new callback type. * subversion/libsvn_client/info.c (svn_client_info): new file, new function. (crawl_entries, info_found_entry_callback, build_info_from_entry, build_info_from_dirent): new funcs, some logic stolen from info-cmd.c. * subversion/clients/cmdline/info-cmd.c (svn_cl__info): rewrite to use new svn_client_info() API. (info_found_entry_callback, entry_walk_callbacks): delete. (print_info): renamed from print_entry(), rewritten. (info_receiver): new callback. Modified: trunk/subversion/clients/cmdline/info-cmd.c Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/clients/cmdline/info-cmd.c?view=diff&rev=13123&p1=trunk/subversion/clients/cmdline/info-cmd.c&r1=13122&p2=trunk/subversion/clients/cmdline/info-cmd.c&r2=13123 ============================================================================== --- trunk/subversion/clients/cmdline/info-cmd.c (original) +++ trunk/subversion/clients/cmdline/info-cmd.c Tue Feb 22 17:21:31 2005 @@ -49,51 +49,40 @@ static svn_error_t * -print_entry (const char *target, - const svn_wc_entry_t *entry, - apr_pool_t *pool) +print_info (const char *target, + const svn_info_t *info, + apr_pool_t *pool) { - svn_boolean_t text_conflict = FALSE, props_conflict = FALSE; - SVN_ERR (svn_cmdline_printf (pool, _("Path: %s\n"), svn_path_local_style (target, pool))); - /* Note: we have to be paranoid about checking that these are - valid, since svn_wc_entry() doesn't fill them in if they - aren't in the entries file. */ - - if (entry->name && strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR)) - SVN_ERR (svn_cmdline_printf (pool, _("Name: %s\n"), entry->name)); + /* ### remove this someday: it's only here for cmdline output + compatibility with svn 1.1 and older. */ + SVN_ERR (svn_cmdline_printf (pool, _("Name: %s\n"), + svn_path_basename(target, pool))); - if (entry->url) - SVN_ERR (svn_cmdline_printf (pool, _("URL: %s\n"), entry->url)); + if (info->URL) + SVN_ERR (svn_cmdline_printf (pool, _("URL: %s\n"), info->URL)); - if (entry->repos) - SVN_ERR (svn_cmdline_printf (pool, _("Repository: %s\n"), entry->repos)); + if (info->repos_root_URL) + SVN_ERR (svn_cmdline_printf (pool, _("Repository: %s\n"), + info->repos_root_URL)); - if (entry->uuid) + if (info->repos_UUID) SVN_ERR (svn_cmdline_printf (pool, _("Repository UUID: %s\n"), - entry->uuid)); + info->repos_UUID)); - if (SVN_IS_VALID_REVNUM (entry->revision)) - SVN_ERR (svn_cmdline_printf (pool, _("Revision: %ld\n"), entry->revision)); + if (SVN_IS_VALID_REVNUM (info->rev)) + SVN_ERR (svn_cmdline_printf (pool, _("Revision: %ld\n"), info->rev)); - switch (entry->kind) + switch (info->kind) { case svn_node_file: SVN_ERR (svn_cmdline_printf (pool, _("Node Kind: file\n"))); - { - const char *dir_name; - svn_path_split (target, &dir_name, NULL, pool); - SVN_ERR (svn_wc_conflicted_p (&text_conflict, &props_conflict, - dir_name, entry, pool)); - } break; case svn_node_dir: SVN_ERR (svn_cmdline_printf (pool, _("Node Kind: directory\n"))); - SVN_ERR (svn_wc_conflicted_p (&text_conflict, &props_conflict, - target, entry, pool)); break; case svn_node_none: @@ -106,7 +95,7 @@ break; } - switch (entry->schedule) + switch (info->schedule) { case svn_wc_schedule_normal: SVN_ERR (svn_cmdline_printf (pool, _("Schedule: normal\n"))); @@ -128,59 +117,56 @@ break; } - if (entry->copied) - { - if (entry->copyfrom_url) - SVN_ERR (svn_cmdline_printf (pool, _("Copied From URL: %s\n"), - entry->copyfrom_url)); - - if (SVN_IS_VALID_REVNUM (entry->copyfrom_rev)) - SVN_ERR (svn_cmdline_printf (pool, _("Copied From Rev: %ld\n"), - entry->copyfrom_rev)); - } + if (info->copyfrom_url) + SVN_ERR (svn_cmdline_printf (pool, _("Copied From URL: %s\n"), + info->copyfrom_url)); + + if (SVN_IS_VALID_REVNUM (info->copyfrom_rev)) + SVN_ERR (svn_cmdline_printf (pool, _("Copied From Rev: %ld\n"), + info->copyfrom_rev)); - if (entry->cmt_author) + if (info->last_changed_author) SVN_ERR (svn_cmdline_printf (pool, _("Last Changed Author: %s\n"), - entry->cmt_author)); + info->last_changed_author)); - if (SVN_IS_VALID_REVNUM (entry->cmt_rev)) + if (SVN_IS_VALID_REVNUM (info->last_changed_rev)) SVN_ERR (svn_cmdline_printf (pool, _("Last Changed Rev: %ld\n"), - entry->cmt_rev)); + info->last_changed_rev)); - if (entry->cmt_date) - SVN_ERR (svn_cl__info_print_time (entry->cmt_date, + if (info->last_changed_date) + SVN_ERR (svn_cl__info_print_time (info->last_changed_date, _("Last Changed Date"), pool)); - if (entry->text_time) - SVN_ERR (svn_cl__info_print_time (entry->text_time, + if (info->text_time) + SVN_ERR (svn_cl__info_print_time (info->text_time, _("Text Last Updated"), pool)); - if (entry->prop_time) - SVN_ERR (svn_cl__info_print_time (entry->prop_time, + if (info->prop_time) + SVN_ERR (svn_cl__info_print_time (info->prop_time, _("Properties Last Updated"), pool)); - if (entry->checksum) + if (info->checksum) SVN_ERR (svn_cmdline_printf (pool, _("Checksum: %s\n"), - entry->checksum)); + info->checksum)); - if (text_conflict && entry->conflict_old) + if (info->conflict_old) SVN_ERR (svn_cmdline_printf (pool, _("Conflict Previous Base File: %s\n"), - svn_path_local_style (entry->conflict_old, + svn_path_local_style (info->conflict_old, pool))); - if (text_conflict && entry->conflict_wrk) + if (info->conflict_wrk) SVN_ERR (svn_cmdline_printf (pool, _("Conflict Previous Working File: %s\n"), - svn_path_local_style (entry->conflict_wrk, pool))); + svn_path_local_style (info->conflict_wrk, pool))); - if (text_conflict && entry->conflict_new) + if (info->conflict_new) SVN_ERR (svn_cmdline_printf (pool, _("Conflict Current Base File: %s\n"), - svn_path_local_style (entry->conflict_new, + svn_path_local_style (info->conflict_new, pool))); - if (props_conflict && entry->prejfile) + if (info->prejfile) SVN_ERR (svn_cmdline_printf (pool, _("Conflict Properties File: %s\n"), - svn_path_local_style (entry->prejfile, + svn_path_local_style (info->prejfile, pool))); /* Print extra newline separator. */ @@ -190,30 +176,18 @@ } + +/* A callback of type svn_info_receiver_t. */ static svn_error_t * -info_found_entry_callback (const char *path, - const svn_wc_entry_t *entry, - void *walk_baton, - apr_pool_t *pool) +info_receiver (void *baton, + const char *path, + const svn_info_t *info, + apr_pool_t *pool) { - /* We're going to receive dirents twice; we want to ignore the - first one (where it's a child of a parent dir), and only print - the second one (where we're looking at THIS_DIR.) */ - if ((entry->kind == svn_node_dir) - && (strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR))) - return SVN_NO_ERROR; - - return print_entry (path, entry, pool); + return print_info (path, info, pool); } -static const svn_wc_entry_callbacks_t -entry_walk_callbacks = - { - info_found_entry_callback - }; - - /* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * @@ -226,57 +200,62 @@ apr_array_header_t *targets; apr_pool_t *subpool = svn_pool_create (pool); int i; + svn_error_t *err; + svn_opt_revision_t revision, peg_revision; SVN_ERR (svn_opt_args_to_target_array2 (&targets, os, opt_state->targets, pool)); /* Add "." if user passed 0 arguments. */ svn_opt_push_implicit_dot_target (targets, pool); - + for (i = 0; i < targets->nelts; i++) { const char *target = ((const char **) (targets->elts))[i]; - svn_wc_adm_access_t *adm_access; - const svn_wc_entry_t *entry; - + svn_pool_clear (subpool); + SVN_ERR (svn_cl__check_cancel (ctx->cancel_baton)); - /* Make sure the user hasn't passed a URL by mistake. */ if (svn_path_is_url (target)) - return svn_error_create - (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("'svn info' only works on working copy paths, not URLs")); - - SVN_ERR (svn_cl__check_cancel (ctx->cancel_baton)); - SVN_ERR (svn_wc_adm_probe_open3 (&adm_access, NULL, target, FALSE, - opt_state->recursive ? -1 : 0, - ctx->cancel_func, ctx->cancel_baton, - subpool)); - SVN_ERR (svn_wc_entry (&entry, target, adm_access, FALSE, subpool)); - if (! entry) { - /* Print non-versioned message and extra newline separator. */ + /* ### remove this very, very soon. set the opt_revision + variables by parsing options. */ + return svn_error_create + (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("'svn info' only works on working copy paths, not URLs")); + } + else + { + revision.kind = svn_opt_revision_unspecified; + peg_revision.kind = svn_opt_revision_unspecified; + } + err = svn_client_info (target, + &peg_revision, &revision, + info_receiver, NULL, + opt_state->recursive, ctx, subpool); + + /* If one of the targets is a non-existent URL or wc-entry, + don't bail out. Just warn and move on to the next target. */ + if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) + { + svn_error_clear (err); SVN_ERR (svn_cmdline_printf (subpool, _("%s: (Not a versioned resource)\n\n"), svn_path_local_style (target, pool))); continue; } - - if (entry->kind == svn_node_file) - SVN_ERR (print_entry (target, entry, subpool)); - - else if (entry->kind == svn_node_dir) + else if (err && err->apr_err == SVN_ERR_RA_ILLEGAL_URL) { - if (opt_state->recursive) - /* the generic entry-walker: */ - SVN_ERR (svn_wc_walk_entries2 (target, adm_access, - &entry_walk_callbacks, NULL, - FALSE, ctx->cancel_func, - ctx->cancel_baton, pool)); - else - SVN_ERR (print_entry (target, entry, subpool)); + svn_error_clear (err); + SVN_ERR (svn_cmdline_printf + (subpool, _("%s: (Not a valid URL)\n\n"), + svn_path_local_style (target, pool))); + continue; } + else + return err; + } svn_pool_destroy (subpool); Modified: trunk/subversion/include/svn_client.h Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/include/svn_client.h?view=diff&rev=13123&p1=trunk/subversion/include/svn_client.h&r1=13122&p2=trunk/subversion/include/svn_client.h&r2=13123 ============================================================================== --- trunk/subversion/include/svn_client.h (original) +++ trunk/subversion/include/svn_client.h Tue Feb 22 17:21:31 2005 @@ -1736,6 +1736,112 @@ apr_pool_t *pool); +/** @since New in 1.2. + * + * A structure which describes various system-generated metadata about + * a working-copy path or URL. + */ +typedef struct svn_info_t +{ + /* Where the item lives in the repository. */ + const char *URL; + + /* The revision of the object. If path_or_url is a working-copy + path, then this is its current working revnum. If path_or_url + is a URL, then this is the repos revision that path_or_url lives in. */ + svn_revnum_t rev; + + /* The node's kind. */ + svn_node_kind_t kind; + + /* The root URL of the repository. */ + const char *repos_root_URL; + + /* The repository's UUID. */ + const char *repos_UUID; + + /* The last revision in which this object changed. */ + svn_revnum_t last_changed_rev; + + /* The date of the last_changed_rev. */ + apr_time_t last_changed_date; + + /* The author of the last_changed_rev. */ + const char *last_changed_author; + + /* The following things only apply to a working-copy path. See + svn_wc_entry_t explanations. */ + svn_wc_schedule_t schedule; + const char *copyfrom_url; + svn_revnum_t copyfrom_rev; + apr_time_t text_time; + apr_time_t prop_time; + const char *checksum; + const char *conflict_old; + const char *conflict_new; + const char *conflict_wrk; + const char *prejfile; + +} svn_info_t; + + +/** @since New in 1.2. + * + * The callback invoked by svn_client_info(). Each invocation + * describes @a path with the information present in @a info. Note + * that any fields within @a info may be NULL if information is + * unavailable. Use @a pool for all temporary allocation. + */ +typedef svn_error_t *(*svn_info_receiver_t) + (void *baton, + const char *path, + const svn_info_t *info, + apr_pool_t *pool); + +/** + * @since New in 1.2. + * + * Invoke @a receiver with @a receiver_baton to return information + * about @a path_or_url in @a revision. The information returned is + * system-generated metadata, not the sort of "property" metadata + * created by users. See @c svn_info_t. + * + * If both revision arguments are either @c + * svn_opt_revision_unspecified or NULL, then information will be + * pulled soley from the working copy; no network connections will be + * made. + * + * Otherwise, information will be pulled from a repository. The + * actual node revision selected is determined by the @a path_or_url + * as it exists in @a peg_revision. If @a peg_revision is @c + * svn_opt_revision_unspecified, then it defaults to @c + * svn_opt_revision_head for URLs or @c svn_opt_revision_working for + * WC targets. + * + * If @a path_or_url is not a local path, then if @a revision is of + * kind @c svn_opt_revision_previous (or some other kind that requires + * a local path), an error will be returned, because the desired + * revision cannot be determined. + * + * Use the authentication baton cached in @a ctx to authenticate + * against the repository. + * + * If @a recurse is true (and @a path_or_url is a directory) this will + * be a recursive operation, invoking @a receiver on each child. + * + */ +svn_error_t * +svn_client_info (const char *path_or_url, + const svn_opt_revision_t *peg_revision, + const svn_opt_revision_t *revision, + svn_info_receiver_t receiver, + void *receiver_baton, + svn_boolean_t recurse, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + + + /* Converting paths to URLs. */ Added: trunk/subversion/libsvn_client/info.c Url: http://svn.collab.net/viewcvs/svn/trunk/subversion/libsvn_client/info.c?view=auto&rev=13123 ============================================================================== --- (empty file) +++ trunk/subversion/libsvn_client/info.c Tue Feb 22 17:21:31 2005 @@ -0,0 +1,196 @@ +/* + * info.c: return system-generated metadata about paths or URLs. + * + * ==================================================================== + * Copyright (c) 2000-2004 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 "client.h" +#include "svn_client.h" +#include "svn_wc.h" + +#include "svn_private_config.h" + + +/* Helper: build an svn_info_t struct from an svn_dirent_t. */ +static svn_error_t * +build_info_from_dirent (svn_info_t **info, + const svn_dirent_t *dirent, + apr_pool_t *pool) +{ + /* ### todo */ + + return SVN_NO_ERROR; +} + + +/* Helper: build an svn_info_t *INFO struct from svn_wc_entry_t ENTRY, + allocated in POOL. Pointer fields are copied by reference, not dup'd. */ +static svn_error_t * +build_info_from_entry (svn_info_t **info, + const svn_wc_entry_t *entry, + apr_pool_t *pool) +{ + svn_info_t *i = apr_pcalloc (pool, sizeof(*i)); + + i->URL = entry->url; + i->rev = entry->revision; + i->kind = entry->kind; + i->repos_UUID = entry->uuid; + i->last_changed_rev = entry->cmt_rev; + i->last_changed_date = entry->cmt_date; + i->last_changed_author = entry->cmt_author; + + /* entry-specific stuff */ + i->schedule = entry->schedule; + i->copyfrom_url = entry->copyfrom_url; + i->copyfrom_rev = entry->copyfrom_rev; + i->text_time = entry->text_time; + i->prop_time = entry->prop_time; + i->checksum = entry->checksum; + i->conflict_old = entry->conflict_old; + i->conflict_new = entry->conflict_new; + i->conflict_wrk = entry->conflict_wrk; + i->prejfile = entry->prejfile; + + *info = i; + return SVN_NO_ERROR; +} + + +/* Callback and baton for crawl_entries() walk over entries files. */ +struct found_entry_baton +{ + svn_info_receiver_t receiver; + void *receiver_baton; +}; + +static svn_error_t * +info_found_entry_callback (const char *path, + const svn_wc_entry_t *entry, + void *walk_baton, + apr_pool_t *pool) +{ + struct found_entry_baton *fe_baton = walk_baton; + svn_info_t *info; + + /* We're going to receive dirents twice; we want to ignore the + first one (where it's a child of a parent dir), and only print + the second one (where we're looking at THIS_DIR.) */ + if ((entry->kind == svn_node_dir) + && (strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR))) + return SVN_NO_ERROR; + + SVN_ERR (build_info_from_entry (&info, entry, pool)); + + return fe_baton->receiver (fe_baton->receiver_baton, path, info, pool); +} + + + +static const svn_wc_entry_callbacks_t +entry_walk_callbacks = + { + info_found_entry_callback + }; + + +/* Helper function: push the svn_wc_entry_t for WCPATH at + RECEIVER/BATON, and possibly recurse over more entries. */ +static svn_error_t * +crawl_entries (const char *wcpath, + svn_info_receiver_t receiver, + void *receiver_baton, + svn_boolean_t recurse, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + svn_wc_adm_access_t *adm_access; + const svn_wc_entry_t *entry; + svn_info_t *info; + struct found_entry_baton fe_baton; + + SVN_ERR (svn_wc_adm_probe_open3 (&adm_access, NULL, wcpath, FALSE, + recurse ? -1 : 0, + ctx->cancel_func, ctx->cancel_baton, + pool)); + SVN_ERR (svn_wc_entry (&entry, wcpath, adm_access, FALSE, pool)); + if (! entry) + { + return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL, + _("Cannot read entry for '%s'"), wcpath); + } + + SVN_ERR (build_info_from_entry (&info, entry, pool)); + fe_baton.receiver = receiver; + fe_baton.receiver_baton = receiver_baton; + + if (entry->kind == svn_node_file) + return receiver (receiver_baton, wcpath, info, pool); + + else if (entry->kind == svn_node_dir) + { + if (recurse) + SVN_ERR (svn_wc_walk_entries2 (wcpath, adm_access, + &entry_walk_callbacks, &fe_baton, + FALSE, ctx->cancel_func, + ctx->cancel_baton, pool)); + else + return receiver (receiver_baton, wcpath, info, pool); + } + + return SVN_NO_ERROR; +} + + +svn_error_t * +svn_client_info (const char *path_or_url, + const svn_opt_revision_t *peg_revision, + const svn_opt_revision_t *revision, + svn_info_receiver_t receiver, + void *receiver_baton, + svn_boolean_t recurse, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + /* svn_ra_session_t *ra_session; + svn_revnum_t rev; + svn_node_kind_t url_kind; + const char *url; */ + + if ((revision == NULL + || revision->kind == svn_opt_revision_unspecified) + && (peg_revision == NULL + || peg_revision->kind == svn_opt_revision_unspecified)) + { + /* Do all digging in the working copy. */ + return crawl_entries (path_or_url, + receiver, receiver_baton, + recurse, ctx, pool); + } + + /* Go repository digging instead. */ + + /* Trace rename history and return RA session to the "final" path_or_url. */ + /* SVN_ERR (svn_client__ra_session_from_path (&ra_session, &rev, + &url, path_or_url, peg_revision, + revision, ctx, pool));*/ + + + return SVN_NO_ERROR; +} |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | svn commit: r13122 - trunk/notes: 00292, breser-jqHnx1hy4Dsdnm+yROfE0A |
|---|---|
| Next by Date: | svn commit: propchange - r13084 - svn:log: 00292, kfogel-jqHnx1hy4Dsdnm+yROfE0A |
| Previous by Thread: | svn commit: r13122 - trunk/notesi: 00292, breser-jqHnx1hy4Dsdnm+yROfE0A |
| Next by Thread: | svn commit: propchange - r13084 - svn:log: 00292, kfogel-jqHnx1hy4Dsdnm+yROfE0A |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |