MODULES-1596 - Repository repeatedly destroyed/created with force
[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"
42
43   feature :p4config,
44           "The provider understands Perforce Configuration"
45
46   ensurable do
47     attr_accessor :latest
48
49     def insync?(is)
50       @should ||= []
51
52       case should
53       when :present
54         return true unless [:absent, :purged, :held].include?(is)
55       when :latest
56         if is == :latest
57           return true
58         else
59           return false
60         end
61       when :bare
62         return is == :bare
63       end
64     end
65
66     newvalue :present do
67       notice "Creating repository from present"
68       provider.create
69     end
70
71     newvalue :bare, :required_features => [:bare_repositories] do
72       if !provider.exists?
73         provider.create
74       end
75     end
76
77     newvalue :absent do
78       provider.destroy
79     end
80
81     newvalue :latest, :required_features => [:reference_tracking] do
82       if provider.exists? && !@resource.value(:force)
83         if provider.respond_to?(:update_references)
84           provider.update_references
85         end
86         if provider.respond_to?(:latest?)
87             reference = provider.latest || provider.revision
88         else
89           reference = resource.value(:revision) || provider.revision
90         end
91         notice "Updating to latest '#{reference}' revision"
92         provider.revision = reference
93       else
94         notice "Creating repository from latest"
95         provider.create
96       end
97     end
98
99     def retrieve
100       prov = @resource.provider
101       if prov
102         if prov.working_copy_exists?
103           (@should.include?(:latest) && prov.latest?) ? :latest : :present
104         elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
105           :bare
106         else
107           :absent
108         end
109       else
110         raise Puppet::Error, "Could not find provider"
111       end
112     end
113
114   end
115
116   newparam :path do
117     desc "Absolute path to repository"
118     isnamevar
119     validate do |value|
120       path = Pathname.new(value)
121       unless path.absolute?
122         raise ArgumentError, "Path must be absolute: #{path}"
123       end
124     end
125   end
126
127   newparam :source do
128     desc "The source URI for the repository"
129   end
130
131   newparam :fstype, :required_features => [:filesystem_types] do
132     desc "Filesystem type"
133   end
134
135   newproperty :revision do
136     desc "The revision of the repository"
137     newvalue(/^\S+$/)
138   end
139
140   newparam :owner do
141     desc "The user/uid that owns the repository files"
142   end
143
144   newparam :group do
145     desc "The group/gid that owns the repository files"
146   end
147
148   newparam :user do
149     desc "The user to run for repository operations"
150   end
151
152   newparam :excludes do
153     desc "Files to be excluded from the repository"
154   end
155
156   newparam :force do
157     desc "Force repository creation, destroying any files on the path in the process."
158     newvalues(:true, :false)
159     defaultto false
160   end
161
162   newparam :compression, :required_features => [:gzip_compression] do
163     desc "Compression level"
164     validate do |amount|
165       unless Integer(amount).between?(0, 6)
166         raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
167       end
168     end
169   end
170
171   newparam :basic_auth_username, :required_features => [:basic_auth] do
172     desc "HTTP Basic Auth username"
173   end
174
175   newparam :basic_auth_password, :required_features => [:basic_auth] do
176     desc "HTTP Basic Auth password"
177   end
178
179   newparam :identity, :required_features => [:ssh_identity] do
180     desc "SSH identity file"
181   end
182
183   newparam :module, :required_features => [:modules] do
184     desc "The repository module to manage"
185   end
186
187   newparam :remote, :required_features => [:multiple_remotes] do
188     desc "The remote repository to track"
189     defaultto "origin"
190   end
191
192   newparam :configuration, :required_features => [:configuration]  do
193     desc "The configuration directory to use"
194   end
195
196   newparam :cvs_rsh, :required_features => [:cvs_rsh] do
197     desc "The value to be used for the CVS_RSH environment variable."
198   end
199
200   newparam :depth, :required_features => [:depth] do
201     desc "The value to be used to do a shallow clone."
202   end
203
204   newparam :p4config, :required_features => [:p4config] do
205     desc "The Perforce P4CONFIG environment."
206   end
207
208   autorequire(:package) do
209     ['git', 'git-core']
210   end
211 end