Class: CVS

Inherits:
Object
  • Object
show all
Defined in:
lib/cvs.rb

Constant Summary collapse

HEAD =
'HEAD'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log = nil) ⇒ CVS

Returns a new instance of CVS.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/cvs.rb', line 12

def initialize(log=nil)
  @logger = log || Logger.new(STDOUT)
  @settings = {
      :basedir => '.',
      :root  => '',
      :executable => '/usr/bin/cvs',
      :default_branch => 'HEAD',
      :timeout => 300
  }

end

Class Method Details

.init(dir, cvs_exec = "/usr/bin/cvs", logger = nil) {|cvs| ... } ⇒ Object

Yields:



262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/cvs.rb', line 262

def CVS.init(dir, cvs_exec="/usr/bin/cvs", logger=nil)
  raise "Directory #{dir} does not exist! Please create it first!" unless Dir.exists?(dir)
  raise "Could not find executable #{cvs_exec}! Do you have CVS installed!" unless File.exists?(cvs_exec)
  cvs = CVS.new(logger).config do |settings|
    settings[:basedir] = dir
    settings[:root] = dir
    settings[:executable] = cvs_exec
  end
  cmd = [cvs_exec, '-d', dir, "init"]
  cvs.execute_command(cmd)  
  yield cvs if block_given?
  cvs
end

Instance Method Details

#add(filename) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/cvs.rb', line 33

def add(filename)
  check_file filename
  parts = filename.split('/')
  parent = parts.shift
  file = parts.join '/'
  file = '' if file.nil?
  cmd = [cvs, '-d',cvsroot,'add', file]
  return execute_command cmd, File.join(root, parent)
end

#apply_patch(file_name, patch_file) ⇒ Object



177
178
179
180
# File 'lib/cvs.rb', line 177

def apply_patch(file_name, patch_file)
  cmd = ['patch', file_name, patch_file]
  execute_command cmd
end

#apply_patch_to_root(patch_file) ⇒ Object



182
183
184
185
# File 'lib/cvs.rb', line 182

def apply_patch_to_root(patch_file)
  cmd = ['patch', '<', patch_file]
  execute_command cmd
end

#branch_module(sub_module, branch, basedir = nil) ⇒ Object



222
223
224
225
# File 'lib/cvs.rb', line 222

def branch_module(sub_module, branch, basedir=nil)
  cmd = [cvs, '-d', cvsroot, 'rtag', '-b', branch, sub_module]
  execute_command cmd , basedir
end

#calculate_previous_revision(current_rev) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/cvs.rb', line 137

def calculate_previous_revision(current_rev)
  return '1.1' if current_rev.nil? or current_rev == 'NONE'
  parts = current_rev.split('.')
  last_index = parts.length-1
  parts[last_index] = Integer(parts[last_index]) - 1
  if parts[last_index] == 0 and last_index >= 3 then
    #when it is a branch or a branch of a branch
    parts.delete_at(last_index)
    parts.delete_at(last_index-1)
  end

  #when you try to go to a previous version on head and there is no "go back" possible return 1.1
  return '1.1' if parts[last_index] == 0 and last_index == 2
  return parts.join('.')
end

#check_CVSROOTObject

Raises:



210
211
212
# File 'lib/cvs.rb', line 210

def check_CVSROOT
  raise CVSOperationError, 'No CVSROOT specified!' if  cvsroot.empty?
end

#check_file(file_name) ⇒ Object



203
204
205
206
207
208
# File 'lib/cvs.rb', line 203

def check_file(file_name)
  target_file = File.join(root(), file_name)
  unless File.exists?(target_file)
    @logger.warn "Could not find #{target_file}. Are you sure you have set the correct CVS basedir?"
  end
end

#checkout(file_name, options = {}) ⇒ Object



63
64
65
66
67
68
69
70
# File 'lib/cvs.rb', line 63

