Class RSCM::Cvs
In: lib/rscm/scm/cvs.rb
Parent: Base

RSCM implementation for CVS.

You need a cvs executable on the PATH in order for it to work.

NOTE: On Cygwin this has to be the win32 build of cvs and not the Cygwin one.

Methods

Attributes

branch  [RW] 
mod  [RW] 
password  [RW] 
root  [RW] 

Public Class methods

[Source]

    # File lib/rscm/scm/cvs.rb, line 20
20:     def initialize(root=nil, mod=nil, branch=nil, password=nil)
21:       @root, @mod, @branch, @password = root, mod, branch, password
22:     end

Public Instance methods

[Source]

    # File lib/rscm/scm/cvs.rb, line 29
29:     def add(relative_filename)
30:       cvs(@checkout_dir, "add #{relative_filename}")
31:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 140
140:     def apply_label(label)
141:       cvs(@checkout_dir, "tag -c #{label}")
142:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 230
230:     def can_create_central?
231:       begin
232:         local?
233:       rescue
234:         false
235:       end
236:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 221
221:     def central_exists?
222:       if(local?)
223:         File.exists?("#{path}/CVSROOT/loginfo")
224:       else
225:         # don't know. assume yes.
226:         true
227:       end
228:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 242
242:     def checked_out?
243:       rootcvs = File.expand_path("#{checkout_dir}/CVS/Root")
244:       File.exists?(rootcvs)
245:     end

The extra simulate parameter is not in accordance with the AbstractSCM API, but it‘s optional and is only being used from within this class (uptodate? method).

[Source]

    # File lib/rscm/scm/cvs.rb, line 42
42:     def checkout(to_identifier=nil, simulate=false)
43:       checked_out_files = []
44:       if(checked_out?)
45:         path_regex = /^[U|P] (.*)/
46:         cvs(@checkout_dir, update_command(to_identifier), simulate) do |line|
47:           if(line =~ path_regex)
48:             path = $1.chomp
49:             yield path if block_given?
50:             checked_out_files << path
51:           end
52:         end
53:       else
54:         prefix = File.basename(@checkout_dir)
55:         path_regex = /^[U|P] #{prefix}\/(.*)/
56:         # This is a workaround for the fact that -d . doesn't work - must be an existing sub folder.
57:         FileUtils.mkdir_p(@checkout_dir) unless File.exist?(@checkout_dir)
58:         target_dir = File.basename(@checkout_dir)
59:         run_checkout_command_dir = File.dirname(@checkout_dir)
60:         # -D is sticky, but subsequent updates will reset stickiness with -A
61:         cvs(run_checkout_command_dir, checkout_command(target_dir, to_identifier), simulate) do |line|
62:           if(line =~ path_regex)
63:             path = $1.chomp
64:             yield path if block_given?
65:             checked_out_files << path
66:           end
67:         end
68:       end
69:       checked_out_files
70:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 72
72:     def commit(message)
73:       cvs(@checkout_dir, commit_command(message))
74:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 207
207:     def create_central
208:       raise "Can't create central CVS repository for #{root}" unless can_create_central?
209:       File.mkpath(path)
210:       cvs(path, "init")
211:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 213
213:     def destroy_central
214:       if(File.exist?(path) && local?)
215:         FileUtils.rm_rf(path)
216:       else
217:         raise "Cannot destroy central repository. '#{path}' doesn't exist or central repo isn't local to this machine"
218:       end
219:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 91
 91:     def diff(revision_file)
 92:       with_working_dir(@checkout_dir) do
 93:         opts = case revision_file.status
 94:           when /#{RevisionFile::MODIFIED}/; "#{revision_option(revision_file.previous_native_revision_identifier)} #{revision_option(revision_file.native_revision_identifier)}"
 95:           when /#{RevisionFile::DELETED}/; "#{revision_option(revision_file.previous_native_revision_identifier)}"
 96:           when /#{RevisionFile::ADDED}/; "#{revision_option(Time.epoch)} #{revision_option(revision_file.native_revision_identifier)}"
 97:         end
 98:         # IMPORTANT! CVS NT has a bug in the -N diff option
 99:         # http://www.cvsnt.org/pipermail/cvsnt-bugs/2004-November/000786.html
