Skip to content

Commit dc639cf

Browse files
author
Stanislav Kolotinskiy
committed
Update SVN warnings and compile using Go 1.13
1 parent f3ab566 commit dc639cf

12 files changed

+205
-141
lines changed

Dockerfile

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM debian:stretch
2+
3+
VOLUME /app
4+
5+
RUN apt-get update && apt-get -y install git wget curl cmake make gcc g++ liblz4-1 pkg-config liblz4-dev \
6+
libutf8proc2 libutf8proc-dev libserf-1-1 libserf-dev libsqlite3-dev zlib1g zlib1g-dev && \
7+
cd /usr/src && \
8+
wget https://www-eu.apache.org/dist/subversion/subversion-1.13.0.tar.bz2 -q -O subversion.tar.bz2 && \
9+
tar xjf subversion.tar.bz2 && cd subversion-1.13.0 && \
10+
./configure --without-berkeley-db && make -j4 && make install && ldconfig && \
11+
cd /usr/src && wget https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz -q -O go.tar.gz && \
12+
tar xzf go.tar.gz -C /usr/local && ln -sf /usr/local/go/bin/go /usr/local/bin/
13+
14+
WORKDIR /app
15+
CMD ["/bin/bash"]

Readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ Subversion bindings for go.
22

33
#Install
44

5-
It needs subversion >= 1.8
5+
It needs subversion >= 1.13.0
66

77
You will need libsvn-dev on Ubuntu/Debian or subversion installed with `brew` on OSX. apr-dev and apr-util-dev are also required.
88

9-
go get github.com/Assembla/svn2go
9+
go get -u github.com/Assembla/svn2go
1010

1111
See svn_test.go for usage.
1212

addons.c

+6-7
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
#include "_cgo_export.h"
77