def checkout(file_name, options={})
  check_CVSROOT()
  cmd = [cvs,'-d',cvsroot, 'co']
  cmd += ['-D', options[:timestamp] ] if options[:timestamp]
  cmd += ['-r',options[:branch] ] if options[:branch] and not ['', HEAD].include?(options[:branch])
  cmd.push file_name
  execute_command(cmd, options[:basedir])
end

#co(file_name, branch = '') ⇒ Object



54
55
56
57
58
59
60
61
# File 'lib/cvs.rb', line 54

def co(file_name, branch = '')
  @logger.debug('The method co is deprecated. Please change to the "checkout" method!')
  check_CVSROOT()
  cmd = [cvs,'-d',cvsroot, 'co']
  cmd += ['-r', branch] unless ['', HEAD].include?(branch)
  cmd.push file_name
  return execute_command cmd
end

#commit(file_name, comment) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/cvs.rb', line 81

def commit(file_name, comment)
  check_CVSROOT()
  check_file(file_name) unless file_name.nil?
  cmd = [cvs, '-d', cvsroot, 'commit', '-m', comment]
  cmd.push(file_name) unless file_name.nil?
  execute_command cmd
end

#config {|@settings, @logger| ... } ⇒ Object

Yields:



89
90
91
92
# File 'lib/cvs.rb', line 89

def config
  yield @settings, @logger if block_given?
  self
end

#current_branch(file_name) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/cvs.rb', line 111

def current_branch(file_name)
  check_file(file_name)
  status = status(file_name).split("\n")
  result = status.grep(/Tag/) do |line|
    if line.include? 'none' then
      rev = status.grep(/Repository revision/) { |repo_revision| repo_revision.split()[2]}[0]
      return HEAD, rev
    end
    parts = line.split(':')
    branch = parts[1].strip.scan(/(.*)\(branch/)[0][0].strip
    branch_revision = parts[2].strip.scan(/(.*)\)/)[0][0].strip
    return branch, branch_revision
  end
  return result
end

#current_revision(file_name) ⇒ Object



127
128
129
130
# File 'lib/cvs.rb', line 127

def current_revision(file_name)
  check_file(file_name)
  status(file_name).split("\n").grep(/Repository revision/) {|repo_revision| repo_revision.split()[2]}[0]
end

#cvsObject



227
228
229
# File 'lib/cvs.rb', line 227

def cvs
  settings[:executable]
end

#cvsrootObject



214
215
216
# File 'lib/cvs.rb', line 214

def cvsroot
  @settings[:root]
end

#default_branchObject



218
219
220
# File 'lib/cvs.rb', line 218

def default_branch
  return HEAD
end

#diff(from_rev, to_rev, file_name) ⇒ Object



171
172
173
174
175
# File 'lib/cvs.rb', line 171

def diff(from_rev, to_rev, file_name)
  check_CVSROOT()
  cmd = [cvs, '-d', cvsroot, 'rdiff', '-u', '-r', from_rev, '-r', to_rev, file_name]
  execute_command cmd
end

#execute_command(cmd, basedir = nil, timeout = nil) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/cvs.rb', line 231

def execute_command(cmd, basedir = nil, timeout=nil)
  basedir = basedir.nil? ? root : basedir
  @logger.debug("Executing command #{cmd.join(' ')} | CWD: #{basedir}")
  command_timeout = timeout || settings[:timeout]
  out = Tempfile.new('cvs_cmd')
  process = ChildProcess.build(*cmd)
  process.cwd = basedir
  process.io.stdout = process.io.stderr = out
  process.start
  process.poll_for_exit(command_timeout)
  out.rewind
  result = out.read
  raise CVSOperationError, "Could not successfully execute command '#{cmd}'\n#{result}" if process.exit_code != 0
  result
rescue ChildProcess::TimeoutError
  raise CVSOperationError, "TIMEOUT[#{command_timeout}]! Could not successfully execute command '#{cmd}'"
ensure
  out.close if out
  out.unlink if out
end

#get_file_content(file_name, revision, basedir = nil) ⇒ Object



