cvstools 0.9.0
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/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
|
+
|