class OhlohScm::Cvs::Activity
Public Instance Methods
rubocop:disable Metrics/AbcSize, Metrics/MethodLength
# File lib/ohloh_scm/cvs/activity.rb, line 16 def commits(opts = {}) after = opts[:after] result = [] open_log_file(opts) do |io| result = OhlohScm::CvsParser.parse(io) end # Git converter needs a backpointer to the scm for each commit result.each { |c| c.scm = scm } return result if result.empty? # Nothing found; we're done here. return result if after.to_s == '' # We requested everything, so just return everything. # We must now remove any duplicates caused by timestamp fudge factors, # and only return commits with timestamp > after. # If the first commit is newer than after, # then the whole list is new and we can simply return. return result if parse_time(result.first.token) > parse_time(after) # Walk the list of commits to find the first new one, throwing away all of the old ones. # I want to string-compare timestamps without converting to dates objects. # Some CVS servers print dates as 2006/01/02 03:04:05, others as 2006-01-02 03:04:05. # To work around this, we'll build a regex that matches either date format. re = Regexp.new(after.gsub(/[\/-]/, '.')) result.each_index do |i| next unless result[i].token&.match?(re) # We found the match for after return [] if i == result.size - 1 # There aren't any new commits. return result[i + 1..-1] end # Something bad is going on: 'after' does not match any timestamp in the rlog. # This is very rare, but it can happen. # # Often this means that the *last* time we ran commits(), there was some kind of # undetected problem (CVS was in an intermediate state?) so the list of timestamps we # calculated last time does not match the list of timestamps we calculated this time. # # There's no work around for this condition here in the code, but there are some things # you can try manually to fix the problem. Typically, you can try throwing way the # commit associated with 'after' and fetching it again (git reset --hard HEAD^). raise "token '#{after}' not found in rlog." end
using :ext (ssh) protocol might trigger ssh to confirm accepting the host's ssh key. This causes the UI to hang asking for manual confirmation. To avoid this we pre-populate the ~/.ssh/known_hosts file with the host's key.
# File lib/ohloh_scm/cvs/activity.rb, line 72 def ensure_host_key return if protocol != :ext ensure_key_file = File.dirname(__FILE__) + '/../../../../bin/ensure_key' cmd = "#{ensure_key_file} '#{host}'" run_with_err(cmd) end
rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# File lib/ohloh_scm/cvs/activity.rb, line 65 def export_tag(dest_dir, tag_name = 'HEAD') run "cvsnt -d #{url} export -d'#{dest_dir}' -r #{tag_name} '#{scm.branch_name}'" end
Private Instance Methods
returns the host this adapter is connecting to
# File lib/ohloh_scm/cvs/activity.rb, line 129 def host @host ||= begin url =~ /@([^:]*):/ Regexp.last_match(1) end end
Gets the rlog of the repository and saves it in a temporary file. If you pass a timestamp token, then only commits after the timestamp will be returned.
Warning!
CVS servers are apparently unreliable when you truncate the log by timestamp – perhaps round-off error? In any case, to be sure not to miss any commits, this method subtracts 10 seconds from the provided timestamp. This means that the returned log might actually contain a few revisions that predate the requested time. That's better than missing revisions completely! Just be sure to check for duplicates. rubocop:disable Metrics/AbcSize
# File lib/ohloh_scm/cvs/activity.rb, line 95 def open_log_file(opts = {}) ensure_host_key status.lock? run "cvsnt -d #{url} rlog #{opt_branch} #{opt_time(opts[:after])} '#{scm.branch_name}'"\ " | #{string_encoder_path} > #{rlog_filename}" File.open(rlog_filename, 'r') { |file| yield file } ensure File.delete(rlog_filename) if File.exist?(rlog_filename) end
# File lib/ohloh_scm/cvs/activity.rb, line 144 def opt_branch '-b -r1:' end
rubocop:enable Metrics/AbcSize
# File lib/ohloh_scm/cvs/activity.rb, line 106 def opt_time(after = nil) return '' unless after most_recent_time = parse_time(after) - 10 # rubocop:disable Metrics/LineLength " -d '#{most_recent_time.strftime('%Y-%m-%d %H:%M:%S')}Z<#{Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')}Z' " # rubocop:enable Metrics/LineLength end
Converts a CVS time string to a Ruby Time object
# File lib/ohloh_scm/cvs/activity.rb, line 120 def parse_time(token) case token when /(\d\d\d\d).(\d\d).(\d\d) (\d\d):(\d\d):(\d\d)/ Time.gm(Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i, Regexp.last_match(4).to_i, Regexp.last_match(5).to_i, Regexp.last_match(6).to_i) end end
returns the protocol this adapter connects with
# File lib/ohloh_scm/cvs/activity.rb, line 137 def protocol @protocol ||= case url when /^:pserver/ then :pserver when /^:ext/ then :ext end end
# File lib/ohloh_scm/cvs/activity.rb, line 115 def rlog_filename File.join(temp_folder, (url + scm.branch_name.to_s).gsub(/\W/, '') + '.rlog') end