88
svn_error_t *
9-
Go_svn_repos_get_logs4(svn_repos_t *repos,
9+
Go_svn_repos_get_logs5(svn_repos_t *repos,
1010
const apr_array_header_t *paths,
1111
svn_revnum_t start,
1212
svn_revnum_t end,
1313
int limit,
14-
svn_boolean_t discover_changed_paths,
1514
svn_boolean_t strict_node_history,
1615
svn_boolean_t include_merged_revisions,
1716
const apr_array_header_t *revprops,
@@ -20,31 +19,31 @@ Go_svn_repos_get_logs4(svn_repos_t *repos,
2019
svn_log_entry_receiver_t receiver,*/
2120
void *receiver_baton,
2221
apr_pool_t *pool) {
23-
return svn_repos_get_logs4(repos,
22+
return svn_repos_get_logs5(repos,
2423
paths,
2524
start,
2625
end,
2726
limit,
28-
discover_changed_paths,
2927
strict_node_history,
3028
include_merged_revisions,
3129
revprops,
3230
NULL,
3331
NULL,
34-
(svn_log_entry_receiver_t)&LogEntryReceiverCallback,
32+
NULL,
33+
NULL,
34+
(svn_repos_log_entry_receiver_t)&LogEntryReceiverCallback,
3535
receiver_baton,
3636
pool);
3737
}
3838

3939
svn_error_t *
40-
Go_repos_history(svn_fs_t *fs,
40+
Go_svn_repos_history2(svn_fs_t *fs,
4141
const char *path,
4242
void *history_baton,
4343
svn_revnum_t start,
4444
svn_revnum_t end,
4545
svn_boolean_t cross_copies,
4646
apr_pool_t *pool) {
47-
4847
return svn_repos_history2(fs,
4948
path,
5049
(svn_repos_history_func_t)&HistoryReceiverCallback,

callbacks.go

+22-21
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
package svn
22

33
/*
4-
#include <svn_types.h>
4+
#include <svn_repos.h>
55
#include <svn_compat.h>
6+
#include <svn_io.h>
7+
#include <svn_string.h>
68
*/
79
import "C"
810
import (
9-
"log"
1011
"unsafe"
1112
)
1213

13-
/* static svn_error_t *
14+
// LogEntryReceiverCallback implements svn_repos_get_logs5 callback:
15+
/*
16+
static svn_error_t *
1417
log_entry_receiver(void *baton,
15-
svn_log_entry_t *log_entry,
18+
svn_repos_log_entry_t *log_entry,
1619
apr_pool_t *pool)
1720
*/
1821
//export LogEntryReceiverCallback
1922
func LogEntryReceiverCallback(_obj, _entry, _pool unsafe.Pointer) unsafe.Pointer {
2023
baton := (*CommitCollector)(_obj)
21-
entry := (*C.svn_log_entry_t)(_entry)
24+
entry := (*C.svn_repos_log_entry_t)(_entry)
2225

2326
var author, date, msg *C.char
2427
C.svn_compat_log_revprops_out(&author, &date, &msg, entry.revprops)
@@ -27,33 +30,31 @@ func LogEntryReceiverCallback(_obj, _entry, _pool unsafe.Pointer) unsafe.Pointer
2730
return nil
2831
}
2932

33+
// HistoryReceiverCallback implements svn_repos_get_history2 callback
34+
/* static svn_error_t *
35+
svn_repos_history_func_t(void *baton,
36+
const char *path,
37+
svn_revnum_t *log_entry,
38+
apr_pool_t *pool)
39+
*/
3040
//export HistoryReceiverCallback
3141
func HistoryReceiverCallback(_obj unsafe.Pointer, path *C.char, revision C.svn_revnum_t, _pool unsafe.Pointer) *C.svn_error_t {
3242
baton := (*CommitCollector)(_obj)
3343

34-
if commit, err := baton.r.CommitInfo(int64(revision)); err != nil {
35-
log.Println(err)
36-
return nil // ignore
37-
} else {
38-
baton.commits = append(baton.commits, *commit)
39-
40-
if len(baton.commits) >= baton.limit {
41-
return C.svn_error_create(C.SVN_ERR_CEASE_INVOCATION, nil, nil)
42-
}
44+
baton.revisions = append(baton.revisions, int64(revision))
45+
if len(baton.revisions) >= baton.limit {
46+
return C.svn_error_create(C.SVN_ERR_CEASE_INVOCATION, nil, nil)
4347
}
4448

4549
return nil
4650
}
4751

52+
// StreamWrite implements svn_stream_write callback
4853
//export StreamWrite
4954
func StreamWrite(_obj unsafe.Pointer, data *C.char, len *C.apr_size_t) *C.svn_error_t {
50-
out := (*stringBuffer)(_obj)
51-
52-
_, err := out.Write([]byte(C.GoString(data)))
55+
out := (*C.svn_stringbuf_t)(_obj)
5356

54-
if err != nil {
55-
log.Println(err)
56-
}
57+
C.svn_stringbuf_appendbytes(out, data, *len)
5758

58-
return nil
59+
return nil;
5960
}

changeset.go

+31-26
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ import (
2727
"unsafe"
2828
)
2929

30+
// ChangesetInfo is used to keep commit info
3031
type ChangesetInfo struct {
3132
Commit *Commit
3233
ChangedPaths map[string]*ChangedEntry
3334
}
3435

35-
// Returns changeset details: author, date, log, change files, dirs, diff of files and properties
36+
// Changeset returns changeset details: author, date, log, change files, dirs, diff of files and properties
3637
func (r *Repo) Changeset(rev int64, diffIgnoreSpace bool) (*ChangesetInfo, error) {
3738
if rev == 0 {
3839
return nil, fmt.Errorf("Invalid revision: %d", rev)
@@ -59,15 +60,13 @@ func (r *Repo) Changeset(rev int64, diffIgnoreSpace bool) (*ChangesetInfo, error
5960

6061
if e := C.svn_fs_revision_root(&c.baseRoot, r.fs, C.svn_revnum_t(rev)-1, pool); e != nil {
6162
return nil, makeError(e)
62-
} else {
63-
defer C.svn_fs_close_root(c.baseRoot)
6463
}
64+
defer C.svn_fs_close_root(c.baseRoot)
6565

6666
if e := C.svn_fs_revision_root(&c.root, r.fs, C.svn_revnum_t(rev), pool); e != nil {
6767
return nil, makeError(e)
68-
} else {
69-
defer C.svn_fs_close_root(c.root)
7068
}
69+
defer C.svn_fs_close_root(c.root)
7170

7271
// TODO improvement: rewrite editor #open_file #open_directory to limit entries count that we will process.
7372
// We had cases with crazy repos with 16k modifications
@@ -94,6 +93,7 @@ func (r *Repo) Changeset(rev int64, diffIgnoreSpace bool) (*ChangesetInfo, error
9493
return rez, nil
9594
}
9695

96+
// ChangedEntry is used for storing a changed entry
9797
type ChangedEntry struct {
9898
Kind int // svn node kind
9999
Action string // file operation A- added,R-changed,D-deleted
@@ -109,11 +109,6 @@ type collector struct {
109109
diffIgnoreSpace bool
110110
}
111111

112-
// Used to collect file diff
113-
type stringBuffer struct {
114-
buf *string
115-
}
116-
117112
// Collect changed paths
118113
// similar with print_changed_tree() from svnlook.c
119114
func (c *collector) collectChangedPaths(node *C.svn_repos_node_t, path string) error {
@@ -173,12 +168,14 @@ func (c *collector) collectChangedPaths(node *C.svn_repos_node_t, path string) e
173168
}
174169
}
175170

176-
stream := &stringBuffer{&entry.Diff} // Create string Writer
171+
var buf *C.svn_stringbuf_t
172+
cdiff := C.CString(entry.Diff)
173+
buf = C.svn_stringbuf_create(cdiff, c.r.pool)
177174

178175
if binaryA || binaryB {
179176
entry.IsBinary = true
180177
header += "(Binary files differ)\n\n"
181-
stream.Write([]byte(header))
178+
C.svn_stringbuf_appendcstr(buf, C.CString(header))
182179
} else {
183180
// TODO check file size and do not dump files bigger than 10Mb for example
184181
rootA = c.baseRoot
@@ -223,7 +220,7 @@ func (c *collector) collectChangedPaths(node *C.svn_repos_node_t, path string) e
223220
}
224221

225222
if C.svn_diff_contains_diffs(diff) == C.TRUE {
226-
stream.Write([]byte(header))
223+
C.svn_stringbuf_appendcstr(buf, C.CString(header))
227224

228225
//log.Println("Has diff")
229226
if rootA != nil {
@@ -239,16 +236,29 @@ func (c *collector) collectChangedPaths(node *C.svn_repos_node_t, path string) e
239236
defer C.free(unsafe.Pointer(clabelA))
240237
defer C.free(unsafe.Pointer(clabelB))
241238

242-
cstream := C.CreateWriterStream(unsafe.Pointer(stream), c.r.pool)
243-
244-
if err := C.svn_diff_file_output_unified3(cstream, diff,
245-
cf1Path, cf2Path,
246-
clabelA, clabelB,
247-
C.defaultEncoding(), nil, C.FALSE, c.r.pool); err != nil {
239+
cstream := C.CreateWriterStream(unsafe.Pointer(buf), c.r.pool)
240+
241+
if err := C.svn_diff_file_output_unified4(
242+
cstream,
243+
diff,
244+
cf1Path,
245+
cf2Path,
246+
clabelA,
247+
clabelB,
248+
C.defaultEncoding(),
249+
nil,
250+
C.FALSE,
251+
-1,
252+
nil,
253+
nil,
254+
c.r.pool,
255+
); err != nil {
248256
return makeError(err)
249257
}
250258
}
251259
} // end binary check
260+
261+
entry.Diff = C.GoStringN(buf.data, (C.int)(buf.len))
252262
} // end file diff
253263

254264
if node.prop_mod == C.TRUE {
@@ -303,22 +313,17 @@ func (c *collector) dumpFile(fsRoot *C.svn_fs_root_t, path string) (string, erro
303313
_, err = io.Copy(tmp, svnStream)
304314

305315
if err != nil {
306-
return "", fmt.Errorf("Can not dump %s:", path, err)
316+
return "", fmt.Errorf("Can not dump %s: %s", path, err.Error())
307317
}
308318
}
309319

310320
if err = tmp.Close(); err != nil {
311-
return "", fmt.Errorf("Can not close temp file %s:", tmp.Name(), err)
321+
return "", fmt.Errorf("Can not close temp file %s: %s", tmp.Name(), err.Error())
312322
}
313323

314324
return tmp.Name(), nil
315325
}
316326

317-
func (s *stringBuffer) Write(p []byte) (int, error) {
318-
*s.buf += string(p)
319-
return len(p), nil
320-
}
321-
322327
func (c *collector) isBinary(fsRoot *C.svn_fs_root_t, path *C.char) (bool, error) {
323328
var mimetype *C.svn_string_t
324329

errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
)
99

10+
// Error is used for wrapping SVN errors
1011
type Error struct {
1112
err *C.svn_error_t
1213
}

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/assembla/svn2go
2+
3+
go 1.13

stream.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ import (
1313
"unsafe"
1414
)
1515

16+
// Stream is used for wrapping SVN stream
1617
// TODO svn stream supports seek, maybe we can use it
17-
type SvnStream struct {
18+
type Stream struct {
1819
io *C.svn_stream_t
1920
pool *C.apr_pool_t
2021
}
2122

2223
// Read bytes from svn stream
23-
func (s *SvnStream) Read(dest []byte) (n int, err error) {
24+
func (s *Stream) Read(dest []byte) (n int, err error) {
2425
c := C.apr_size_t(len(dest))
2526

26-
if err := C.svn_stream_read(s.io, (*C.char)(unsafe.Pointer(&dest[0])), &c); err != nil {
27+
if err := C.svn_stream_read_full(s.io, (*C.char)(unsafe.Pointer(&dest[0])), &c); err != nil {
2728
return int(c), makeError(err)
2829
}
2930

@@ -33,8 +34,8 @@ func (s *SvnStream) Read(dest []byte) (n int, err error) {
3334
return int(c), nil
3435
}
3536

36-
// Closes svn stream
37-
func (s *SvnStream) Close() error {
37+
// Close closes stream
38+
func (s *Stream) Close() error {
3839
runtime.SetFinalizer(s, nil)
3940
C.svn_pool_destroy(s.pool)
4041
return nil

0 commit comments

Comments
 (0)