source: trunk/lib/SVN.h @ 1218

Last change on this file since 1218 was 1218, checked in by Peter Johansson, 11 years ago

refs #371. Remove variable binary_ in SVNblame, which was not
used. SVNblame will now fail if ued on binary file (but we don't call
blame on binary files). The SVN class now takes care of svn errors and
translate them into exceptions via the cleanup function.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.6 KB
Line 
1#ifndef _theplu_svndigest_svn_
2#define _theplu_svndigest_svn_
3
4// $Id: SVN.h 1218 2010-10-10 02:27:39Z peter $
5
6/*
7  Copyright (C) 2006 Jari Häkkinen
8  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
9  Copyright (C) 2009 Peter Johansson
10
11  This file is part of svndigest, http://dev.thep.lu.se/svndigest
12
13  svndigest is free software; you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation; either version 3 of the License, or
16  (at your option) any later version.
17
18  svndigest is distributed in the hope that it will be useful, but
19  WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  General Public License for more details.
22
23  You should have received a copy of the GNU General Public License
24  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
25*/
26
27// Turning off warnings from using deprecated function, i.e., we are
28// using subversion 1.4
29#ifndef SVN_DEPRECATED
30#define SVN_DEPRECATED
31#endif
32
33
34#include <map>
35#include <stdexcept>
36#include <string>
37#include <vector>
38
39#include <subversion-1/svn_client.h>
40#include <subversion-1/svn_types.h>
41
42namespace theplu {
43namespace svndigest {
44
45  struct log_receiver_baton;
46
47  ///
48  /// If something goes wrong in the use of the different SVN classes,
49  /// an SVNException is thrown.
50  ///
51  struct SVNException : public std::runtime_error
52  { 
53    SVNException(const std::string& msg, svn_error_t* error=NULL);
54
55    virtual ~SVNException(void) throw();
56    /**
57       override base implementation
58     */
59    const char* what(void) const throw();
60
61    /**
62       access svn_error_t
63     */
64    const svn_error_t* error(void) const;
65  private:
66    svn_error_t* error_;
67    std::string msg_;
68  };
69
70  /**
71     \brief The SVN class is a front end to the subversion API.
72
73     SVN provides one single global access point to the underlying
74     subversion API and makes sure that there is only one point of
75     access for the binary.
76
77     The singleton SVN object should be initialized with
78     SVN::instancs(const std::string& path), rather than
79     SVN::instance(void), before using any other subversion related
80     classes or calls. Best practice is to initilize the singleton
81     object early in the main program. The logic behind this
82     requirement is that all subverison related classes and calls
83     expect that repository and WC access is properly set up at
84     initialization. However, most functionality is available
85     irrespectively which instance call is made.
86
87     \see Design Patterns (the singleton pattern). Subversion API
88     documents, SVN::instancs(void), SVN::instancs(const
89     std::string&).
90  */
91  class SVN {
92  public:
93
94    enum vc_status {
95      unversioned=0,
96      uptodate,
97      unresolved
98    };
99
100    /**
101       \brief Call the underlying svn_client_blame3 for \a path with
102       \a receiver and \a baton.
103
104       This function is called from SVNblame to do 'svn blame' on an
105       item. The \a receiver and \a baton is defined in SVNblame and
106       the \a receiver is called by the underlying subversion API for
107       every line in \a path provided it the item is under subversion
108       control. The \a baton is used to communicate anonymous
109       information through the API to the \a receiver. If \a path is a
110       binary object an error is returned, all other errors will
111       generate an SVNException.
112
113       \a path can be either a URL or an WC target.
114    */
115    void client_blame(const std::string& path,
116                      svn_client_blame_receiver_t receiver,
117                      void *baton);
118
119    /**
120       \brief Same as function above with the extension that revision
121       \a rev can be set.
122     */
123    void client_blame(const std::string& path,
124                      svn_client_blame_receiver_t receiver,
125                      void *baton, svn_revnum_t rev);
126
127    /**
128       \brief Call the underlying svn_client_info for \a path with \a
129       receiver and \a baton.
130
131       This function is called from SVNinfo to do 'svn info' on an
132       item. The \a receiver and \a baton is defined in SVNinfo and
133       the \a receiver is called by the underlying subversion API if
134       \a path is under subversion control. The \a baton is used to
135       communicate anonymous information through the API to the \a
136       receiver.
137
138       \a path can be either a URL or an WC target.
139
140       \see Subversion API documentation, SVNinfo
141    */
142    void client_info(const std::string& path, svn_info_receiver_t receiver,
143                     void *baton);
144
145    /**
146       \a path can be either a URL or an WC target.
147
148       \todo doc
149    */
150    void client_log(const std::string& path, svn_log_message_receiver_t receiver,
151                    void *baton);
152
153    /**
154       \brief Get the subversion properties for \a path.
155
156       The retrieved properties are stored in \a properties. To check
157       whether \a is a binary item use SVNproperty::binary(void).
158
159       \a path can be either a URL or an WC target.
160    */
161    void client_proplist(const std::string& path,
162                         std::map<std::string, std::string>& properties);
163
164    /**
165       \brief Get an instance of SVN.
166
167       The singleton SVN object should be initialized with
168       SVN::instancs(const std::string&) before usage of this
169       function. Best practice is to initilize the singleton object
170       early in the main program. The logic behind this requirement is
171       that subverison related classes and calls may expect that
172       repository and WC access is properly set up at initialization.
173
174       \throw An SVNException if the singleton SVN onject is not
175       already initilized.
176
177       \see SVN::instancs(const std::string&)
178    */
179    static SVN* instance(void);
180
181    /**
182       \brief Get an instance of SVN setup against repository pointed
183       to by \a path.
184
185       The singleton SVN object should be initialized with this
186       instance call before any subversion related classes or calls
187       are made. Best practice is to initilize the singleton object
188       early in the main program. The logic behind this requirement is
189       that subverison related classes and calls may expect that
190       repository and WC access is properly set up at initialization.
191
192       \throw Throws an SVNException if initialization fails in the
193       underlying subversion API calls, or if \a path is a URL.
194    */
195    static SVN* instance(const std::string& path);
196
197    /**
198       \brief Set up a repository access session.
199
200       \throws SVNException if session setup fails, or if a session is
201       already set up (i.e., repository cannot be changed during
202       program lifetime).
203    */
204    //    void setup_ra_session(const std::string& path);
205
206    ///
207    /// @brief Check if entry \a path is under version control
208    ///
209    /// @return True if \a path is under version control, false
210    /// otherwise.
211    ///
212    vc_status version_controlled(const std::string& path);
213
214  private:
215    /**
216       \brief Constructor
217
218       The only way to create an object of SVN type is by calling
219       SVN::instance(const std::string&). \a path must be a WC path,
220       i.e., not a URL.
221    */
222    SVN(const std::string& path);
223
224    ///
225    /// @brief Copy Constructor, not implemented.
226    ///
227    SVN(const SVN&);
228    SVN& operator=(const SVN&);
229
230    ///
231    /// @brief The destructor.
232    ///
233    virtual ~SVN(void);
234
235    /**
236       @brief Free resources when svn API calls fail.
237
238       This function will free \a pool resources and throw an
239       exception holding the \a message. If mute is false, the thrown
240       exception also contains \a err.
241
242       \throw cleanup will throw a SVNException
243
244       @see SVNException
245    */
246    void cleanup(svn_error_t *err, apr_pool_t *pool,
247                 std::string message=std::string(), bool mute=false);
248
249    /**
250       @brief Free resources when failing to reach end of
251       constructor.
252
253       cleanup_failed_init will free all resource acquired in the
254       constructor and throw an SVNException with \a message as the
255       message.
256
257       @see SVNException
258    */
259    void cleanup_failed_init(svn_error_t *err, const std::string& message);
260
261    static SVN* instance_;
262
263    // Subversion API stuff
264
265    /**
266       the url is fech with svn info. The ursl is stored in a
267       url_receiver_baton. The struct is filled in the url_receiver
268       function.
269    */
270    struct root_url_receiver_baton {
271      std::string path;
272    };
273
274    /**
275       url_receiver is the function passed to the underlying
276       subversion API call svn_client_info. This function is called by
277       the subversion API for every item matched by the conditions of
278       the API call.
279
280       \see Subversion API documentation
281    */
282    static svn_error_t*
283    root_url_receiver(void *baton, const char *path, 
284                      const svn_info_t *info, apr_pool_t *pool);
285
286    void client_blame_call(const std::string& path,
287                           svn_client_blame_receiver_t receiver,
288                           void *baton, svn_opt_revision_t& head);
289
290    svn_wc_adm_access_t* adm_access_;
291    apr_allocator_t* allocator_;
292    svn_client_ctx_t* context_;
293    apr_pool_t* pool_;
294    svn_ra_session_t* ra_session_;
295  };
296
297}} // end of namespace svndigest and namespace theplu
298
299#endif
Note: See TracBrowser for help on using the repository browser.