Class: Capistrano::Deploy::SCM::Accurev

Inherits:
Base
  • Object
show all
Includes:
REXML
Defined in:
lib/capistrano/recipes/deploy/scm/accurev.rb

Overview

Accurev bridge for use by Capistrano. This implementation does not implement all features of a Capistrano SCM module. The ones that are left out are either exceedingly difficult to implement with Accurev or are considered bad form.

When using this module in a project, the following variables are used:

* :repository - This should match the depot that code lives in. If your code
                exists in a subdirectory, you can append the path depot.
                eg. foo-depot/bar_dir
* :stream - The stream in the depot that code should be pulled from. If
            left blank, the depot stream will be used
* :revision - Should be in the form 'stream/transaction'.

Defined Under Namespace

Classes: InternalRevision

Instance Attribute Summary

Attributes inherited from Base

#configuration

Instance Method Summary collapse

Methods inherited from Base

#checkout, #command, default_command, #handle_data, #initialize, #local, #local?, #next_revision, #scm, #sync

Constructor Details

This class inherits a constructor from Capistrano::Deploy::SCM::Base

Instance Method Details

#diff(from, to = head) ⇒ Object

Returns the command needed to show the diff between what is deployed and what is pending. Because Accurev can not do this task without creating some streams, two time basis streams will be created for the purposes of doing the diff.



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/capistrano/recipes/deploy/scm/accurev.rb', line 95

def diff(from, to=head)
  from = InternalRevision.parse(from)
  to = InternalRevision.parse(to)

  from_stream = "#{from.stream}-capistrano-diff-from"
  to_stream = "#{to.stream}-capistrano-diff-to"

  [
    change_or_create_stream(from_stream, from),
    change_or_create_stream(to_stream, to),
    scm(:diff, '-v', from_stream, '-V', to_stream, '-a')
  ].join(' && ')
end

#export(revision_id, destination) ⇒ Object

Pops a copy of the code for the specified Accurev revision identifier. The revision identifier is represented as a stream & transaction ID combo. Accurev can only pop a particular transaction if a stream is created on the server with a time basis of that transaction id. Therefore, we will create a stream with the required criteria and pop that.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/capistrano/recipes/deploy/scm/accurev.rb', line 62

def export(revision_id, destination)
  revision = InternalRevision.parse(revision_id)
  logger.debug("Exporting #{revision.stream}/#{revision.transaction_id} to #{destination}")

  commands = [
    change_or_create_stream("#{revision.stream}-capistrano-deploy", revision),
    "mkdir -p #{destination}",
    scm_quiet(:pop, "-Rv #{stream}", "-L #{destination}", "'/./#{subdir}'")
  ]
  if subdir
    commands.push(
      "mv #{destination}/#{subdir}/* #{destination}",
      "rm -rf #{File.join(destination, subdir)}"
    )
  end
  commands.join(' && ')
end

#headObject

Defines pseudo-revision value for the most recent changes to be deployed.



25
26
27
# File 'lib/capistrano/recipes/deploy/scm/accurev.rb', line 25

def head
  "#{stream}/highest"
end

#log(from, to = head) ⇒ Object

Returns the command needed to show the changes that exist between the two revisions.



81
82
83
84
85
86
87
88
89
90
# File 'lib/capistrano/recipes/deploy/scm/accurev.rb', line 81

def log(from, to=head)
  logger.info("Getting transactions between #{from} and #{to}")
  from_rev = InternalRevision.parse(from)
  to_rev = InternalRevision.parse(to)

  [
    scm(:hist, '-s', from_rev.stream, '-t', "#{to_rev.transaction_id}-#{from_rev.transaction_id}"),
    "sed -e '/transaction #{from_rev.transaction_id}/ { Q }'"
  ].join(' | ')
end

#query_revision(revision) ⇒ Object

Given an Accurev revision identifier, this method returns an identifier that can be used for later SCM calls. This returned identifier will not change as a result of further SCM activity.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/capistrano/recipes/deploy/scm/accurev.rb', line 32

def query_revision(revision)
  internal_revision = InternalRevision.parse(revision)
  return revision unless internal_revision.psuedo_revision?

  logger.debug("Querying for real revision for #{internal_revision}")
  rev_stream = internal_revision.stream

  logger.debug("Determining what type of stream #{rev_stream} is...")
  stream_xml = yield show_streams_for(rev_stream)
  stream_doc = Document.new(stream_xml)
  type = XPath.first(stream_doc, '//streams/stream/@type').value

  case type
  when 'snapshot'
    InternalRevision.new(rev_stream, 'highest').to_s
  else
    logger.debug("Getting latest transaction id in #{rev_stream}")
    # Doing another yield for a second Accurev call. Hopefully this is ok.
    hist_xml = yield scm(:hist, '-ftx', '-s', rev_stream, '-t', 'now.1')
    hist_doc = Document.new(hist_xml)
    transaction_id = XPath.first(hist_doc, '//AcResponse/transaction/@id').value
    InternalRevision.new(stream, transaction_id).to_s
  end
end