Merge remote-tracking branch 'puppetlabs/master'
[puppet_vcsrepo.git] / lib / puppet / type / vcsrepo.rb
1 require 'pathname'
2
3 Puppet::Type.newtype(:vcsrepo) do
4   desc "A local version control repository"
5
6   feature :gzip_compression,
7           "The provider supports explicit GZip compression levels"
8   feature :basic_auth,
9           "The provider supports HTTP Basic Authentication"
10   feature :bare_repositories,
11           "The provider differentiates between bare repositories
12           and those with working copies",
13           :methods => [:bare_exists?, :working_copy_exists?]
14
15   feature :filesystem_types,
16           "The provider supports different filesystem types"
17
18   feature :reference_tracking,
19           "The provider supports tracking revision references that can change
20            over time (eg, some VCS tags and branch names)"
21
22   feature :ssh_identity,
23           "The provider supports a configurable SSH identity file"
24
25   feature :user,
26           "The provider can run as a different user"
27
28   feature :modules,
29           "The repository contains modules that can be chosen of"
30
31   feature :multiple_remotes,
32           "The repository tracks multiple remote repositories"
33
34   feature :configuration,
35           "The configuration directory to use"
36
37   feature :cvs_rsh,
38           "The provider understands the CVS_RSH environment variable"
39
40   feature :depth,
41           "The provider can do shallow clones or set scope limit"
42
43   feature :branch,
44           "The name of the branch"
45
46   feature :p4config,
47           "The provider understands Perforce Configuration"
48
49   feature :submodules,
50           "The repository contains submodules which can be optionally initialized"
51
52   feature :conflict,
53           "The provider supports automatic conflict resolution"
54
55   ensurable do
56     attr_accessor :latest
57
58     def insync?(is)
59       @should ||= []
60
61       case should
62       when :present
63         return true unless [:absent, :purged, :held].include?(is)
64       when :latest
65         if is == :latest
66           return true
67         else
68           return false
69         end
70       when :bare
71         return is == :bare
72       when :mirror
73         return is == :mirror
74       when :absent
75         return is == :absent
76       end
77     end
78
79     newvalue :present do
80       notice "Creating repository from present"
81       provider.create
82     end
83
84     newvalue :bare, :required_features => [:bare_repositories] do
85       if !provider.exists?
86         provider.create
87       end
88     end
89
90     newvalue :mirror, :required_features => [:bare_repositories] do
91       if !provider.exists?
92         provider.create
93       end
94     end
95
96     newvalue :absent do
97       provider.destroy
98     end
99
100     newvalue :latest, :required_features => [:reference_tracking] do
101       if provider.exists? && !@resource.value(:force)
102         if provider.respond_to?(:update_references)
103           provider.update_references
104         end
105         if provider.respond_to?(:latest?)
106             reference = provider.latest || provider.revision
107         else
108           reference = resource.value(:revision) || provider.revision
109         end
110         notice "Updating to latest '#{reference}' revision"
111         provider.revision = reference
112       else
113         notice "Creating repository from latest"
114         provider.create
115       end
116     end
117
118     def retrieve
119       prov = @resource.provider
120       if prov
121         if prov.working_copy_exists?
122           (@should.include?(:latest) && prov.latest?) ? :latest : :present
123         elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
124           :bare
125         else
126           :absent
127         end
128       else
129         raise Puppet::Error, "Could not find provider"
130       end
131     end
132
133   end
134
135   newparam :path do
136     desc "Absolute path to repository"
137     isnamevar
138     validate do |value|
139       path = Pathname.new(value)
140       unless path.absolute?
141         raise ArgumentError, "Path must be absolute: #{path}"
142       end
143     end
144   end
145
146   newparam :source do
147     desc "The source URI for the repository"
148   end
149
150   newparam :fstype, :required_features => [:filesystem_types] do
151     desc "Filesystem type"
152   end
153
154   newproperty :revision do
155     desc "The revision of the repository"
156     newvalue(/^\S+$/)
157   end
158
159   newparam :owner do
160     desc "The user/uid that owns the repository files"
161   end
162
163   newparam :group do
164     desc "The group/gid that owns the repository files"
165   end
166
167   newparam :user do
168     desc "The user to run for repository operations"
169   end
170
171   newparam :excludes do
172     desc "Files to be excluded from the repository"
173   end
174
175   newparam :force do
176     desc "Force repository creation, destroying any files on the path in the process."
177     newvalues(:true, :false)
178     defaultto false
179   end
180
181   newparam :compression, :required_features => [:gzip_compression] do
182     desc "Compression level"
183     validate do |amount|
184       unless Integer(amount).between?(0, 6)
185         raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
186       end
187     end
188   end
189
190   newparam :basic_auth_username, :required_features => [:basic_auth] do
191     desc "HTTP Basic Auth username"
192   end
193
194   newparam :basic_auth_password, :required_features => [:basic_auth] do
195     desc "HTTP Basic Auth password"
196   end
197
198   newparam :identity, :required_features => [:ssh_identity] do
199     desc "SSH identity file"
200   end
201
202   newparam :module, :required_features => [:modules] do
203     desc "The repository module to manage"
204   end
205
206   newparam :remote, :required_features => [:multiple_remotes] do
207     desc "The remote repository to track"
208     defaultto "origin"
209   end
210
211   newparam :configuration, :required_features => [:configuration]  do
212     desc "The configuration directory to use"
213   end
214
215   newparam :cvs_rsh, :required_features => [:cvs_rsh] do
216     desc "The value to be used for the CVS_RSH environment variable."
217   end
218
219   newparam :depth, :required_features => [:depth] do
220     desc "The value to be used to do a shallow clone."
221   end
222
223   newparam :branch, :required_features => [:branch] do
224     desc "The name of the branch to clone."
225   end
226
227   newparam :p4config, :required_features => [:p4config] do
228     desc "The Perforce P4CONFIG environment."
229   end
230
231   newparam :submodules, :required_features => [:submodules] do
232     desc "Initialize and update each submodule in the repository."
233     newvalues(:true, :false)
234     defaultto true
235   end
236
237   newparam :conflict do
238     desc "The action to take if conflicts exist between repository and working copy"
239   end
240
241   newparam :trust_server_cert do
242     desc "Trust server certificate"
243     newvalues(:true, :false)
244     defaultto :false
245   end
246
247   autorequire(:package) do
248     ['git', 'git-core', 'mercurial']
249   end
250 end