source: trunk/lib/SVN.h

Last change on this file was 1547, checked in by Peter Johansson, 9 years ago

refs #518. Implement SVNcat using 'svn_ra_get_file' which does not expand svn:keywords.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.3 KB
Line 
1#ifndef _theplu_svndigest_svn_
2#define _theplu_svndigest_svn_
3
4// $Id: SVN.h 1547 2012-10-20 08:31:38Z peter $
5
6/*
7  Copyright (C) 2006 Jari Häkkinen
8  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
9  Copyright (C) 2009, 2010, 2012 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    /**
56       Copy constructor
57     */
58    SVNException(const SVNException& other);
59
60    /**
61       Destructor
62     */
63    virtual ~SVNException(void) throw();
64
65    /**
66       override base implementation
67     */
68    const char* what(void) const throw();
69
70    /**
71       access svn_error_t
72     */
73    const svn_error_t* error(void) const;
74  private:
75    svn_error_t* error_;
76    std::string msg_;
77    int* ref_count_;
78
79    // assignment not allowed
80    SVNException& operator=(const SVNException&);
81  };
82
83  /**
84     \brief The SVN class is a front end to the subversion API.
85
86     SVN provides one single global access point to the underlying
87     subversion API and makes sure that there is only one point of
88     access for the binary.
89
90     The singleton SVN object should be initialized with
91     SVN::instancs(const std::string& path), rather than
92     SVN::instance(void), before using any other subversion related
93     classes or calls. Best practice is to initilize the singleton
94     object early in the main program. The logic behind this
95     requirement is that all subverison related classes and calls
96     expect that repository and WC access is properly set up at
97     initialization. However, most functionality is available
98     irrespectively which instance call is made.
99
100     \see Design Patterns (the singleton pattern). Subversion API
101     documents, SVN::instancs(void), SVN::instancs(const
102     std::string&).
103  */
104  class SVN {
105  public:
106
107    enum vc_status {
108      unversioned=0,
109      uptodate,
110      unresolved
111    };
112
113    /**
114       \brief Call the underlying svn_client_blame3 for \a path with
115       \a receiver and \a baton.
116
117       This function is called from SVNblame to do 'svn blame' on an
118       item. The \a receiver and \a baton is defined in SVNblame and
119       the \a receiver is called by the underlying subversion API for
120       every line in \a path provided it the item is under subversion
121       control. The \a baton is used to communicate anonymous
122       information through the API to the \a receiver. If \a path is a
123       binary object an error is returned, all other errors will
124       generate an SVNException.
125
126       \a path can be either a URL or an WC target.
127    */
128    void client_blame(const std::string& path,
129                      svn_client_blame_receiver_t receiver,
130                      void *baton);
131
132    /**
133       \brief Same as function above with the extension that revision
134       \a rev can be set.
135     */
136    void client_blame(const std::string& path,
137                      svn_client_blame_receiver_t receiver,
138                      void *baton, svn_revnum_t rev);
139
140    /**
141       \brief access the content of file \a path at revision \a rev
142
143       Content of file \a path at revision \a rev is copied to \a
144       result. svn:keywords are expanded just as in 'svn cat'.
145
146       \see svn_client_call2(6)
147    */
148    void client_cat(const std::string& path, svn_revnum_t rev,
149                    std::string& result);
150
151
152
153    /**
154       \brief Call the underlying svn_client_info for \a path with \a
155       receiver and \a baton.
156
157       This function is called from SVNinfo to do 'svn info' on an
158       item. The \a receiver and \a baton is defined in SVNinfo and
159       the \a receiver is called by the underlying subversion API if
160       \a path is under subversion control. The \a baton is used to
161       communicate anonymous information through the API to the \a
162       receiver.
163
164       \a path can be either a URL or an WC target.
165
166       \see Subversion API documentation, SVNinfo
167    */
168    void client_info(const std::string& path, svn_info_receiver_t receiver,
169                     void *baton);
170
171    /**
172       \a path can be either a URL or an WC target.
173
174       \todo doc
175    */
176    void client_log(const std::string& path, svn_log_message_receiver_t receiver,
177                    void *baton);
178
179    /**
180       \brief Get the subversion properties for \a path.
181
182       The retrieved properties are stored in \a properties. To check
183       whether \a is a binary item use SVNproperty::binary(void).
184
185       \a path can be either a URL or an WC target.
186    */
187    void client_proplist(const std::string& path,
188                         std::map<std::string, std::string>& properties);
189
190    /**
191       \brief Get an instance of SVN.
192
193       The singleton SVN object should be initialized with
194       SVN::instancs(const std::string&) before usage of this
195       function. Best practice is to initilize the singleton object
196       early in the main program. The logic behind this requirement is
197       that subverison related classes and calls may expect that
198       repository and WC access is properly set up at initialization.
199
200       \throw An SVNException if the singleton SVN onject is not
201       already initilized.
202
203       \see SVN::instancs(const std::string&)
204    */
205    static SVN* instance(void);
206
207    /**
208       \brief Get an instance of SVN setup against repository pointed
209       to by \a path.
210
211       The singleton SVN object should be initialized with this
212       instance call before any subversion related classes or calls
213       are made. Best practice is to initilize the singleton object
214       early in the main program. The logic behind this requirement is
215       that subverison related classes and calls may expect that
216       repository and WC access is properly set up at initialization.
217
218       \throw Throws an SVNException if initialization fails in the
219       underlying subversion API calls, or if \a path is a URL.
220    */
221    static SVN* instance(const std::string& path);
222
223    /**
224       \brief Set up a repository access session.
225
226       \throws SVNException if session setup fails, or if a session is
227       already set up (i.e., repository cannot be changed during
228       program lifetime).
229    */
230    //    void setup_ra_session(const std::string& path);
231
232    ///
233    /// @brief Check if entry \a path is under version control
234    ///
235    /// @return True if \a path is under version control, false
236    /// otherwise.
237    ///
238    vc_status version_controlled(const std::string& path);
239
240  private:
241    /**
242       \brief Constructor
243
244       The only way to create an object of SVN type is by calling
245       SVN::instance(const std::string&). \a path must be a WC path,
246       i.e., not a URL.
247    */
248    SVN(const std::string& path);
249
250    ///
251    /// @brief Copy Constructor, not implemented.
252    ///
253    SVN(const SVN&);
254    SVN& operator=(const SVN&);
255
256    ///
257    /// @brief The destructor.
258    ///
259    virtual ~SVN(void);
260
261    /**
262       @brief Free resources when failing to reach end of
263       constructor.
264
265       cleanup_failed_init will free all resource acquired in the
266       constructor and throw an SVNException with \a message as the
267       message.
268
269       @see SVNException
270    */
271    void cleanup_failed_init(svn_error_t *err, const std::string& message);
272
273    static SVN* instance_;
274
275    // Subversion API stuff
276
277    /**
278       the url is fech with svn info. The url is stored in a
279       url_receiver_baton. The struct is filled in the url_receiver
280       function.
281    */
282    struct url_receiver_baton {
283      std::string root_url;
284      std::string url;
285    };
286
287    /**
288       url_receiver is the function passed to the underlying
289       subversion API call svn_client_info. This function is called by
290       the subversion API for every item matched by the conditions of
291       the API call.
292
293       \see Subversion API documentation
294    */
295    static svn_error_t*
296    url_receiver(void *baton, const char *path,
297                 const svn_info_t *info, apr_pool_t *pool);
298
299    void client_blame_call(const std::string& path,
300                           svn_client_blame_receiver_t receiver,
301                           void *baton, svn_opt_revision_t& head);
302
303    svn_wc_adm_access_t* adm_access_;
304    apr_allocator_t* allocator_;
305    svn_client_ctx_t* context_;
306    apr_pool_t* pool_;
307    svn_ra_session_t* ra_session_;
308    std::string abs_wc_root_path_;
309    std::string relative_url_;
310
311    /**
312       Private class holding an apr_pool_t* and that takes care of
313       deallocation (in destructor) which decreases risk for memory
314       leaks especially in case of errors and when exceptions are
315       thrown.
316     */
317    class AprPool
318    {
319    public:
320      /**
321         create a sub-pool of \a pool
322      */
323      AprPool(apr_pool_t* pool);
324
325      /**
326         \brief destructor deallocates apr pool
327       */
328      ~AprPool(void);
329
330      /**
331         Access apr pool
332       */
333      apr_pool_t* get(void);
334    private:
335      apr_pool_t* pool_;
336    };
337
338  };
339
340}} // end of namespace svndigest and namespace theplu
341
342#endif
Note: See TracBrowser for help on using the repository browser.