100:         cmd = command_line("diff -Nu #{opts} #{revision_file.path}")
101:         Better.popen(cmd, "r", 1) do |io|
102:           return(yield(io))
103:         end
104:       end
105:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 24
24:     def import_central(dir, message)
25:       modname = File.basename(dir)
26:       cvs(dir, "import -m \"#{message}\" #{modname} VENDOR START")
27:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 172
172:     def install_trigger(trigger_command, trigger_files_checkout_dir)
173:       raise "mod can't be null or empty" if (mod.nil? || mod == "")
174: 
175:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
176:       root_cvs.checkout
177:       with_working_dir(trigger_files_checkout_dir) do
178:         trigger_line = "#{mod} #{trigger_command}\n"
179:         File.open("loginfo", File::WRONLY | File::APPEND) do |file|
180:           file.puts(trigger_line)
181:         end
182:         begin
183:           root_cvs.commit("Installed trigger for CVS module '#{mod}'")
184:         rescue
185:           raise ["Didn't have permission to commit CVSROOT/loginfo.",
186:                 "Try to manually add the following line:",
187:                 trigger_command,
188:                 "Finally make commit the file to the repository"]
189:         end
190:       end
191:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 116
116:     def ls(relative_path)
117:       prefix = relative_path == "" ? relative_path : "#{relative_path}/"
118:       with_working_dir(@checkout_dir) do
119:         cmd = "cvs -Q ls -l #{relative_path}"
120:         Better.popen(cmd) do |io|
121:           parse_ls_log(io, prefix)
122:         end
123:       end
124:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 33
33:     def move(relative_src, relative_dest)
34:       FileUtils.mv(@checkout_dir + '/' + relative_src, @checkout_dir + '/' + relative_dest, :force=>true)
35:       cvs(@checkout_dir, "rm #{relative_src}")
36:       # This will fail if the directories are new. More advanced support for adding can be added if needed.
37:       cvs(@checkout_dir, "add #{relative_dest}")
38:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 107
107:     def open(revision_file, &block)
108:       with_working_dir(@checkout_dir) do
109:         cmd = "cvs -Q update -p -r #{revision_file.native_revision_identifier} #{revision_file.path}"
110:         Better.popen(cmd) do |io|
111:           block.call io
112:         end
113:       end
114:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 86
86:     def revisions(from_identifier, to_identifier=Time.infinity, relative_path=nil)
87:       checkout(to_identifier) unless uptodate?(to_identifier) # must checkout to get revisions
88:       parse_log(changes_command(from_identifier, to_identifier, relative_path))
89:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 238
238:     def supports_trigger?
239:       true
240:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 148
148:     def trigger_installed?(trigger_command, trigger_files_checkout_dir)
149:       loginfo_line = "#{mod} #{trigger_command}"
150:       regex = Regexp.new(Regexp.escape(loginfo_line))
151: 
152:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
153:       begin
154:         root_cvs.checkout
155:         loginfo = File.join(trigger_files_checkout_dir, "loginfo")
156:         return false if !File.exist?(loginfo)
157: 
158:         # returns true if commented out. doesn't modify the file.
159:         in_local_copy = LineEditor.comment_out(File.new(loginfo), regex, "# ", "")
160:         # Also verify that loginfo has been committed back to the repo
161:         entries = File.join(trigger_files_checkout_dir, "CVS", "Entries")
162:         committed = File.mtime(entries) >= File.mtime(loginfo)
163: 
164:         in_local_copy && committed
165:       rescue Exception => e
166:         $stderr.puts(e.message)
167:         $stderr.puts(e.backtrace.join("\n"))
168:         false
169:       end
170:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 144
144:     def trigger_mechanism
145:       "CVSROOT/loginfo"
146:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 193
193:     def uninstall_trigger(trigger_command, trigger_files_checkout_dir)
194:       loginfo_line = "#{mod} #{trigger_command}"
195:       regex = Regexp.new(Regexp.escape(loginfo_line))
196: 
197:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
198:       root_cvs.checkout
199:       loginfo_path = File.join(trigger_files_checkout_dir, "loginfo")
200:       File.comment_out(loginfo_path, regex, "# ")
201:       with_working_dir(trigger_files_checkout_dir) do
202:         root_cvs.commit("Uninstalled trigger for CVS mod '#{mod}'")
203:       end
204:       raise "Couldn't uninstall/commit trigger to loginfo" if trigger_installed?(trigger_command, trigger_files_checkout_dir)
205:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 76
76:     def uptodate?(identifier)
77:       if(!checked_out?)
78:         return false
79:       end
80: 
81:       # simulate a checkout
82:       files = checkout(identifier, true)
83:       files.empty?
84:     end

[Validate]