Class: Perforce2Svn::Subversion::SvnRepo

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/perforce2svn/subversion/svn_repo.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

configure, log, #log

Constructor Details

#initialize(repository_path) ⇒ SvnRepo

Initializes a repository at a given path. IF that repository does not exist, it creates one.

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 17

def initialize(repository_path)
  raise ArgumentError, "No path given" if repository_path.nil?

  @repository_path = repository_path

  unless File.directory? repository_path
    fs_config = {
      Svn::Fs::CONFIG_FS_TYPE => Svn::Fs::TYPE_FSFS
    }
    Svn::Repos.create(@repository_path, {}, fs_config)
  end
end

Instance Attribute Details

#repository_pathObject (readonly)

Returns the value of attribute repository_path.



13
14
15
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 13

def repository_path
  @repository_path
end

Instance Method Details

#children(path, revision = nil) ⇒ Object



128
129
130
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 128

def children(path, revision = nil)
  repository.fs.root(revision).dir_entries(path).keys
end

#clean_transactions!Object

Occasionally, we may interrupt a transaction in process. In that case, we should make sure to clean up after we are done.



87
88
89
90
91
92
93
94
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 87

def clean_transactions!
  `svnadmin lstxns #{@repository_path}`.each do |txn|
    `svnadmin rmtxns #{@repository_path} #{txn}`
    if $? != 0
      log.error "Unable to clean transaction: #{txn}"
    end
  end
end

#commit_log(revision) ⇒ Object

Retrieve the commit log for a given revision number



115
116
117
118
119
120
121
122
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 115

def commit_log(revision)
  author = repository.prop(Svn::Core::PROP_REVISION_AUTHOR, revision)
  date = repository.prop(Svn::Core::PROP_REVISION_DATE, revision)
  commit_log = repository.prop(Svn::Core::PROP_REVISION_LOG, revision)
  timestamp = Time.parse_svn_format(date)
    
  SvnCommitInfo.new(revision, author, timestamp, commit_log)
end

#delete!Object

Deletes a repository



78
79
80
81
82
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 78

def delete!
  if File.exists? @repository_path
    FileUtils.rm_rf @repository_path
  end
end

#exists?(path, revision = nil) ⇒ Boolean

Checks that a path exists at a revision

Returns:

  • (Boolean)


110
111
112
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 110

def exists?(path, revision = nil)
  repository.fs.root(revision).check_path(path) != 0
end

#prop_get(path, prop_name, revision = nil) ⇒ Object



124
125
126
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 124

def prop_get(path, prop_name, revision = nil)
  repository.fs.root(revision).node_prop(path, prop_name)
end

#pull_contents(file_path, revision = nil) ⇒ Object

Retrieves the current contents of the file in the SVN repository at the given path. You can optionally supply the revision number

Raises a Svn::Error::FsNotFound if the specific file path cannot be found.

Raises a Svn::Error::FsNoSuchRevision if the revision cannot be found.



105
106
107
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 105

def pull_contents(file_path, revision = nil)
  repository.fs.root(revision).file_contents(file_path){|f| f.read}
end

#transaction(author, time, log_message, &block) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/perforce2svn/subversion/svn_repo.rb', line 30

def transaction(author, time, log_message, &block)
  if not block_given?
    raise Perforce2Svn::SvnTransactionError, "Transactions must be block-scoped"
  end

  if author.nil? or author == '' or time.nil?
    raise "The author or time was empty"
  end

  props = {
    Svn::Core::PROP_REVISION_AUTHOR => author,
    Svn::Core::PROP_REVISION_DATE => time.to_svn_format,
    Svn::Core::PROP_REVISION_LOG => sanitize(log_message)
  }

  begin
    # Yield the transaction
    txn = repository.transaction_for_commit(props)
    svn_txn = SvnTransaction.new(txn, repository.fs.root)
    yield svn_txn
    # Finalize the transaction
    svn_txn.send(:finalize!)

    if not repository.fs.transactions.include?(txn.name)
      log.fatal "Unable to commit the transaction to the repository (#{txn.name}): #{author} #{time}"
      raise Perforce2Svn::SvnTransactionError, "Transaction doesn't exist in repository."
    end

    svn_revision = repository.commit(txn)
    # It doesn't look like the 'svn:date' 
    # property gets set correctly during
    # a commit, so we need to update it now
    repository.set_prop(author, # Person authorizing change
                        Svn::Core::PROP_REVISION_DATE, # Property to modify
                        time.to_svn_format, # value
                        svn_revision,   # revision
                        nil,            # callbacks
                        false,          # run pre-commit hooks
                        false)          # run post-commit hooks
    log.info("Committed Subversion revision: #{svn_revision}")
    return svn_revision
  rescue Exception => e
    clean_transactions!
    raise
  end
end