Module: RightScraper::SvnClient

Included in:
Retrievers::Svn
Defined in:
lib/right_scraper/svn_client.rb

Overview

Simplified interface to the process of creating SVN client contexts.

SVN client contexts are needed for almost every nontrivial SVN operation, and the authentication procedure is truly baroque. Thus, when you need a client context, do something like this:

client = SvnClient.new(repository)
client.with_context do |ctx|
  ...
end

Defined Under Namespace

Classes: SvnClientError

Instance Method Summary collapse

Instance Method Details

#calculate_versionObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/right_scraper/svn_client.rb', line 42

def calculate_version
  unless @svn_version
    begin
      cmd = 'svn --version --quiet'
      out = `#{cmd}`
      if $?.success?
        @svn_version = out.chomp.split('.').map {|e| e.to_i}
      else
        raise SvnClientError, "Unable to determine svn version: #{cmd.inspect} exited with #{$?.exitstatus}"
      end
    rescue Errno::ENOENT => e
      raise SvnClientError, "Unable to determine svn version: #{e.message}"
    end
  end
  @svn_version
end

#exit_svn_client(status) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/right_scraper/svn_client.rb', line 143

def exit_svn_client(status)
  unless status.success?
    self.method(@output_handler).call("Exit code = #{status.exitstatus}")
    raise SvnClientError, "svn client failed: #{@output.display_text}"
  end
  true
end

#get_tagObject

Fetch the tag from the repository, or nil if one doesn’t exist. This is a separate method because the repo tag should be a number but is a string in the database.



154
155
156
157
158
159
160
161
# File 'lib/right_scraper/svn_client.rb', line 154

def get_tag
  case repository.tag
  when Fixnum then repository.tag
  when /^\d+$/ then repository.tag.to_i
  else
    repository.tag
  end
end

#get_tag_argumentObject



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

def get_tag_argument
  if repository.tag
    tag_cmd = ["-r", get_tag.to_s]
  else
    tag_cmd = ["-r", "HEAD"]
  end
end

#run_svn(*args) ⇒ Object



93
94
95
# File 'lib/right_scraper/svn_client.rb', line 93

def run_svn(*args)
  run_svn_with(repo_dir, :safe_output_svn_client, *args)
end

#run_svn_no_chdir(*args) ⇒ Object



89
90
91
# File 'lib/right_scraper/svn_client.rb', line 89

def run_svn_no_chdir(*args)
  run_svn_with(nil, :safe_output_svn_client, *args)
end

#run_svn_with(initial_directory, output_handler, *args) ⇒ Array

runs svn client with safe buffering (by default).

Parameters

Return

Parameters:

  • args (Array)

    for svn client command line

Returns:

  • (Array)

    lines of output or empty



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

def run_svn_with(initial_directory, output_handler, *args)
  @output = ::RightScale::RightPopen::SafeOutputBuffer.new
  cmd = ['svn', args, svn_arguments].flatten
  ::RightScale::RightPopen.popen3_sync(
    cmd,
    :target             => self,
    :directory          => initial_directory,
    :timeout_handler    => :timeout_svn_client,
    :size_limit_handler => :size_limit_svn_client,
    :exit_handler       => :exit_svn_client,
    :stderr_handler     => output_handler,
    :stdout_handler     => output_handler,
    :inherit_io         => true,  # avoid killing any rails connection
    :watch_directory    => repo_dir,
    :size_limit_bytes   => @max_bytes,
    :timeout_seconds    => @max_seconds)
  @output.buffer
end

#run_svn_with_buffered_output(*args) ⇒ Object



97
98
99
# File 'lib/right_scraper/svn_client.rb', line 97

def run_svn_with_buffered_output(*args)
  run_svn_with(repo_dir, :unsafe_output_svn_client, *args)
end

#safe_output_svn_client(data) ⇒ Object



127
128
129
# File 'lib/right_scraper/svn_client.rb', line 127

def safe_output_svn_client(data)
  @output.safe_buffer_data(data)
end

#size_limit_svn_clientObject

Raises:



139
140
141
# File 'lib/right_scraper/svn_client.rb', line 139

def size_limit_svn_client
  raise SvnClientError, "svn client exceeded size limit"
end

#svn_argumentsObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/right_scraper/svn_client.rb', line 59

def svn_arguments
  version = calculate_version
  case
  when version[0] != 1
    raise "SVN major revision is not 1, cannot be sure it will run properly."
  when version[1] < 4
    raise "SVN minor revision < 4; cannot be sure it will run properly."
  when version[1] < 6
    # --trust-server-cert is a 1.6ism
    args = ["--no-auth-cache", "--non-interactive"]
  else
    args = ["--no-auth-cache", "--non-interactive", "--trust-server-cert"]
  end
  if repository.first_credential && repository.second_credential
    args << "--username"
    args << repository.first_credential
    args << "--password"
    args << repository.second_credential
  end
  args
end

#timeout_svn_clientObject

Raises:



135
136
137
# File 'lib/right_scraper/svn_client.rb', line 135

def timeout_svn_client
  raise SvnClientError, "svn client timed out"
end

#unsafe_output_svn_client(data) ⇒ Object



131
132
133
# File 'lib/right_scraper/svn_client.rb', line 131

def unsafe_output_svn_client(data)
  @output.buffer << data.chomp
end