logo       

svn commit: r13123 - in trunk/subversion: clients/cmdline include libsvn_cl: msg#00292

version-control.subversion.svn

Subject: svn commit: r13123 - in trunk/subversion: clients/cmdline include libsvn_client

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>
Google Custom Search

News | FAQ | advertise