svn_wc_tree 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +4 -0
- data/LICENSE +165 -0
- data/Manifest +57 -0
- data/README.rdoc +333 -0
- data/bin/svn_wc_tree +190 -0
- data/cgi/svn_wc_broker.cgi +38 -0
- data/lib/svn_wc_broker.rb +161 -0
- data/lib/svn_wc_client.rb +266 -0
- data/svn_conf.yaml +9 -0
- data/svn_wc_tree/css/swt.css +4 -0
- data/svn_wc_tree/img/swt_spinner.gif +0 -0
- data/svn_wc_tree/index.html +137 -0
- data/svn_wc_tree/index.php +29 -0
- data/svn_wc_tree/js/jquery-1.3.2.js +4376 -0
- data/svn_wc_tree/js/jquery.blockUI-2.31.js +477 -0
- data/svn_wc_tree/js/jquery.cookie.js +96 -0
- data/svn_wc_tree/js/jquery.tree.checkbox.js +75 -0
- data/svn_wc_tree/js/jquery.tree.js +2058 -0
- data/svn_wc_tree/js/source/jquery.tree.js +2058 -0
- data/svn_wc_tree/js/source/jquery.tree.min.js +1 -0
- data/svn_wc_tree/js/source/lib/jquery.cookie.js +96 -0
- data/svn_wc_tree/js/source/lib/jquery.hotkeys.js +244 -0
- data/svn_wc_tree/js/source/lib/jquery.js +19 -0
- data/svn_wc_tree/js/source/lib/jquery.metadata.js +122 -0
- data/svn_wc_tree/js/source/lib/sarissa.js +110 -0
- data/svn_wc_tree/js/source/plugins/_jquery.tree.rtl.js +32 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.checkbox.js +75 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.contextmenu.js +129 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.cookie.js +70 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.hotkeys.js +78 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.metadata.js +17 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.themeroller.js +33 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.xml_flat.js +123 -0
- data/svn_wc_tree/js/source/plugins/jquery.tree.xml_nested.js +124 -0
- data/svn_wc_tree/js/source/themes/apple/bg.jpg +0 -0
- data/svn_wc_tree/js/source/themes/apple/dot_for_ie.gif +0 -0
- data/svn_wc_tree/js/source/themes/apple/icons.png +0 -0
- data/svn_wc_tree/js/source/themes/apple/style.css +34 -0
- data/svn_wc_tree/js/source/themes/apple/throbber.gif +0 -0
- data/svn_wc_tree/js/source/themes/checkbox/dot_for_ie.gif +0 -0
- data/svn_wc_tree/js/source/themes/checkbox/icons.png +0 -0
- data/svn_wc_tree/js/source/themes/checkbox/style.css +38 -0
- data/svn_wc_tree/js/source/themes/checkbox/throbber.gif +0 -0
- data/svn_wc_tree/js/source/themes/classic/dot_for_ie.gif +0 -0
- data/svn_wc_tree/js/source/themes/classic/icons.png +0 -0
- data/svn_wc_tree/js/source/themes/classic/style.css +31 -0
- data/svn_wc_tree/js/source/themes/classic/throbber.gif +0 -0
- data/svn_wc_tree/js/source/themes/default/dot_for_ie.gif +0 -0
- data/svn_wc_tree/js/source/themes/default/icons.png +0 -0
- data/svn_wc_tree/js/source/themes/default/style.css +30 -0
- data/svn_wc_tree/js/source/themes/default/throbber.gif +0 -0
- data/svn_wc_tree/js/source/themes/themeroller/dot_for_ie.gif +0 -0
- data/svn_wc_tree/js/source/themes/themeroller/icons.png +0 -0
- data/svn_wc_tree/js/source/themes/themeroller/style.css +39 -0
- data/svn_wc_tree/js/source/themes/themeroller/throbber.gif +0 -0
- data/svn_wc_tree/js/swt.js +534 -0
- data/svn_wc_tree.conf +9 -0
- metadata +122 -0
data/bin/svn_wc_tree
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
#
|
5
|
+
# svn_wc_tree: install the svn_wc_tree web application.
|
6
|
+
#
|
7
|
+
# == Usage
|
8
|
+
#
|
9
|
+
# svn_wc_tree [OPTIONS]
|
10
|
+
#
|
11
|
+
# --help, -h:
|
12
|
+
# show help
|
13
|
+
#
|
14
|
+
# --html, -l [html_dir]:
|
15
|
+
# Move all web files to the directory path specified.
|
16
|
+
# A directory called svn_wc_tree will be created at this path.
|
17
|
+
#
|
18
|
+
# --cgi, -c [cgi_dir]:
|
19
|
+
# Move the included CGI script to the path specified.
|
20
|
+
# path/directory must exist and must be able to execute CGI scripts
|
21
|
+
#
|
22
|
+
# --post_to_url, -u [post_to_url]:
|
23
|
+
# a URL that will receive AJAX requests and return the required JSON.
|
24
|
+
# (see the CGI script provided)
|
25
|
+
#
|
26
|
+
# --php, -p [php]:
|
27
|
+
# Run as a PHP application. (use only as last choice)
|
28
|
+
# (Ruby is still required; CGI not needed)
|
29
|
+
#
|
30
|
+
# --conf_location, -u [conf_location]:
|
31
|
+
# location (filesystem path) of your svn_wc.conf file (readable by 'httpd
|
32
|
+
# runs as' owner)
|
33
|
+
#
|
34
|
+
# --move_conf_from, -f [move_conf_from]:
|
35
|
+
# move your conf file (svn_wc_tree.conf) from filesystem path to
|
36
|
+
# (move_conf_to)
|
37
|
+
#
|
38
|
+
# --move_conf_to, -t [move_conf_to]:
|
39
|
+
# move your conf file (svn_wc_tree.conf) to filesystem path from
|
40
|
+
# (move_conf_from)
|
41
|
+
#
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
# svn_wc_tree --html /var/htdocs --cgi /var/cgi-bin \
|
45
|
+
# --post_to_url 'http://example.com/cgi-bin/ \
|
46
|
+
# --conf_location /opt/conf/svn_conf.yaml
|
47
|
+
#
|
48
|
+
# sudo svn_wc_tree --html /var/htdocs --post_to_url 'cgi-bin/cgi.rb'
|
49
|
+
#
|
50
|
+
# sudo svn_wc_tree --html /var/htdocs --php true \
|
51
|
+
# --conf_location /opt/svn_wc_tree/svn_conf.yaml
|
52
|
+
#
|
53
|
+
# sudo svn_wc_tree --html /var/www --cgi /usr/lib/cgi-bin \
|
54
|
+
# --post_to_url 'http://localhost/cgi-bin/' --move_conf_from \
|
55
|
+
# /tmp/svn_conf.yaml --move_conf_to /usr/local/svn_wc_tree
|
56
|
+
|
57
|
+
|
58
|
+
require 'getoptlong'
|
59
|
+
require 'rdoc/usage'
|
60
|
+
require 'fileutils'
|
61
|
+
|
62
|
+
opts = GetoptLong.new(
|
63
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT],
|
64
|
+
[ '--html', '-l', GetoptLong::REQUIRED_ARGUMENT],
|
65
|
+
[ '--post_to_url', '-u', GetoptLong::OPTIONAL_ARGUMENT],
|
66
|
+
[ '--cgi', '-c', GetoptLong::OPTIONAL_ARGUMENT],
|
67
|
+
[ '--php', '-p', GetoptLong::OPTIONAL_ARGUMENT],
|
68
|
+
[ '--conf_location', '-o', GetoptLong::OPTIONAL_ARGUMENT],
|
69
|
+
[ '--move_conf_from', '-f', GetoptLong::OPTIONAL_ARGUMENT],
|
70
|
+
[ '--move_conf_to' , '-t', GetoptLong::OPTIONAL_ARGUMENT]
|
71
|
+
)
|
72
|
+
|
73
|
+
html_dir = nil
|
74
|
+
cgi_dir = nil
|
75
|
+
php = nil
|
76
|
+
post_to_url = 'index.php' # assume php mode
|
77
|
+
conf_location = nil
|
78
|
+
move_conf_from = nil
|
79
|
+
move_conf_to = nil
|
80
|
+
|
81
|
+
opts.each do |opt, arg|
|
82
|
+
case opt
|
83
|
+
when '--help'
|
84
|
+
RDoc::usage
|
85
|
+
when '--html'
|
86
|
+
if arg == '' then raise ArgumentError, 'path cannot be empty!'
|
87
|
+
else html_dir = arg
|
88
|
+
end
|
89
|
+
when '--cgi'
|
90
|
+
if arg != '' then cgi_dir = arg end
|
91
|
+
when '--php'
|
92
|
+
if arg != ''
|
93
|
+
php = true
|
94
|
+
end
|
95
|
+
when '--post_to_url'
|
96
|
+
#if php then raise ArgumentError, 'post_to_url, is not used when php'
|
97
|
+
if arg != '' then post_to_url = arg end
|
98
|
+
when '--conf_location'
|
99
|
+
if arg != '' then conf_location = arg end
|
100
|
+
when '--move_conf_from'
|
101
|
+
if arg != '' then move_conf_from = arg end
|
102
|
+
when '--move_conf_to'
|
103
|
+
if arg != '' then move_conf_to = arg end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# methods
|
108
|
+
|
109
|
+
def handle_conf(move_conf_from, move_conf_to, cgi_dir=nil)
|
110
|
+
begin
|
111
|
+
FileUtils.mkdir move_conf_to
|
112
|
+
FileUtils.cp move_conf_from, move_conf_to
|
113
|
+
rescue
|
114
|
+
#puts "Destination conf file exists #{move_conf_to}"
|
115
|
+
end
|
116
|
+
# now edit lib to set conf_file path
|
117
|
+
to_path = File.dirname(move_conf_to) # moved to path
|
118
|
+
to_name = File.basename(move_conf_from) # name of conf file
|
119
|
+
conf_abs_path = File.join(to_path, to_name)
|
120
|
+
set_conf_file_in_cgi(cgi_dir, conf_abs_path) if cgi_dir
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_conf_file_in_cgi(cgi_dir, conf_location, php=nil)
|
124
|
+
cgi_file = File.join(cgi_dir, 'svn_wc_broker.cgi')
|
125
|
+
File.open(cgi_file, 'r+') do |cf|
|
126
|
+
lines = cf.readlines
|
127
|
+
lines.each do |el|
|
128
|
+
el.gsub! /CONF_FILE = nil/,
|
129
|
+
"CONF_FILE = '#{conf_location}'"
|
130
|
+
# dont print header when run under php
|
131
|
+
el.gsub! /print cgi.header/, '#print cgi.header' if php
|
132
|
+
end
|
133
|
+
cf.pos = 0
|
134
|
+
cf.print lines
|
135
|
+
cf.truncate(cf.pos)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def set_cgi_path_in_js(html_dir, post_to_url)
|
140
|
+
js_file = File.join(html_dir, 'js', 'swt.js')
|
141
|
+
File.open(js_file, 'r+') do |fst|
|
142
|
+
lines = fst.readlines
|
143
|
+
lines.each do |el|
|
144
|
+
el.gsub! /var POST_URL = '.*;/,
|
145
|
+
"var POST_URL = '#{post_to_url}';"
|
146
|
+
end
|
147
|
+
fst.pos = 0
|
148
|
+
fst.print lines
|
149
|
+
fst.truncate(fst.pos)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# actions
|
154
|
+
if html_dir
|
155
|
+
|
156
|
+
swt_gem_ins_dir = File.join File.dirname(__FILE__), '..'
|
157
|
+
|
158
|
+
begin
|
159
|
+
# copy web app (html related) files
|
160
|
+
html_dest = File.join(html_dir, 'svn_wc_tree')
|
161
|
+
FileUtils.rm_rf html_dest
|
162
|
+
FileUtils.mkdir html_dest
|
163
|
+
FileUtils.cp_r(File.join(swt_gem_ins_dir, 'svn_wc_tree/'), html_dir)
|
164
|
+
|
165
|
+
# cgi script
|
166
|
+
cgi_path = html_dest if php
|
167
|
+
cgi_path = cgi_dir if cgi_dir # if set, will overwrite php cgi url
|
168
|
+
# copy web app cgi script to web app specified location
|
169
|
+
FileUtils.cp(File.join(swt_gem_ins_dir, 'cgi', 'svn_wc_broker.cgi'), cgi_path)
|
170
|
+
set_conf_file_in_cgi(cgi_path, conf_location, php) if conf_location
|
171
|
+
|
172
|
+
# edit js/swt.js file to full web accessible CGI URL
|
173
|
+
set_cgi_path_in_js(html_dest, post_to_url)
|
174
|
+
|
175
|
+
# conf file
|
176
|
+
if move_conf_from or move_conf_to
|
177
|
+
if not (move_conf_from and move_conf_to)
|
178
|
+
raise ArgumentError, \
|
179
|
+
'if using "move_", both move_conf_to and move_conf_from must be set'
|
180
|
+
end
|
181
|
+
handle_conf(move_conf_from, move_conf_to, cgi_dir)
|
182
|
+
end
|
183
|
+
rescue Exception => e
|
184
|
+
raise "Exception: #{e.message}"
|
185
|
+
end
|
186
|
+
else
|
187
|
+
puts "Required argument missing. try --help"
|
188
|
+
exit 0
|
189
|
+
end
|
190
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:encoding=UTF-8
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010 David Wright
|
5
|
+
#
|
6
|
+
# You are free to modify and use this file under the terms of the GNU LGPL.
|
7
|
+
# You should have received a copy of the LGPL along with this file.
|
8
|
+
#
|
9
|
+
# Alternatively, you can find the latest version of the LGPL here:
|
10
|
+
#
|
11
|
+
# http://www.gnu.org/licenses/lgpl.txt
|
12
|
+
#
|
13
|
+
# This library is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16
|
+
# Lesser General Public License for more details.
|
17
|
+
|
18
|
+
begin; require 'rubygems'; rescue LoadError; end
|
19
|
+
require 'cgi'
|
20
|
+
require 'json'
|
21
|
+
require 'fileutils'
|
22
|
+
require 'svn_wc_broker'
|
23
|
+
|
24
|
+
CONF_FILE = nil
|
25
|
+
|
26
|
+
cgi = CGI.new(:encoding => 'UTF-8')
|
27
|
+
|
28
|
+
print cgi.header('type' => 'application/x-javascript', 'charset' => 'UTF-8')
|
29
|
+
|
30
|
+
include SvnWcBroker
|
31
|
+
|
32
|
+
# emergency debug only!
|
33
|
+
#File.open('/tmp/DEBUG2', 'w') { |f| f.write(cgi.params.inspect) }
|
34
|
+
|
35
|
+
# this cgi file *should* be as simple as this now
|
36
|
+
set_conf_file(CONF_FILE)
|
37
|
+
print handle_responses(cgi.params).to_json
|
38
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# vim:fileencoding=UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010 David Wright
|
4
|
+
#
|
5
|
+
# You are free to modify and use this file under the terms of the GNU LGPL.
|
6
|
+
# You should have received a copy of the LGPL along with this file.
|
7
|
+
#
|
8
|
+
# Alternatively, you can find the latest version of the LGPL here:
|
9
|
+
#
|
10
|
+
# http://www.gnu.org/licenses/lgpl.txt
|
11
|
+
#
|
12
|
+
# This library is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Lesser General Public License for more details.
|
16
|
+
|
17
|
+
require 'fileutils'
|
18
|
+
require 'svn_wc_client'
|
19
|
+
|
20
|
+
#XXX/TODO docs;tests
|
21
|
+
#
|
22
|
+
# Broker requests between web app (AJAX) to svn_wc_client
|
23
|
+
#
|
24
|
+
# (this probably totally unnecessary and can be done away with
|
25
|
+
# is left over form an early design decision which has
|
26
|
+
# already changed)
|
27
|
+
#
|
28
|
+
# mostly what it does is populate the top level array element with :run_error
|
29
|
+
# with any exception that occurs: #repo[0]={:run_error => "Error: #{e.message}"}
|
30
|
+
#
|
31
|
+
module SvnWcBroker
|
32
|
+
|
33
|
+
# any action we want to support gets added to this list
|
34
|
+
#--
|
35
|
+
# this list gets 'evaled' is why
|
36
|
+
#++
|
37
|
+
SUPPORTED_ACTIONS = %w(add commit delete info
|
38
|
+
revert list ignore diff update
|
39
|
+
status)
|
40
|
+
|
41
|
+
# set abs_path to your configuration file
|
42
|
+
def set_conf_file(conf) ; @conf_file = conf ; end
|
43
|
+
|
44
|
+
# makes the requests against svn_wc
|
45
|
+
include SvnRepoClient
|
46
|
+
|
47
|
+
# pass web requests in, handle defined actions, return results
|
48
|
+
# params can be a cgi request object, or a rails request object, whatever
|
49
|
+
# contains our web POST request
|
50
|
+
def handle_responses(params)
|
51
|
+
|
52
|
+
# to debug
|
53
|
+
#return svn_results debug_request(params['do_svn_action'])
|
54
|
+
#return svn_results debug_request(params.to_s.to_a)
|
55
|
+
if params['do_svn_action'] \
|
56
|
+
&& (params['do_svn_action'].to_s == 'Do Svn Action')
|
57
|
+
|
58
|
+
#return svn_results debug_request(params)
|
59
|
+
if params and params['svn_action'].to_s.strip.empty?
|
60
|
+
return svn_results
|
61
|
+
else
|
62
|
+
return svn_results send( :do_requested_action, params )
|
63
|
+
end
|
64
|
+
|
65
|
+
else
|
66
|
+
return svn_results
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def debug_request(message)
|
72
|
+
resp_data = Array.new
|
73
|
+
resp_data[0] = {:run_error => "Debug: #{message}"}
|
74
|
+
end
|
75
|
+
|
76
|
+
def do_requested_action(params)
|
77
|
+
resp_data = Array.new
|
78
|
+
|
79
|
+
action = params['svn_action'].to_s.strip.downcase
|
80
|
+
files = params['svn_files']
|
81
|
+
|
82
|
+
begin
|
83
|
+
if files and files.to_a.size > 0
|
84
|
+
files_striped = ret_just_files_list(
|
85
|
+
process_params_to_list_of_files(files.to_s))
|
86
|
+
@files = files_striped.to_a.uniq
|
87
|
+
#@files.uniq
|
88
|
+
#return svn_results debug_request(@files)
|
89
|
+
|
90
|
+
# diff need status info
|
91
|
+
if ('diff' == action )
|
92
|
+
@files = process_params_to_list_of_files(files.to_s).to_a.uniq
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
eval("svn_#{action}") if SUPPORTED_ACTIONS.index(action)
|
97
|
+
rescue Exception => exn
|
98
|
+
resp_data[0] = {:run_error => "Error: #{exn.message}"}
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# default action, always return the status list
|
104
|
+
def get_status_list
|
105
|
+
svn_status_list = Array.new
|
106
|
+
run_error = String.new
|
107
|
+
|
108
|
+
begin
|
109
|
+
svn_status_list = svn_status
|
110
|
+
rescue Exception => e
|
111
|
+
run_error << e.message
|
112
|
+
end
|
113
|
+
|
114
|
+
##if svn_status_list.empty? or svn_status_list.size == 1
|
115
|
+
##if svn_status_list.empty?
|
116
|
+
#if @entries_list[0][:entry_name].nil?
|
117
|
+
# svn_status_list[0] = {:repo_status => 'upto date',
|
118
|
+
# :repo_root_local_path => repo_root}
|
119
|
+
#end
|
120
|
+
|
121
|
+
if run_error.length > 0
|
122
|
+
svn_status_list[0] = {:run_error => run_error}
|
123
|
+
end
|
124
|
+
|
125
|
+
svn_status_list
|
126
|
+
end
|
127
|
+
|
128
|
+
# svn_wc_broker always returns results, data if set, otherwise svn status list
|
129
|
+
def svn_results(data=[])
|
130
|
+
if data.empty? then get_status_list else data end
|
131
|
+
end
|
132
|
+
|
133
|
+
# clean up POST requests
|
134
|
+
def process_params_to_list_of_files(passed_file_list) # :nodoc:
|
135
|
+
if passed_file_list and passed_file_list.match(/,/)
|
136
|
+
passed_file_list = passed_file_list.split(/,/).to_a
|
137
|
+
end
|
138
|
+
|
139
|
+
passed_file_list_cleaned = Array.new
|
140
|
+
passed_file_list.each do |f_list_str|
|
141
|
+
# cgi params cleanup
|
142
|
+
# i.e. substituting the cgi with another 'http request broker'
|
143
|
+
#f_list_str.gsub!(/((\302\240)+|\t+|\s+)/, "\s")# becomes odd 2 byte char
|
144
|
+
f_list_str.gsub!(/((\302\240)+|\t+|\s+)/, "\s")# becomes odd 2 byte char
|
145
|
+
passed_file_list_cleaned.push f_list_str
|
146
|
+
end
|
147
|
+
passed_file_list_cleaned
|
148
|
+
end
|
149
|
+
|
150
|
+
def ret_just_files_list(file_status_list) # :nodoc:
|
151
|
+
just_files = Array.new
|
152
|
+
return file_status_list unless file_status_list.class == Array
|
153
|
+
file_status_list.each do |f_list_str|
|
154
|
+
f_stat, f_name = f_list_str.split(/\s/)
|
155
|
+
just_files.push(f_name)
|
156
|
+
end
|
157
|
+
just_files
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
@@ -0,0 +1,266 @@
|
|
1
|
+
# vim:fileencoding=UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010 David Wright
|
4
|
+
#
|
5
|
+
# You are free to modify and use this file under the terms of the GNU LGPL.
|
6
|
+
# You should have received a copy of the LGPL along with this file.
|
7
|
+
#
|
8
|
+
# Alternatively, you can find the latest version of the LGPL here:
|
9
|
+
#
|
10
|
+
# http://www.gnu.org/licenses/lgpl.txt
|
11
|
+
#
|
12
|
+
# This library is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Lesser General Public License for more details.
|
16
|
+
|
17
|
+
require 'svn_wc'
|
18
|
+
|
19
|
+
#
|
20
|
+
# receives method/action requests from web app (AJAX) returns data in expected format
|
21
|
+
# is just a client of svn_wc
|
22
|
+
#
|
23
|
+
# returned data is generally a array of anonymous hashes containing
|
24
|
+
# svn entries info, or errors.
|
25
|
+
#
|
26
|
+
# e.g.
|
27
|
+
# each_details = {}
|
28
|
+
# each_details[:file] = path
|
29
|
+
# each_details[:status] = status
|
30
|
+
# each_details[:content] = content
|
31
|
+
# each_details[:entries] = entries_list
|
32
|
+
# each_details[:error] = error
|
33
|
+
# each_details[:repo_root_local_path] = File.join(@repo_root, '/')
|
34
|
+
#
|
35
|
+
module SvnRepoClient
|
36
|
+
|
37
|
+
@@svn_wc = SvnWc::RepoAccess.new
|
38
|
+
|
39
|
+
# getter for repo root
|
40
|
+
def repo_root ; @@svn_wc.svn_repo_working_copy ; end
|
41
|
+
|
42
|
+
# if conf file exists and have a working copy of the repo, return the path
|
43
|
+
# to it, otherwise create it (do a checkout, not forced)
|
44
|
+
# returns svn_repo_working_copy abs_path
|
45
|
+
def get_repo
|
46
|
+
if File.file? @conf_file
|
47
|
+
@@svn_wc.set_conf @conf_file
|
48
|
+
else raise ArgumentError, "config file not found! #{@conf_file}" end
|
49
|
+
|
50
|
+
if not File.directory? @@svn_wc.svn_repo_working_copy
|
51
|
+
begin
|
52
|
+
@@svn_wc.do_checkout true
|
53
|
+
rescue SvnWc::RepoAccessError => e
|
54
|
+
raise e.message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@repo_root = @@svn_wc.svn_repo_working_copy
|
58
|
+
end
|
59
|
+
|
60
|
+
# basic status list of entries in repo root
|
61
|
+
# do checkout if not exists at local path
|
62
|
+
def svn_status
|
63
|
+
get_repo
|
64
|
+
st_list = Array.new
|
65
|
+
ent = Array.new
|
66
|
+
begin
|
67
|
+
@@svn_wc.status.each do |ef|
|
68
|
+
each_details = Hash.new
|
69
|
+
each_details[:status] = ef[:status]
|
70
|
+
each_details[:error] = ''
|
71
|
+
each_details[:entry_name] = ef[:path]
|
72
|
+
each_details[:kind] = 1 # is 'file'
|
73
|
+
if File.directory?(File.join(@repo_root, ef[:path]))
|
74
|
+
each_details[:dir_name] = File.join(@repo_root, el)
|
75
|
+
each_details[:kind] = 2 # is dir
|
76
|
+
end
|
77
|
+
ent.push each_details
|
78
|
+
end
|
79
|
+
add_repo_as_dir = Hash.new
|
80
|
+
add_repo_as_dir[:dir_name] = @repo_root
|
81
|
+
add_repo_as_dir[:kind] = 2
|
82
|
+
ent.push add_repo_as_dir
|
83
|
+
rescue SvnWc::RepoAccessError => e
|
84
|
+
@error = "#{e.message} #{@@svn_wc}"
|
85
|
+
st_list.push info_data
|
86
|
+
end
|
87
|
+
@entries_list = ent
|
88
|
+
st_list.push info_data if ent.length > 0
|
89
|
+
st_list
|
90
|
+
end
|
91
|
+
|
92
|
+
# diff current to previous (HEAD only)
|
93
|
+
# returns diff content
|
94
|
+
def svn_diff
|
95
|
+
file_list_diffs = Array.new
|
96
|
+
@files.each { |f_list_str|
|
97
|
+
f_stat, f_name = f_list_str.split(/\s/)
|
98
|
+
begin
|
99
|
+
get_repo
|
100
|
+
@path = f_name
|
101
|
+
@content = @@svn_wc.diff(f_name).to_s
|
102
|
+
@status = f_stat
|
103
|
+
file_list_diffs.push info_data
|
104
|
+
rescue SvnWc::RepoAccessError => e
|
105
|
+
@error = e.message
|
106
|
+
file_list_diffs.push info_data
|
107
|
+
end
|
108
|
+
}
|
109
|
+
|
110
|
+
file_list_diffs
|
111
|
+
end
|
112
|
+
|
113
|
+
# commit, return message and revision, committed file list
|
114
|
+
def svn_commit
|
115
|
+
get_repo
|
116
|
+
rev = Array.new
|
117
|
+
begin
|
118
|
+
@content = "Committed. Revision: #{@@svn_wc.commit(@files)}
|
119
|
+
Files:
|
120
|
+
#{@files.join("\n")}"
|
121
|
+
rev.push info_data
|
122
|
+
rescue SvnWc::RepoAccessError => e
|
123
|
+
@error = e.message
|
124
|
+
rev.push info_data
|
125
|
+
end
|
126
|
+
rev
|
127
|
+
end
|
128
|
+
|
129
|
+
# add, returns 'added' message and added file list
|
130
|
+
def svn_add
|
131
|
+
get_repo
|
132
|
+
rev = Array.new
|
133
|
+
begin
|
134
|
+
@content = "Added. #{@@svn_wc.add(@files).to_a.join("\n")}"
|
135
|
+
rev.push info_data
|
136
|
+
rescue SvnWc::RepoAccessError => e
|
137
|
+
@error = e.message
|
138
|
+
rev.push info_data
|
139
|
+
end
|
140
|
+
rev
|
141
|
+
end
|
142
|
+
|
143
|
+
# update, returns 'updated' message, revision and update data
|
144
|
+
def svn_update
|
145
|
+
get_repo
|
146
|
+
remote_files = Array.new
|
147
|
+
begin
|
148
|
+
@content = "Updated: Revision #{@@svn_wc.update.to_a.join("\n")}"
|
149
|
+
remote_files.push info_data
|
150
|
+
rescue SvnWc::RepoAccessError => e
|
151
|
+
@error = e.message
|
152
|
+
remote_files.push info_data
|
153
|
+
end
|
154
|
+
remote_files
|
155
|
+
end
|
156
|
+
|
157
|
+
# delete
|
158
|
+
def svn_delete
|
159
|
+
get_repo
|
160
|
+
rev = Array.new
|
161
|
+
begin
|
162
|
+
@content = "Deleted. #{@@svn_wc.delete(@files).to_a.join("\n")}"
|
163
|
+
rev.push info_data
|
164
|
+
rescue SvnWc::RepoAccessError => e
|
165
|
+
@error = e.message
|
166
|
+
rev.push info_data
|
167
|
+
end
|
168
|
+
rev
|
169
|
+
end
|
170
|
+
|
171
|
+
# info, returns 'updated' message, revision and update data
|
172
|
+
def svn_info
|
173
|
+
get_repo
|
174
|
+
infos = Array.new
|
175
|
+
begin
|
176
|
+
@content = "Info: #{@@svn_wc.info(@files)[:url]}"
|
177
|
+
infos.push info_data
|
178
|
+
rescue SvnWc::RepoAccessError => e
|
179
|
+
@error = e.message
|
180
|
+
infos.push info_data
|
181
|
+
end
|
182
|
+
infos
|
183
|
+
end
|
184
|
+
|
185
|
+
# revert, returns message
|
186
|
+
def svn_revert
|
187
|
+
get_repo
|
188
|
+
infos = Array.new
|
189
|
+
begin
|
190
|
+
@content = "Reverted: #{@@svn_wc.revert(@files)}
|
191
|
+
Files:
|
192
|
+
#{@files.join("\n")}"
|
193
|
+
infos.push info_data
|
194
|
+
rescue SvnWc::RepoAccessError => e
|
195
|
+
@error = e.message
|
196
|
+
infos.push info_data
|
197
|
+
end
|
198
|
+
infos
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
# ignore, returns 'added' message and added file list
|
203
|
+
def svn_ignore
|
204
|
+
get_repo
|
205
|
+
rev = Array.new
|
206
|
+
begin
|
207
|
+
cmd = @@svn_wc.propset('ignore', @files, @repo_root)
|
208
|
+
#@content = "Ignoring. #{cmd} #{@files.to_a.join("\n")}"
|
209
|
+
@content = "Ignoring. #{cmd}"
|
210
|
+
rev.push info_data
|
211
|
+
rescue SvnWc::RepoAccessError => e
|
212
|
+
@error = e.message
|
213
|
+
rev.push info_data
|
214
|
+
end
|
215
|
+
rev
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
# recursively list entries, provides file or dir info and access to
|
220
|
+
# nice repo/file info
|
221
|
+
def svn_list
|
222
|
+
get_repo
|
223
|
+
repo_entries = Array.new
|
224
|
+
begin
|
225
|
+
l_svn_list = Array.new
|
226
|
+
@@svn_wc.list.each { |el|
|
227
|
+
status_info = {}
|
228
|
+
status_info[:entry_name] = el[:entry]
|
229
|
+
status_info[:kind] = 1 # is 'file'
|
230
|
+
#status_info[:last_changed_rev] = el[:last_changed_rev]
|
231
|
+
if File.directory?(File.join(@repo_root, el[:entry]))
|
232
|
+
status_info[:dir_name] = File.join(@repo_root, el[:entry])
|
233
|
+
status_info[:kind] = 2
|
234
|
+
end
|
235
|
+
l_svn_list.push status_info
|
236
|
+
}
|
237
|
+
@entries_list = l_svn_list
|
238
|
+
repo_entries.push info_data
|
239
|
+
rescue SvnWc::RepoAccessError => e
|
240
|
+
@error = e.message
|
241
|
+
repo_entries.push info_data
|
242
|
+
end
|
243
|
+
repo_entries
|
244
|
+
end
|
245
|
+
|
246
|
+
def info_data
|
247
|
+
each_details = Hash.new
|
248
|
+
each_details[:file] = @path
|
249
|
+
each_details[:status] = @status
|
250
|
+
each_details[:content] = @content
|
251
|
+
#each_details[:rev] = rev
|
252
|
+
# entries_list expects an array of anon hash's
|
253
|
+
each_details[:entries] = @entries_list
|
254
|
+
each_details[:error] = @error
|
255
|
+
each_details[:repo_root_local_path] = File.join(@repo_root, '/')
|
256
|
+
|
257
|
+
# high level repo details
|
258
|
+
each_details[:svn_repo_master] = @@svn_wc.svn_repo_master
|
259
|
+
each_details[:svn_user] = @@svn_wc.svn_user
|
260
|
+
#each_details[:svn_pass] = @@svn_wc.svn_pass
|
261
|
+
each_details[:svn_repo_config_file] = @@svn_wc.svn_repo_config_file
|
262
|
+
|
263
|
+
each_details
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
data/svn_conf.yaml
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#svn_repo_master : file:///tmp/svn/repo_test
|
2
|
+
#svn_repo_master : svn+ssh:///tmp/svnrepo
|
3
|
+
svn_repo_master : svn+ssh://svn_test_user@localhost/tmp/svnrepo
|
4
|
+
#svn_repo_master : svn+ssh://example.com/tmp/svnrepo
|
5
|
+
svn_repo_working_copy : /tmp/repo_test
|
6
|
+
svn_user : svn_test_user
|
7
|
+
svn_pass : svn_test_pass
|
8
|
+
svn_repo_config_path : /tmp/config
|
9
|
+
|
Binary file
|