You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/10/16 17:59:43 UTC
svn commit: r1398863 - in /subversion/trunk/subversion:
include/private/svn_subr_private.h include/svn_error_codes.h
libsvn_subr/version.c tests/libsvn_subr/compat-test.c
Author: cmpilato
Date: Tue Oct 16 15:59:42 2012
New Revision: 1398863
URL: http://svn.apache.org/viewvc?rev=1398863&view=rev
Log:
Add private APIs for parsing Subversion release version strings and
testing that they meet some minimum required version number. This is
intended for use with a new SVNMasterVersion httpd.conf directive (to
replace the plethora of per-feature toggles required to make
version-mismatched proxy servers happy).
That said, we might consider making these public and exposing them to
hook authors who wish to use the ephemeral txnprops in start-commit
and pre-commit to test and deny/allow commits based on client version
pedigree. Just a thought.
* subversion/include/svn_error_codes.h
(SVN_ERR_MALFORMED_VERSION_STRING): New error code.
* subversion/include/private/svn_subr_private.h,
* subversion/libsvn_subr/version.c
(svn_version__parse_version_string, svn_version__at_least): New functions.
* subversion/tests/libsvn_subr/compat-test.c
(test_version_parsing, test_version_at_least): New tests.
(test_funcs): Add reference to new tests.
Modified:
subversion/trunk/subversion/include/private/svn_subr_private.h
subversion/trunk/subversion/include/svn_error_codes.h
subversion/trunk/subversion/libsvn_subr/version.c
subversion/trunk/subversion/tests/libsvn_subr/compat-test.c
Modified: subversion/trunk/subversion/include/private/svn_subr_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_subr_private.h?rev=1398863&r1=1398862&r2=1398863&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_subr_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_subr_private.h Tue Oct 16 15:59:42 2012
@@ -295,6 +295,36 @@ svn_hash__make(apr_pool_t *pool);
/** @} */
+/**
+ * @defgroup svn_version Version number dotted triplet parsing
+ * @{
+ */
+
+/* Set @a *version to a version structure parsed from the version
+ * string representation in @a version_string. Return
+ * @c SVN_ERR_MALFORMED_VERSION_STRING if the string fails to parse
+ * cleanly.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_version__parse_version_string(svn_version_t **version,
+ const char *version_string,
+ apr_pool_t *result_pool);
+
+/* Return true iff @a version represents a version number of at least
+ * the level represented by @a major, @a minor, and @a patch.
+ *
+ * @since New in 1.8.
+ */
+svn_boolean_t
+svn_version__at_least(svn_version_t *version,
+ int major,
+ int minor,
+ int patch);
+
+/** @} */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/trunk/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_error_codes.h?rev=1398863&r1=1398862&r2=1398863&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_error_codes.h (original)
+++ subversion/trunk/subversion/include/svn_error_codes.h Tue Oct 16 15:59:42 2012
@@ -1415,6 +1415,11 @@ SVN_ERROR_START
SVN_ERR_MISC_CATEGORY_START + 36,
"too many memcached servers configured")
+ /** @since New in 1.8. */
+ SVN_ERRDEF(SVN_ERR_MALFORMED_VERSION_STRING,
+ SVN_ERR_MISC_CATEGORY_START + 37,
+ "too many memcached servers configured")
+
/* command-line client errors */
SVN_ERRDEF(SVN_ERR_CL_ARG_PARSING_ERROR,
Modified: subversion/trunk/subversion/libsvn_subr/version.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/version.c?rev=1398863&r1=1398862&r2=1398863&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/version.c (original)
+++ subversion/trunk/subversion/libsvn_subr/version.c Tue Oct 16 15:59:42 2012
@@ -28,6 +28,7 @@
#include "sysinfo.h"
#include "svn_private_config.h"
+#include "private/svn_subr_private.h"
const svn_version_t *
svn_subr_version(void)
@@ -193,3 +194,85 @@ svn_version_ext_loaded_libs(const svn_ve
{
return ext_info->loaded_libs;
}
+
+svn_error_t *
+svn_version__parse_version_string(svn_version_t **version_p,
+ const char *version_string,
+ apr_pool_t *result_pool)
+{
+ svn_error_t *err;
+ svn_version_t *version;
+ apr_array_header_t *pieces =
+ svn_cstring_split(version_string, ".", FALSE, result_pool);
+
+ if ((pieces->nelts < 2) || (pieces->nelts > 3))
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, NULL, NULL);
+
+ version = apr_pcalloc(result_pool, sizeof(*version));
+ version->tag = "";
+
+ /* Parse the major and minor integers strictly. */
+ err = svn_cstring_atoi(&(version->major),
+ APR_ARRAY_IDX(pieces, 0, const char *));
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, err, NULL);
+ err = svn_cstring_atoi(&(version->minor),
+ APR_ARRAY_IDX(pieces, 1, const char *));
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING, err, NULL);
+
+ /* If there's a third component, we'll parse it, too. But we don't
+ require that it be present. */
+ if (pieces->nelts == 3)
+ {
+ const char *piece = APR_ARRAY_IDX(pieces, 2, const char *);
+ char *hyphen = strchr(piece, '-');
+ if (hyphen)
+ {
+ version->tag = apr_pstrdup(result_pool, hyphen + 1);
+ *hyphen = '\0';
+ }
+ err = svn_cstring_atoi(&(version->patch), piece);
+ if (err)
+ return svn_error_create(SVN_ERR_MALFORMED_VERSION_STRING,
+ err, NULL);
+ }
+
+ *version_p = version;
+ return SVN_NO_ERROR;
+}
+
+
+svn_boolean_t
+svn_version__at_least(svn_version_t *version,
+ int major,
+ int minor,
+ int patch)
+{
+ /* Compare major versions. */
+ if (version->major < major)
+ return FALSE;
+ if (version->major > major)
+ return TRUE;
+
+ /* Major versions are the same. Compare minor versions. */
+ if (version->minor < minor)
+ return FALSE;
+ if (version->minor > minor)
+ return TRUE;
+
+ /* Major and minor versions are the same. Compare patch
+ versions. */
+ if (version->patch < patch)
+ return FALSE;
+ if (version->patch > patch)
+ return TRUE;
+
+ /* Major, minor, and patch versions are identical matches. But tags
+ in our schema are always used for versions not yet quite at the
+ given patch level. */
+ if (version->tag && version->tag[0])
+ return FALSE;
+
+ return TRUE;
+}
Modified: subversion/trunk/subversion/tests/libsvn_subr/compat-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/compat-test.c?rev=1398863&r1=1398862&r2=1398863&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/compat-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/compat-test.c Tue Oct 16 15:59:42 2012
@@ -24,10 +24,12 @@
#include <apr_pools.h>
#include "svn_error.h"
+#include "svn_pools.h"
#include "svn_version.h"
#include "../svn_test.h"
#include "svn_private_config.h"
+#include "private/svn_subr_private.h"
#ifndef SVN_DISABLE_FULL_VERSION_MATCH
#define FALSE_IF_FULL FALSE
@@ -100,11 +102,121 @@ test_version_compatibility(apr_pool_t *p
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+test_version_parsing(apr_pool_t *pool)
+{
+ unsigned int i;
+ apr_pool_t *iterpool;
+
+ struct version_pair {
+ const char *str;
+ svn_boolean_t malformed;
+ svn_version_t version;
+ } versions[] = {
+ /* str malformed version */
+ { "1.8", FALSE, { 1, 8, 0, ""} },
+ { "1.8-dev", TRUE, { 0, 0, 0, ""} },
+ { "1.1.0", FALSE, { 1, 1, 0, ""} },
+ { "1.1.3", FALSE, { 1, 1, 3, ""} },
+ { "2.10.0", FALSE, { 2, 10, 0, ""} },
+ { "1.8.0-dev", FALSE, { 1, 8, 0, "dev"} },
+ { "1.7.0-beta1", FALSE, { 1, 7, 0, "beta1"} },
+ { "1a.8.0", TRUE, { 0, 0, 0, ""} },
+ { "1a.8.0", TRUE, { 0, 0, 0, ""} },
+ { "1.a8.0", TRUE, { 0, 0, 0, ""} },
+ { "1.8.0a", TRUE, { 0, 0, 0, ""} },
+ { "1.8.0.1", TRUE, { 0, 0, 0, ""} },
+ };
+
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < sizeof(versions)/sizeof(versions[0]); ++i)
+ {
+ svn_version_t *version;
+ svn_error_t *err;
+
+ svn_pool_clear(iterpool);
+
+ err = svn_version__parse_version_string(&version, versions[i].str,
+ iterpool);
+ if (err && (err->apr_err != SVN_ERR_MALFORMED_VERSION_STRING))
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Unexpected error code");
+ if (err)
+ {
+ if (! versions[i].malformed)
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Unexpected parsing error returned");
+ else
+ svn_error_clear(err);
+ }
+ else
+ {
+ if (versions[i].malformed)
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+ "Parsing error expected; none returned");
+ if (! svn_ver_equal(version, &(versions[i].version)))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Parsed version of '%s' doesn't match "
+ "expected", versions[i].str);
+ }
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_version_at_least(apr_pool_t *pool)
+{
+ unsigned int i;
+
+ struct version_pair {
+ svn_version_t version;
+ int major;
+ int minor;
+ int patch;
+ svn_boolean_t at_least;
+ } versions[] = {
+ /* maj min pat version at_least */
+ { { 1, 3, 3, ""}, 1, 3, 3, TRUE },
+ { { 1, 3, 3, ""}, 1, 3, 4, FALSE },
+ { { 1, 3, 3, ""}, 1, 4, 3, FALSE },
+ { { 1, 3, 3, ""}, 0, 4, 3, TRUE },
+ { { 1, 3, 3, ""}, 2, 0, 0, FALSE },
+ { { 1, 3, 3, ""}, 1, 3, 2, TRUE },
+ { { 1, 3, 3, ""}, 1, 2, 4, TRUE },
+ { { 1, 3, 3, "dev"}, 1, 3, 2, TRUE },
+ { { 1, 3, 3, "dev"}, 1, 3, 3, FALSE },
+ { { 1, 3, 3, ""}, 0, 4, 3, TRUE },
+ };
+
+ for (i = 0; i < sizeof(versions)/sizeof(versions[0]); ++i)
+ {
+ svn_boolean_t at_least = svn_version__at_least(&(versions[i].version),
+ versions[i].major,
+ versions[i].minor,
+ versions[i].patch);
+ if (at_least && (! versions[i].at_least))
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+ "Expected at-least to be FALSE; got TRUE");
+ if ((! at_least) && versions[i].at_least)
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+ "Expected at-least to be TRUE; got FALSE");
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* An array of all test functions */
struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_version_compatibility,
"svn_ver_compatible"),
+ SVN_TEST_PASS2(test_version_parsing,
+ "svn_version__parse_version_string"),
+ SVN_TEST_PASS2(test_version_at_least,
+ "svn_version__at_least"),
SVN_TEST_NULL
};
RE: svn commit: r1398863 - in /subversion/trunk/subversion: include/private/svn_subr_private.h include/svn_error_codes.h libsvn_subr/version.c tests/libsvn_subr/compat-test.c
Posted by Bert Huijben <be...@qqmail.nl>.
> -----Original Message-----
> From: C. Michael Pilato [mailto:cmpilato@collab.net]
> Sent: dinsdag 16 oktober 2012 20:11
> To: Bert Huijben
> Cc: dev@subversion.apache.org
> Subject: Re: svn commit: r1398863 - in /subversion/trunk/subversion:
> include/private/svn_subr_private.h include/svn_error_codes.h
> libsvn_subr/version.c tests/libsvn_subr/compat-test.c
>
> On 10/16/2012 12:47 PM, Bert Huijben wrote:
> >> Add private APIs for parsing Subversion release version strings and
> >> testing that they meet some minimum required version number. This is
> >> intended for use with a new SVNMasterVersion httpd.conf directive (to
> >> replace the plethora of per-feature toggles required to make
> >> version-mismatched proxy servers happy).
> >>
> >> That said, we might consider making these public and exposing them to
> >> hook authors who wish to use the ephemeral txnprops in start-commit
> and
> >> pre-commit to test and deny/allow commits based on client version
> >> pedigree. Just a thought.
> >
> > Can we also use this for a more future proof svnadmin create
> > --pre-1.6-compatible variant?
> >
> > There is currently no way I can always create a Subversion 1.7 repository
> > with either a 1.7 or a future client. (1.7 doesn't accept a pre-1.8
> > compatible version argument, etc.)
>
> So, you're thinking something along the lines of:
>
> $ svnadmin create --compat-version=MAJOR.MINOR
Something like that.
I really dislike the existing pattern here, of just adding a new argument on new versions for making the repository compatible with an old version. This only makes us compatible one version after breaking compatibility.
Bert
Re: svn commit: r1398863 - in /subversion/trunk/subversion: include/private/svn_subr_private.h
include/svn_error_codes.h libsvn_subr/version.c tests/libsvn_subr/compat-test.c
Posted by "C. Michael Pilato" <cm...@collab.net>.
On 10/16/2012 12:47 PM, Bert Huijben wrote:
>> Add private APIs for parsing Subversion release version strings and
>> testing that they meet some minimum required version number. This is
>> intended for use with a new SVNMasterVersion httpd.conf directive (to
>> replace the plethora of per-feature toggles required to make
>> version-mismatched proxy servers happy).
>>
>> That said, we might consider making these public and exposing them to
>> hook authors who wish to use the ephemeral txnprops in start-commit and
>> pre-commit to test and deny/allow commits based on client version
>> pedigree. Just a thought.
>
> Can we also use this for a more future proof svnadmin create
> --pre-1.6-compatible variant?
>
> There is currently no way I can always create a Subversion 1.7 repository
> with either a 1.7 or a future client. (1.7 doesn't accept a pre-1.8
> compatible version argument, etc.)
So, you're thinking something along the lines of:
$ svnadmin create --compat-version=MAJOR.MINOR
?
--
C. Michael Pilato <cm...@collab.net>
CollabNet <> www.collab.net <> Enterprise Cloud Development
RE: svn commit: r1398863 - in /subversion/trunk/subversion: include/private/svn_subr_private.h include/svn_error_codes.h libsvn_subr/version.c tests/libsvn_subr/compat-test.c
Posted by Bert Huijben <be...@qqmail.nl>.
> -----Original Message-----
> From: cmpilato@apache.org [mailto:cmpilato@apache.org]
> Sent: dinsdag 16 oktober 2012 18:00
> To: commits@subversion.apache.org
> Subject: svn commit: r1398863 - in /subversion/trunk/subversion:
> include/private/svn_subr_private.h include/svn_error_codes.h
> libsvn_subr/version.c tests/libsvn_subr/compat-test.c
>
> Author: cmpilato
> Date: Tue Oct 16 15:59:42 2012
> New Revision: 1398863
>
> URL: http://svn.apache.org/viewvc?rev=1398863&view=rev
> Log:
> Add private APIs for parsing Subversion release version strings and
> testing that they meet some minimum required version number. This is
> intended for use with a new SVNMasterVersion httpd.conf directive (to
> replace the plethora of per-feature toggles required to make
> version-mismatched proxy servers happy).
>
> That said, we might consider making these public and exposing them to
> hook authors who wish to use the ephemeral txnprops in start-commit
> and pre-commit to test and deny/allow commits based on client version
> pedigree. Just a thought.
Can we also use this for a more future proof svnadmin create --pre-1.6-compatible variant?
There is currently no way I can always create a Subversion 1.7 repository with either a 1.7 or a future client. (1.7 doesn't accept a pre-1.8 compatible version argument, etc.)
Bert
RE: svn commit: r1398863 - in /subversion/trunk/subversion: include/private/svn_subr_private.h include/svn_error_codes.h libsvn_subr/version.c tests/libsvn_subr/compat-test.c
Posted by Bert Huijben <be...@qqmail.nl>.
> -----Original Message-----
> From: cmpilato@apache.org [mailto:cmpilato@apache.org]
> Sent: dinsdag 16 oktober 2012 18:00
> To: commits@subversion.apache.org
> Subject: svn commit: r1398863 - in /subversion/trunk/subversion:
> include/private/svn_subr_private.h include/svn_error_codes.h
> libsvn_subr/version.c tests/libsvn_subr/compat-test.c
>
> Author: cmpilato
> Date: Tue Oct 16 15:59:42 2012
> New Revision: 1398863
>
> URL: http://svn.apache.org/viewvc?rev=1398863&view=rev
> Log:
> Add private APIs for parsing Subversion release version strings and
> testing that they meet some minimum required version number. This is
> intended for use with a new SVNMasterVersion httpd.conf directive (to
> replace the plethora of per-feature toggles required to make
> version-mismatched proxy servers happy).
>
> That said, we might consider making these public and exposing them to
> hook authors who wish to use the ephemeral txnprops in start-commit
> and pre-commit to test and deny/allow commits based on client version
> pedigree. Just a thought.
Can we also use this for a more future proof svnadmin create --pre-1.6-compatible variant?
There is currently no way I can always create a Subversion 1.7 repository with either a 1.7 or a future client. (1.7 doesn't accept a pre-1.8 compatible version argument, etc.)
Bert