Class: RSCM::Subversion

Inherits:
Base
  • Object
show all
Includes:
FileUtils, PathConverter
Defined in:
lib/rscm/scm/subversion.rb

Overview

RSCM implementation for Subversion.

You need the svn/svnadmin executable on the PATH in order for it to work.

NOTE: On Cygwin these have to be the win32 builds of svn/svnadmin and not the Cygwin ones.

Constant Summary

Constants inherited from Base

Base::DEFAULT_QUIET_PERIOD, Base::THIRTY_TWO_WEEKS_AGO, Base::TWO_WEEKS_AGO

Instance Attribute Summary collapse

Attributes inherited from Base

#default_options, #logger

Instance Method Summary collapse

Methods included from PathConverter

ensure_trailing_slash, filepath_to_nativepath, filepath_to_nativeurl, nativepath_to_filepath

Methods inherited from Base

#==, #checkout, #checkout_commandline, #checkout_dir, #checkout_dir=, #destroy_working_copy, #edit, #file, #poll_new_revisions, #rootdir, #to_yaml_properties, #update_commandline

Constructor Details

#initialize(url = "", path = "") ⇒ Subversion

Returns a new instance of Subversion.



25
26
27
28
29
# File 'lib/rscm/scm/subversion.rb', line 25

def initialize(url="", path="")
  @url, @path = url, path
  @username = ""
  @password = ""
end

Instance Attribute Details

#passwordObject

Returns the value of attribute password.



23
24
25
# File 'lib/rscm/scm/subversion.rb', line 23

def password
  @password
end

#pathObject

Must be specified in order to create repo and install triggers. Must also be specified as “” if the url represents the root of the repository, or files in revisions will not be detected.



21
22
23
# File 'lib/rscm/scm/subversion.rb', line 21

def path
  @path
end

#urlObject

Returns the value of attribute url.



18
19
20
# File 'lib/rscm/scm/subversion.rb', line 18

def url
  @url
end

#usernameObject

Returns the value of attribute username.



22
23
24
# File 'lib/rscm/scm/subversion.rb', line 22

def username
  @username
end

Instance Method Details

#add(relative_filename, options = {}) ⇒ Object



35
36
37
# File 'lib/rscm/scm/subversion.rb', line 35

def add(relative_filename, options={})
  svn("add #{relative_filename}", options)
end

#can_create_central?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/rscm/scm/subversion.rb', line 80

def can_create_central?
  local? && !path.nil? && !(path == "")
end

#central_exists?Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rscm/scm/subversion.rb', line 92

def central_exists?
  if(local?)
    File.exists?("#{svnrootdir}/db")
  else
    # Do a simple command over the network
    # If the repo/path doesn't exist, we'll get zero output
    # on stdout (and an error msg on std err).
    exists = false
    cmd = "svn log #{url} -r HEAD"
    execute(cmd) do |stdout|
      stdout.each_line do |line|
        exists = true
      end
    end
    exists
  end
end

#checked_out?Boolean

Returns:

  • (Boolean)


185
186
187
188
189
# File 'lib/rscm/scm/subversion.rb', line 185

def checked_out?
  rootentries = File.expand_path("#{checkout_dir}/.svn/entries")
  result = File.exists?(rootentries)
  result
end

#commit(message, options = {}) ⇒ Object



56
57
58
59
60
# File 'lib/rscm/scm/subversion.rb', line 56

def commit(message, options={})
  svn(commit_command(message), options)
  # We have to do an update to get the local revision right
  svn("update", options)
end

#create_central(options = {}) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rscm/scm/subversion.rb', line 121

def create_central(options={})
  options = options.dup.merge({:dir => svnrootdir})
  native_path = PathConverter.filepath_to_nativepath(svnrootdir, false)
  mkdir_p(PathConverter.nativepath_to_filepath(native_path))
  svnadmin("create #{native_path}", options)
  if(@path && @path != "")
    options = options.dup.merge({:dir => "."})
    # create the directories
    paths = @path.split("/")
    paths.each_with_index do |p,i|
      p = paths[0..i]
      u = "#{repourl}/#{p.join('/')}"
      svn("mkdir #{u} -m \"Adding directories\"", options)
    end
  end
end

#destroy_centralObject



84
85
86
87
88
89
90
# File 'lib/rscm/scm/subversion.rb', line 84

def destroy_central
  if(File.exist?(svnrootdir) && local?)
    FileUtils.rm_rf(svnrootdir)
  else
    raise "Cannot destroy central repository. '#{svnrootdir}' doesn't exist or central repo isn't local to this machine"
  end
end

#diff(file, options = {}, &block) ⇒ Object



