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 29
29:     def initialize(root=nil, mod=nil, branch=nil, password=nil)
30:       @root, @mod, @branch, @password = root, mod, branch, password
31:     end

Public Instance methods

[Source]

    # File lib/rscm/scm/cvs.rb, line 40
40:     def add(relative_filename, options={})
41:       cvs("add #{relative_filename}", options)
42:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 98
 98:     def apply_label(label)
 99:       cvs("tag -c #{label}")
100:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 191
191:     def can_create_central?
192:       begin
193:         local?
194:       rescue
195:         false
196:       end
197:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 182
182:     def central_exists?
183:       if(local?)
184:         File.exists?("#{path}/CVSROOT/loginfo")
185:       else
186:         # don't know. assume yes.

187:         true
188:       end
189:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 203
203:     def checked_out?
204:       rootcvs = File.expand_path("#{checkout_dir}/CVS/Root")
205:       File.exists?(rootcvs)
206:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 51
51:     def commit(message, options={})
52:       cvs(commit_command(message), options)
53:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 167
167:     def create_central(options={})
168:       options = options.dup.merge({:dir => path})
169:       raise "Can't create central CVS repository for #{root}" unless can_create_central?
170:       File.mkpath(path)
171:       cvs("init", options)
172:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 174
174:     def destroy_central
175:       if(File.exist?(path) && local?)
176:         FileUtils.rm_rf(path)
177:       else
178:         raise "Cannot destroy central repository. '#{path}' doesn't exist or central repo isn't local to this machine"
179:       end
180:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 80
80:     def diff(path, from, to, options={}, &block)
81:       # IMPORTANT! CVS NT has a bug in the -N diff option

82:       # http://www.cvsnt.org/pipermail/cvsnt-bugs/2004-November/000786.html

83:       from ||= Time.epoch
84:       cmd = command_line("diff -Nu #{revision_option(from)} #{revision_option(to)} #{path}")
85:       execute(cmd, options.dup.merge({:exitstatus => 1})) do |io|
86:         block.call io
87:       end
88:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 33
33:     def import_central(dir, options={})
34:       modname = File.basename(dir)
35:       FileUtils.mkdir_p(@checkout_dir) unless File.exist?(@checkout_dir)
36:       options = options.dup.merge :dir => dir
37:       cvs("import -m \"#{options[:message]}\" #{modname} VENDOR START", options)
38:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 131
131:     def install_trigger(trigger_command, trigger_files_checkout_dir, options={})
132:       raise "mod can't be null or empty" if (mod.nil? || mod == "")
133:       trigger_command = fix_trigger_command(trigger_command)
134: 
135:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
136:       root_cvs.checkout(nil, options)
137:       Dir.chdir(trigger_files_checkout_dir) do
138:         trigger_line = "#{mod} #{trigger_command}\n"
139:         File.open("loginfo", File::WRONLY | File::APPEND) do |file|
140:           file.puts(trigger_line)
141:         end
142:       end
143: 
144:       begin
145:         root_cvs.commit("Installed trigger for CVS module '#{mod}'", options)
146:       rescue Errno::EACCES
147:         raise ["Didn't have permission to commit CVSROOT/loginfo.",
148:               "Try to manually add the following line:",
149:               trigger_command,
150:               "Finally make commit the file to the repository"].join("\n")
151:       end
152:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 20
20:     def installed?
21:       begin
22:         cvs("--version", {}) 
23:         true
24:       rescue
25:         false
26:       end
27:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 44
44:     def move(relative_src, relative_dest, options={})
45:       FileUtils.mv(@checkout_dir + '/' + relative_src, @checkout_dir + '/' + relative_dest, :force=>true)
46:       cvs("rm #{relative_src}", options)
47:       # This will fail if the directories are new. More advanced support for adding can be added if needed.

