/
Automating Subversion with Bindings Automating Subversion with Bindings

Automating Subversion with Bindings - PowerPoint Presentation

briana-ranney
briana-ranney . @briana-ranney
Follow
388 views
Uploaded On 2017-06-22

Automating Subversion with Bindings - PPT Presentation

BenReser http svnms autosvnslides Subversion Committer working at WANdisco since 2012 Started working on Perl Bindings in 2003 to automate Subversion as a replacement for CVS Never finished the project that inspired the work and ended up working on Subversion itself ID: 562006

subversion svn automating bindings svn subversion bindings automating slide core config rev log target client swig cfg revision import ctx javahl auth

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "Automating Subversion with Bindings" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

Automating Subversion with Bindings

@

BenReser

http://

svn.ms

/

autosvnslidesSlide2

Subversion Committer working at WANdisco

since 2012.

Started working on Perl Bindings in 2003 to automate Subversion as a replacement for CVS. Never finished the project that inspired the work and ended up working on Subversion itself.My work isn’t limited to bindings anymore and has expanded across the different parts of Subversion including acting as the Release Manager.

Automating Subversion with Bindings

About Ben

Slide

2Slide3

What are Bindings?Slide4

An implementation of a Version Control System?

Automating Subversion with Bindings

What is Subversion…

Slide 4Slide5

An implementation of a Version Control System?

Libraries

that implement a Version Control System.Automating Subversion with BindingsWhat is Subversion…

Slide

5Slide6

An implementation of a Version Control System?

Libraries

that implement a Version Control System.Written in CAutomating Subversion with Bindings

What is Subversion…

Slide 6Slide7

Automating Subversion with Bindings

Layered Library Design

Slide

7Slide8

Client

Implements the basic functions of a client. Knows about working copies and uses the…

Automating Subversion with BindingsLayered Library Design - Client

Slide

8Slide9

Client

Implements the basic functions of a client. Knows about working copies and uses the…

WC (Working Copy)Implements the working copy Automating Subversion with Bindings

Layered Library Design - Client

Slide 9Slide10

Client

Implements the basic functions of a client. Knows about working copies and uses the…

