cvstools 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/cvstools.rb +316 -0
- metadata +55 -0
data/lib/cvstools.rb
ADDED
@@ -0,0 +1,316 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# = CVSTools : Object tools for CVS manipulations
|
4
|
+
#
|
5
|
+
# == Copyright Ultragreen (c) 2005
|
6
|
+
#
|
7
|
+
# == About :
|
8
|
+
#
|
9
|
+
# * Author:: Romain GEORGES
|
10
|
+
# * type:: class definition Ruby
|
11
|
+
# * obj:: Generic CVS tools class
|
12
|
+
# * CVS Version:: $Id: cvstools.rb,v 1.5 2006/10/20 09:33:50 lecid Exp $
|
13
|
+
#
|
14
|
+
# === Websites :
|
15
|
+
# * http://www.ultragreen.net
|
16
|
+
# * http://ldapmapper.rubyforge.org
|
17
|
+
#
|
18
|
+
# === Contact :
|
19
|
+
# Romain GEORGES <romain@ultragreen.net>
|
20
|
+
#
|
21
|
+
# == Exemples :
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
# General module for LDAP CRUD Ojects
|
26
|
+
module Cvstools
|
27
|
+
|
28
|
+
# identity lib
|
29
|
+
# version of the library
|
30
|
+
LIB_VERSION='0.9.0'
|
31
|
+
# name of the author
|
32
|
+
AUTHOR='Romain GEORGES'
|
33
|
+
# date of creation
|
34
|
+
DATE='30/07/2005'
|
35
|
+
# valuable observations
|
36
|
+
OBS='Generic LDAP class'
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
class CVS
|
41
|
+
|
42
|
+
|
43
|
+
# accessors
|
44
|
+
attr_accessor :command
|
45
|
+
attr_reader :root
|
46
|
+
attr_accessor :cvsmodule
|
47
|
+
attr_reader :server_type
|
48
|
+
attr_accessor :user
|
49
|
+
attr_accessor :host
|
50
|
+
attr_accessor :password
|
51
|
+
attr_accessor :workdir
|
52
|
+
attr_accessor :exportdir
|
53
|
+
attr_accessor :tag
|
54
|
+
attr_accessor :path
|
55
|
+
attr_accessor :port
|
56
|
+
|
57
|
+
|
58
|
+
def local?
|
59
|
+
return @local
|
60
|
+
end
|
61
|
+
|
62
|
+
def remote?
|
63
|
+
return @remote
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(_root,_cvsmodule='CVSROOT',_password=nil,_tag=nil,_command=nil)
|
67
|
+
@checkout = false
|
68
|
+
@uptodate = false
|
69
|
+
@tag = _tag.nil? ? 'HEAD' : _tag
|
70
|
+
@command = _command.nil? ? `which cvs`.chomp : _command
|
71
|
+
@exportdir = String::new('')
|
72
|
+
@workdir = '/tmp'
|
73
|
+
raise CVSCommandNotFound if @command.empty? or not File::executable?(@command)
|
74
|
+
@root = _root
|
75
|
+
@cvsmodule = _cvsmodule
|
76
|
+
@password = _password
|
77
|
+
@local = false
|
78
|
+
@remote = true
|
79
|
+
@port = 2401
|
80
|
+
case @root
|
81
|
+
when /^\/.+$/
|
82
|
+
@server_type = 'none'
|
83
|
+
@local = true
|
84
|
+
@remote = false
|
85
|
+
@host = 'localhost'
|
86
|
+
@path = @root
|
87
|
+
raise CVSInvalidRoot if not File::exist?("#{@root}/CVSROOT")
|
88
|
+
when/^:ext:(\w+)@(([\w\n-]+\.)+[\w\n-]{2,4}):(\/.+)$/
|
89
|
+
@server_type = 'ssh'
|
90
|
+
@user = $1
|
91
|
+
@host = $2
|
92
|
+
@path = $4
|
93
|
+
when /^:pserver:(\w+)@(([\w\n-]+\.)+[\w\n-]{2,4}):(\/.+)$/
|
94
|
+
raise CVSNoPassword if @password.nil?
|
95
|
+
@server_type = 'pserver'
|
96
|
+
@user,@host,@path = $1,$2,$4
|
97
|
+
@root = ":pserver:#{$1}:#{@password}@#{$2}:#{@port}:#{$4}"
|
98
|
+
when /^:pserver:(\w+):(.+)@(([\w\n-]+\.)+[\w\n-]{2,4}):(\/.+)$/
|
99
|
+
@user,@password,@host,@path = $1,$2,$3,$5
|
100
|
+
@root = ":pserver:#{$1}:#{$2}@#{$3}:#{@port}:#{$5}"
|
101
|
+
when /^:pserver:(\w+):(.+)@(([\w\n-]+\.)+[\w\n-]{2,4}):(\d+):(\/.+)$/
|
102
|
+
@user,@password,@host,@port,@path = $1,$2,$3,$5,$6
|
103
|
+
@root = ":pserver:#{$1}:#{$2}@#{$3}:#{$5}:#{$6}"
|
104
|
+
when /^:pserver:(\w+)@(([\w\n-]+\.)+[\w\n-]{2,4}):(\d+):(\/.+)$/
|
105
|
+
raise CVSNoPassword if @password.nil?
|
106
|
+
@user,@host,@port,@path = $1,$2,$4,$5
|
107
|
+
@root = ":pserver:#{$1}:#{@password}@#{$2}:#{$4}:#{$5}"
|
108
|
+
else
|
109
|
+
raise CVSNotSupportedServer
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def export(_path=nil)
|
114
|
+
raise CVSExportdirNotFound if not File::exist?(@exportdir)
|
115
|
+
_res = system("cd #{@workdir};#{@command} -d#{@root} -Q export -r#{tag} #{@cvsmodule} >/dev/null 2>&1")
|
116
|
+
raise CVSExportFailed if not _res
|
117
|
+
return _res
|
118
|
+
end
|
119
|
+
|
120
|
+
def checkout(_path=nil)
|
121
|
+
raise CVSWorkdirNotFound if not File::exist?(@workdir)
|
122
|
+
_res = system("cd #{@workdir};#{@command} -d#{@root} -Q co -r#{tag} #{@cvsmodule} >/dev/null 2>&1")
|
123
|
+
raise CVSCheckoutFailed if not _res
|
124
|
+
return _res
|
125
|
+
end
|
126
|
+
|
127
|
+
def checkout?
|
128
|
+
return File::exist?("#{@workdir}/#{@cvsmodule}/CVS")
|
129
|
+
end
|
130
|
+
|
131
|
+
def status
|
132
|
+
_list = Hash::new
|
133
|
+
begin
|
134
|
+
_mycmd = open("|cd #{@workdir}/#{@cvsmodule};#{@command}-Q status >/dev/null 2>&1")
|
135
|
+
_mycmd.each{|_line|
|
136
|
+
_list[$1.chomp] = $2.chomp if _line =~ /^File:\s+(\S+)\s+Status:\s+(.*)$/
|
137
|
+
}
|
138
|
+
if _list.empty?then
|
139
|
+
raise CVSStatusFailed
|
140
|
+
return Hash::new
|
141
|
+
else
|
142
|
+
return _list
|
143
|
+
end
|
144
|
+
rescue
|
145
|
+
raise CVSStatusFailed
|
146
|
+
return Hash::new
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def uptodate?
|
151
|
+
return self.status.values.sort.uniq.to_s == 'Up-to-date'
|
152
|
+
end
|
153
|
+
|
154
|
+
def commit
|
155
|
+
raise CVSNotCheckout if not self.checkout?
|
156
|
+
_res = system("cd #{@workdir}/#{@cvsmodule};#{@command} -d#{@root} -Q commit >/dev/null 2>&1")
|
157
|
+
raise CVSCommitFailed if not _res
|
158
|
+
return _res
|
159
|
+
end
|
160
|
+
|
161
|
+
def get_cvsmodule_list
|
162
|
+
raise CVSNotSupported if self.remote?
|
163
|
+
return Dir["#{@path}/*"].map!{|item| item.gsub(/#{@path}\//,'')}
|
164
|
+
end
|
165
|
+
|
166
|
+
def log(_file)
|
167
|
+
return Log::new(_file,@cvsmodule,@workdir,@command,@root)
|
168
|
+
end
|
169
|
+
|
170
|
+
def get_file(_file)
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
class Log
|
177
|
+
|
178
|
+
def initialize(_file,_cvsmodule,_workdir,_command,_root)
|
179
|
+
_myfile = open("\|cd #{@workdir}/#{@cvsmodule};#{@command} -d#{@root} log #{_file}")
|
180
|
+
@mapping = Hash::new
|
181
|
+
@mapping['revisions'] = Hash::new
|
182
|
+
@mapping['revisions_order'] = Array::new
|
183
|
+
_myfile.each {|_line|
|
184
|
+
@mapping['rcs'] = $1 if _line =~ /^RCS\s+file:\s+(\S+)/
|
185
|
+
@mapping['head'] = $1 if _line =~ /^head:\s+([\d|\.]+)/
|
186
|
+
if _line =~ /^total\s+revisions:\s+(\d+);\s+selected\s+revisions:\s+(\d+)/ then
|
187
|
+
@mapping['nb_revisions'] = $1
|
188
|
+
@mapping['current_revision'] = $2
|
189
|
+
end
|
190
|
+
if _line =~ /^symbolic\s+names:/
|
191
|
+
@mapping['tags'] = Hash::new
|
192
|
+
while true
|
193
|
+
_myfile.lineno = _myfile.lineno + 1
|
194
|
+
_line_after = _myfile.gets
|
195
|
+
break if not _line_after =~ /^\s+/
|
196
|
+
_tag,_rel = _line_after.split(":")
|
197
|
+
@mapping['tags'][_tag.strip] = _rel.strip
|
198
|
+
end
|
199
|
+
end
|
200
|
+
if _line =~ /^revision\s+([\d|\.]+)/ then
|
201
|
+
_content = String::new('')
|
202
|
+
_content << _line
|
203
|
+
_rev = $1
|
204
|
+
while true
|
205
|
+
_myfile.lineno = _myfile.lineno + 1
|
206
|
+
_line_after = _myfile.gets
|
207
|
+
break if _line_after =~ /^[\-]/ or _line_after =~ /^[\=]/
|
208
|
+
_content << _line_after
|
209
|
+
end
|
210
|
+
@mapping['revisions_order'].push _rev
|
211
|
+
@mapping['revisions'][_rev] = Revision::new(_rev,_content)
|
212
|
+
end
|
213
|
+
}
|
214
|
+
@mapping['revisions_order']
|
215
|
+
_myfile.close
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
def rcs
|
220
|
+
@mapping['rcs']
|
221
|
+
end
|
222
|
+
|
223
|
+
def head
|
224
|
+
@mapping['head']
|
225
|
+
end
|
226
|
+
|
227
|
+
def nb_revisions
|
228
|
+
@mapping['nb_revisions']
|
229
|
+
end
|
230
|
+
|
231
|
+
def current_revision
|
232
|
+
@mapping['revisions_order'].reverse[@mapping['current_revision'].to_i - 1]
|
233
|
+
end
|
234
|
+
|
235
|
+
def tags
|
236
|
+
@mapping['tags']
|
237
|
+
end
|
238
|
+
|
239
|
+
def revisions_order
|
240
|
+
@mapping['revisions_order']
|
241
|
+
end
|
242
|
+
|
243
|
+
def revisions
|
244
|
+
@mapping['revisions']
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
class Revision
|
252
|
+
|
253
|
+
attr_accessor :revision
|
254
|
+
attr_accessor :date
|
255
|
+
attr_accessor :author
|
256
|
+
attr_accessor :state
|
257
|
+
attr_accessor :lines
|
258
|
+
attr_accessor :branches
|
259
|
+
|
260
|
+
|
261
|
+
def initialize(_rev,_content)
|
262
|
+
_table = _content.split(/\n/)
|
263
|
+
_table.each{|_line|
|
264
|
+
if _line =~ /^date:\s+([\d|\.]+)/ then
|
265
|
+
_line.split(';').each{|_couple| _key,_value = _couple.split(':') ; eval("@#{_key.strip} = '#{_value.strip}'") }
|
266
|
+
end
|
267
|
+
@branches = $1 if _line =~ /^branches:\s+(.+)/
|
268
|
+
@comments = _line if not _line =~ /date:\s+([\d|\.]+)/ or not _line =~ /^revision\s+([\d|\.]+)/ or not _line =~ /^branches:\s+(.+)/
|
269
|
+
if _line =~ /^revision\s+([\d|\.]+)/
|
270
|
+
if $1.strip == _rev
|
271
|
+
@revision = $1
|
272
|
+
else
|
273
|
+
raise CVSRevisionNbMismatch
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
}
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# exception class definitions for CVS Object
|
282
|
+
class CVSCommandNotFound < Exception; end
|
283
|
+
class CVSNoPassword < Exception; end
|
284
|
+
class CVSNotSupported < Exception; end
|
285
|
+
class CVSNotSupportedServer < CVSNotSupported; end
|
286
|
+
class CVSInvalidRoot < Exception; end
|
287
|
+
class CVSWorkdirNotFound < Exception; end
|
288
|
+
class CVSExportdirNotFound < Exception; end
|
289
|
+
class CVSStatusFailed < Exception; end
|
290
|
+
class CVSLogFailed < Exception; end
|
291
|
+
class CVSCommitFailed < Exception; end
|
292
|
+
class CVSCheckoutFailed < Exception; end
|
293
|
+
class CVSExportFailed < Exception; end
|
294
|
+
class CVSError < Exception; end
|
295
|
+
class CVSRevisionNbMismatch < Exception; end
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
# run description of the library in interactive mode
|
300
|
+
if $0 == __FILE__ then
|
301
|
+
puts "#{File::basename(__FILE__)}:"
|
302
|
+
puts 'this is a RUBY library file'
|
303
|
+
puts "Copyright (c) Ultragreen"
|
304
|
+
puts "Version : #{LIB_VERSION}"
|
305
|
+
puts "Author : #{AUTHOR}"
|
306
|
+
puts "Date release : #{DATE}"
|
307
|
+
puts "Observation : #{OBS}"
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
#==END==#
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cvstools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Romain GEORGES
|
8
|
+
autorequire:
|
9
|
+
bindir:
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2006-09-18 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: "Cvstools : provide object bindings on CVS SCM"
|
17
|
+
email: romain@ultragreen.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/cvstools.rb
|
26
|
+
has_rdoc: true
|
27
|
+
homepage: http://www.ultragreen.net
|
28
|
+
licenses: []
|
29
|
+
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.8.1
|
40
|
+
version:
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 1.3.5
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: "Cvstools : CVS Object Ruby binding"
|
54
|
+
test_files: []
|
55
|
+
|