| 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.
| branch | [RW] | |
| mod | [RW] | |
| password | [RW] | |
| root | [RW] |
# 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
# File lib/rscm/scm/cvs.rb, line 40
40: def add(relative_filename, options={})
41: cvs("add #{relative_filename}", options)
42: end
# 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
# 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
# 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
# File lib/rscm/scm/cvs.rb, line 51
51: def commit(message, options={})
52: cvs(commit_command(message), options)
53: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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