WC (Working Copy)Implements the working copyRA (Repository Access)Implements protocol to talk to (possibly remote) repositoryLocal (file://)Neon (http(s):// 1.7.x and older was called DAV in 1.4.x and older, gone in 1.8.x)

Serf (http(s):// 1.5.x and newer)SVN (svn://

)

Automating Subversion with Bindings

Layered Library Design - Client

Slide

10Slide11

Repos

Repository interface which implements high level repository functionality and uses…

Automating Subversion with Bindings

Layered Library Design - Server

Slide 11Slide12

Repos

Repository interface

which implements high level repository functionality and uses…FSFile system implementation to store a repositoryFS_Base (Berkeley DB)FS_FS (non database implementation)

Automating Subversion with Bindings

Layered Library Design - Server

Slide

12Slide13

Subr

Miscellaneous subroutines

Automating Subversion with BindingsLayered Library Design – Misc.

Slide

13Slide14

Subr

Miscellaneous subroutines

DeltaTree and byte-stream differencing routines Automating Subversion with Bindings

Layered Library Design – Misc.

Slide 14Slide15

Subr

Miscellaneous subroutines

DeltaTree and byte-stream differencing routinesDiffContextual differencing and merge routines

Automating Subversion with Bindings

Layered Library Design – Misc.

Slide

15Slide16

Access Subversion C APIs from other Higher Level Programming Languages

Automating Subversion with Bindings

What are Bindings?

Slide 16Slide17

Access Subversion C APIs from other Higher Level Programming Languages

Somewhat easier to use than C

Automating Subversion with Bindings

What are Bindings?

Slide

17Slide18

Access Subversion C APIs from other Higher Level Programming Languages

Somewhat easier to use than C

Provide an interface that somewhat matches the Higher Level Language’s idioms Automating Subversion with Bindings

What are Bindings?

Slide

18Slide19

Access Subversion C APIs from other Higher Level Programming Languages

Somewhat easier to use than C

Provide an interface that somewhat matches the Higher Level Language’s idiomsMay even hide some annoying details from using the libraries

Automating Subversion with Bindings

What are Bindings?

Slide

19Slide20

Why use Bindings?Slide21

The client tries to have machine readable formats

Automating Subversion with Bindings

Can’t I Just Script The Client?

Slide

21Slide22

The client tries to have machine readable formats

I recently used something like this to try and find a bug in diff –summarize:

(svn log $URL | grep -

Eo '^r[0-9]+ \| ' | sed 's/[^0-9]//g') | while read

rev; do

svn

diff

--summarize $URL -c

$rev; done

Automating Subversion with Bindings

Can’t I Just Script The Client?

Slide

22Slide23

It worked great until it ran into this output:

svn

log –c 933481 https://svn.apache.org/repos/asf

/subversion/trunk------------------------------------------------------------------------

r933481 | gstein | 2010-04-12 21:20:50 -0700 (Mon, 12 Apr 2010) | 27 lines

Add some new methods to the Sandbox class for performing simple,

unverified operations.

Also introduce deep magic with

svntest.main.make_log_msg

() to produce log

messages that show the source of the command invocation. These automated

log messages look like:

----

r2 |

jrandom

| 2010-04-12 23:57:10 -0400 (Mon, 12 Apr 2010) | 1 line

File './

schedule_tests.py

', line 543, in

status_add_deleted_directory

---

-

Automating Subversion with Bindings

Can’t I Just Script The Client?

Slide

23Slide24

The client supports XML output with --xml on most commands.

Automating Subversion with Bindings

What about XML?

Slide

24Slide25

The client supports XML output with --xml on most commands.

XML is hard to parse correctly

Regexps aren’t reliableXSLT is a pain to writeXML parsers are far from easy to drive

Automating Subversion with Bindings

What about XML?

Slide

25Slide26

We try to avoid changing the output and behavior of commands.

Automating Subversion with Bindings

Command behavior changes

Slide

26Slide27

We try to avoid changing the output and behavior of commands.

Automating Subversion with Bindings

Command behavior changes

Slide

27Slide28

We try to avoid changing the output and behavior of commands.

svn

mergeinfo prior to 1.8.0 behaved as though --show-revs=merged was passed if no --show-revs option was passed. In 1.8.x this shows a graph.

Automating Subversion with Bindings

Command behavior changes

Slide

28Slide29

We can implement functionality that the command line client doesn’t have.

Examples:

ViewVCSubclipsecontrol-chars.py hook-script

Automating Subversion with Bindings

Greater capabilities

Slide

29Slide30

Poor documentation

Automating Subversion with Bindings

Why not use Bindings?

Slide 30Slide31

Poor documentation

Need to install them

Automating Subversion with Bindings

Why not use Bindings?

Slide 31Slide32

Poor documentation

Need to install them

Expose internal details that may be hard to understand Automating Subversion with Bindings

Why not use Bindings?

Slide

32Slide33

Poor documentation

Need to install them

Expose internal details that may be hard to understandNot always updated for the latest features

Automating Subversion with Bindings

Why not use Bindings?

Slide

33Slide34

Getting StartedSlide35

SWIG

Python

PerlRubyJavaHL

ctypes-pythonSVNKit

pySVN

Automating Subversion with Bindings

What Bindings Are Available

Slide

35Slide36

Simplified Wrapper and Interface Generator

Automating Subversion with BindingsWhat is SWIG?

Slide

36Slide37

Simplified Wrapper and Interface Generator

Partly automated generator

Automating Subversion with Bindings

What is SWIG?

Slide 37Slide38

Simplified Wrapper and Interface Generator

Partly automated generator

Acts like a specialized C compiler Automating Subversion with Bindings

What is SWIG?

Slide 38Slide39

Simplified Wrapper and Interface Generator

Partly automated generator

Acts like a specialized C compilerOnly needed at interface generation time Automating Subversion with Bindings

What is SWIG?

Slide

39Slide40

WindowsMac

RedHat

based LinuxDebian based LinuxOtherAutomating Subversion with Bindings

How To Install Bindings

Slide

40Slide41

WANdisco installer

Provides

swig-python (for Python 2.7.2) and JavaHLAlagazam.netProvides swig-python, swig-perl, swig-ruby, and JavaHL

Automating Subversion with Bindings

Windows

Slide

41Slide42

WANdisco packages

subversion-python (SWIG)

subversion-ruby (subversion 1.8.x only)subversion-perlsubversion-javahlOS Packages

Older but usually available and named same as above.

Automating Subversion with Bindings

RedHat

based Linux

Slide

42Slide43

WANdisco packages

python-subversion (SWIG)

libsvn-ruby (and libsvn-ruby1.8 for Ruby 1.8)libsvn-perllibsvn-java (JavaHL

)OS PackagesOlder but usually available and named same as above.

Automating Subversion with Bindings

Debian

based Linux

Slide

43Slide44

WANdisco

installer

Provides swig-python, swig-perl, swig-ruby and JavaHLMacPortssubversion-javahlbindingssubversion-perlbindings-5.16 (number is

perl version)subversion-python27bindings (number is python version)subversion-

rubybindingsHomebrewcan

provide

JavaHL

, swig-

perl

, swig-python, and swig-

ruby

Xcode

Command line tools

old but includes swig-python, swig-

perl

and swig-ruby

Automating Subversion with Bindings

Mac

Slide

44Slide45

WANdisco packages should have Bindings for most

OSes

*NIX platforms build it yourself by:[usual Subversion build instructions]make $bindingmake check-$bindingmake install-$bindingw

here $binding can be: javahl swig-

pl swig-py

swig-

rb

Don’t use do parallel builds of bindings (-j option to make)

Automating Subversion with Bindings

Other

Slide

45Slide46

On the Mac you need to do this before the normal Subversion instructions due to a bug in our API that makes the bindings fail to compile (requires SWIG,

libtool

and autoconf):make extraclean./autogen.sh

Automating Subversion with Bindings

Build It Yourself - SWIG

Slide

46Slide47

On the Mac you need to do this before the normal Subversion instructions due to a bug in our API that makes the bindings fail to compile (requires SWIG,

libtool

and autoconf):make extraclean./autogen.shMay need the same instructions on other platforms if you get an error about an undeclared symbol starting with SVN_AUTH

Automating Subversion with Bindings

Build It Yourself - SWIG

Slide

47Slide48

On the Mac you need to do this before the normal Subversion instructions due to a bug in our API that makes the bindings fail to compile (requires SWIG,

libtool

and autoconf):make extraclean./autogen.shMay need the same instructions on other platforms if you get an error about an undeclared symbol starting with SVN_AUTH

To use Ruby 1.9 need Subversion 1.8.x

Automating Subversion with Bindings

Build It Yourself - SWIG

Slide

48Slide49

On the Mac you need to do this before the normal Subversion instructions due to a bug in our API that makes the bindings fail to compile (requires SWIG,

libtool

and autoconf):make extraclean./autogen.shMay need the same instructions on other platforms if you get an error about an undeclared symbol starting with SVN_AUTH

To use Ruby 1.9 need Subversion 1.8.xPython 3 doesn’t work

Automating Subversion with Bindings

Build It Yourself - SWIG

Slide

49Slide50

Need --enable-

javahl

passed to configureAutomating Subversion with Bindings

Build It Yourself - JavaHL

Slide

50Slide51

Need --enable-

javahl

passed to configureNeed JUnit, specify where it is by passing this to configure (make sure this is an absolute path): --with-

junit=/usr/share/java/junit.jar

Automating Subversion with Bindings

Build It Yourself -

JavaHL

Slide

51Slide52

Need --enable-

javahl

passed to configureNeed JUnit, specify where it is by passing this to configure (make sure this is an absolute path): --with-

junit=/usr/share/java/junit.jar

Can specify which JDK to use by passing this to configure:

-

-with-

jdk

=/

usr

/lib/

jvm

/java-6-openjdk-amd64

Automating Subversion with Bindings

Build It Yourself -

JavaHL

Slide

52Slide53

Using the BindingsSlide54

Thin layer over C API

Automating Subversion with Bindings

SWIG Bindings

Slide

54Slide55

Thin layer over C API

Perl and Ruby have more syntactic sugar to make it feel more like a normal Perl or Ruby program

Automating Subversion with Bindings

SWIG Bindings

Slide 55Slide56

Thin layer over C API

Perl and Ruby have more syntactic sugar to make it feel more like a normal Perl or Ruby program

Python has very little syntactic sugar but is more completeAutomating Subversion with Bindings

SWIG Bindings

Slide

56Slide57

Thin layer over C API

Perl and Ruby have more syntactic sugar to make it feel more like a normal Perl or Ruby program

Python has very little syntactic sugar but is more completeNot every language has everything completely wrapped.

Automating Subversion with Bindings

SWIG Bindings

Slide

57Slide58

Core

The things that don’t fit anywhere else, includes APR functions that are needed and

libsvn_subr.ClientWcDiffDeltaRaReposFs

Automating Subversion with Bindings

SWIG Modules

Slide

58Slide59

APR is Apache Portable Runtime

Automating Subversion with Bindings

APR Pools

Slide

59Slide60

APR is Apache Portable Runtime

Pools are used for memory management.

Automating Subversion with Bindings

APR Pools

Slide 60Slide61

APR is Apache Portable Runtime

Pools are used for memory management.

Pools have a lifetime. Lifetime ends when pool or its parent is destroyed.Automating Subversion with Bindings

APR Pools

Slide

61Slide62

APR is Apache Portable Runtime

Pools are used for memory management.

Pools have a lifetime. Lifetime ends when pool or its parent is destroyed.Pools can be cleared to free memory and reuse the same pool (iteration)

Automating Subversion with Bindings

APR Pools

Slide

62Slide63

APR is Apache Portable Runtime

Pools are used for memory management.

Pools have a lifetime. Lifetime ends when pool or its parent is destroyed.Pools can be cleared to free memory and reuse the same pool (iteration)SWIG bindings largely let you ignore pools by defaulting to a single global pool

Automating Subversion with Bindings

APR Pools

Slide

63Slide64

APR is Apache Portable Runtime

Pools are used for memory management.

Pools have a lifetime. Lifetime ends when pool or its parent is destroyed.Pools can be cleared to free memory and reuse the same pool (iteration)SWIG bindings largely let you ignore pools by defaulting to a single global poolYou can still use pools and may want to in some cases (iteration, long running programs)

Automating Subversion with Bindings

APR Pools

Slide

64Slide65

C API uses a lot of callbacks, so SWIG does as well

Automating Subversion with Bindings

Callbacks and Batons

Slide

65Slide66

C API uses a lot of callbacks, so SWIG does as well

Callback

args are func, baton.

Automating Subversion with Bindings

Callbacks and Batons

Slide

66Slide67

C API uses a lot of callbacks, so SWIG does as well

Callback

args are func, baton.You can provide a binding language function for the callback.

Automating Subversion with Bindings

Callbacks and Batons

Slide

67Slide68

C API uses a lot of callbacks, so SWIG does as well

Callback

args are func, baton.You can provide a binding language function for the callback.Batons are a way of passing data through to the callback that you provide.

Automating Subversion with Bindings

Callbacks and Batons

Slide

68Slide69

C API uses a lot of callbacks, so SWIG does as well

Callback

args are func, baton.You can provide a binding language function for the callback.Batons are a way of passing data through to the callback that you provide.SWIG doesn’t support batons so use closures/lambdas.

Automating Subversion with Bindings

Callbacks and Batons

Slide

69Slide70

SWIG wraps the C types for you

Automating Subversion with Bindings

SWIG Types

Slide

70Slide71

SWIG wraps the C types for you

Structs

have getters and setters (type_field_get/type_field_set), but syntactic sugar allows you to use structs like objects in binding language

Automating Subversion with Bindings

SWIG Types

Slide

71Slide72

SWIG wraps the C types for you

Structs

have getters and setters (type_field_get/type_field_set), but syntactic sugar allows you to use structs like objects in binding languageStructs can be allocated and freed (

new_type/delete_type) e.g. new_svn_opt_revision_t

()

Automating Subversion with Bindings

SWIG Types

Slide

72Slide73

SWIG wraps the C types for you

Structs

have getters and setters (type_field_get/type_field_set), but syntactic sugar allows you to use structs like objects in binding languageStructs can be allocated and freed (

new_type/delete_type) e.g. new_svn_opt_revision_t

()Ints, Hashes and Arrays are mapped to the binding languages equivalent types

Automating Subversion with Bindings

SWIG Types

Slide

73Slide74

SWIG wraps the C types for you

Structs

have getters and setters (type_field_get/type_field_set), but syntactic sugar allows you to use structs like objects in binding languageStructs can be allocated and freed (

new_type/delete_type) e.g. new_svn_opt_revision_t

()Ints, Hashes and Arrays are mapped to the binding languages equivalent types

If a type hasn’t been mapped in SWIG you may have trouble using it

Automating Subversion with Bindings

SWIG Types

Slide

74Slide75

C API requires that paths be UTF-8 and canonical

Automating Subversion with Bindings

Canonicalization

Slide

75Slide76

C API requires that paths be UTF-8 and canonical

There are 3 types of paths

URL or URIDirent (path on local fileystem)Relpath (unrooted relative path)

Automating Subversion with Bindings

Canonicalization

Slide

76Slide77

C API requires that paths be UTF-8 and canonical

There are 3 types of paths

URL or URIDirent (path on local fileystem)Relpath (unrooted relative path)Use

svn_path_is_url() and context to determine which you have

Automating Subversion with Bindings

Canonicalization

Slide

77Slide78

C API requires that paths be UTF-8 and canonical

There are 3 types of paths

URL or URIDirent (path on local fileystem)Relpath (unrooted relative path)Use

svn_path_is_url() and context to determine which you haveUse svn_uri_canonicalize

(), svn_dirent_canonicalize() or svn_relpath_canonicalize

() to

canonicalize

a path.

Automating Subversion with Bindings

Canonicalization

Slide

78Slide79

C API requires that paths be UTF-8 and canonical

There are 3 types of paths

URL or URIDirent (path on local fileystem)Relpath (unrooted relative path)Use

svn_path_is_url() and context to determine which you haveUse svn_uri_canonicalize

(), svn_dirent_canonicalize() or svn_relpath_canonicalize

() to

canonicalize

a path.

Not doing this will cause assertions or crashes.

Automating Subversion with Bindings

Canonicalization

Slide

79Slide80

Python and Ruby have exceptions so errors are handled via that mechanism

Automating Subversion with Bindings

Error Handling

Slide 80Slide81

Python and Ruby have exceptions so errors are handled via that mechanism

Perl does not have exceptions

Uses an error handler callback $SVN::Error::handlerDefault callback croaks with message provided by libraries.See perldoc SVN::Core and read the documentation on SVN::Error for details

Automating Subversion with Bindings

Error Handling

Slide

81Slide82

Python and Ruby have exceptions so errors are handled via that mechanism

Perl does not have exceptions

Uses an error handler callback $SVN::Error::handlerDefault callback croaks with message provided by libraries.See perldoc SVN::Core and read the documentation on SVN::Error for detailsAll have access to data from Subversion’s error

struct svn_error_t

Errors can be chained, next error is in child fieldapr_err is a numeric code for the error

m

essage is a human readable string

Automating Subversion with Bindings

Error Handling

Slide

82Slide83

import sys

from

svn import core, clientctx

= client.create_context()

cfg =

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

83Slide84

import

sys

from svn

import core, client

ctx

=

client.create_context

()

cfg

=

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

84Slide85

import sys

from

svn import core, client

ctx =

client.create_context()

cfg

=

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

85Slide86

import sys

from

svn import core, client

ctx

=

client.create_context

()

cfg

=

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

86Slide87

import sys

from

svn import core, client

ctx

=

client.create_context

()

cfg

=

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

87Slide88

import sys

from

svn import core, client

ctx

= client.create_context

()

cfg

=

core.svn_config_get_config

(None)

cfg_config

=

cfg

[

core.SVN_CONFIG_CATEGORY_CONFIG

]

ctx.auth_baton

=

core.svn_cmdline_create_auth_baton

(False, #

non_interactive

None, #username

None, #password

None, #

config_dir

False, #

no_auth_cache

False, #

trust_server_cert

cfg_config

, #

config

category

None, #

cancel_func

None) #

cancel_baton

rev =

core.svn_opt_revision_t

()

rev.kind

=

core.svn_opt_revision_head

if

core.svn_path_is_url

(

sys.argv

[1]):

target =

core.svn_uri_canonicalize

(

sys.argv

[1])

else:

target =

core.svn_dirent_canonicalize

(

sys.argv

[1])

client.cat

(

sys.stdout

, # output file handle

target,

rev, # revision

ctx

) #client context

Automating Subversion with Bindings

Python Example - Cat

Slide

88Slide89

use SVN::Client;

my $

ctx = new SVN::Client();my $

cfg = SVN::Core::config_get_config

(undef

);

my $

cfg_config

= $

cfg

->{SVN::Core::CONFIG_CATEGORY_CONFIG};

$

ctx

->

auth

(

SVN::Core::

cmdline_create_auth_baton

(0, #

non_interactive

undef

, #username

undef

, #password

undef

, #

config_dir

0, #

no_auth_cache

0, #

trust_server_cert

,

$

cfg_config

, #

config

category

undef

, #

cancel_func

undef

) #

cancel_baton

);

my $target;

if (SVN::Core::

path_is_url

($ARGV[0])) {

$target = SVN::Core::

uri_canonicalize

($ARGV[0]);

} else {

$target = SVN::Core::

dirent_canonicalize

($ARGV[0]);

}

$

ctx

->cat(\*STDOUT, #output

filehandle

$target,

'HEAD'); #rev

Automating Subversion with Bindings

Perl Example - Cat

Slide

89Slide90

use SVN::Client;

my $

ctx

= new SVN::Client();my $

cfg

= SVN::Core::

config_get_config

(

undef

);

my $

cfg_config

= $

cfg

->{SVN::Core::CONFIG_CATEGORY_CONFIG};

$

ctx

->

auth

(

SVN::Core::

cmdline_create_auth_baton

(0, #

non_interactive

undef

, #username

undef

, #password

undef

, #

config_dir

0, #

no_auth_cache

0, #

trust_server_cert

,

$

cfg_config

, #

config

category

undef

, #

cancel_func

undef

) #

cancel_baton

);

my $target;

if (SVN::Core::

path_is_url

($ARGV[0])) {

$target = SVN::Core::

uri_canonicalize

($ARGV[0]);

} else {

$target = SVN::Core::

dirent_canonicalize

($ARGV[0]);

}

$

ctx

->cat(\*STDOUT, #output

filehandle

$target,

'HEAD'); #rev

Automating Subversion with Bindings

Perl Example - Cat

Slide

90Slide91

use SVN::Client;

my $

ctx = new SVN::Client();

my $cfg = SVN::Core::

config_get_config(

undef

);

my $

cfg_config

= $

cfg

->{SVN::Core::CONFIG_CATEGORY_CONFIG};

$

ctx

->

auth

(

SVN::Core::

cmdline_create_auth_baton

(0, #

non_interactive

undef

, #username

undef

, #password

undef

, #

config_dir

0, #

no_auth_cache

0, #

trust_server_cert

,

$

cfg_config

, #

config

category

undef

, #

cancel_func

undef

) #

cancel_baton

);

my $target;

if (SVN::Core::

path_is_url

($ARGV[0])) {

$target = SVN::Core::

uri_canonicalize

($ARGV[0]);

} else {

$target = SVN::Core::

dirent_canonicalize

($ARGV[0]);

}

$

ctx

->cat(\*STDOUT, #output

filehandle

$target,

'HEAD'); #rev

Automating Subversion with Bindings

Perl Example - Cat

Slide

91Slide92

use SVN::Client;

my $

ctx

= new SVN::Client();

my $cfg

= SVN::Core::

config_get_config

(

undef

);

my $

cfg_config

= $

cfg

->{SVN::Core::CONFIG_CATEGORY_CONFIG};

$

ctx

->

auth

(

SVN::Core::

cmdline_create_auth_baton

(0, #

non_interactive

undef

, #username

undef

, #password

undef

, #

config_dir

0, #

no_auth_cache

0, #

trust_server_cert

,

$

cfg_config

, #

config

category

undef

, #

cancel_func

undef

) #

cancel_baton

);

my $target;

if (SVN::Core::

path_is_url

($ARGV[0])) {

$target = SVN::Core::

uri_canonicalize

($ARGV[0]);

} else {

$target = SVN::Core::

dirent_canonicalize

($ARGV[0]);

}

$

ctx

->cat(\*STDOUT, #output

filehandle

$target,

'HEAD'); #rev

Automating Subversion with Bindings

Perl Example - Cat

Slide

92Slide93

use SVN::Client;

my $

ctx

= new SVN::Client();my $

cfg = SVN::Core::

config_get_config

(

undef

);

my $

cfg_config

= $

cfg

->{SVN::Core::CONFIG_CATEGORY_CONFIG};

$

ctx

->

auth

(

SVN::Core::

cmdline_create_auth_baton

(0, #

non_interactive

undef

, #username

undef

, #password

undef

, #

config_dir

0, #

no_auth_cache

0, #

trust_server_cert

,

$

cfg_config

, #

config

category

undef

, #

cancel_func

undef

) #

cancel_baton

);

my $target;

if (SVN::Core::

path_is_url

($ARGV[0])) {

$target = SVN::Core::

uri_canonicalize

($ARGV[0]);

} else {

$target = SVN::Core::

dirent_canonicalize

($ARGV[0]);

}

$

ctx

->cat(\*STDOUT, #output

filehandle

$target,

'HEAD'); #rev

Automating Subversion with Bindings

Perl Example - Cat

Slide

93Slide94

require "

svn

/client"Svn

::Client::Context.new do |

ctx|

cfg

=

Svn

::Core::

Config.get

()

cfg_config

=

cfg

[

Svn

::Core::CONFIG_CATEGORY_CONFIG]

ctx.auth_baton

=

Svn

::

Core.cmdline_create_auth_baton

(

false, #

non_interactive

nil, #username

nil, #password

nil, #

config_dir

false, #

no_auth_cache

false, #

trust_server_cert

cfg_config

, #

config

category

nil, #

cancel_func

nil) #

cancel_baton

if

Svn

::

Core.path_is_url

(ARGV[0])

target =

Svn

::Core::

uri_canonicalize

(ARGV[0])

else

target =

Svn

::Core::

dirent_canonicalize

(ARGV[0])

end

ctx.cat

(target,

"HEAD", #rev

nil, #

pegrev

STDOUT) #output

filehandle

end

Automating Subversion with Bindings

Ruby Example - Cat

Slide

94Slide95

require "

svn

/client"

Svn::Client::

Context.new do |

ctx

|

cfg

=

Svn

::Core::

Config.get

()

cfg_config

=

cfg

[

Svn

::Core::CONFIG_CATEGORY_CONFIG]

ctx.auth_baton

=

Svn

::

Core.cmdline_create_auth_baton

(

false, #

non_interactive

nil, #username

nil, #password

nil, #

config_dir

false, #

no_auth_cache

false, #

trust_server_cert

cfg_config

, #

config

category

nil, #

cancel_func

nil) #

cancel_baton

if

Svn

::

Core.path_is_url

(ARGV[0])

target =

Svn

::Core::

uri_canonicalize

(ARGV[0])

else

target =

Svn

::Core::

dirent_canonicalize

(ARGV[0])

end

ctx.cat

(target,

"HEAD", #rev

nil, #

pegrev

STDOUT) #output

filehandle

end

Automating Subversion with Bindings

Ruby Example - Cat

Slide

95Slide96

require "

svn

/client"Svn

::Client::Context.new do |

ctx|

cfg

=

Svn

::Core::

Config.get

()

cfg_config

=

cfg

[

Svn

::Core::CONFIG_CATEGORY_CONFIG]

ctx.auth_baton

=

Svn

::

Core.cmdline_create_auth_baton

(

false, #

non_interactive

nil, #username

nil, #password

nil, #

config_dir

false, #

no_auth_cache

false, #

trust_server_cert

cfg_config

, #

config

category

nil, #

cancel_func

nil) #

cancel_baton

if

Svn

::

Core.path_is_url

(ARGV[0])

target =

Svn

::Core::

uri_canonicalize

(ARGV[0])

else

target =

Svn

::Core::

dirent_canonicalize

(ARGV[0])

end

ctx.cat

(target,

"HEAD", #rev

nil, #

pegrev

STDOUT) #output

filehandle

end

Automating Subversion with Bindings

Ruby Example - Cat

Slide

96Slide97

require "

svn

/client"

Svn

::Client::Context.new

do |

ctx

|

cfg

=

Svn

::Core::

Config.get

()

cfg_config

=

cfg

[

Svn

::Core::CONFIG_CATEGORY_CONFIG]

ctx.auth_baton

=

Svn

::

Core.cmdline_create_auth_baton

(

false, #

non_interactive

nil, #username

nil, #password

nil, #

config_dir

false, #

no_auth_cache

false, #

trust_server_cert

cfg_config

, #

config

category

nil, #

cancel_func

nil) #

cancel_baton

if

Svn

::

Core.path_is_url

(ARGV[0])

target =

Svn

::Core::

uri_canonicalize

(ARGV[0])

else

target =

Svn

::Core::

dirent_canonicalize

(ARGV[0])

end

ctx.cat

(target,

"HEAD", #rev

nil, #

pegrev

STDOUT) #output

filehandle

end

Automating Subversion with Bindings

Ruby Example - Cat

Slide

97Slide98

require "

svn

/client"

Svn::Client::Context.new

do |

ctx

|

cfg

=

Svn

::Core::

Config.get

()

cfg_config

=

cfg

[

Svn

::Core::CONFIG_CATEGORY_CONFIG]

ctx.auth_baton

=

Svn

::

Core.cmdline_create_auth_baton

(

false, #

non_interactive

nil, #username

nil, #password

nil, #

config_dir

false, #

no_auth_cache

false, #

trust_server_cert

cfg_config

, #

config

category

nil, #

cancel_func

nil) #

cancel_baton

if

Svn

::

Core.path_is_url

(ARGV[0])

target =

Svn

::Core::

uri_canonicalize

(ARGV[0])

else

target =

Svn

::Core::

dirent_canonicalize

(ARGV[0])

end

ctx.cat

(target,

"HEAD", #rev

nil, #

pegrev

STDOUT) #output

filehandle

end

Automating Subversion with Bindings

Ruby Example - Cat

Slide

98Slide99

def

log_entry_receiver(log_entry

, pool): print("r"+

str(

log_entry.revision

))

revprops

=

log_entry.revprops

print(

revprops

['

svn:log

']+"\n")

end =

core.svn_opt_revision_t

()

end.kind

=

core.svn_opt_revision_number

end.value.number

= 0

rev_range

=

core.svn_opt_revision_range_t

()

rev_range.start

= rev

rev_range.end

= end

client.log5((target,), #target

rev, #

pegrev

(

rev_range

,), #rev range

0, #limit (0=unlimited)

True, #discover changed paths

True, #

strict_node_history

False, #

include_merged_revisions

None, #array of

revprops

to retrieve

# (None for all)

log_entry_receiver

, #callback

ctx

)

Automating Subversion with Bindings

Python Example - Log

Slide

99Slide100

def

log_entry_receiver(log_entry

, pool): print("r"+

str

(

log_entry.revision

))

revprops

=

log_entry.revprops

print(

revprops

['

svn:log

']+"\n")

end =

core.svn_opt_revision_t

()

end.kind

=

core.svn_opt_revision_number

end.value.number

= 0

rev_range

=

core.svn_opt_revision_range_t

()

rev_range.start

= rev

rev_range.end

= end

client.log5((target,), #target

rev, #

pegrev

(

rev_range

,), #rev range

0, #limit (0=unlimited)

True, #discover changed paths

True, #

strict_node_history

False, #

include_merged_revisions

None, #array of

revprops

to retrieve

# (None for all)

log_entry_receiver

, #callback

ctx

)

Automating Subversion with Bindings

Python Example - Log

Slide

100Slide101

def

log_entry_receiver(log_entry

, pool): print("r"+

str(

log_entry.revision

))

revprops

=

log_entry.revprops

print(

revprops

['

svn:log

']+"\n")

end =

core.svn_opt_revision_t

()

end.kind

=

core.svn_opt_revision_number

end.value.number

= 0

rev_range

=

core.svn_opt_revision_range_t

()

rev_range.start

= rev

rev_range.end

= end

client.log5((target,), #target

rev, #

pegrev

(

rev_range

,), #rev range

0, #limit (0=unlimited)

True, #discover changed paths

True, #

strict_node_history

False, #

include_merged_revisions

None, #array of

revprops

to retrieve

# (None for all)

log_entry_receiver

, #callback

ctx

)

Automating Subversion with Bindings

Python Example - Log

Slide

101Slide102

def

log_entry_receiver(

log_entry, pool):

print("r"+

str

(

log_entry.revision

))

revprops

=

log_entry.revprops

print(

revprops

['

svn:log

']+"\n")

end =

core.svn_opt_revision_t

()

end.kind

=

core.svn_opt_revision_number

end.value.number

= 0

rev_range

=

core.svn_opt_revision_range_t

()

rev_range.start

= rev

rev_range.end

= end

client.log5((target,), #target

rev, #

pegrev

(

rev_range

,), #rev range

0, #limit (0=unlimited)

True, #discover changed paths

True, #

strict_node_history

False, #

include_merged_revisions

None, #array of

revprops

to retrieve

# (None for all)

log_entry_receiver

, #callback

ctx

)

Automating Subversion with Bindings

Python Example - Log

Slide

102Slide103

sub

log_entry_receiver

{ my ($log_entry,$pool

) = @_;

my $revprops

= $

log_entry

->

revprops

;

print "r",$

log_entry

->revision;

print "\

n$revprops

->{'

svn:log

'}\n\n"

}

$

ctx

->log5($target,

'HEAD', #

pegrev

['HEAD',0], #rev range

0, #limit (0=unlimited)

1, #

discover_changed_paths

1, #

strict_node_history

0, #

include_merged_revisions

undef

, #array of

revprops

to

retrive

# (

undef

for all)

\&

log_entry_receiver

); #callback

Automating Subversion with Bindings

Perl Example - Log

Slide

103Slide104

sub

log_entry_receiver

{ my ($log_entry,$pool

) = @_;

my $revprops

= $

log_entry

->

revprops

;

print "r",$

log_entry

->revision;

print "\

n$revprops

->{'

svn:log

'}\n\n"

}

$

ctx

->log5($target,

'HEAD', #

pegrev

['HEAD',0], #rev range

0, #limit (0=unlimited)

1, #

discover_changed_paths

1, #

strict_node_history

0, #

include_merged_revisions

undef

, #array of

revprops

to

retrive

# (

undef

for all)

\&

log_entry_receiver

); #callback

Automating Subversion with Bindings

Perl Example - Log

Slide

104Slide105

sub

log_entry_receiver

{ my ($log_entry,$pool

) = @_;

my $revprops

= $

log_entry

->

revprops

;

print "r",$

log_entry

->revision;

print "\

n$revprops

->{'

svn:log

'}\n\n"

}

$

ctx

->log5($target,

'HEAD', #

pegrev

['HEAD',0], #rev range

0, #limit (0=unlimited)

1, #

discover_changed_paths

1, #

strict_node_history

0, #

include_merged_revisions

undef

, #array of

revprops

to

retrive

# (

undef

for all)

\&

log_entry_receiver

); #callback

Automating Subversion with Bindings

Perl Example - Log

Slide

105Slide106

args

= [target, "HEAD", #start rev

0, #end rev 0, #limit

true, #

discover_changed_paths

true] #strict node history

ctx.log

(*

args

) do |

changed_paths

, rev, author, date, message|

print("

r",rev

,"\n")

print(message,"\n\n")

end

Automating Subversion with Bindings

Ruby Example - Log

Slide

106Slide107

args

= [target, "HEAD", #start rev

0, #end rev 0, #limit

true, #

discover_changed_paths

true] #strict node history

ctx.log

(*

args

) do |

changed_paths

, rev, author, date, message|

print("

r",rev

,"\n")

print(message,"\n\n")

end

Automating Subversion with Bindings

Ruby Example - Log

Slide

107Slide108

args

= [target, "HEAD", #start rev

0, #end rev 0, #limit

true, #

discover_changed_paths

true] #strict node history

ctx.log

(*

args

)

do |

changed_paths

, rev, author, date, message|

print("

r",rev

,"\n")

print(message,"\n\n")

end

Automating Subversion with Bindings

Ruby Example - Log

Slide

108Slide109

args

= [target, "HEAD", #start rev

0, #end rev

0, #limit

true, #

discover_changed_paths

true] #strict node history

ctx.log

(*

args

)

do |

changed_paths

, rev, author, date, message|

print("

r",rev

,"\n")

print(message,"\n\n")

end

Automating Subversion with Bindings

Ruby Example - Log

Slide

109Slide110

Use the latest version

Automating Subversion with Bindings

SWIG Advice

Slide

110Slide111

Use the latest version

Refer to C API documentation to determine arguments

Automating Subversion with Bindings

SWIG Advice

Slide

111Slide112

Use the latest version

Refer to C API documentation to determine arguments

Use the forceAutomating Subversion with Bindings

SWIG Advice

Slide

112Slide113

Use the latest version

Refer to C API documentation to determine arguments

Use the force source

Automating Subversion with Bindings

SWIG Advice

Slide

113Slide114

Use the latest version

Refer to C API documentation to determine arguments

Use the source and examples under tools/examples, {tools,contrib}/{client-side,hook-scripts,server-side}, and the test suites for the bindings.

Automating Subversion with Bindings

SWIG Advice

Slide

114Slide115

Use the latest version

Refer to C API documentation to determine arguments

Use the source and examples under tools/examples, {tools,contrib}/{client-side,hook-scripts,server-side}, and the test suites for the bindings.Errors about missing functions are often a sign of mismatched libraries. Check that the language path is correct and that the Subversion libraries being loaded match. Adding a sleep to your code and then using

lsof against that process can be helpful here.

Automating Subversion with Bindings

SWIG Advice

Slide

115Slide116

If you can, build your own with debug symbols by passing this to configure:

--enable-maintainer-modeAutomating Subversion with Bindings

SWIG Advice

Slide

116Slide117

If you can, build your own with debug symbols by passing this to configure:

--enable-maintainer-modeUse the start.sh script included with my examples to use uninstalled bindings from a Subversion build to ease debugging/testing: SVN_BUILDDIR=$HOME/subversion-1.8.3 \

start.sh

gdb –

args

perl

cat.pl

Automating Subversion with Bindings

SWIG Advice

Slide

117Slide118

If you can, build your own with debug symbols by passing this to configure:

--enable-maintainer-modeUse the start.sh script included with my examples to use uninstalled bindings from a Subversion build to ease debugging/testing: SVN_BUILDDIR=$HOME/subversion-1.8.3 \

start.sh

gdb

-

args

perl

cat.pl

The

start.sh

script can be helpful in understanding what parameters are needed to point your language at the right libraries.

Automating Subversion with Bindings

SWIG Advice

Slide

118Slide119

HL stands for High Level

Automating Subversion with Bindings

JavaHL

Slide

119Slide120

HL stands for High LevelUses the C API behind the scenes via

JNI

Automating Subversion with Bindings

JavaHL

Slide 120Slide121

HL stands for High Level

Uses the C API behind the scenes via

JNIInterface is not based on C APIAutomating Subversion with Bindings

JavaHL

Slide 121Slide122

HL stands for High Level

Uses the C API behind the scenes via

JNIInterface is not based on C APIHides details like APR PoolsAutomating Subversion with Bindings

JavaHL

Slide

122Slide123

HL stands for High Level

Uses the C API behind the scenes via

JNIInterface is not based on C APIHides details like APR PoolsInterface is more Java like than SWIG bindings are to their languagesAutomating Subversion with Bindings

JavaHL

Slide

123Slide124

HL stands for High Level

Uses the C API behind the scenes via JNI

Interface is not based on C APIHides details like APR PoolsInterface is more Java like than SWIG bindings are to their languagesDon’t need to canonicalize

Automating Subversion with Bindings

JavaHL

Slide

124Slide125

HL stands for High Level

Uses the C API behind the scenes via JNI

Interface is not based on C APIHides details like APR PoolsInterface is more Java like than SWIG bindings are to their languagesDon’t need to canonicalizeThrows SubversionException and

ClientException

Automating Subversion with Bindings

JavaHL

Slide

125Slide126

import

org.apache.subversion.javahl.SVNClient

;import org.apache.subversion.javahl.types.*;

import org.apache.subversion.javahl.ClientException;

public class cat {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

client.streamFileContent

(

args

[0], // target

Revision.HEAD

, // rev

Revision.HEAD

, // peg rev

System.out

); //output

}

}

Automating Subversion with Bindings

JavaHL

Example - Cat

Slide

126Slide127

import

org.apache.subversion.javahl.SVNClient

;import org.apache.subversion.javahl.types.*;

import org.apache.subversion.javahl.ClientException

;

public class cat {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

client.streamFileContent

(

args

[0], // target

Revision.HEAD

, // rev

Revision.HEAD

, // peg rev

System.out

); //output

}

}

Automating Subversion with Bindings

JavaHL

Example - Cat

Slide

127Slide128

import

org.apache.subversion.javahl.SVNClient

;

import org.apache.subversion.javahl.types

.*;

import

org.apache.subversion.javahl.ClientException

;

public class cat {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

client.streamFileContent

(

args

[0], // target

Revision.HEAD

, // rev

Revision.HEAD

, // peg rev

System.out

); //output

}

}

Automating Subversion with Bindings

JavaHL

Example - Cat

Slide

128Slide129

import

org.apache.subversion.javahl.SVNClient

;import org.apache.subversion.javahl.types

.*;

import org.apache.subversion.javahl.ClientException

;

public class cat {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

client.streamFileContent

(

args

[0], // target

Revision.HEAD

, // rev

Revision.HEAD

, // peg rev

System.out

); //output

}

}

Automating Subversion with Bindings

JavaHL

Example - Cat

Slide

129Slide130

import

org.apache.subversion.javahl.SVNClient

;import org.apache.subversion.javahl.types.*;

import org.apache.subversion.javahl.callback.*;

import org.apache.subversion.javahl.ClientException

;

import

java.util.ArrayList

;

import

java.util.HashSet

;

import

java.util.List

;

import

java.util.Set

;

import

java.util.Map

;

import

java.io.UnsupportedEncodingException

;

public class log {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

List<

RevisionRange

>

revRanges

= new

ArrayList

<

RevisionRange

>(1);

revRanges.add

(new

RevisionRange

(

Revision.HEAD

,

Revision.getInstance

(0)));

Set<String>

revProps

= new

HashSet

<String>(1);

revProps.add

("

svn:log

");

Automating Subversion with Bindings

JavaHL

Example – Log (1/2)

Slide

130Slide131

import

org.apache.subversion.javahl.SVNClient

;import org.apache.subversion.javahl.types

.*;

import org.apache.subversion.javahl.callback

.*;

import

org.apache.subversion.javahl.ClientException

;

import

java.util.ArrayList

;

import

java.util.HashSet

;

import

java.util.List

;

import

java.util.Set

;

import

java.util.Map

;

import

java.io.UnsupportedEncodingException

;

public class log {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

List<

RevisionRange

>

revRanges

= new

ArrayList

<

RevisionRange

>(1);

revRanges.add

(new

RevisionRange

(

Revision.HEAD

,

Revision.getInstance

(0)));

Set<String>

revProps

= new

HashSet

<String>(1);

revProps.add

("

svn:log

");

Automating Subversion with Bindings

JavaHL

Example – Log (1/2)

Slide

131Slide132

import

org.apache.subversion.javahl.SVNClient

;

import org.apache.subversion.javahl.types

.*;

import

org.apache.subversion.javahl.callback

.*;

import

org.apache.subversion.javahl.ClientException

;

import

java.util.ArrayList

;

import

java.util.HashSet

;

import

java.util.List

;

import

java.util.Set

;

import

java.util.Map

;

import

java.io.UnsupportedEncodingException

;

public class log {

public static void main(String[]

args

)

throws

ClientException

{

SVNClient

client = new

SVNClient

();

List<

RevisionRange

>

revRanges

= new

ArrayList

<

RevisionRange

>(1);

revRanges.add

(new

RevisionRange

(

Revision.HEAD

,

Revision.getInstance

(0)));

Set<String>

revProps

= new

HashSet

<String>(1);

revProps.add

("

svn:log

");

Automating Subversion with Bindings

JavaHL

Example – Log (1/2)

Slide

132Slide133

client.logMessages

(args[0], // target Revision.HEAD

, //peg rev

revRanges, // rev ranges

true, // stop on copy

true, // discover path

false, // include merged revisions

revProps

, //

revprops

to get

0, // limit (0 = unlimited)

new

LogMessageCallback

() {

public void

singleMessage

(Set<

ChangePath

>

changedPaths

,

long revision,

Map<

String,byte

[]>

revprops

,

boolean

hasChildren

)

{

byte[] message =

revprops.get

("

svn:log

");

System.out.println

("r" + revision);

if (message != null) {

try {

System.out.println

(new String(message, "UTF-8"));

} catch (

UnsupportedEncodingException

e) { /* ignore */ }

}

System.out.println

("\n");

}

});

}

}

Automating Subversion with Bindings

JavaHL

Example – Log (2/2)

Slide

133Slide134

client.logMessages

(args[0], // target

Revision.HEAD, //peg rev

revRanges, // rev ranges

true, // stop on copy

true, // discover path

false, // include merged revisions

revProps

, //

revprops

to get

0, // limit (0 = unlimited)

new

LogMessageCallback

() {

public void

singleMessage

(Set<

ChangePath

>

changedPaths

,

long revision,

Map<

String,byte

[]>

revprops

,

boolean

hasChildren

)

{

byte[] message =

revprops.get

("

svn:log

");

System.out.println

("r" + revision);

if (message != null) {

try {

System.out.println

(new String(message, "UTF-8"));

} catch (

UnsupportedEncodingException

e) { /* ignore */ }

}

System.out.println

("\n");

}

});

}

}

Automating Subversion with Bindings

JavaHL

Example – Log (2/2)

Slide

134Slide135

client.logMessages

(args[0], // target

Revision.HEAD

, //peg rev

revRanges

, // rev ranges

true, // stop on copy

true, // discover path

false, // include merged revisions

revProps

, //

revprops

to get

0, // limit (0 = unlimited)

new

LogMessageCallback

() {

public void

singleMessage

(Set<

ChangePath

>

changedPaths

,

long revision,

Map<

String,byte

[]>

revprops

,

boolean

hasChildren

)

{

byte[] message =

revprops.get

("

svn:log

");

System.out.println

("r" + revision);

if (message != null) {

try {

System.out.println

(new String(message, "UTF-8"));

} catch (

UnsupportedEncodingException

e) { /* ignore */ }

}

System.out.println

("\n");

}

});

}

}

Automating Subversion with Bindings

JavaHL

Example – Log (2/2)

Slide

135Slide136

ResourcesSlide137

http://svn.ms/autosvnexamples

http

://subversion.apache.org/mailing-lists.html (particularly users@subversion.apache.org)http://subversion.apache.org/docs/

(C API and JavaHL documentation)http://svnbook.red-bean.com

/ (Chapter 8)perldoc

SVN::Client (et al)

http://svn.apache.org/repos/asf/subversion/

trunk/

http://www.wandisco.com/subversion/

download

http://

alagazam.net/

http://pysvn.tigris.org

/

http://svnkit.com

/

Automating Subversion with Bindings

Getting Help/Resources

Slide

137Slide138

Found a Bug? Have a fix for a bug? Want to write documentation?

Participate at

dev@subversion.apache.org mailing list.Automating Subversion with Bindings

Contributing

Slide

138Slide139

Questions?