187
188
189
190
191
192
193
# File 'lib/cvs.rb', line 187

def get_file_content(file_name, revision, basedir=nil)
  cmd = [cvs, '-d', cvsroot, 'co', '-r', revision, file_name]
  execute_command cmd , basedir
  working_dir = basedir.nil? ? root : basedir
  full_path = File.join(working_dir, file_name)
  File.open(full_path, 'r').read
end

#get_file_content_as_binary(file_name, revision, basedir = nil) ⇒ Object



195
196
197
198
199
200
201
# File 'lib/cvs.rb', line 195

def get_file_content_as_binary(file_name, revision, basedir=nil)
  cmd = [cvs, '-d', cvsroot, 'co', '-r', revision, file_name]
  execute_command cmd , basedir
  working_dir = basedir.nil? ? root : basedir
  full_path = File.join(working_dir, file_name)
  File.open(full_path, 'rb').read
end

#import(module_dir) ⇒ Object



252
253
254
255
256
257
258
# File 'lib/cvs.rb', line 252

def import(module_dir)
  raise "Please specify the module_directory" unless Dir.exists?(module_dir)
  absolute_path = File.absolute_path(module_dir)
  module_name = Pathname.new(absolute_path).basename.to_s    
  cmd = [cvs,'-d', cvsroot, 'import', '-m', "Created module #{module_name}", module_name, "INITIAL", "start"]
  execute_command cmd , absolute_path
end

#last_diff(file_name, base_rev = nil) ⇒ Object



161
162
163
164
165
166
167
168
169
# File 'lib/cvs.rb', line 161

def last_diff(file_name, base_rev=nil)
  if base_rev.nil? or base_rev == 'NONE' then
    rev = current_revision(file_name)
  else
    rev = base_rev
  end
  previous_rev = calculate_previous_revision(rev)
  return diff(previous_rev, rev, file_name)
end

#previous_revision(file_name) ⇒ Object



132
133
134
135
# File 'lib/cvs.rb', line 132

def previous_revision(file_name)
  check_file(file_name)
  calculate_previous_revision(current_revision(file_name))
end

#remove(filename) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/cvs.rb', line 43

def remove(filename)
  check_file filename
  parts = filename.split('/')
  parent = parts.shift
  file = parts.join '/'
  file_path = File.join(root, filename)
  File.delete(file_path) if File.exists?(file_path)
  cmd = [cvs,'-d',cvsroot,'remove',file]
  return execute_command cmd, File.join(root, parent)
end

#reset_settingsObject



94
95
96
97
98
99
100
101
102
# File 'lib/cvs.rb', line 94

def reset_settings
  @settings = {
      :basedir => '.',
      :root => '',
      :executable => '/usr/bin/cvs',
      :default_branch => 'HEAD',
      :timeout => 300
  }
end

#rootObject

wrapper around cvs common tasks



25
26
27
# File 'lib/cvs.rb', line 25

def root
  settings[:basedir]
end

#rtag(file_name, tag_name, options = {}) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/cvs.rb', line 72

def rtag(file_name, tag_name, options={})
  check_CVSROOT()
  cmd = [cvs,'-d', cvsroot, 'rtag']
  cmd += ['-b'] if options[:branch]
  cmd.push tag_name
  cmd.push file_name
  execute_command(cmd, options[:basedir])
end

#settingsObject



29
30
31
# File 'lib/cvs.rb', line 29

def settings
  return @settings
end

#status(file_name) ⇒ Object



104
105
106
107
108
109
# File 'lib/cvs.rb', line 104

def status(file_name)
  check_CVSROOT()
  check_file(file_name)
  cmd = [cvs, '-d', cvsroot, 'status', file_name]
  execute_command cmd
end

#update(file_name, branch) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/cvs.rb', line 153

def update(file_name, branch)
  full_name = File.join(root(), file_name)
  if File.exists? full_name then
    File.delete full_name
  end
  co(file_name, branch)
end