source: project/release/4/qwiki/trunk/qwiki-svn.scm @ 26108

Last change on this file since 26108 was 26108, checked in by sjamaan, 9 years ago

qwiki: Update copyright year on other files too

File size: 6.0 KB
Line 
1;;
2;; qwiki-svn - Subversion implementation of revisioning system for qwiki
3;;
4;; Copyright (c) 2009-2012 Peter Bex
5;;
6;;  Redistribution and use in source and binary forms, with or without
7;;  modification, are permitted provided that the following conditions
8;;  are met:
9;;
10;;  - Redistributions of source code must retain the above copyright
11;;  notice, this list of conditions and the following disclaimer.
12;;
13;;  - Redistributions in binary form must reproduce the above
14;;  copyright notice, this list of conditions and the following
15;;  disclaimer in the documentation and/or other materials provided
16;;  with the distribution.
17;;
18;;  - Neither name of the copyright holders nor the names of its
19;;  contributors may be used to endorse or promote products derived
20;;  from this software without specific prior written permission.
21;;
22;;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE
23;;  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24;;  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25;;  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26;;  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR THE
27;;  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28;;  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29;;  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30;;  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31;;  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32;;  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33;;  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34;;  POSSIBILITY OF SUCH DAMAGE.
35
36(provide 'qwiki-svn)
37
38(module qwiki-svn
39  (qwiki-repos-uri qwiki-repos-username qwiki-repos-password
40   get-history call-with-input-revision checkout-sources! update-sources!
41   store-changes! undo-changes! get-extended-property get-last-modified-revision)
42
43(import chicken scheme)
44(use data-structures regex posix files svn-client)
45
46;; The version control system's repos uri, username and password
47(define qwiki-repos-uri (make-parameter #f)) ; string, not uri-reference!
48(define qwiki-repos-username (make-parameter "anonymous"))
49(define qwiki-repos-password (make-parameter ""))
50
51;; Get the history for a given file starting at rev, going back in
52;; time.  If rev is #f, start at the latest revision.  If limit is not
53;; specified or #f, the full history is returned.  Otherwise, a
54;; maximum of that many items is returned.
55(define (get-history file rev #!optional limit)
56  (let ((history (reverse (svn-client-log
57                           file (if rev
58                                    (make-svn-opt-revision-number rev)
59                                    svn-opt-revision-head)
60                           (make-svn-opt-revision-number 0) (or limit 0) #f #f
61                           (qwiki-repos-username) (qwiki-repos-password)))))
62    (map (lambda (entry)
63           ;; What about the timezone?  Is it always GMT?  POSIX strptime
64           ;; doesn't know about this so we may need to use srfi-19...
65           (let* ((seconds-date (string-substitute "\\.[0-9]+.*" ""
66                                                   (svn-log-date entry)))
67                  (date (string->time (svn-log-date entry) "%Y-%m-%dT%H:%M")))
68             (list (svn-log-revision entry)
69                   (svn-log-author entry)
70                   date
71                   (svn-log-message entry))))
72         history)))
73
74(define (call-with-input-revision file rev proc)
75  (let ((filename (svn-client-cat
76                    file (make-svn-opt-revision-number rev)
77                    (qwiki-repos-username) (qwiki-repos-password))))
78    (unless filename (error "No such file" file))
79    (handle-exceptions exn
80      (begin
81        (delete-file* filename)
82        (signal exn))
83      (let ((result (call-with-input-file filename
84                      (lambda (f)
85                        (handle-exceptions exn
86                          (begin (close-input-port f) (signal exn))
87                          (proc f))))))
88        (delete-file* filename)
89        result))))
90
91(define (checkout-sources! source-path)
92  (svn-checkout (qwiki-repos-uri) source-path svn-opt-revision-head #t
93                (qwiki-repos-username) (qwiki-repos-password)))
94
95(define (update-sources! source-path)
96  (svn-update source-path svn-opt-revision-head #t
97              (qwiki-repos-username) (qwiki-repos-password)))
98
99(define (get-last-modified-revision path)
100  (and-let* ((i (get-info path)))
101    (svn-info-last-changed-rev i)))
102
103(define (get-info path)
104  (let ((info (svn-client-info path svn-opt-revision-unspecified
105                               svn-opt-revision-unspecified #f
106                               (qwiki-repos-username) (qwiki-repos-password))))
107    (and info (not (null? info)) (cadar info))))
108
109(define (store-changes! source-path message username password)
110  (or
111   (let* ((user (or username (qwiki-repos-username)))
112          (pass (or password (qwiki-repos-password))))
113     (let loop ((source-path source-path))
114       (if (get-info source-path)
115           (svn-commit source-path #t user pass message)
116           (begin
117             (loop (pathname-directory source-path)) ; Add parent dirs if needed
118             (svn-add source-path #t user pass)
119             (svn-commit source-path #t user pass message)))))
120   (error "Could not store changes")))
121
122(define (undo-changes! source-path)
123  (if (get-info source-path)            ; Existing file?
124      (svn-client-revert (list source-path) #t
125                         (qwiki-repos-username)
126                         (qwiki-repos-password))
127      (begin
128        (delete-file* source-path)
129        (let loop ((path (pathname-directory source-path)))
130          (unless (get-info path)
131            (begin
132              (delete-directory path)
133              (loop (pathname-directory path))))))))
134
135(define (get-extended-property path property)
136  (and-let* ((retval (svn-propget property path svn-opt-revision-unspecified #t
137                                  (qwiki-repos-username) (qwiki-repos-password)))
138             (props (alist-ref path retval string=?))
139             (prop (car props)))
140    prop))
141
142)
Note: See TracBrowser for help on using the repository browser.