66
67
68
69
70
71
# File 'lib/rscm/scm/subversion.rb', line 66

def diff(file, options={}, &block)
  cmd = "svn diff --revision #{file.previous_native_revision_identifier}:#{file.native_revision_identifier} \"#{url}/#{file.path}\""
  execute(cmd, options) do |io|
    return(yield(io))
  end
end

#import_central(options) ⇒ Object



156
157
158
159
# File 'lib/rscm/scm/subversion.rb', line 156

def import_central(options)
  import_cmd = "import #{url} -m \"#{options[:message]}\""
  svn(import_cmd, options)
end

#install_trigger(trigger_command, trigger_files_checkout_dir, options = {}) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/rscm/scm/subversion.rb', line 138

def install_trigger(trigger_command, trigger_files_checkout_dir, options={})
  if (WINDOWS)
    install_win_trigger(trigger_command, trigger_files_checkout_dir, options)
  else
    install_unix_trigger(trigger_command, trigger_files_checkout_dir, options)
  end
end

#labelObject



62
63
64
# File 'lib/rscm/scm/subversion.rb', line 62

def label
  local_revision_identifier.to_s
end

#move(relative_src, relative_dest, options = {}) ⇒ Object



39
40
41
# File 'lib/rscm/scm/subversion.rb', line 39

def move(relative_src, relative_dest, options={})
  svn("mv #{relative_src} #{relative_dest}", options)
end

#open(revision_file, options, &block) ⇒ Object



73
74
75
76
77
78
# File 'lib/rscm/scm/subversion.rb', line 73

def open(revision_file, options, &block)
  cmd = "svn cat #{url}/#{revision_file.path}@#{revision_file.native_revision_identifier}"
  execute(cmd, options) do |io|
    return(yield(io))
  end
end

#repourlObject

url pointing to the root of the repo



180
181
182
183
# File 'lib/rscm/scm/subversion.rb', line 180

def repourl
  last = (path.nil? || path == "") ? -1 : -(path.length)-2
  url[0..last]
end

#revisions(from_identifier, options = {}) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/rscm/scm/subversion.rb', line 161

def revisions(from_identifier, options={})
  options = {
    :from_identifier => from_identifier,
    :to_identifier => Time.infinity, 
    :relative_path => "",
    :dir => Dir.pwd
  }.merge(options)
  
  checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
  revisions = nil
  command = "svn #{changes_command(options[:from_identifier], options[:to_identifier], options[:relative_path])}"
  execute(command, options) do |stdout|
    parser = SubversionLogParser.new(stdout, @url, options[:from_identifier], @path)
    revisions = parser.parse_revisions
  end
  revisions
end

#supports_trigger?Boolean

Returns:

  • (Boolean)


110
111
112
113
114
115
# File 'lib/rscm/scm/subversion.rb', line 110

def supports_trigger?
  true
  # we'll assume it supports trigger even if not local. this is to ensure user interfaces
  # can display appropriate options, even if the object is not 'fully initialised'
  # local?
end

#to_identifier(raw_identifier) ⇒ Object



31
32
33
# File 'lib/rscm/scm/subversion.rb', line 31

def to_identifier(raw_identifier)
  raw_identifier.to_i
end

#transactional?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/rscm/scm/subversion.rb', line 43

def transactional?
  true
end

#trigger_installed?(trigger_command, trigger_files_checkout_dir, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


150
151
152
153
154
# File 'lib/rscm/scm/subversion.rb', line 150

def trigger_installed?(trigger_command, trigger_files_checkout_dir, options={})
  return false unless File.exist?(post_commit_file)
  not_already_commented = LineEditor.comment_out(File.new(post_commit_file), /#{Regexp.escape(trigger_command)}/, "# ", "")
  not_already_commented
end

#trigger_mechanismObject



117
118
119
# File 'lib/rscm/scm/subversion.rb', line 117

def trigger_mechanism
  "hooks/post-commit"
end

#uninstall_trigger(trigger_command, trigger_files_checkout_dir, options = {}) ⇒ Object



146
147
148
# File 'lib/rscm/scm/subversion.rb', line 146

def uninstall_trigger(trigger_command, trigger_files_checkout_dir, options={})
  File.comment_out(post_commit_file, /#{Regexp.escape(trigger_command)}/, nil)
end

#uptodate?(identifier, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
# File 'lib/rscm/scm/subversion.rb', line 47

def uptodate?(identifier, options={})
  if(!checked_out?)
    false
  else
    rev = identifier.nil? ? head_revision_identifier(options) : identifier 
    local_revision_identifier(options) == rev
  end
end