Bring stderr output to the Puppet visible output
[puppet_vcsrepo.git] / lib / puppet / provider / vcsrepo / cvs.rb
1 require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
2
3 Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do
4   desc "Supports CVS repositories/workspaces"
5
6   commands :cvs => 'cvs'
7   has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user
8
9   def create
10     if !@resource.value(:source)
11       create_repository(@resource.value(:path))
12     else
13       checkout_repository
14     end
15     update_owner
16   end
17
18   def exists?
19     if @resource.value(:source)
20       directory = File.join(@resource.value(:path), 'CVS')
21     else
22       directory = File.join(@resource.value(:path), 'CVSROOT')
23     end
24     File.directory?(directory)
25   end
26
27   def working_copy_exists?
28     File.directory?(File.join(@resource.value(:path), 'CVS'))
29   end
30
31   def destroy
32     FileUtils.rm_rf(@resource.value(:path))
33   end
34
35   def latest?
36     Puppet.debug "Checking for updates because 'ensure => latest'"
37     at_path do
38       # We cannot use -P to prune empty dirs, otherwise
39       # CVS would report those as "missing", regardless
40       # if they have contents or updates.
41       is_current = (runcvs('-nq', 'update', '-d').strip == "")
42       if (!is_current) then Puppet.debug "There are updates available on the checkout's current branch/tag." end
43       return is_current
44     end
45   end
46
47   def latest
48     # CVS does not have a conecpt like commit-IDs or change
49     # sets, so we can only have the current branch name (or the
50     # requested one, if that differs) as the "latest" revision.
51     should = @resource.value(:revision)
52     current = self.revision
53     return should != current ? should : current
54   end
55
56   def revision
57     if !@rev
58       if File.exist?(tag_file)
59         contents = File.read(tag_file).strip
60         # Note: Doesn't differentiate between N and T entries
61         @rev = contents[1..-1]
62       else
63         @rev = 'HEAD'
64       end
65       Puppet.debug "Checkout is on branch/tag '#{@rev}'"
66     end
67     return @rev
68   end
69
70   def revision=(desired)
71     at_path do
72       runcvs('update', '-dr', desired, '.')
73       update_owner
74       @rev = desired
75     end
76   end
77
78   private
79
80   def tag_file
81     File.join(@resource.value(:path), 'CVS', 'Tag')
82   end
83
84   def checkout_repository
85     dirname, basename = File.split(@resource.value(:path))
86     Dir.chdir(dirname) do
87       args = ['-d', @resource.value(:source)]
88       if @resource.value(:compression)
89         args.push('-z', @resource.value(:compression))
90       end
91       args.push('checkout')
92       if @resource.value(:revision)
93         args.push('-r', @resource.value(:revision))
94       end
95       args.push('-d', basename, module_name)
96       runcvs(*args)
97     end
98   end
99
100   # When the source:
101   # * Starts with ':' (eg, :pserver:...)
102   def module_name
103     if (m = @resource.value(:module))
104       m
105     elsif (source = @resource.value(:source))
106       source[0, 1] == ':' ? File.basename(source) : '.'
107     end
108   end
109
110   def create_repository(path)
111     runcvs('-d', path, 'init')
112   end
113
114   def update_owner
115     if @resource.value(:owner) or @resource.value(:group)
116       set_ownership
117     end
118   end
119
120   def runcvs(*args)
121     if @resource.value(:cvs_rsh)
122       Puppet.debug "Using CVS_RSH = " + @resource.value(:cvs_rsh)
123       e = { :CVS_RSH => @resource.value(:cvs_rsh) }
124     else
125       e = {}
126     end
127
128     if @resource.value(:user) and @resource.value(:user) != Facter['id'].value
129       Puppet.debug "Running as user " + @resource.value(:user)
130       Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e, :combine => true)
131     else
132       Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e, :combine => true)
133     end
134   end
135 end