48:       cvs("add #{relative_dest}", options)
49:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 90
90:     def open(path, native_revision_identifier, options={}, &block)
91:       raise "native_revision_identifier cannot be nil" if native_revision_identifier.nil?
92:       cmd = "cvs -Q update -p -r #{native_revision_identifier} #{path}"
93:       execute(cmd, options) do |io|
94:         block.call io
95:       end
96:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 69
69:     def revisions(from_identifier=Time.new.utc, options={})
70:       raise "from_identifer cannot be nil" if from_identifier.nil?
71:       options = {
72:         :from_identifier => from_identifier,
73:         :to_identifier => Time.infinity, 
74:         :relative_path => nil
75:       }.merge(options)
76:       checkout(options[:to_identifier], options) unless checked_out? # must checkout to get revisions

77:       parse_log(changes_command(options), options)
78:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 199
199:     def supports_trigger?
200:       true
201:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 106
106:     def trigger_installed?(trigger_command, trigger_files_checkout_dir, options={})
107:       trigger_command = fix_trigger_command(trigger_command)
108:       loginfo_line = "#{mod} #{trigger_command}"
109:       regex = Regexp.new(Regexp.escape(loginfo_line))
110: 
111:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
112:       begin
113:         root_cvs.checkout(nil, options)
114:         loginfo = File.join(trigger_files_checkout_dir, "loginfo")
115:         return false if !File.exist?(loginfo)
116: 
117:         # returns true if commented out. doesn't modify the file.

118:         in_local_copy = LineEditor.comment_out(File.new(loginfo), regex, "# ", "")
119:         # Also verify that loginfo has been committed back to the repo

120:         entries = File.join(trigger_files_checkout_dir, "CVS", "Entries")
121:         committed = File.mtime(entries) >= File.mtime(loginfo)
122: 
123:         in_local_copy && committed
124:       rescue Exception => e
125:         $stderr.puts(e.message)
126:         $stderr.puts(e.backtrace.join("\n"))
127:         false
128:       end
129:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 102
102:     def trigger_mechanism
103:       "CVSROOT/loginfo"
104:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 154
154:     def uninstall_trigger(trigger_command, trigger_files_checkout_dir, options={})
155:       trigger_command = fix_trigger_command(trigger_command)
156:       loginfo_line = "#{mod} #{trigger_command}"
157:       regex = Regexp.new(Regexp.escape(loginfo_line))
158: 
159:       root_cvs = create_root_cvs(trigger_files_checkout_dir)
160:       root_cvs.checkout nil, options
161:       loginfo_path = File.join(trigger_files_checkout_dir, "loginfo")
162:       File.comment_out(loginfo_path, regex, "# ")
163:       root_cvs.commit("Uninstalled trigger for CVS mod '#{mod}'", options)
164:       raise "Couldn't uninstall/commit trigger to loginfo" if trigger_installed?(trigger_command, trigger_files_checkout_dir, options)
165:     end

[Source]

    # File lib/rscm/scm/cvs.rb, line 55
55:     def uptodate?(identifier, options={})
56:       if(!checked_out?)
57:         return false
58:       end
59: 
60:       checkout_silent(identifier, options.dup.merge({:simulate => true})) do |io|
61:         path_regex = /^[U|P|C] (.*)/
62:         io.each_line do |line|
63:           return false if(line =~ path_regex)
64:         end
65:       end
66:       return true
67:     end

Protected Instance methods

[Source]

     # File lib/rscm/scm/cvs.rb, line 214
214:     def checkout_silent(to_identifier, options={}, &proc)
215:       to_identifier = nil if to_identifier == Time.infinity
216:       if(checked_out?)
217:         options = options.dup.merge({
218:           :dir => @checkout_dir
219:         })
220:         cvs(update_command(to_identifier), options, &proc)
221:       else
222:         # This is a workaround for the fact that -d . doesn't work - must be an existing sub folder.

223:         FileUtils.mkdir_p(@checkout_dir) unless File.exist?(@checkout_dir)
224:         target_dir = File.basename(@checkout_dir)
225:         # -D is sticky, but subsequent updates will reset stickiness with -A

226:         options = options.dup.merge({
227:           :dir => File.dirname(@checkout_dir)
228:         })
229:         cvs(checkout_command(target_dir, to_identifier), options, &proc)
230:       end
231:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 210
210:     def cmd_dir
211:       @checkout_dir
212:     end

[Source]

     # File lib/rscm/scm/cvs.rb, line 233
233:     def ignore_paths
234:       [/CVS\/.*/]
235:     end

[Validate]